BzzWare AS, Norway This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /*************************************************************************** * lwat_login - tries to log in user either given or stored admindn/adminpw * lwat_key - Reads session key, or create a new one * lwat_ldap - connects to the ldap-server, with proper options set * reportLdapError - Reports error number and textual message of * ldap error occured * loadConfig - Loads configuration, either from config.php, or use * predefined values * loadLocale - Checks for browser language and tries to load locale * xorstring - xors a string, to either crypt or decrypt data * readKey - Decodes data posted through the web-browser * debug - Displays data top debug through development * pwgen - generates a random password * cryptgen - generates a crypted password from a given password * getnextid - fetch (and update) the next id to be used. This is * stored in ldap under ou=variables * get_sn - parses a full name, and fetches the surname * chk_username - Checks if a given username is already taken * get_username - generates a username from a fullname * get_givenName - parses a fullname, and extract a givenName * get_sambasid - looks up the sambasid to be used. * ldapAddUser - Adds a user into ldap * sambaAddInfo - Adds samba information for a user * userAddGroup - Add a user into a group ***************************************************************************/ require_once ("createlm.php"); require_once("llx_log.php"); /********************************************************************** * lwat_login - tries to log in user either given or stored * admindn/adminpw ***************** * Arguments * ldap - ldap connection * adminUser - the username to log in as * admindn - password ? * key - key used to xor the stored password * Returns * authenticated - True if logged in succesfully ***************** * if AdminUser is given * Loop while possible to look closer to base * Try to look up the full dn of the admin user * if found * try to connect as the admin user * if succesfull * store admindn and admin pw * return true * look closer to the ldap base for a user * return false * if no stored admin dn * return failure * fetch stored password * if able to bind using stored dn/pw * update cookie * return success * return failure **********************************************************************/ function lwat_login ($ldap, $adminUser, $adminpw, $key) { global $base ; if (!empty ($adminUser)&&(!empty ($adminpw))) { $loginbase = $base ; $filter = '(|(&(objectClass=posixAccount)(uid=' . $adminUser . '))(&(objectClass=simpleSecurityObject)(cn=' . $adminUser . ')))' ; $want = array ("dn") ; while (!empty ($loginbase)) { $result = @ldap_search($ldap, $loginbase, $filter, $want); $entries = @ldap_get_entries ($ldap, $result); $admindn = htmlspecialchars($entries[0]['dn']) ; $bind = @ldap_bind ($ldap, $admindn, $adminpw); if ($bind) { $xorstring = xorstring ($key, $adminpw); $packstring = unpack ("H*", $xorstring) ; setcookie ('admindn', $admindn, time () + 1800) ; setcookie ('xorstring', $packstring[1], time () + 1800) ; return true ; } else { $loginbase = ldap_explode_dn ($loginbase,0) ; array_splice ($loginbase, 0,2) ; $loginbase = implode (",", $loginbase) ; } } return false ; } $admindn = $_COOKIE['admindn'] ; if (empty ($admindn)) return false ; $packstring = $_COOKIE['xorstring'] ; $xorstring = pack ("H*", $packstring); $adminpw = xorstring ($key, $xorstring) ; $bind = @ldap_bind ($ldap, $admindn, $adminpw); if ($bind) { setcookie ("admindn", $admindn, time () + 1800) ; setcookie ("xorstring", $packstring, time () + 1800) ; return true ; } return false ; } /********************************************************************** * lwat_key - Reads session key, or create a new one ***************** * Returns * key - either read from session, or newlyt created ***************** * Read key from session * if no key found * create new key * store key in session * return key value **********************************************************************/ function lwat_key () { if (isset($_SESSION['key'])) $key = $_SESSION['key'] ; else { $key = substr (crypt(sprintf (gettimeofday (true))),4) ; $_SESSION['key'] = $key ; } return $key ; } /********************************************************************** * lwat_ldap - connects to the ldap-server, with proper options set ***************** * Returns * ldap - ldap connection ***************** * connect to ldap host * set ldap options * if not tls is available * check error * error 2: tls not available, ignore ? * error 81: unable to contact ldap server * other error: * report ldaperror * * if error * close conection * return 0 * return ldap connection **********************************************************************/ function lwat_ldap () { global $ldaphost, $tlsRequire ; $ldaperr = 0 ; $ldap=ldap_connect ($ldaphost); ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); if (!@ldap_start_tls($ldap)) { $ldaperr = ldap_errno ($ldap) ; switch ($ldaperr) { case 2: if ($tlsRequire) printf (_("Unable to start encrypted connection with the ldapserver"), $ldaphost) ; else $ldaperr = 0 ; break ; case 81: printf (_("Sorry, but we are not able to contact your ldapserver running on the host %s"), $ldaphost) ; break ; default: reportLdapError (ldap_errno ($ldap), "Tried to connect") ; break ; } } if ($ldaperr) { ldap_close ($ldap) ; die ("
" . _("Please check your configuration")) ; } return $ldap ; } /********************************************************************** * reportLdapError - Reports error number and textual message of * ldap error occured ***************** * Arguments: * ldaperr - Error code from ldap * myAction - Description of what lead to the error from lwat ***************** * Display an error message to the user **********************************************************************/ function reportLdapError ($ldaperr, $myAction) { printf (_("An Unknown error occured.") . "
") ; printf (_("The error code from ldap was: %d") . "
", $ldaperr) ; printf (_("The error string from ldap was: %s") ."
", ldap_err2str ($ldaperr)); } /*************************************************************************** * loadConfig - Loads configuration, either from config.php, or use * predefined values *********************** * Load predefined values * if config.php exists load settings **************************************************************************/ function loadConfig () { global $domain, $base, $ldaphost, $homelocation, $useLisGroup, $groupbase, $authbase, $hostbase, $netgroupbase, $automountbase, $variablesbase, $groupprefix, $authprefix, $hostprefix, $netgroupprefix, $automountprefix, $variablesprefix, $minPwLength, $minPwUpper, $minPwLower, $minPwNumber, $allowPwSet, $tlsRequire, $smarty_templ, $smarty_compile, $llxCreateGroup,$configured; $groupprefix = "ou=Group" ; $hostprefix = "ou=Hosts" ; $netgroupprefix = "ou=Netgroup" ; $variablesprefix = "ou=Variables" ; $automountprefix = "ou=Automount" ; $homelocation = "/home" ; $minPwLength = 6 ; $minPwUpper = 1 ; $minPwLower = 1 ; $minPwNumber = 1 ; $allowPwSet = true ; $smarty_templ = realpath ("../templates") ; $smarty_compile = "/var/spool/lliurex-lwat" ; $domain = 'aula.ma3.lliurex.es' ; $ldaphost = "localhost"; $useLisGroup = false ; $tlsRequire = true ; $configured= false; @include_once ("/etc/lliurex-lwat/config.php"); if (!isset ($base)) { $base_array = split ('.', $domain) ; $base = 'dc=' . $base_array[0] ; for ($i = 1 ; $i < count($base_array) ; $i++) $base .= ",dc=" . $base_array[$i] ; } if (!is_dir ($smarty_compile)) $smarty_compile = "/var/tmp" ; if (isset ($groupbase)) { $groupprefix = NULL ; } elseif (isset($groupprefix)) $groupbase = $groupprefix . "," . $base ; else $groupbase = $base ; if ($useLisGroup) { $authbase = NULL ; $authprefix = NULL ; } elseif (isset ($authbase)) { $useLisGroup = false ; $authprefix = NULL ; } elseif (isset($authprefix)) $authbase = $authprefix . "," . $base ; else $authbase = $base ; if (isset ($hostbase)) $hostprefix = NULL ; elseif (isset($hostprefix)) $hostbase = $hostprefix . "," . $base ; else $hostbase = $base ; if (isset ($netgroupbase)) $netgroupprefix = NULL ; elseif (isset($netgroupprefix)) $netgroupbase = $netgroupprefix . "," . $base ; else $netgroupbase = $base ; if (isset ($variablesbase)) $variablesprefix = NULL ; elseif (isset($variablesprefix)) $variablesbase = $variablesprefix . "," . $base ; else $variablesbase = $base ; if (isset ($automountbase)) $automountprefix = NULL ; elseif (isset($automountprefix)) $automountbase = $automountprefix . "," . $base ; else $automountbase = $base ; //Si no definimos llxCreateGroup utilizaremos groupbase para crear los grupos if (!isset ($llxCreateGroup)) $llxCreateGroup = $groupbase ; //Checked $unconfigured to init lliurex-lwat if (!$configured){ printf (_("Sorry, lliurex-lwat is not configured, you must execute")." llxcfg-ldap init --force
") ; exit; } } /**************************************************************************** * loadLocale - Checks for browser language and tries to load locale ************ * try to load locale from cookie * if no locale is found, and there is a locale subfolder * create array of locales found under locales subfolder * fetch the languages the browser accepts * try to match exactly and mostly the locales for browser and application * if exact locale is found use it * else if match locale is found, use it * if locale to use is found, set cookie * set textdomain to use for locales * set application output to be UTF8 ****************************************************************************/ function loadLocale () { if (isset ($_COOKIE['locale'])) $found_locale = $_COOKIE['locale'] ; if (!isset($found_locale) && is_dir ('../locales')) { $handle = @opendir ('../locales') ; $all_locales = array () ; while (false !== ($file = readdir ($handle))) { if (is_dir ('../locales/' . $file . '/LC_MESSAGES')) { $all_locales = array_merge ($all_locales, array ($file)) ; } } closedir ($handle) ; $lang_accept = array () ; $lang_accept = explode (",", $_SERVER['HTTP_ACCEPT_LANGUAGE']); for ($i = 0 ; $i < count ($lang_accept) ; $i++ ) { $lang_accept[$i] = split(";", $lang_accept[$i]) ; $lang_accept[$i] = $lang_accept[$i][0] ; } if (!empty($lang_accept[0])) foreach ($lang_accept as $lang) { if (!isset ($locale_exact)) { foreach ($all_locales as $locales) { if ($locales == $lang) $locale_exact = $lang ; elseif (!isset ($locale_match)) { if (strpos ($locales, $lang) === 0) $locale_match = $locales ; } } } } if (isset ($locale_exact)) $found_locale=$locale_exact ; elseif (isset ($locale_match)) $found_locale=$locale_match ; if (isset ($found_locale)) setcookie ( 'locale', $found_locale) ; unset ($all_locales, $lang_accept, $locale_match, $locale_exact, $lang, $locales) ; } if (isset ($found_locale)) { $locale = setlocale (LC_ALL, $found_locale) ; if (empty($locale)) setlocale (LC_ALL, $found_locale . ".UTF8"); bindtextdomain ("lliurex-lwat", "../locales/"); bind_textdomain_codeset ("lliurex-lwat", "UTF-8"); textdomain ("lliurex-lwat"); } header('Content-Type: text/html; charset=UTF-8') ; } /**************************************************************************** * xorstring - xors a string, to either crypt or decrypt data ***************** * Arguments: * key - key to use when encrypting or decrypting data * xor - Data to xor, either clear text, or previously encrypted * Returns: * either encrypted or decrypted string ***************** * if no key * return nothing * perform an xor with every character in string to be encrupted/decrypted * with the correspondent charcater in key, repeat key if necesarry * if at the end of a keyindex (assume decrypting) * find first occurence of chr 0 * return string up to chr 0 * while not end of keyindex * add with the rest of the key * return encrypted string ****************************************************************************/ function xorstring ($key, $xor) { $keylen=strlen ($key) ; if (! $keylen) return "" ; $newstr="" ; $index=0 ; $keyindex = $index ; while ($index < strlen ($xor)) { $newstr .= chr(ord($xor[$index]) ^ ord ($key[$keyindex])) ; $index ++ ; $keyindex= $index % $keylen ; } if ($keyindex == 0) { $last=strpos ($newstr, chr(0)); if ($last === false) { return $newstr ; } return(substr ($newstr, 0, $last)) ; } while ($keyindex != 0) { $newstr .= $key[$keyindex] ; $index ++ ; $keyindex= $index % $keylen ; } return ($newstr) ; } /**************************************************************************** * readKey - Decodes data posted through the web-browser ***************** * Arguments: * key - which posted data to read * Returns: * the trimmed and stripped value of the data read ***************** * Lookup data in posted array, trim, and remove clean data ****************************************************************************/ function readKey ($key) { if (isset ($_POST[$key])) return htmlspecialchars(trim($_POST[$key])) ; return "" ; } /**************************************************************************** * debug - Displays data top debug through development ***************** * Arguments: * mixed - Data to display (array is preferred ***************** * Display as preformatted code ****************************************************************************/ function debug ($mixed) { echo "
\n" ; 
    print_r ($mixed);
    echo "\n
\n" ; } /**************************************************************************** * pwgen - generates a random password ***************** * Returns: * a password that should be easy to say, but hard to guess ***************** * First define consonants and vowels * select random characters, 2 set of three * Add a random number between 10 and 99 ****************************************************************************/ function pwgen(){ $pw = ''; $a = 'bcdfghjkmnprstvwzaeiou123456789'; for($i=0;$i < 5; $i++) { $pw .= $a[rand(0, strlen($a)-1)]; } return $pw; } /**************************************************************************** * cryptgen - generates a crypted password from a given password, * ready to be stored in ldap ***************** * Arguments: * clear - the clear text password * Returns: * a crypted password ***************** * First prepare a salt using md5sum of random data * Return base64 encoded sha1 encrypted password ****************************************************************************/ function cryptgen($clear){ //prepare a salt $salt = md5(uniqid(rand(), true)); $salt=substr($salt,0,4); return '{SSHA}'.base64_encode(pack("H*", sha1($clear.$salt)).$salt); } /**************************************************************************** * getnextid - fetch (and update) the next id to be used. This is * stored in ldap under ou=variables ***************** * Arguments * connect - the ldap connection * Returns: * the next ID to be used ***************** * Search for a nextID under ou=Variables * Loop * minimum nextID should be 10000 * if nextID > 59999 * if already looped * Die with an error message * else * set looped * restart from 10000 * search ldap for found gidNumber or uidNumber * increase NextID if found * until free uidNumber and gidNumber is found * build new ID to be stored in ldap * if add newID to ldap with success * delete old nextID * rename newID nextID * return nextID * die with error message ****************************************************************************/ /* function getnextid ($connect) { global $variablesbase, $base ; $looped = false ; $nextID=0 ; $want= array ("gidNumber", "uidNumber"); $filter = "(&(gidNumber=*)(cn=nextID))" ; $result= @ldap_search ($connect, "ou=Variables," . $base, $filter, $want); if ($result) { $entries = ldap_get_entries ($connect, $result) ; if ($entries["count"]) $nextID=$entries[0]["gidnumber"][0] ; } do { if ($nextID < 10000) $nextID=10000 ; else if ($nextID > 59999) { if ($looped) { die ('Sorry, all user id\'s between 10000 and 59999 seems to have been taken') ; } else { $looped = true ; $nextID=10000 ; } } $filter = "(&(|(gidNumber=$nextID)(uidNumber=$nextID))(!(cn=nextID)))" ; $result = @ldap_search ($connect, $base, $filter, $want); $entries = @ldap_get_entries ($connect, $result) ; if ($entries["count"] > 0) $nextID++ ; } while ($entries["count"]) ; $info=array () ; $info["objectClass"] = array ("top", "posixGroup") ; $info["gidnumber"] = $nextID + 1 ; $info["cn"] = "newID" ; if (@ldap_add ($connect,"cn=newID," . $variablesbase,$info)) { @ldap_delete ($connect,"cn=nextID," . $variablesbase) ; @ldap_rename ($connect,"cn=newID," . $variablesbase, "cn=nextID", $variablesbase, true) ; return $nextID ; } $ldaperr = ldap_errno ($connect) ; switch ($ldaperr) { case 50: die (_("Sorry, you are not authorized")) ; break ; default: reportLdapError ($ldaperr, "getnextid") ; break ; } die ("
" . _("Please report a bug to the lwat developers")) ; } */ /**************************************************************************** * getnextid - fetch (and update) the next id to be used. This is * stored in ldap under ou=variables ***************** * Arguments * connect - the ldap connection * Returns: * the next ID to be used ***************** * Search for a nextID under ou=Variables * Loop * minimum nextID should be 10000 * if nextID > 59999 * if already looped * Die with an error message * else * set looped * restart from 10000 * search ldap for found gidNumber or uidNumber * increase NextID if found * until free uidNumber and gidNumber is found * build new ID to be stored in ldap * if add newID to ldap with success * delete old nextID * rename newID nextID * return nextID * die with error message ****************************************************************************/ function getnextid ($connect,$template) { global $variablesbase, $base ; switch ($template) { case "Alumnos": $cnID="stuID"; $cnNewID="newstuID"; break; case "Profesores": $cnID="teaID"; $cnNewID="newteaID"; break; case "Otros": $cnID="otID"; $cnNewID="newotID"; break; default: $cnID="nextID"; $cnNewID="newID"; } $looped = false ; $nextID=0 ; $want= array ("gidNumber", "uidNumber"); $filter = "(&(gidNumber=*)(cn=$cnID))" ; $result= @ldap_search ($connect, "ou=Variables," . $base, $filter, $want); if ($result) { $entries = ldap_get_entries ($connect, $result) ; if ($entries["count"]) $nextID=$entries[0]["gidnumber"][0] ; } do { if ($nextID < 5000) $nextID=5000 ; else if ($nextID > 59999) { if ($looped) { die ('Sorry, all user id\'s between 5000 and 59999 seems to have been taken') ; } else { $looped = true ; $nextID=5000 ; } } $filter = "(&(|(gidNumber=$nextID)(uidNumber=$nextID))(!(cn=$cnID)))" ; $result = @ldap_search ($connect, $base, $filter, $want); $entries = @ldap_get_entries ($connect, $result) ; if ($entries["count"] > 0) $nextID++ ; } while ($entries["count"]) ; $info=array () ; $info["objectClass"] = array ("top", "posixGroup") ; $info["gidnumber"] = $nextID + 1 ; $info["cn"] = "$cnNewID" ; if (@ldap_add ($connect,"cn=$cnNewID," . $variablesbase,$info)) { @ldap_delete ($connect,"cn=$cnID," . $variablesbase) ; @ldap_rename ($connect,"cn=$cnNewID," . $variablesbase, "cn=$cnID", $variablesbase, true) ; return $nextID ; } $ldaperr = ldap_errno ($connect) ; switch ($ldaperr) { case 50: die (_("Sorry, you are not authorized")) ; break ; default: reportLdapError ($ldaperr, "getnextid") ; break ; } die ("
" . _("Please report a bug to the lwat developers")) ; } /**************************************************************************** * get_sn - parses a full name, and fetches the surname ***************** * Arguments: * newname - name to extract surname from * Returns: * surname ***************** * split fullname by spaces * find the last name * return the last name ****************************************************************************/ function get_sn ($newname) { $sn="" ; $allnames = explode (" ", $newname) ; foreach ($allnames as $name) { $sn=$name ; } return $sn; } /**************************************************************************** * chk_username - Checks if a given username is already taken ***************** * Arguments: * connect - ldap connection * username - Username to check * excludes - username not to use (maybe they are already checked, * and prepared for other users in an import) * Returns: * false if found, true if username can be used ***************** * search ldap for username or groupName * if found * return false * search trough username which should be excluded * if found, return false * return true (actually, return username) ****************************************************************************/ function chk_username ($connect, $username, $excludes) { global $base ; $filter = "(|(uid=$username)(cn=$username))" ; $result= ldap_search ($connect, $base, $filter); $entries = ldap_get_entries ($connect, $result) ; if ($entries["count"]) return "" ; if (is_array($excludes)) { $result = in_array ($username, $excludes) ; if ($result) return "" ; } return $username ; } /**************************************************************************** * get_username - generates a username from a fullname ***************** * Arguments: * connect - ldap connection * newname - the fullname to generate a new name from * excludes - username not to be used (already prepared to imported?) * Returns: * new username generated ***************** * try to detect encoding * found encoding ISO-8859-1 * no need to convert characters * default * convert from found charset to ISO-8859-1 * Look through found characters for known characters > chr 128 * convert them to A, C, E, I, N, O, U, Y, P (or lowercase variants) * convert everything to lower chars * split the names based on spaces and other separators * find first and last name * try taking 3 chars from first and last name * check found name against existing * if not found return name * loop while vowels * loop while vowels * take 1, then 2, then 3... from each name but firstname * trim from firstname till firstname and X characters from other * names is 8 chars * if username not used, return name * Remove a vowel from "restnames" * Remove a vovel from first name * Try to use 3 from first + 3 from last and add 00-99 * if username not used return username * finally give up :( ****************************************************************************/ function get_username ($connect, $newname, $excludes = NULL) { global $base ; $charset = mb_detect_encoding ($newname, 'UTF-8, ISO-8859-1') ; switch ($charset) { case 'ISO-8859-1': $basename = $newname ; break ; default: $basename = mb_convert_encoding ($newname, 'ISO-8859-1', $charset); break ; } for ($i=0 ; $i < strlen($basename); $i++) { switch (ord($basename[$i])) { case 192: case 193: case 194: case 195: case 196: case 197: $basename[$i] = "A" ; break ; case 199: $basename[$i] = "C" ; break ; case 198: case 200: case 201: case 202: case 203: $basename[$i] = "E" ; break ; case 204: case 205: case 206: case 207: $basename[$i] = "I" ; break ; case 209 : $basename[$i] = "N" ; break ; case 208: case 210: case 211: case 212: case 213: case 214: case 216 : $basename[$i] = "O" ; break ; case 217: case 218: case 219: case 220 : $basename[$i] = "U" ; break ; case 221 : $basename[$i] = "Y" ; break ; case 222 : $basename[$i] = "P" ; break ; case 223 : $basename[$i] = "I" ; break ; case 224: case 225: case 226: case 227: case 228: case 229 : $basename[$i] = "a" ; break ; case 231 : $basename[$i] = "c" ; break ; case 230: case 232: case 233: case 234: case 235 : $basename[$i] = "e" ; break ; case 236: case 237: case 238: case 239 : $basename[$i] = "i" ; break ; case 241 : $basename[$i] = "n" ; break ; case 240: case 242: case 243: case 244: case 245: case 246: case 248 : $basename[$i] = "o" ; break ; case 249: case 250: case 251: case 252 : $basename[$i] = "u" ; break ; case 253: case 255 : $basename[$i] = "y" ; break ; case 254 : $basename[$i] = "p" ; break ; default: if ($basename[$i] >= "0" and $basename[$i] <= "9") break ; if ($basename[$i] >= "A" and $basename[$i] <= "Z") break ; if ($basename[$i] >= "a" and $basename[$i] <= "z") break ; $basename[$i] = " " ; break ; } } $basename = trim (strtolower ($basename)) ; $allnames = split (" +", $basename) ; $firstname = $allnames[0] ; foreach ($allnames as $name) if (!empty ($name)) $lastname=$name ; $bigname = substr ($firstname, 0,3) . substr ($lastname, 0,3) ; $username = chk_username ($connect, $bigname, $excludes); if (!empty($username)) return $username ; $loop="aeiouy" ; while (ereg ("[aeiouy]", $loop)) { $restname="" ; for ($i=1 ; $i < (count($allnames)); $i++) $restname .= $allnames[$i] . " " ; while (ereg ("[aeiouy]", $loop)) { for ($count=1 ; $count <= 6 ; $count++ ) { $addname="" ; foreach (explode (" ", $restname) as $name) $addname .= substr ($name, 0, $count); while (strlen ($addname) > 6) $addname=substr($addname, $count); $username= chk_username($connect, substr($firstname,0,8 - strlen($addname)) . $addname, $excludes) ; if (!empty($username)) return $username ; } $length=strlen($restname); $loop="" ; while ($length--) { switch ($restname[$length]) { case "a": case "e": case "i": case "o": case "u": case "y": $loop=$restname[$length] ; $restname=substr($restname, 0,$length) . substr($restname, $length + 1) ; $length = 0 ; break ; } } } $length=strlen($firstname); $loop="" ; while ($length--) { switch ($firstname[$length]) { case "a": case "e": case "i": case "o": case "u": case "y": $loop=$firstname[$length] ; $firstname=substr($firstname, 0,$length) . substr($firstname, $length + 1) ; $length = 0 ; break ; } } } for ($i=0 ; $i < 100 ; $i++) { $username = chk_username ($connect, sprintf ("%s%02d", $bigname, $i), $excludes) ; if (! empty($username)) return $username ; } echo _("Sorry, I'm unable to generate a unique username for $newname")."
"; return "" ; } /**************************************************************************** * get_givenName - parses a fullname, and extract a givenName ***************** * Arguments: * newname - The full name * Returns: * The given name (everything but the last name) ***************** * for each name in full name * add previous name to the given name * remember the last name * if no given name is found * use the last name * return given name ****************************************************************************/ function get_givenName ($newname) { $last="" ; foreach (explode (" ", $newname) as $value) { $givenName .= $last ; $last = "$value" . " " ; } if (! $givenName) $givenName=$last ; return $givenName ; } /**************************************************************************** * get_sambasid - looks up the sambasid to be used. ***************** * Arguments: * connect - ldap connection * userid - userid to create sambaSid for * Returns: * the samba sid as a string ***************** * look up a sambaDomain in ldap * check number of entries * 0: warn that there is none * 1: continue * *: warn that there is to many ****************************************************************************/ function get_sambasid ($connect, $userid) { global $base ; $want= array ("sambasid"); $filter = "(objectClass=sambaDomain)" ; $result = @ldap_search ($connect, $base, $filter, $want); $entries = @ldap_get_entries ($connect, $result) ; switch ($entries["count"]) { case 0: die (_("Sorry, can't find no sambaDomain in your ldap"). "
") ; case 1: break ; default: die (_("Sorry, there is more than one sambaDomain in your ldap server, and this version of lwat only supports one"). "
") ; } $sambaSID=$entries[0]["sambasid"][0] . sprintf("-%d", $userid * 2 + 1000) ; return $sambaSID ; } /**************************************************************************** * ldapAddUser - Adds a user into ldap ***************** * Arguments: * ldap - ldap connection * cn - Common name of the new user * template - Template to use to create user * username - The username * userpw - password * groups - list of groups (in addition to those from the template) * to add the user into * batchMode- mode not snyncronize with backend * Returns: * returns true if the user was created, false otherwise ***************** * parse template file * fetch surname from username * fetch the next userid to use * check if special lis schema should be used when creatign a personal group * Set up to replace username, basem domain and surname with real values * Parse template, to build a complete ldap object * ou: this is the objectunit which the object is stored under * groups: add these groups from the template to the list of groups * for the user * objectClass: this must be added as an array * *) the rest is just added as normal key => value stuff * if samba Account * Add samba Info * Add the user * report any error * if lisGroup are to be used, set groupbase * add personal group * for each group the user should be added into * if unable to add * remember * if not unable to add to any group * return success * Remove all groups we could not add the user into * return success ****************************************************************************/ function ldapAddUser ($ldap, $gecos, $template, $username, $userpw, $groups, $profile, $cn, $sn, $fd) { global $groupbase, $base, $domain, $useLisGroup, $llxCreateGroup; $groupbk=$groups; $userid = getnextid ($ldap,$template); $logtemplate=$template; $templates = parse_ini_file ('/etc/lliurex-lwat/admin.ini', true) ; $template = $templates[$template] ; //$sn = get_sn ($sn) ; $userldif['uidNumber'] = $userid ; //$userldif['gidNumber'] = $userid ; //El gidnumber se saca del grupo primario $userldif['uid'] = $username ; $userldif['cn'] = $cn ; $userldif['sabayonProfileName']=$profile; $userldif['userPassword'] = cryptgen($userpw) ; $userldif['description'] = $gecos ; $userldif['sn'] = $sn; if ($useLisGroup === true) { $groupldif["objectClass"] = array ("top", "posixGroup", 'lisGroup') ; $groupldif["groupType"] = "private" ; } else $groupldif["objectClass"] = array ("top", "posixGroup") ; $groupldif["cn"] = $username ; $groupldif["gidNumber"] = $userid ; $groupldif["description"] = "$cn personal group" ; $replace=array("%username%", "%base%", "%domain%", "%sn%") ; $replacewith =array($username, $base, $domain, $sn) ; foreach ($template as $key => $value) { $value = str_replace ($replace, $replacewith, $value) ; switch ($key) { case "ou": $ou=$value ; break ; case "groups": if (is_array ($groups)) $groups = array_merge (explode (" ", $value),$groups) ; else $groups = explode (" ", $value) ; break ; case "objectClass": $userldif['objectClass'] = explode (" ", $value); break ; default: $userldif[$key] = $value ; break ; } } //El primer grupo de $groups es considerado el grupo primario, se extraen en orden segun el orden en el fichero admin.ini if (getGidNumber($ldap,$groups[0])>0) $userldif['gidNumber'] = getGidNumber($ldap,$groups[0]) ; else return false; //Comprobamos que todos los grupos existan antes de añadir al usuario if (!checkGroups($ldap,$groups)) return false; if (in_array ('sambaSamAccount',$userldif['objectClass'])) $userldif = (array_merge($userldif, sambaAddInfo ($ldap, $userldif, $userpw))) ; if (!@ldap_add($ldap, "uid=" . $username . "," . $ou, $userldif)) { $ldaperr = ldap_errno ($ldap) ; switch ($ldaperr) { case 68: die (sprintf (_("The username %s already exists"), $username)) ; default: reportLdapError (ldap_errno ($ldap), "Add user") ; break ; } return false; } else { if (!isset($fd)){ llxUserSync("add", "uid=" . $username . "," . $ou, $userpw, $groups); } } if ($useLisGroup) $ou=$llxCreateGroup ; $nogroup = array (); foreach ($groups as $group) { if (strlen($group)>0) { $filter="(&(objectClass=posixGroup)(cn=" . $group . "))"; $want = array ('gidNumber'); $result = ldap_search($ldap, $groupbase, $filter, $want); $entries = ldap_get_entries ($ldap, $result); $gid= $entries[0]['gidnumber'][0] ; if (!userAddGroup ($ldap, $username, $gid, $fd)) $nogroup[] = $group ; } } //saving users pass in a log $log=new log($logtemplate); $sep="###"; $log->write($cn." ".$sn.$sep.$username.$sep.$userpw.$sep.date("d-m-y G:i:s")."\n"); if(isset($fd)) { $profile = str_replace("\n", "", $profile); if ($profile == "other") { $stringpreback = $username." ".$userpw." /home/".$username." ".$profile."s ".$groupbk[0]."\n"; } else { $stringpreback = $username." ".$userpw." /net/home/".$profile."s/".$username." ".$profile."s ".$groupbk[0]."\n"; } fwrite($fd,$stringpreback); } /* * Parece que no hace nada * * */ if (empty($nogroup)) return true ; foreach ($nogroup as $group) { $pos = in_array ($group, $groups,true) ; if (isset ($pos)) array_splice ($groups, $pos - 1 , 1) ; } return true ; } /* * Function : ldapDelUser - it delete users from ldap ************************************************************** * Arguments: * $userToDelete : type = array (string) : complet name (cn) collection's of users to be deleted * $ldap : type = resource : link return by ldap_connect * $base : type = string : cn base for ldap */ function ldapDelUser ($userToDelete,$ldap,$base) { $want = array ('cn') ; foreach ($userToDelete as $value ) { $filter = "member=" . $value ; $result = ldap_search ($ldap, $base, $filter, $want); $entries = ldap_get_entries ($ldap, $result); for ($i = 0 ; $i < $entries['count']; $i++) { $remove = array ("member" => $value) ; ldap_mod_del ($ldap, $entries[$i]["dn"], $remove) ; } } foreach ($userToDelete as $value ) { $dn = ldap_explode_dn ($value, 1) ; $filter = "memberUid=" . $dn[0] ; $result = ldap_search ($ldap, $groupbase, $filter, $want); $entries = ldap_get_entries ($ldap, $result); for ($i = 0 ; $i < $entries[count]; $i++) { $remove = array ("memberUid" => $dn[0]) ; ldap_mod_del ($ldap, $entries[$i]["dn"], $remove) ; } } foreach ($userToDelete as $value ) { $dn = ldap_explode_dn ($value, 0) ; $want = array ('gidNumber') ; $filter = $dn[0] ; $result = ldap_search ($ldap, $base, $filter, $want); $entries = ldap_get_entries ($ldap, $result); $want = array ('memberUid') ; $filter = "(&(objectClass=posixGroup)(gidNumber=" .$entries[0]['gidnumber'][0] . "))" ; $result = ldap_search ($ldap, $base, $filter, $want); $entries = ldap_get_entries ($ldap, $result); #Store User Information before delete it $need = array ("homeDirectory") ; $character = ","; $position = strpos($value, $character); $filter = substr($value,0,$position); $sr= ldap_search($ldap, $value,$filter, $need); $info = ldap_get_entries($ldap, $sr); ldap_delete ($ldap, $value); llxUserSync("del",$value,$info[0]["homedirectory"][0]); } } function ldapModUser($userToMod,$ldap,$base,$newgroups,$profile,$fd) { global $groupbase; $want = array ('cn') ; foreach ($userToMod as $usercn ) { $dnarray = ldap_explode_dn ($usercn, 1) ; $filter = "member=" . $value ; $result = ldap_search ($ldap, $base, $filter, $want); $entries = ldap_get_entries ($ldap, $result); for ($i = 0 ; $i < $entries['count']; $i++) { $remove = array ("member" => $value) ; ldap_mod_del ($ldap, $entries[$i]["dn"], $remove) ; } $parseoldgroups = ""; $filter = "memberUid=" . $dnarray[0] ; $result = ldap_search ($ldap, $base, $filter, $want); $entries = ldap_get_entries ($ldap, $result); for ($i = 0 ; $i < $entries[count]; $i++) { $parseoldgroups = $parseoldgroups . $entries[$i]["cn"][0].":"; $remove = array ("memberUid" => $dnarray[0]) ; ldap_mod_del ($ldap, $entries[$i]["dn"], $remove) ; } $parsenewgroups = ""; foreach ($newgroups as $group) { $parsenewgroups = $parsenewgroups .$group.":"; $filter ="(&(objectClass=posixGroup)(cn=" . $group . "))"; $want = array ('gidNumber'); $result = ldap_search($ldap, $groupbase, $filter, $want); $entries = ldap_get_entries ($ldap, $result); $gid = $entries[0]['gidnumber'][0] ; userAddGroup ($ldap, $dnarray[0], $gid, $fd); } $parsenewgroups = substr($parsenewgroups,0,strlen($parsenewgroups) - 1); $parseoldgroups = substr($parseoldgroups,0,strlen($parseoldgroups) - 1); if(isset($fd)) { $profile = str_replace("\n", "", $profile); if ($profile == "other") { $stringpreback = $dnarray[0].";".$userpw."/home/".$dnarray[0].";".$parseoldgroups.";".$parsenewgroups."\n"; } else { $stringpreback = $dnarray[0].";".$userpw."/net/home/".$profile."s/".$dnarray[0].";".$parseoldgroups.";".$parsenewgroups."\n"; } fwrite($fd,$stringpreback); } } } /**************************************************************************** * sambaAddInfo - Adds samba information for a user ***************** * Arguments: * Returns: ***************** * FIXME describe this function (and other not described functions in this file ****************************************************************************/ function sambaAddInfo ($ldap, $userldif, $userpw) { $sambahash = new smbHash () ; $sambaldif = array () ; $sambaldif['sambaSID'] = get_sambasid ($ldap, $userldif['uidNumber']) ; $sambaldif["sambaAcctFlags"] = "[U ]" ; $sambaldif["sambaLMPassword"] = $sambahash->lmhash($userpw) ; $sambaldif["sambaNTPassword"] = $sambahash->nthash($userpw) ; return $sambaldif ; } /**************************************************************************** * userAddGroup - Add a user into a group ***************** * Arguments: * Returns: ***************** * FIXME describe this function (and other not described functions in this file ****************************************************************************/ function userAddGroup ($ldap, $uid, $gid, $fd) { global $groupbase, $base ; $filter="(&(objectClass=posixAccount)(uid=" . $uid ."))"; $want = array('dn'); $result = ldap_search($ldap, $base, $filter, $want); $entries = ldap_get_entries ($ldap, $result) ; $llxUserDN = $entries[0] ["dn"]; $filter="(&(objectClass=posixGroup)(gidNumber=" . $gid . "))"; $want = array ('cn'); $searchbase=$groupbase ; $result = ldap_search($ldap, $searchbase, $filter, $want); $entries = ldap_get_entries ($ldap, $result); $groupdn=$entries[0]["dn"] ; $cn=$entries[0]["cn"][0] ; $change = array (); $change["memberUid"][] = $uid ; if (!@ldap_mod_add($ldap, $groupdn, $change)) { return false ; } if(!isset($fd)) { llxUserSync("addgroup", $llxUserDN , $groupdn); } $filter="(&(member=*)(cn=" . $cn . "))"; $result = ldap_search($ldap, $base, $filter, $want); $entries = ldap_get_entries ($ldap, $result); $groupdn=$entries[0]["dn"] ; $change = array (); if ($entries[count]) { $want = array (); $filter="(&(objectClass=posixAccount)(uid=" . $uid ."))"; $result = ldap_search($ldap, $base, $filter, $want); $entries = ldap_get_entries ($ldap, $result) ; $change["member"][] = $entries[0]["dn"] ; @ldap_mod_add($ldap, $groupdn, $change) ; if(!isset($fd)) { llxUserSync("addgroup", $llxUserDN , $groupdn); } } return true ; } /**************************************************************************** * get_profile - Return username's profile ***************** * Arguments: * connect - ldap connection * username - Username to check * Returns: * usernameś profile ***************** * search ldap for profile * if found * return profile (Administrador,Alumno,Profesor,Otro) ****************************************************************************/ function get_profile ($ldap, $username) { global $base ; //Comprobamos administradores $want = array ('gidnumber') ; $filter = "(&(objectClass=posixGroup)(cn=admins))" ; $result = ldap_search ($ldap, $base, $filter, $want); $entries = ldap_get_entries ($ldap, $result); //print($entries[0]['gidnumber'][0]); $gidnumber=$entries[0]['gidnumber'][0]; //Recuperamos miembros del grupo seleccionado $want = array ('memberUid') ; $filter = "(&(objectClass=posixGroup)(gidNumber=" . $gidnumber . "))" ; $result = ldap_search ($ldap, $base, $filter, $want); $entries = ldap_get_entries ($ldap, $result); //print($entries[0]['memberuid']); $users = array () ; $users=$entries[0]['memberuid']; if (is_array($users)) { $result = in_array ($username, $users,true) ; if ($result) return "Admin" ; } //Checking Teachers $want = array('cn'); $filter = "(uid=".$username.")" ; $group="ou=Teachers,ou=People,".$base; $result = ldap_search ($ldap, $group, $filter, $want); $entries = ldap_get_entries ($ldap, $result); $user=$entries[0]['cn']; if ($user) return "Profesor" ; //Checking Students $want = array('cn'); $filter = "(uid=".$username.")" ; $group="ou=Students,ou=People,".$base; $result = ldap_search ($ldap, $group, $filter, $want); $entries = ldap_get_entries ($ldap, $result); $user=$entries[0]['cn']; if ($user) return "Alumno" ; //Checking Others $want = array('cn'); $filter = "(uid=".$username.")" ; $group="ou=Other,ou=People,".$base; $result = ldap_search ($ldap, $group, $filter, $want); $entries = ldap_get_entries ($ldap, $result); $user=$entries[0]['cn']; if ($user) return "Otros" ; //Comprobamos si es el administrador del LDAP $filter = "(&(objectClass=simpleSecurityObject)(cn=$username))" ; $result= ldap_search ($ldap, $base, $filter); $entries = ldap_get_entries ($ldap, $result) ; if ($entries["count"]>0) return "Admin" ; } /**************************************************************************** * get_fullname - Return username's full name ***************** * Arguments: * connect - ldap connection * username - Username to check * Returns: * username's full name ****************************************************************************/ function get_fullname ($ldap, $username) { global $base ; $profile=get_profile($ldap, $username); $basedn=""; switch ($profile) { case "Admin": $basedn="ou=People,".$base; break; case "Profesor": $basedn="ou=Teachers,ou=People,".$base; break; case "Alumno": $basedn="ou=Students,ou=People,".$base; break; case "Otros": $basedn="ou=Teachers,ou=People,".$base; break; default: $basedn=$base; break; } $want = array ('cn') ; $filter = "(&(objectClass=posixAccount)(uid=".$username."))" ; $result = ldap_search ($ldap, $basedn, $filter, $want); $entries = ldap_get_entries ($ldap, $result); //print($entries[0]['gidnumber'][0]); $fullname=$entries[0]['cn'][0]; return $fullname; } /**************************************************************************** * getUser - Get "cn" or "uid" from a distinguished name "dn" ***************** * Arguments: * dn - * Returns: * cn or uid ***************** ****************************************************************************/ function getUser ($dn) { $user=""; if (isset($dn)){ $mycn = ldap_explode_dn ($dn, 0); $value=array(); $value=explode("=", $mycn[0]) ; if (!empty($value[1])) { $user=$value[1]; } } return $user ; } function checkGroups($ldap,$groups) { global $groupbase; foreach ($groups as $group) { if (strlen($group)>0){ $filter="(&(objectClass=posixGroup)(cn=" . $group . "))"; $want = array ('gidNumber'); $result = ldap_search($ldap, $groupbase, $filter, $want); $entries = ldap_get_entries ($ldap, $result); if ($entries[count]==0){ print _("The group ".$group." does not exist.")."
"; return false; } } } return true; } function getGidNumber ($ldap, $group) { global $groupbase; //$base="ou=Profiles,".$groupbase; $base=$groupbase; $want = array ('gidnumber') ; $filter = "(&(objectClass=posixGroup)(cn=".$group."))" ; $result = ldap_search ($ldap,$base, $filter, $want); $entries = ldap_get_entries ($ldap, $result); $gidnumber=$entries[0]['gidnumber'][0]; return $gidnumber; } function get_sabayon_list($ldap){ global $base; $basesabayon="ou=Sabayon,".$base; //$base=$groupbase; $want = array ('description','cn') ; $filter = "(&(objectClass=sabayonProfile))" ; $result = ldap_search ($ldap,$basesabayon, $filter, $want); ldap_sort($ldap,$result,"cn"); $entries = ldap_get_entries ($ldap, $result); for($i=0;$i0){ $filter="(&(objectClass=posixGroup)(cn=" . $group . "))"; $want = array ('gidNumber'); $result = ldap_search($ldap, $groupbase, $filter, $want); $entries = ldap_get_entries ($ldap, $result); if ($entries[count]>0){ return true; } } return false; } function createGroup ($ldap, $cn, $description) { global $groupbase, $base, $llxCreateGroup; $filter="(|(uid=" . $cn . ")(cn=" . $cn . "))"; $want = array ("cn","uid"); $searchbase=$base ; $result = ldap_search($ldap, $searchbase, $filter, $want); $entries = ldap_get_entries ($ldap, $result); if ($entries["count"] > 0) { return false; } else { $gidNumber = getnextid ($ldap,"") ; $add = array (); $add["objectClass"] = array ("top", "posixGroup") ; $add["cn"] = $cn ; $add["gidNumber"] = $gidNumber ; $add["description"] = $description ; if (isset($llxCreateGroup) && @ldap_add($ldap, "cn=" . $cn . "," . $llxCreateGroup, $add)){ return true; } } return false; } function existFullname ($ldap, $fullname,$template) { global $base ; $basedn=""; switch ($template) { case "Profesores": $basedn="ou=Teachers,ou=People,".$base; break; case "Alumnos": $basedn="ou=Students,ou=People,".$base; break; case "Otros": $basedn="ou=Teachers,ou=People,".$base; break; default: $basedn=$base; break; } $want = array ('cn') ; $filter = "(&(objectClass=posixAccount)(cn=".trim($fullname)."))" ; $result = ldap_search ($ldap, $basedn, $filter, $want); $entries = ldap_get_entries ($ldap, $result); if (strlen($entries[0]['cn'][0])>1) return true; else return false; } function muestra($cadena){ print($cadena."
"); } function llxEscape($text) { return str_replace("=", "==", $text); } function llxUnescape($text) { return str_replace("==", "=", $text); } function llxShowResponse($text) { $newText=$text; $llxCommand=""; $llxText=""; // $string="::STDOUT=llxcfg-cpkg: Running post-cpkg scripts ... = ::"; // verify format if (ereg("^::[a-zA-Z0-9_]+=.* = ::$", $newText)) { // remove :: $newText=ereg_replace("^::","",$newText); $newText=ereg_replace("::$","",$newText); // extract command and text $llxCommand=ereg_replace("=.*$","",$newText); $llxText=ereg_replace("^[a-zA-Z0-9_]+=","",$newText); if ($llxCommand == "STDOUT") { echo $llxText; } } } function llxUserSync() { $action=llxEscape(func_get_arg(0)); $glue=" = "; $string = "::USERSYNC=".$action.$glue; for($i = 1; $i < func_num_args(); $i++) { $newArg=func_get_arg($i); if (is_array($newArg)) { foreach ($newArg as $arg) { $string .= llxEscape($arg).$glue; } } else { $string .= llxEscape($newArg).$glue; } } $string .= "::\n"; $fp = stream_socket_client("unix:///var/run/llxcfg/llxcfg-ldap.sock", $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)
\n"; return false; } else { fwrite($fp, $string ); while (!feof($fp)) { fgets($fp, 1024); } } fclose($fp); return true; } /* * This validate is malignant. If lwat survives more that 1 August 2010, * look for better solution for this function. * */ function validate() { $path_token = '/backup/llxcfg/archive/vars/LDAP.varset'; return is_file($path_token); } ?>