4 * ldap.php - The LDAP library
5 * This is the PostgreSQL version of our database connection/querying layer
7 * SourceForge: Breaking Down the Barriers to Open Source Development
8 * Copyright 1999-2001 (c) VA Linux Systems
9 * http://sourceforge.net
12 * @author Paul Sokolovsky pfalcon@users.sourceforge.net
17 require_once('common/include/account.php');
24 * Value to add to group_id to get unix gid
26 * @var constant $GID_ADD
31 * Value to add to unix_uid to get unix uid
33 * @var constant $UID_ADD
38 * Value to add to unix gid to get unix uid of anoncvs special user
40 * @var constant $ANONCVS_UID_ADD
42 $ANONCVS_UID_ADD = 2000;
49 * asciize() - Replace non-ascii characters with question marks
51 * LDAP expects utf-8 encoded character string. Since we cannot
52 * know which encoding 8-bit characters in database use, we
53 * just replace them with question marks.
55 * @param string UTF-8 encoded character string.
56 * @return string which contains only ascii characters
58 function asciize($str) {
60 // LDAP don't allow empty strings for some attributes
64 return ereg_replace("[\x80-\xff]","?",$str);
68 * Error message passing facility
72 * sf_ldap_set_error_msg() - Set an LDAP error message
74 * @param string The message string to set
77 //var $_sf_ldap_error_msg;
78 function sf_ldap_set_error_msg($msg) {
79 global $_sf_ldap_error_msg;
80 $_sf_ldap_error_msg .= $msg;
84 * sf_ldap_get_error_msg() - Get an LDAP error message
86 * @returns The error message string
89 function sf_ldap_get_error_msg() {
90 global $_sf_ldap_error_msg;
91 return $_sf_ldap_error_msg;
95 * sf_ldap_reset_error_msg() - Reset the stored LDAP error message
98 function sf_ldap_reset_error_msg() {
99 global $_sf_ldap_error_msg;
100 $_sf_ldap_error_msg='';
105 * Wrappers for PHP LDAP functions
109 * sf_ldap_connect() - Connect to the LDAP server
111 * @returns true on success/false on error
114 function sf_ldap_connect() {
115 global $sys_ldap_host,$sys_ldap_port;
116 global $sys_ldap_bind_dn,$sys_ldap_passwd,$ldap_conn;
119 sf_ldap_reset_error_msg();
120 $ldap_conn = @ldap_connect($sys_ldap_host,$sys_ldap_port);
122 sf_ldap_set_error_msg('ERROR: Cannot connect to LDAP server<br>');
125 ldap_bind($ldap_conn,$sys_ldap_bind_dn,$sys_ldap_passwd);
131 * sf_ldap_add() - Wrapper for ldap_add()
134 * @param string entry
137 function sf_ldap_add($dn, $entry) {
139 return @ldap_add($ldap_conn,$dn,$entry);
143 * sf_ldap_delete() - Wrapper for ldap_delete()
148 function sf_ldap_delete($dn) {
150 return @ldap_delete($ldap_conn,$dn);
154 * sf_ldap_modify() - Wrapper for ldap_modify()
157 * @param string entry
160 function sf_ldap_modify($dn,$entry) {
162 return @ldap_modify($ldap_conn,$dn,$entry);
166 * sf_ldap_mod_add() - Wrapper for ldap_mod_add()
169 * @param string entry
172 function sf_ldap_mod_add($dn,$entry) {
174 return @ldap_mod_add($ldap_conn,$dn,$entry);
178 * sf_ldap_mod_del() - Wrapper for ldap_mod_del()
181 * @param string entry
184 function sf_ldap_mod_del($dn,$entry) {
186 return @ldap_mod_del($ldap_conn,$dn,$entry);
190 * sf_ldap_read() - Wrapper for ldap_read()
193 * @param string filter
197 function sf_ldap_read($dn,$filter,$attrs=0) {
199 return @ldap_read($ldap_conn,$dn,$filter,$attrs);
203 * sf_ldap_error() - Wrapper for ldap_error()
208 function sf_ldap_error() {
210 return ldap_error($ldap_conn);
214 * sf_ldap_errno() - Wrapper for ldap_errno()
219 function sf_ldap_errno() {
221 return ldap_errno($ldap_conn);
225 * sf_ldap_already_exists()
227 function sf_ldap_already_exists() {
229 return ldap_errno($ldap_conn)==20;
233 * sf_ldap_does_not_exist()
235 function sf_ldap_does_not_exist() {
237 return ldap_errno($ldap_conn)==16;
241 * User management functions
245 * sf_ldap_check_user() - Check for the existence of a user
247 * @param int The user ID of the user to check
248 * @returns true on success/false on error
251 function sf_ldap_check_user($user_id) {
252 $user =& user_get_object($user_id);
256 return sf_ldap_check_user_by_name($user->getUnixName());
260 * sf_ldap_check_user_by_name() - Check for a user by the username
262 * @param string The username
263 * @returns true on success/false on error
266 function sf_ldap_check_user_by_name($user_name) {
268 global $sys_ldap_base_dn;
270 global $sys_use_ldap;
271 if (!$sys_use_ldap) {
275 if (!sf_ldap_connect()) {
279 $dn = 'uid='.$user_name.',ou=People,'.$sys_ldap_base_dn;
280 $res = sf_ldap_read($dn,"objectClass=*",array("uid"));
282 ldap_free_result($res);
290 * sf_ldap_create_user() - Create a user
292 * @param int The user ID of the user to create
293 * @returns The return status of sf_ldap_create_user_from_object()
296 function sf_ldap_create_user($user_id) {
297 $user = &user_get_object($user_id);
298 return sf_ldap_create_user_from_object($user);
302 * sf_ldap_check_create_user() - Check that a user has been created
304 * @param int The ID of the user to check
305 * @returns true on success/false on error
308 function sf_ldap_check_create_user($user_id) {
309 global $sys_use_ldap;
310 if (!$sys_use_ldap) {
314 if (!sf_ldap_check_user($user_id)){
315 $user = &user_get_object($user_id);
316 return sf_ldap_create_user_from_object($user);
322 * sf_ldap_create_user_from_object() - Create a user from information contained within an object
324 * @param object The user object
325 * @returns true on success/false on error
328 function sf_ldap_create_user_from_object(&$user) {
329 global $sys_ldap_base_dn;
332 global $sys_use_ldap;
333 if (!$sys_use_ldap) {
337 //echo "sf_ldap_create_user_from_object(".$user->getUnixName().")<br>";
338 if (!sf_ldap_connect()) {
341 $dn = 'uid='.$user->getUnixName().',ou=People,'.$sys_ldap_base_dn;
342 $entry['objectClass'][0]='top';
343 $entry['objectClass'][1]='account';
344 $entry['objectClass'][2]='posixAccount';
345 $entry['objectClass'][3]='shadowAccount';
346 $entry['objectClass'][4]='x-sourceforgeAccount';
347 $entry['uid']=$user->getUnixName();
348 $entry['cn']=asciize($user->getRealName());
349 $entry['gecos']=asciize($user->getRealName());
350 $entry['userPassword']='{crypt}'.$user->getUnixPasswd();
351 $entry['homeDirectory'] = account_user_homedir($user->getUnixName());
352 $entry['loginShell']=$user->getShell();
353 $entry['x-cvsShell']="/bin/cvssh"; // unless explicitly set otherwise, developer has write access
354 $entry['uidNumber']=$user->getUnixUID() + $UID_ADD;
355 $entry['gidNumber']=100; // users
356 $entry['shadowLastChange']=1; // We don't have expiration, so any non-0
357 $entry['shadowMax']=99999;
358 $entry['shadowWarning']=7;
360 if (!sf_ldap_add($dn,$entry)) {
361 sf_ldap_set_error_msg("ERROR: cannot add LDAP user entry '".
362 $user->getUnixName()."': ".sf_ldap_error()."<br>");
369 * sf_ldap_create_user_from_props() - Creates an LDAP user from
371 * @param string The username
373 * @param string The encrypted password
374 * @returns true on success/false on error
377 function sf_ldap_create_user_from_props($username, $cn, $crypt_pw,
378 $shell, $cvsshell, $uid, $gid) {
379 global $sys_ldap_base_dn;
381 global $sys_use_ldap;
382 if (!$sys_use_ldap) {
386 if (!sf_ldap_connect()) {
389 $dn = 'uid='.$username.',ou=People,'.$sys_ldap_base_dn;
390 $entry['objectClass'][0]='top';
391 $entry['objectClass'][1]='account';
392 $entry['objectClass'][2]='posixAccount';
393 $entry['objectClass'][3]='shadowAccount';
394 $entry['objectClass'][4]='x-sourceforgeAccount';
395 $entry['uid']=$username;
396 $entry['cn']=asciize($cn);
397 $entry['gecos']=asciize($cn);
398 $entry['userPassword']='{crypt}'.$crypt_pw;
399 $entry['homeDirectory'] = account_user_homedir($username);
400 $entry['loginShell']=$shell;
401 $entry['x-cvsShell']=$cvsshell;
402 $entry['uidNumber']=$uid;
403 $entry['gidNumber']=$gid;
404 $entry['shadowLastChange']=1;
405 $entry['shadowMax']=99999;
406 $entry['shadowWarning']=7;
408 if (!sf_ldap_add($dn,$entry)) {
409 sf_ldap_set_error_msg("ERROR: cannot add LDAP user entry '".
410 $username."': ".sf_ldap_error()."<br>");
417 * sf_ldap_remove_user() - Remove an LDAP user
419 * @param int The user ID of the user to remove
420 * @returns true on success/false on failure
423 function sf_ldap_remove_user($user_id) {
424 global $sys_ldap_base_dn;
426 global $sys_use_ldap;
427 if (!$sys_use_ldap) {
431 $user = &user_get_object($user_id);
432 if (!sf_ldap_connect()) {
435 $dn = 'uid='.$user->getUnixName().',ou=People,'.$sys_ldap_base_dn;
437 if (!sf_ldap_delete($dn)) {
438 sf_ldap_set_error_msg("ERROR: cannot delete LDAP user entry '".
439 $user->getUnixName()."': ".sf_ldap_error()."<br>");
446 * sf_ldap_user_set_attribute() - Set an attribute for a user
448 * @param int The user ID
449 * @param string The attribute to set
450 * @param string The new value of the attribute
451 * @returns true on success/false on error
454 function sf_ldap_user_set_attribute($user_id,$attr,$value) {
455 global $sys_ldap_base_dn;
457 global $sys_use_ldap;
458 if (!$sys_use_ldap) {
462 $user = &user_get_object($user_id);
463 //echo "sf_ldap_user_set_attribute(".$user->getUnixName().",".$attr.",".$value.")<br>";
464 if (!sf_ldap_connect()) {
467 $dn = 'uid='.$user->getUnixName().',ou=People,'.$sys_ldap_base_dn;
468 $entry[$attr]=$value;
470 if (!sf_ldap_modify($dn, $entry)) {
471 sf_ldap_set_error_msg("ERROR: cannot change LDAP attribute '$attr' for user '".
472 $user->getUnixName()."': ".sf_ldap_error()."<br>");
479 * Group management functions
483 * sf_ldap_check_group() - Check for the existence of a group
485 * @param int The ID of the group to check
486 * @returns true on success/false on error
489 function sf_ldap_check_group($group_id) {
491 global $sys_ldap_base_dn;
493 global $sys_use_ldap;
494 if (!$sys_use_ldap) {
498 $group = &group_get_object($group_id);
500 sf_ldap_set_error_msg("ERROR: Cannot find group [$group_id]<br>");
503 if (!sf_ldap_connect()) {
506 $dn = 'cn='.$group->getUnixName().',ou=Group,'.$sys_ldap_base_dn;
507 $res=sf_ldap_read($dn, "objectClass=*", array("cn"));
509 ldap_free_result($res);
516 * sf_ldap_create_group() - Create a group
518 * @param int The ID of the group to create
519 * @returns true on success/false on error
522 function sf_ldap_create_group($group_id) {
523 global $sys_ldap_base_dn;
525 global $ANONCVS_UID_ADD;
527 global $sys_use_ldap;
528 if (!$sys_use_ldap) {
532 $group = &group_get_object($group_id);
533 if (!sf_ldap_connect()) {
536 $dn = 'cn='.$group->getUnixName().',ou=Group,'.$sys_ldap_base_dn;
537 $entry['objectClass'][0]='top';
538 $entry['objectClass'][1]='posixGroup';
539 $entry['cn']=$group->getUnixName();
540 $entry['userPassword']='{crypt}x';
541 $entry['gidNumber']=$group->getID() + $GID_ADD;
547 if (!sf_ldap_add($dn,$entry)) {
548 sf_ldap_set_error_msg("ERROR: cannot add LDAP group entry '".
549 $group->getUnixName()."': ".sf_ldap_error()."<br>");
550 // If there's error, that's bad. But don't stop.
555 // Now create CVS group
558 // Add virtual anoncvs user to CVS group
559 $cvs_member_list[$i_cvs++] = 'anoncvs_'.$group->getUnixName();
561 $dn = 'cn='.$group->getUnixName().',ou=cvsGroup,'.$sys_ldap_base_dn;
563 if ($cvs_member_list) {
564 $entry['memberUid']=$cvs_member_list;
566 unset($entry['memberUid']);
569 if (!sf_ldap_add($dn,$entry)) {
570 sf_ldap_set_error_msg("ERROR: cannot add LDAP CVS group entry '"
571 .$group->getUnixName()."': ".sf_ldap_error()."<br>");
576 // Finally, setup AnonCVS virtual user
579 if (!sf_ldap_check_user_by_name('anoncvs_'.$group->getUnixName())
580 && !sf_ldap_create_user_from_props('anoncvs_'.$group->getUnixName(),
582 '/bin/false', '/bin/false',
583 $group_id+$GID_ADD+$ANONCVS_UID_ADD,
584 $group_id+$GID_ADD)) {
585 sf_ldap_set_error_msg("ERROR: cannot add LDAP AnonCVS user entry '"
586 .$group->getUnixName()."': ".sf_ldap_error()."<br>");
594 * sf_ldap_remove_group() - Remove a group
596 * @param int The ID of the group to remove
597 * @returns true on success/false on error
600 function sf_ldap_remove_group($group_id) {
601 global $sys_ldap_base_dn;
603 global $sys_use_ldap;
604 if (!$sys_use_ldap) {
608 $group = &group_get_object($group_id);
609 if (!sf_ldap_connect()) {
614 // Remove shell LDAP group
618 $dn = 'cn='.$group->getUnixName().',ou=Group,'.$sys_ldap_base_dn;
620 if (!sf_ldap_delete($dn)) {
621 sf_ldap_set_error_msg("ERROR: cannot delete LDAP group entry '".
622 $group->getUnixName()."': ".sf_ldap_error()."<br>");
627 // Remove CVS LDAP group
630 $dn = 'cn='.$group->getUnixName().',ou=cvsGroup,'.$sys_ldap_base_dn;
632 if (!sf_ldap_delete($dn)) {
633 sf_ldap_set_error_msg("ERROR: cannot delete LDAP CVS group entry '".
634 $group->getUnixName()."': ".sf_ldap_error()."<br>");
639 // Remove AnonCVS virtual user
642 $dn = 'uid=anoncvs_'.$group->getUnixName().',ou=People,'.$sys_ldap_base_dn;
643 if (!sf_ldap_delete($dn)) {
644 sf_ldap_set_error_msg("ERROR: cannot delete LDAP AnonCVS user entry '".
645 $group->getUnixName()."': ".sf_ldap_error()."<br>");
653 * sf_ldap_group_add_user() - Add a user to an LDAP group
655 * @param int The ID of the group two which the user will be added
656 * @param int The ID of the user to add
657 * @param bool Only add this user to CVS
658 * @returns true on success/false on error
661 function sf_ldap_group_add_user($group_id,$user_id,$cvs_only=0) {
663 global $sys_ldap_base_dn;
665 global $sys_use_ldap;
666 if (!$sys_use_ldap) {
670 $group = &group_get_object($group_id);
671 $user = &user_get_object($user_id);
672 if (!sf_ldap_connect()) {
675 $dn = 'cn='.$group->getUnixName().',ou=Group,'.$sys_ldap_base_dn;
676 $cvs_dn = 'cn='.$group->getUnixName().',ou=cvsGroup,'.$sys_ldap_base_dn;
677 $entry['memberUid'] = $user->getUnixName();
680 // Check if user already a member of CVS group
683 $res=sf_ldap_read($cvs_dn,"memberUid=".$user->getUnixName(),array("cn"));
684 if ($res && ldap_count_entries($ldap_conn,$res)>0) {
685 //echo "already a member of CVS<br>";
691 if (!sf_ldap_mod_add($cvs_dn,$entry)) {
692 sf_ldap_set_error_msg("ERROR: cannot add member to LDAP CVS group entry '".
693 $group->getUnixName()."': ".sf_ldap_error()."<br>");
698 ldap_free_result($res);
705 // Check if user already a member of shell group
707 $res = sf_ldap_read($dn, "memberUid=".$user->getUnixName(), array("cn"));
709 if ($res && ldap_count_entries($ldap_conn,$res)>0) {
710 //echo "already a member<br>";
716 if (!sf_ldap_mod_add($dn,$entry)) {
717 sf_ldap_set_error_msg("ERROR: cannot add member to LDAP group entry '".
718 $group->getUnixName()."': ".sf_ldap_error()."<br>");
723 ldap_free_result($res);
729 * sf_ldap_group_remove_user() - Remove a user from an LDAP group
731 * @param int The ID of the group from which to remove the user
732 * @param int The ID of the user to remove
733 * @param bool Only remove user from CVS group
734 * @returns true on success/false on error
737 function sf_ldap_group_remove_user($group_id,$user_id,$cvs_only=0) {
738 global $sys_ldap_base_dn;
740 global $sys_use_ldap;
741 if (!$sys_use_ldap) {
745 $group = &group_get_object($group_id);
746 $user = &user_get_object($user_id);
747 if (!sf_ldap_connect()) {
751 $dn = 'cn='.$group->getUnixName().',ou=Group,'.$sys_ldap_base_dn;
752 $cvs_dn = 'cn='.$group->getUnixName().',ou=cvsGroup,'.$sys_ldap_base_dn;
753 $entry['memberUid'] = $user->getUnixName();
757 if (!sf_ldap_mod_del($cvs_dn,$entry) && !sf_ldap_does_not_exist()) {
758 sf_ldap_set_error_msg("ERROR: cannot remove member from LDAP CVS group entry '".
759 $group->getUnixName()."': ".sf_ldap_error()."(".sf_ldap_errno().")"."<br>");
767 if (!sf_ldap_mod_del($dn,$entry) && !sf_ldap_does_not_exist()) {
768 sf_ldap_set_error_msg("ERROR: cannot remove member from LDAP group entry '".
769 $group->getUnixName()."': ".sf_ldap_error()."(".sf_ldap_errno().")"."<br>");