packages/ssoinabox-webui/root/usr/local/share/ssoinabox/htdocs/includes/ldap.php
changeset 0 3906ca745819
child 3 a044870a9d3d
equal deleted inserted replaced
-1:000000000000 0:3906ca745819
       
     1 <?php
       
     2 
       
     3 // BEGIN CONSTANTS
       
     4 
       
     5 $ldap_readonly_attrs = array(
       
     6 		'uid'
       
     7 		, 'objectClass'
       
     8 		, 'userPassword'
       
     9 		, 'homeDirectory'
       
    10 		, 'uidNumber'
       
    11 		, 'gidNumber'
       
    12 	);
       
    13 
       
    14 $ldap_field_names = array(
       
    15 		'cn' => 'Common name'
       
    16 		, 'uid' => 'Username'
       
    17 		, 'givenName' => 'Given name'
       
    18 		, 'sn' => 'Surname'
       
    19 		, 'mail' => 'E-mail'
       
    20 		, 'title' => 'Job title'
       
    21 		, 'telephoneNumber' => 'Phone'
       
    22 	);
       
    23 
       
    24 $ldap_add_single = array(
       
    25 		'title'
       
    26 		, 'mail'
       
    27 	);
       
    28 
       
    29 $ldap_add_multiple = array(
       
    30 		'telephoneNumber'
       
    31 		, 'mobile'
       
    32 		, 'mail'
       
    33 	);
       
    34 
       
    35 // END CONSTANTS
       
    36 
       
    37 global $_ldapconn;
       
    38 $_ldapconn = ldap_connect($ldap_server);
       
    39 if ( !$_ldapconn )
       
    40 	die("Failed to connect to the LDAP database");
       
    41 
       
    42 if ( !ldap_set_option($_ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3) )
       
    43 	die("Failed to set LDAP version to 3");
       
    44 
       
    45 if ( !ldap_bind($_ldapconn, $ldap_manager['dn'], $ldap_manager['password']) )
       
    46 	die("Failed to bind to LDAP as a manager");
       
    47 
       
    48 register_shutdown_function(function() use ($_ldapconn)
       
    49 	{
       
    50 		ldap_unbind($_ldapconn);
       
    51 	});
       
    52 
       
    53 
       
    54 function ldap_escape($str)
       
    55 {
       
    56 	// FIXME escape properly
       
    57 	return $str;
       
    58 }
       
    59 
       
    60 function ldap_get_user($username)
       
    61 {
       
    62 	global $_ldapconn, $ldap_user_basedn;
       
    63 	
       
    64 	$search_filter = sprintf("(&(uid=%s)(objectClass=posixAccount))", ldap_escape($username));
       
    65 	
       
    66 	$search_result = ldap_search($_ldapconn, $ldap_user_basedn, $search_filter);
       
    67 	if ( ldap_count_entries($_ldapconn, $search_result) !== 1 )
       
    68 		return false;
       
    69 	
       
    70 	return ldap_array_cleanup(ldap_get_attributes($_ldapconn, ldap_first_entry($_ldapconn, $search_result)));
       
    71 }
       
    72 
       
    73 function ldap_get_group($group)
       
    74 {
       
    75 	global $_ldapconn, $ldap_group_basedn;
       
    76 	
       
    77 	$search_filter = sprintf("(&(cn=%s)(objectClass=posixGroup))", ldap_escape($group));
       
    78 	
       
    79 	$search_result = ldap_search($_ldapconn, $ldap_group_basedn, $search_filter);
       
    80 	if ( ldap_count_entries($_ldapconn, $search_result) !== 1 )
       
    81 		return false;
       
    82 	
       
    83 	$result = ldap_array_cleanup(ldap_get_attributes($_ldapconn, ldap_first_entry($_ldapconn, $search_result)));
       
    84 	if ( !isset($result['memberUid']) )
       
    85 		$result['memberUid'] = array();
       
    86 	if ( !is_array($result['memberUid']) )
       
    87 		$result['memberUid'] = array($result['memberUid']);
       
    88 	
       
    89 	return $result;
       
    90 }
       
    91 
       
    92 function ldap_update_user($user, $entry)
       
    93 {
       
    94 	global $_ldapconn;
       
    95 	
       
    96 	return ldap_modify($_ldapconn, ldap_make_user_dn($user), $entry);
       
    97 }
       
    98 
       
    99 function ldap_list_users()
       
   100 {
       
   101 	global $_ldapconn, $ldap_user_basedn;
       
   102 	
       
   103 	$search_result = ldap_search($_ldapconn, $ldap_user_basedn, '(objectClass=organizationalPerson)');
       
   104 	
       
   105 	$results = array();
       
   106 	for ( $entry = ldap_first_entry($_ldapconn, $search_result);
       
   107 			$entry;
       
   108 			$entry = ldap_next_entry($_ldapconn, $entry) )
       
   109 	{
       
   110 		$entry_arr = ldap_array_cleanup(ldap_get_attributes($_ldapconn, $entry));
       
   111 		$results[$entry_arr['uid']] = $entry_arr;
       
   112 	}
       
   113 	
       
   114 	return $results;
       
   115 }
       
   116 
       
   117 function ldap_list_groups()
       
   118 {
       
   119 	global $_ldapconn, $ldap_group_basedn;
       
   120 	
       
   121 	$search_result = ldap_search($_ldapconn, $ldap_group_basedn, '(objectClass=posixGroup)');
       
   122 	
       
   123 	$results = array();
       
   124 	for ( $entry = ldap_first_entry($_ldapconn, $search_result);
       
   125 			$entry;
       
   126 			$entry = ldap_next_entry($_ldapconn, $entry) )
       
   127 	{
       
   128 		$entry_arr = ldap_array_cleanup(ldap_get_attributes($_ldapconn, $entry));
       
   129 		$results[$entry_arr['cn']] = $entry_arr;
       
   130 	}
       
   131 	
       
   132 	return $results;
       
   133 }
       
   134 
       
   135 function ldap_array_cleanup($arr)
       
   136 {
       
   137 	$result = array();
       
   138 	foreach ( $arr as $k => $v )
       
   139 	{
       
   140 		if ( is_int($k) || $k == 'count' )
       
   141 			continue;
       
   142 		
       
   143 		if ( $v['count'] === 1 )
       
   144 			$v = $v[0];
       
   145 		else
       
   146 			unset($v['count']);
       
   147 		
       
   148 		$result[$k] = $v;
       
   149 	}
       
   150 	
       
   151 	return $result;
       
   152 }
       
   153 
       
   154 function ldap_make_user_dn($username)
       
   155 {
       
   156 	global $ldap_user_basedn;
       
   157 	return sprintf('uid=%s,%s', ldap_escape($username), $ldap_user_basedn);
       
   158 }
       
   159 
       
   160 function ldap_make_group_dn($group)
       
   161 {
       
   162 	global $ldap_group_basedn;
       
   163 	return sprintf('cn=%s,%s', ldap_escape($group), $ldap_group_basedn);
       
   164 }
       
   165 
       
   166 function ldap_replace_attr($dn, $attribute, $value)
       
   167 {
       
   168 	global $_ldapconn;
       
   169 	
       
   170 	$ldif = array(
       
   171 			$attribute => array($value)
       
   172 		);
       
   173 	
       
   174 	return ldap_mod_replace($_ldapconn, $dn, $ldif);
       
   175 }
       
   176 
       
   177 function ldap_delete_user($username)
       
   178 {
       
   179 	global $_ldapconn, $ldap_user_basedn, $ldap_group_basedn;
       
   180 	
       
   181 	// remove user from all LDAP groups
       
   182 	$search_filter = sprintf("(&(memberUid=%s)(objectClass=posixGroup))", ldap_escape($username));
       
   183 	$search_result = ldap_search($_ldapconn, $ldap_group_basedn, $search_filter);
       
   184 	for ( $entry = ldap_first_entry($_ldapconn, $search_result);
       
   185 			$entry;
       
   186 			$entry = ldap_next_entry($_ldapconn, $entry) )
       
   187 	{
       
   188 		$entry_arr = ldap_array_cleanup(ldap_get_attributes($_ldapconn, $entry));
       
   189 		$dn = ldap_get_dn($_ldapconn, $entry);
       
   190 		ldap_mod_del($_ldapconn, $dn, array('memberUid' => array($username)));
       
   191 	}
       
   192 	
       
   193 	// delete user DN
       
   194 	return ldap_delete($_ldapconn, ldap_make_user_dn($username));
       
   195 }
       
   196 
       
   197 function ldap_delete_group_member($gid, $uid)
       
   198 {
       
   199 	global $_ldapconn;
       
   200 	
       
   201 	return ldap_mod_del($_ldapconn, ldap_make_group_dn($gid), array('memberUid' => array($uid)));
       
   202 }
       
   203 
       
   204 function ldap_add_group_member($gid, $uid)
       
   205 {
       
   206 	global $_ldapconn;
       
   207 	
       
   208 	return ldap_mod_add($_ldapconn, ldap_make_group_dn($gid), array('memberUid' => array($uid)));
       
   209 }
       
   210 
       
   211 function get_next_available_uid()
       
   212 {
       
   213 	$users = ldap_list_users();
       
   214 	$uids = array();
       
   215 	foreach ( $users as $u )
       
   216 		$uids[] = intval($u['uidNumber']);
       
   217 	
       
   218 	asort($uids);
       
   219 	$uid = UID_MIN;
       
   220 	$last_uid = $uids[0];
       
   221 	foreach ( $uids as $u )
       
   222 	{
       
   223 		if ( $u > $last_uid + 1 && ($last_uid + 1) > UID_MIN )
       
   224 		{
       
   225 			return $last_uid + 1;
       
   226 		}
       
   227 		
       
   228 		$last_uid = $u;
       
   229 	}
       
   230 	
       
   231 	return max($uids) + 1;
       
   232 }
       
   233 
       
   234 function get_next_available_gid()
       
   235 {
       
   236 	$groups = ldap_list_groups();
       
   237 	$gids = array();
       
   238 	foreach ( $groups as $g )
       
   239 		$gids[] = intval($g['gidNumber']);
       
   240 	
       
   241 	asort($gids);
       
   242 	$gid = GID_MIN;
       
   243 	$last_gid = $gids[0];
       
   244 	foreach ( $gids as $g )
       
   245 	{
       
   246 		if ( $g > $last_gid + 1 && ($last_gid + 1) > GID_MIN )
       
   247 		{
       
   248 			return $last_gid + 1;
       
   249 		}
       
   250 		
       
   251 		$last_gid = $g;
       
   252 	}
       
   253 	
       
   254 	return max($gids) + 1;
       
   255 }
       
   256 
       
   257 function get_next_available_extension()
       
   258 {
       
   259 	$users = ldap_list_users();
       
   260 	$exts = array();
       
   261 	foreach ( $users as $u )
       
   262 	{
       
   263 		if ( !isset($u['telephoneNumber']) )
       
   264 			continue;
       
   265 		
       
   266 		if ( !is_array($u['telephoneNumber']) )
       
   267 			$u['telephoneNumber'] = array($u['telephoneNumber']);
       
   268 		
       
   269 		foreach ( $u['telephoneNumber'] as $n )
       
   270 		{
       
   271 			if ( preg_match('/^([0-9]+) \(extension\)$/', $n, $match) )
       
   272 				$exts[] = intval($n);
       
   273 		}
       
   274 	}
       
   275 	
       
   276 	asort($exts);
       
   277 	$ext = PHONE_EXT_MIN;
       
   278 	$last_ext = PHONE_EXT_MIN - 1;
       
   279 	foreach ( $exts as $e )
       
   280 	{
       
   281 		if ( $e > $last_ext + 1 && ($last_ext + 1) > UID_MIN )
       
   282 		{
       
   283 			return $last_ext + 1;
       
   284 		}
       
   285 		
       
   286 		$last_ext = $e;
       
   287 	}
       
   288 	
       
   289 	return count($exts) ? max($exts) + 1 : PHONE_EXT_MIN;
       
   290 }
       
   291 
       
   292 function ldap_create_user($username, $gn, $sn, $cn, $title)
       
   293 {
       
   294 	global $_ldapconn;
       
   295 	
       
   296 	$krb_realm = get_default_kerberos_realm();
       
   297 	
       
   298 	if ( !ldap_add($_ldapconn, ldap_make_user_dn($username), array(
       
   299 			'cn' => array($cn)
       
   300 			, 'uid' => array($username)
       
   301 			, 'objectClass' => array(
       
   302 				'top'
       
   303 				, 'person'
       
   304 				, 'inetOrgPerson'
       
   305 				, 'organizationalPerson'
       
   306 				, 'posixAccount'
       
   307 				)
       
   308 			, 'gn' => array($gn)
       
   309 			, 'sn' => array($sn)
       
   310 			, 'userPassword' => array("{SASL}$username@$krb_realm")
       
   311 			, 'loginShell' => array('/bin/bash')
       
   312 			, 'homeDirectory' => array("/home/users/$username")
       
   313 			, 'uidNumber' => array(get_next_available_uid())
       
   314 			, 'gidNumber' => array(500)
       
   315 			, 'title' => array($title)
       
   316 		)) )
       
   317 		return false;
       
   318 	
       
   319 	if ( !ldap_mod_add($_ldapconn, ldap_make_group_dn('users'), array('memberUid' => array($username))) )
       
   320 		return false;
       
   321 	
       
   322 	return true;
       
   323 }
       
   324 
       
   325 function ldap_create_group($cn, $description)
       
   326 {
       
   327 	global $_ldapconn;
       
   328 	
       
   329 	if ( !ldap_add($_ldapconn, ldap_make_group_dn($cn), array(
       
   330 			'cn' => array($cn)
       
   331 			, 'description' => array($description)
       
   332 			, 'gidNumber' => array(get_next_available_gid())
       
   333 			, 'objectClass' => array(
       
   334 				'top'
       
   335 				, 'posixGroup'
       
   336 				)
       
   337 		)) )
       
   338 		return false;
       
   339 }
       
   340 
       
   341 function ldap_delete_group($cn)
       
   342 {
       
   343 	global $_ldapconn;
       
   344 	
       
   345 	$group = ldap_get_group($cn);
       
   346 	$users = ldap_list_users();
       
   347 	
       
   348 	foreach ( $users as $u )
       
   349 	{
       
   350 		if ( $u['gidNumber'] === $group['gidNumber'] )
       
   351 			return false;
       
   352 	}
       
   353 	
       
   354 	return ldap_delete($_ldapconn, ldap_make_group_dn($cn));
       
   355 }