Commit 1ccfe953909063552a1b075b7f5215b4df414a8b

Authored by Frederik Lindenaar
1 parent b6323e66

Made groups work on OpenDirectory (Apple's OpenLDAP shipped with OS X Server),

which is like standard POSIX. Existing AD group support should also still work
(but has not been tested as I don't have a working AD setup).

Added support for the group check to the login code (which was still missing)

Improved the user experience by only dumping a newly created user on the profile
page when the e-mail address was missing.
admin/configuration.php
@@ -53,7 +53,7 @@ if (isset($_POST['check_ldap'])){ @@ -53,7 +53,7 @@ if (isset($_POST['check_ldap'])){
53 $error=$me->check_ldap(); 53 $error=$me->check_ldap();
54 if($error==1 && $username) { 54 if($error==1 && $username) {
55 if ($me->ldap_bind_as($username,$_POST['PASSWORD'])){ 55 if ($me->ldap_bind_as($username,$_POST['PASSWORD'])){
56 - if($me->check_ldap_group_membership($username,$me->config['ld_group'])){ 56 + if($me->check_ldap_group_membership($username,$_POST['USERNAME'])){
57 $template->assign('LD_CHECK_LDAP','<p style="color:green;">Configuration LDAP OK : '.$username.'</p>'); 57 $template->assign('LD_CHECK_LDAP','<p style="color:green;">Configuration LDAP OK : '.$username.'</p>');
58 } else { 58 } else {
59 $template->assign('LD_CHECK_LDAP','<p style="color:orange;">Credentials OK, Check GroupMembership for: '.$username.'</p>'); 59 $template->assign('LD_CHECK_LDAP','<p style="color:orange;">Credentials OK, Check GroupMembership for: '.$username.'</p>');
class.ldap.php
@@ -125,11 +125,6 @@ class Ldap { @@ -125,11 +125,6 @@ class Ldap {
125 return ldap_err2str(ldap_errno($this->cnx)); 125 return ldap_err2str(ldap_errno($this->cnx));
126 } 126 }
127 127
128 - // return the name ldap understand  
129 - public function ldap_name($name){  
130 - return $this->config['ld_attr'].'='.$name.','.$this->config['basedn'];  
131 - }  
132 -  
133 // authentication public 128 // authentication public
134 public function ldap_bind_as($user,$user_passwd){ 129 public function ldap_bind_as($user,$user_passwd){
135 $this->write_log("[function]> ldap_bind_as"); 130 $this->write_log("[function]> ldap_bind_as");
@@ -152,18 +147,20 @@ class Ldap { @@ -152,18 +147,20 @@ class Ldap {
152 return false; 147 return false;
153 } 148 }
154 149
155 - public function ldap_mail($name){  
156 - //echo $this->cnx;  
157 - //echo $this->ldap_name($name);  
158 - $sr=@ldap_read($this->cnx, $this->ldap_name($name), "(objectclass=*)", array('mail')); 150 + public function ldap_get_email($user_dn){
  151 + $sr=@ldap_read($this->cnx, $user_dn, "(objectclass=*)", array('mail'));
159 $entry = @ldap_get_entries($this->cnx, $sr); 152 $entry = @ldap_get_entries($this->cnx, $sr);
160 153
161 if (!empty($entry[0]['mail'])) { 154 if (!empty($entry[0]['mail'])) {
162 return $entry[0]['mail'][0]; 155 return $entry[0]['mail'][0];
163 - }  
164 - return False; 156 + }
  157 + return null;
165 } 158 }
166 159
  160 + public function ldap_get_user_email($username) {
  161 + return $this->ldap_email($this->ldap_get_dn($username));
  162 + }
  163 +
167 // return userdn (and username) for authentication 164 // return userdn (and username) for authentication
168 public function ldap_search_dn($value_to_search){ 165 public function ldap_search_dn($value_to_search){
169 $this->write_log("[function]> ldap_search_dn(".$value_to_search.")"); 166 $this->write_log("[function]> ldap_search_dn(".$value_to_search.")");
@@ -205,8 +202,9 @@ class Ldap { @@ -205,8 +202,9 @@ class Ldap {
205 } 202 }
206 203
207 // look for LDAP group membership 204 // look for LDAP group membership
208 - public function check_ldap_group_membership($user_dn,$group_dn){  
209 - $this->write_log("[function]> check_ldap_group_membership(".$user_dn." , ".$group_dn.")"); 205 + public function check_ldap_group_membership($user_dn, $user_login){
  206 + $group_dn = $this->config['ld_group'];
  207 + $this->write_log("[function]> check_ldap_group_membership('$user_dn', '$group_dn', '$user_login')");
210 //if no group specified return true 208 //if no group specified return true
211 if(!$group_dn){ 209 if(!$group_dn){
212 return true; 210 return true;
@@ -219,22 +217,17 @@ class Ldap { @@ -219,22 +217,17 @@ class Ldap {
219 $this->write_log("[check_ldap_group_membership]> Cannot bind to server!"); 217 $this->write_log("[check_ldap_group_membership]> Cannot bind to server!");
220 return false; 218 return false;
221 } 219 }
222 - // search for all memberOf-attributes for a given user_dn  
223 - $this->write_log("[check_ldap_group_membership]> @ldap_search(\$this->cnx,\"".$user_dn."\",\"(objectClass=*)\", array(\"memberOf\"),0,1)");  
224 - if($search = @ldap_search($this->cnx, $user_dn, "(objectClass=*)", array("memberOf"),0,1)){ 220 + // search for all member and memberUid attributes for a group_dn
  221 + $search_filter = "(|(&(objectClass=posixGroup)(memberUid=$user_login))(&(objectClass=group)(member=$user_dn)))";
  222 + $this->write_log("[check_ldap_group_membership]> @ldap_search(\$this->cnx,'$group_dn', '$search_filter', array('memberOf'),0,1)");
  223 + if($search = @ldap_search($this->cnx, $group_dn, $search_filter, array("dn"),0,1)){
225 $entry = @ldap_get_entries($this->cnx, $search); 224 $entry = @ldap_get_entries($this->cnx, $search);
226 - //check if there are memberof-attributes  
227 - if(isset($entry[0]["memberof"])){  
228 - $this->write_log("[check_ldap_group_membership]> Found ". $entry[0]["memberof"]["count"] ." memberOf-attributes");  
229 - for($i=0; $i < $entry["0"]["memberof"]["count"]; $i++){  
230 - $this->write_log("[check_ldap_group_membership]> checking: ". $entry["0"]["memberof"][$i]);  
231 - if(strcmp($group_dn,$entry["0"]["memberof"][$i]) == 0){  
232 - $this->write_log("[check_ldap_group_membership]> Match found for \"". $group_dn ."\" AND \"".$entry["0"]["memberof"][$i]."\"");  
233 - return true;  
234 - }  
235 - } 225 + //check if there are dn-attributes
  226 + if (!empty($entry[0]["dn"])) {
  227 + $this->write_log("[check_ldap_group_membership]> match found: ".$entry[0]["dn"]);
  228 + return true;
236 } else { 229 } else {
237 - $this->write_log("[check_ldap_group_membership]> No groups found for given user, check on ldap side"); 230 + $this->write_log("[check_ldap_group_membership]> no group membership for user found for given group and user, check on ldap side");
238 } 231 }
239 } else { 232 } else {
240 $this->write_log("[check_ldap_group_membership]> ldap_search NOT successfull: " .$this->getErrorString()); 233 $this->write_log("[check_ldap_group_membership]> ldap_search NOT successfull: " .$this->getErrorString());
main.inc.php
@@ -61,10 +61,13 @@ function login($success, $username, $password, $remember_me){ @@ -61,10 +61,13 @@ function login($success, $username, $password, $remember_me){
61 $obj->load_config(); 61 $obj->load_config();
62 $obj->ldap_conn() or die("Unable to connect LDAP server : ".$ldap->getErrorString()); 62 $obj->ldap_conn() or die("Unable to connect LDAP server : ".$ldap->getErrorString());
63 63
64 - //if (!$obj->ldap_bind_as($username,$password)){ // bind with userdn  
65 - if (!$obj->ldap_search_dn($username) || !$obj->ldap_bind_as($obj->ldap_search_dn($username),$password)){ // bind with userdn 64 + $user_dn = $obj->ldap_search_dn($username); // retrieve the userdn
  65 +
  66 + // If we have userdn, attempt to login an check user's group access
  67 + if (!($user_dn && !$obj->ldap_bind_as($user_dn,$password) &&
  68 + check_ldap_group_membership($user_dn, $username))) {
66 trigger_notify('login_failure', stripslashes($username)); 69 trigger_notify('login_failure', stripslashes($username));
67 - return false; // wrong password 70 + return false; // wrong user/password or no group access
68 } 71 }
69 72
70 // search user in piwigo database 73 // search user in piwigo database
@@ -84,24 +87,19 @@ function login($success, $username, $password, $remember_me){ @@ -84,24 +87,19 @@ function login($success, $username, $password, $remember_me){
84 // this is where we check we are allowed to create new users upon that. 87 // this is where we check we are allowed to create new users upon that.
85 if ($obj->config['allow_newusers']) { 88 if ($obj->config['allow_newusers']) {
86 89
87 - // we got the email address  
88 - if ($obj->ldap_mail($username)) {  
89 - $mail = $obj->ldap_mail($username);  
90 - }  
91 - else {  
92 - $mail = NULL;  
93 - }  
94 -  
95 - // we actually register the new user 90 + // retrieve LDAP e-mail address and create a new user
  91 + $mail = $obj->ldap_get_email($user_dn);
96 $new_id = register_user($username,random_password(8),$mail); 92 $new_id = register_user($username,random_password(8),$mail);
97 -  
98 - // now we fetch again his id in the piwigo db, and we get them, as we just created him !  
99 - //$query = 'SELECT '.$conf['user_fields']['id'].' AS id FROM '.USERS_TABLE.' WHERE '.$conf['user_fields']['username'].' = \''.pwg_db_real_escape_string($username).'\' ;';  
100 - //$row = pwg_db_fetch_assoc(pwg_query($query));  
101 93
  94 + // Login user
102 log_user($new_id, False); 95 log_user($new_id, False);
103 trigger_notify('login_success', stripslashes($username)); 96 trigger_notify('login_success', stripslashes($username));
104 - redirect('profile.php'); 97 +
  98 + // in case the e-mail address is empty, redirect to profile page
  99 + if($mail==NULL) {
  100 + redirect('profile.php');
  101 + }
  102 +
105 return true; 103 return true;
106 } 104 }
107 // else : this is the normal behavior ! user is not created. 105 // else : this is the normal behavior ! user is not created.