diff -r 000000000000 -r 3906ca745819 packages/ssoinabox-webui/root/usr/local/share/ssoinabox/htdocs/includes/ldap.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/packages/ssoinabox-webui/root/usr/local/share/ssoinabox/htdocs/includes/ldap.php Tue Jan 08 23:13:29 2013 -0500 @@ -0,0 +1,355 @@ + 'Common name' + , 'uid' => 'Username' + , 'givenName' => 'Given name' + , 'sn' => 'Surname' + , 'mail' => 'E-mail' + , 'title' => 'Job title' + , 'telephoneNumber' => 'Phone' + ); + +$ldap_add_single = array( + 'title' + , 'mail' + ); + +$ldap_add_multiple = array( + 'telephoneNumber' + , 'mobile' + , 'mail' + ); + +// END CONSTANTS + +global $_ldapconn; +$_ldapconn = ldap_connect($ldap_server); +if ( !$_ldapconn ) + die("Failed to connect to the LDAP database"); + +if ( !ldap_set_option($_ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3) ) + die("Failed to set LDAP version to 3"); + +if ( !ldap_bind($_ldapconn, $ldap_manager['dn'], $ldap_manager['password']) ) + die("Failed to bind to LDAP as a manager"); + +register_shutdown_function(function() use ($_ldapconn) + { + ldap_unbind($_ldapconn); + }); + + +function ldap_escape($str) +{ + // FIXME escape properly + return $str; +} + +function ldap_get_user($username) +{ + global $_ldapconn, $ldap_user_basedn; + + $search_filter = sprintf("(&(uid=%s)(objectClass=posixAccount))", ldap_escape($username)); + + $search_result = ldap_search($_ldapconn, $ldap_user_basedn, $search_filter); + if ( ldap_count_entries($_ldapconn, $search_result) !== 1 ) + return false; + + return ldap_array_cleanup(ldap_get_attributes($_ldapconn, ldap_first_entry($_ldapconn, $search_result))); +} + +function ldap_get_group($group) +{ + global $_ldapconn, $ldap_group_basedn; + + $search_filter = sprintf("(&(cn=%s)(objectClass=posixGroup))", ldap_escape($group)); + + $search_result = ldap_search($_ldapconn, $ldap_group_basedn, $search_filter); + if ( ldap_count_entries($_ldapconn, $search_result) !== 1 ) + return false; + + $result = ldap_array_cleanup(ldap_get_attributes($_ldapconn, ldap_first_entry($_ldapconn, $search_result))); + if ( !isset($result['memberUid']) ) + $result['memberUid'] = array(); + if ( !is_array($result['memberUid']) ) + $result['memberUid'] = array($result['memberUid']); + + return $result; +} + +function ldap_update_user($user, $entry) +{ + global $_ldapconn; + + return ldap_modify($_ldapconn, ldap_make_user_dn($user), $entry); +} + +function ldap_list_users() +{ + global $_ldapconn, $ldap_user_basedn; + + $search_result = ldap_search($_ldapconn, $ldap_user_basedn, '(objectClass=organizationalPerson)'); + + $results = array(); + for ( $entry = ldap_first_entry($_ldapconn, $search_result); + $entry; + $entry = ldap_next_entry($_ldapconn, $entry) ) + { + $entry_arr = ldap_array_cleanup(ldap_get_attributes($_ldapconn, $entry)); + $results[$entry_arr['uid']] = $entry_arr; + } + + return $results; +} + +function ldap_list_groups() +{ + global $_ldapconn, $ldap_group_basedn; + + $search_result = ldap_search($_ldapconn, $ldap_group_basedn, '(objectClass=posixGroup)'); + + $results = array(); + for ( $entry = ldap_first_entry($_ldapconn, $search_result); + $entry; + $entry = ldap_next_entry($_ldapconn, $entry) ) + { + $entry_arr = ldap_array_cleanup(ldap_get_attributes($_ldapconn, $entry)); + $results[$entry_arr['cn']] = $entry_arr; + } + + return $results; +} + +function ldap_array_cleanup($arr) +{ + $result = array(); + foreach ( $arr as $k => $v ) + { + if ( is_int($k) || $k == 'count' ) + continue; + + if ( $v['count'] === 1 ) + $v = $v[0]; + else + unset($v['count']); + + $result[$k] = $v; + } + + return $result; +} + +function ldap_make_user_dn($username) +{ + global $ldap_user_basedn; + return sprintf('uid=%s,%s', ldap_escape($username), $ldap_user_basedn); +} + +function ldap_make_group_dn($group) +{ + global $ldap_group_basedn; + return sprintf('cn=%s,%s', ldap_escape($group), $ldap_group_basedn); +} + +function ldap_replace_attr($dn, $attribute, $value) +{ + global $_ldapconn; + + $ldif = array( + $attribute => array($value) + ); + + return ldap_mod_replace($_ldapconn, $dn, $ldif); +} + +function ldap_delete_user($username) +{ + global $_ldapconn, $ldap_user_basedn, $ldap_group_basedn; + + // remove user from all LDAP groups + $search_filter = sprintf("(&(memberUid=%s)(objectClass=posixGroup))", ldap_escape($username)); + $search_result = ldap_search($_ldapconn, $ldap_group_basedn, $search_filter); + for ( $entry = ldap_first_entry($_ldapconn, $search_result); + $entry; + $entry = ldap_next_entry($_ldapconn, $entry) ) + { + $entry_arr = ldap_array_cleanup(ldap_get_attributes($_ldapconn, $entry)); + $dn = ldap_get_dn($_ldapconn, $entry); + ldap_mod_del($_ldapconn, $dn, array('memberUid' => array($username))); + } + + // delete user DN + return ldap_delete($_ldapconn, ldap_make_user_dn($username)); +} + +function ldap_delete_group_member($gid, $uid) +{ + global $_ldapconn; + + return ldap_mod_del($_ldapconn, ldap_make_group_dn($gid), array('memberUid' => array($uid))); +} + +function ldap_add_group_member($gid, $uid) +{ + global $_ldapconn; + + return ldap_mod_add($_ldapconn, ldap_make_group_dn($gid), array('memberUid' => array($uid))); +} + +function get_next_available_uid() +{ + $users = ldap_list_users(); + $uids = array(); + foreach ( $users as $u ) + $uids[] = intval($u['uidNumber']); + + asort($uids); + $uid = UID_MIN; + $last_uid = $uids[0]; + foreach ( $uids as $u ) + { + if ( $u > $last_uid + 1 && ($last_uid + 1) > UID_MIN ) + { + return $last_uid + 1; + } + + $last_uid = $u; + } + + return max($uids) + 1; +} + +function get_next_available_gid() +{ + $groups = ldap_list_groups(); + $gids = array(); + foreach ( $groups as $g ) + $gids[] = intval($g['gidNumber']); + + asort($gids); + $gid = GID_MIN; + $last_gid = $gids[0]; + foreach ( $gids as $g ) + { + if ( $g > $last_gid + 1 && ($last_gid + 1) > GID_MIN ) + { + return $last_gid + 1; + } + + $last_gid = $g; + } + + return max($gids) + 1; +} + +function get_next_available_extension() +{ + $users = ldap_list_users(); + $exts = array(); + foreach ( $users as $u ) + { + if ( !isset($u['telephoneNumber']) ) + continue; + + if ( !is_array($u['telephoneNumber']) ) + $u['telephoneNumber'] = array($u['telephoneNumber']); + + foreach ( $u['telephoneNumber'] as $n ) + { + if ( preg_match('/^([0-9]+) \(extension\)$/', $n, $match) ) + $exts[] = intval($n); + } + } + + asort($exts); + $ext = PHONE_EXT_MIN; + $last_ext = PHONE_EXT_MIN - 1; + foreach ( $exts as $e ) + { + if ( $e > $last_ext + 1 && ($last_ext + 1) > UID_MIN ) + { + return $last_ext + 1; + } + + $last_ext = $e; + } + + return count($exts) ? max($exts) + 1 : PHONE_EXT_MIN; +} + +function ldap_create_user($username, $gn, $sn, $cn, $title) +{ + global $_ldapconn; + + $krb_realm = get_default_kerberos_realm(); + + if ( !ldap_add($_ldapconn, ldap_make_user_dn($username), array( + 'cn' => array($cn) + , 'uid' => array($username) + , 'objectClass' => array( + 'top' + , 'person' + , 'inetOrgPerson' + , 'organizationalPerson' + , 'posixAccount' + ) + , 'gn' => array($gn) + , 'sn' => array($sn) + , 'userPassword' => array("{SASL}$username@$krb_realm") + , 'loginShell' => array('/bin/bash') + , 'homeDirectory' => array("/home/users/$username") + , 'uidNumber' => array(get_next_available_uid()) + , 'gidNumber' => array(500) + , 'title' => array($title) + )) ) + return false; + + if ( !ldap_mod_add($_ldapconn, ldap_make_group_dn('users'), array('memberUid' => array($username))) ) + return false; + + return true; +} + +function ldap_create_group($cn, $description) +{ + global $_ldapconn; + + if ( !ldap_add($_ldapconn, ldap_make_group_dn($cn), array( + 'cn' => array($cn) + , 'description' => array($description) + , 'gidNumber' => array(get_next_available_gid()) + , 'objectClass' => array( + 'top' + , 'posixGroup' + ) + )) ) + return false; +} + +function ldap_delete_group($cn) +{ + global $_ldapconn; + + $group = ldap_get_group($cn); + $users = ldap_list_users(); + + foreach ( $users as $u ) + { + if ( $u['gidNumber'] === $group['gidNumber'] ) + return false; + } + + return ldap_delete($_ldapconn, ldap_make_group_dn($cn)); +}