--- /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 @@
+<?php
+
+// BEGIN CONSTANTS
+
+$ldap_readonly_attrs = array(
+ 'uid'
+ , 'objectClass'
+ , 'userPassword'
+ , 'homeDirectory'
+ , 'uidNumber'
+ , 'gidNumber'
+ );
+
+$ldap_field_names = array(
+ 'cn' => '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));
+}