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);
}
?>