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 53 $error=$me->check_ldap();
54 54 if($error==1 && $username) {
55 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 57 $template->assign('LD_CHECK_LDAP','<p style="color:green;">Configuration LDAP OK : '.$username.'</p>');
58 58 } else {
59 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 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 128 // authentication public
134 129 public function ldap_bind_as($user,$user_passwd){
135 130 $this->write_log("[function]> ldap_bind_as");
... ... @@ -152,18 +147,20 @@ class Ldap {
152 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 152 $entry = @ldap_get_entries($this->cnx, $sr);
160 153  
161 154 if (!empty($entry[0]['mail'])) {
162 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 164 // return userdn (and username) for authentication
168 165 public function ldap_search_dn($value_to_search){
169 166 $this->write_log("[function]> ldap_search_dn(".$value_to_search.")");
... ... @@ -205,8 +202,9 @@ class Ldap {
205 202 }
206 203  
207 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 208 //if no group specified return true
211 209 if(!$group_dn){
212 210 return true;
... ... @@ -219,22 +217,17 @@ class Ldap {
219 217 $this->write_log("[check_ldap_group_membership]> Cannot bind to server!");
220 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 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 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 232 } else {
240 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 61 $obj->load_config();
62 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 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 73 // search user in piwigo database
... ... @@ -84,24 +87,19 @@ function login($success, $username, $password, $remember_me){
84 87 // this is where we check we are allowed to create new users upon that.
85 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 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 95 log_user($new_id, False);
103 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 103 return true;
106 104 }
107 105 // else : this is the normal behavior ! user is not created.
... ...