* Admin: split password strength config in minimum length and number of character types, allow account backends specially AD to report password policy failures

This commit is contained in:
Ralf Becker 2013-06-25 16:37:44 +00:00
parent f33e49b4a5
commit aa1426b8de
16 changed files with 275 additions and 676 deletions

View File

@ -32,11 +32,6 @@
)
);
function boaccounts()
{
$this->so =& CreateObject('admin.soaccounts');
}
function delete_group($account_id='')
{
if(!$account_id || $GLOBALS['egw']->acl->check('group_access',32,'admin'))
@ -144,63 +139,6 @@
return False;
}
function add_user($userData)
{
if($GLOBALS['egw']->acl->check('account_access',4,'admin'))
{
return False;
}
$accountPrefix = '';
if(isset($GLOBALS['egw_info']['server']['account_prefix']))
{
$accountPrefix = $GLOBALS['egw_info']['server']['account_prefix'];
}
if($accountPrefix)
{
$userData['account_lid'] = $accountPrefix . $userData['account_lid'];
}
// add the primary group, to the users other groups, if not already added
if(is_array($userData['account_groups']))
{
if(!in_array($userData['account_primary_group'],$userData['account_groups']))
{
$userData['account_groups'][] = (int)$userData['account_primary_group'];
}
}
else
{
$userData['account_groups'] = array((int)$userData['account_primary_group']);
}
// do we have all needed data??
if(!($errors = $this->validate_user($userData)) &&
($userData['account_id'] = $account_id = $this->so->add_user($userData))) // no error in the creation
{
if($userData['anonymous'])
{
$GLOBALS['egw']->acl->add_repository('phpgwapi','anonymous',$account_id,1);
}
else
{
$GLOBALS['egw']->acl->delete_repository('phpgwapi','anonymous',$account_id);
}
// make this information for the hooks available
$GLOBALS['hook_values'] = $userData + array('new_passwd' => $userData['account_passwd']);
$GLOBALS['egw']->hooks->process($GLOBALS['hook_values']+array(
'location' => 'addaccount'
),False,True); // called for every app now, not only enabled ones
return True;
}
else
{
return $errors;
}
return False;
}
function edit_group($group_info)
{
if($GLOBALS['egw']->acl->check('group_access',16,'admin'))
@ -254,9 +192,16 @@
return True;
}
function edit_user($userData)
/**
* Process a user edit
*
* @param array $userData
* @param int $required_account_access=16 can be set to 4 for add user
* @return boolean|array with errors or true on success, false on acl failure
*/
function edit_user(&$userData, $required_account_access=16)
{
if($GLOBALS['egw']->acl->check('account_access',16,'admin'))
if($GLOBALS['egw']->acl->check('account_access',$required_account_access,'admin'))
{
return False;
}
@ -272,21 +217,17 @@
}
$errors = $this->validate_user($userData);
if(@is_array($errors))
if(!$errors)
{
return $errors;
}
else
{
$this->save_user($userData);
$errors = $this->save_user($userData);
$GLOBALS['hook_values'] = $userData;
$GLOBALS['egw']->hooks->process($GLOBALS['hook_values']+array(
'location' => 'editaccount'
),False,True); // called for every app now, not only enabled ones)
return True;
}
return True;
error_log(__METHOD__."(".array2string($userData).") returning ".array2string($errors ? $errors : true));
return $errors ? $errors : true;
}
function validate_group($group_info)
@ -326,31 +267,29 @@
}
}
/* checks if the userdata are valid
returns FALSE if the data are correct
otherwise the error array
*/
/**
* checks if the userdata are valid
*
* @return array with errors or empty array if there are none
*/
function validate_user(&$_userData)
{
$totalerrors = 0;
$errors = array();
if($GLOBALS['egw_info']['server']['account_repository'] == 'ldap' &&
(!$_userData['account_lastname'] && !$_userData['lastname']))
{
$error[$totalerrors] = lang('You must enter a lastname');
$totalerrors++;
$errors[] = lang('You must enter a lastname');
}
if(!$_userData['account_lid'])
{
$error[$totalerrors] = lang('You must enter a loginid');
$totalerrors++;
$errors[] = lang('You must enter a loginid');
}
if(!in_array($_userData['account_primary_group'],$_userData['account_groups']))
{
$error[$totalerrors] = lang('The groups must include the primary group');
$totalerrors++;
$errors[] = lang('The groups must include the primary group');
}
// Check if an account already exists as system user, and if it does deny creation
// (increase the totalerrors counter and the message thereof)
@ -358,8 +297,7 @@
!$GLOBALS['egw_info']['server']['ldap_allow_systemusernames'] && !$_userData['account_id'] &&
function_exists('posix_getpwnam') && posix_getpwnam($_userData['account_lid']))
{
$error[$totalerrors] = lang('There already is a system-user with this name. User\'s should not have the same name as a systemuser');
$totalerrors++;
$errors[] = lang('There already is a system-user with this name. User\'s should not have the same name as a systemuser');
}
if($_userData['old_loginid'] != $_userData['account_lid'])
{
@ -367,13 +305,12 @@
{
if($GLOBALS['egw']->accounts->exists($_userData['account_lid']) && $GLOBALS['egw']->accounts->get_type($_userData['account_lid'])=='g')
{
$error[$totalerrors] = lang('There already is a group with this name. Userid\'s can not have the same name as a groupid');
$errors[] = lang('There already is a group with this name. Userid\'s can not have the same name as a groupid');
}
else
{
$error[$totalerrors] = lang('That loginid has already been taken');
$errors[] = lang('That loginid has already been taken');
}
$totalerrors++;
}
}
@ -381,15 +318,13 @@
{
if($_userData['account_passwd'] != $_userData['account_passwd_2'])
{
$error[$totalerrors] = lang('The two passwords are not the same');
$totalerrors++;
$errors[] = lang('The two passwords are not the same');
}
}
if(!count($_userData['account_permissions']) && !count($_userData['account_groups']))
{
$error[$totalerrors] = lang('You must add at least 1 permission or group to this account');
$totalerrors++;
$errors[] = lang('You must add at least 1 permission or group to this account');
}
if($_userData['account_expires_month'] || $_userData['account_expires_day'] || $_userData['account_expires_year'] || $_userData['account_expires_never'])
@ -403,8 +338,7 @@
{
if(! checkdate($_userData['account_expires_month'],$_userData['account_expires_day'],$_userData['account_expires_year']))
{
$error[$totalerrors] = lang('You have entered an invalid expiration date');
$totalerrors++;
$errors[] = lang('You have entered an invalid expiration date');
}
else
{
@ -423,49 +357,64 @@
$check_account_file_space = explode('-', $_userData['file_space']);
if(preg_match("/\D/", $check_account_file_space[0]))
{
$error[$totalerrors] = lang('File space must be an integer');
$totalerrors++;
$errors[] = lang('File space must be an integer');
}
*/
if($totalerrors == 0)
{
return False;
}
else
{
return $error;
}
return $errors;
}
/* stores the userdata */
function save_user($_userData)
/**
* stores the userdata
*
* @param array &$_userData "account_id" got set for new accounts
* @return array with error-messages
*/
function save_user(array &$_userData)
{
//error_log(__METHOD__.array2string($_userData));
//error_log(__METHOD__.array2string($old_passwd));
$account =& CreateObject('phpgwapi.accounts',$_userData['account_id'],'u');
$account->update_data($_userData);
$account->save_repository();
error_log(__METHOD__."(".array2string($_userData).")");
$errors = array();
$account->set_memberships($_userData['account_groups'],$_userData['account_id']);
if($_userData['account_passwd'])
// do NOT save password via accounts::save, as pw policy violation can happen and we cant/dont report that way
$passwd = $_userData['account_passwd'];
unset($_userData['account_passwd']);
unset($_userData['account_passwd_2']);
if (!$GLOBALS['egw']->accounts->save($_userData))
{
$auth =& CreateObject('phpgwapi.auth');
$auth->change_password($old_passwd, $_userData['account_passwd'], $_userData['account_id']);
$GLOBALS['hook_values']['account_id'] = $_userData['account_id'];
$GLOBALS['hook_values']['old_passwd'] = $old_passwd;
$GLOBALS['hook_values']['new_passwd'] = $_userData['account_passwd'];
$errors[] = lang('Failed to save user!');
return $errors;
}
$GLOBALS['egw']->hooks->process($GLOBALS['hook_values']+array(
'location' => 'changepassword'
),False,True); // called for every app now, not only enabled ones)
if ($_userData['account_lastpwd_change']==0)
{
// change password sets the shadow_timestamp/account_lastpwd_change timestamp
// so we need to reset that to 0 as Admin required the change of password upon next login
unset($_userData['account_passwd']);
$this->save_user($_userData);
$GLOBALS['egw']->accounts->set_memberships($_userData['account_groups'],$_userData['account_id']);
if ($passwd)
{
try {
$auth = new auth();
if ($auth->change_password('', $passwd, $_userData['account_id']))
{
$GLOBALS['hook_values']['account_id'] = $_userData['account_id'];
$GLOBALS['hook_values']['old_passwd'] = '';
$GLOBALS['hook_values']['new_passwd'] = $_userData['account_passwd'];
$GLOBALS['egw']->hooks->process($GLOBALS['hook_values']+array(
'location' => 'changepassword'
),False,True); // called for every app now, not only enabled ones)
if ($_userData['account_lastpwd_change']==0)
{
// change password sets the shadow_timestamp/account_lastpwd_change timestamp
// so we need to reset that to 0 as Admin required the change of password upon next login
unset($_userData['account_passwd']);
$this->save_user($_userData);
}
}
else
{
$errors[] = lang('Failed to change password. Please contact your administrator.');
}
}
catch(Exception $e) {
$errors[] = $e->getMessage();
}
}
if ($_userData['account_lastpwd_change']==0)
@ -475,7 +424,7 @@
$auth->setLastPwdChange($_userData['account_id'],NULL, $_userData['account_lastpwd_change']);
}
$apps =& CreateObject('phpgwapi.applications',(int)$_userData['account_id']);
$apps = new applications((int)$_userData['account_id']);
if($_userData['account_permissions'])
{
foreach($_userData['account_permissions'] as $app => $enabled)
@ -488,7 +437,7 @@
}
$apps->save_repository();
$acl =& CreateObject('phpgwapi.acl',$_userData['account_id']);
$acl = new acl($_userData['account_id']);
if($_userData['anonymous'])
{
$acl->add_repository('phpgwapi','anonymous',$_userData['account_id'],1);
@ -506,6 +455,9 @@
$GLOBALS['egw']->acl->delete_repository('preferences','nopasswordchange',$_userData['account_id']);
}
$GLOBALS['egw']->session->delete_cache((int)$_userData['account_id']);
error_log(__METHOD__."(".array2string($_userData).") returning ".array2string($errors));
return $errors;
}
function load_group_managers($account_id)
@ -540,22 +492,4 @@
@reset($account_apps);
return $account_apps;
}
// xmlrpc functions
function rpc_add_user($data)
{
exit;
if(!$errors = $this->validate_user($data))
{
$result = $this->so->add_user($data);
}
else
{
$result = $errors;
}
return $result;
}
}
?>

View File

@ -1,92 +0,0 @@
<?php
/***************************************************************************\
* eGroupWare - account administration *
* http://www.egroupware.org *
* -------------------------------------------- *
* 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. *
\**************************************************************************/
/* $Id$ */
class soaccounts
{
function soaccounts()
{
}
function add_user($userData)
{
$userData['account_expires'] = $userData['expires'];
if($userData['email'] != "")
{
$userData['account_email'] = $userData['email'];
}
if ($userData['mustchangepassword'] == 1) $userData['account_lastpwd_change']=0;
if (!($userData['account_id'] = $GLOBALS['egw']->accounts->create($userData)))
{
return false;
}
$GLOBALS['egw']->accounts->set_memberships($userData['account_groups'],$userData['account_id']);
$apps =& CreateObject('phpgwapi.applications',$userData['account_id']);
$apps->read_installed_apps();
/* dont think this is still used -- RalfBecker 2006-06-03
// Read Group Apps
if ($userData['account_groups'])
{
$apps->account_type = 'g';
reset($userData['account_groups']);
while($groups = each($userData['account_groups']))
{
$apps->account_id = $groups[0];
$old_app_groups = $apps->read_account_specific();
@reset($old_app_groups);
while($old_group_app = each($old_app_groups))
{
if (!$apps_after[$old_group_app[0]])
{
$apps_after[$old_group_app[0]] = $old_app_groups[$old_group_app[0]];
}
}
}
}
*/
$apps->account_type = 'u';
$apps->account_id = $userData['account_id'];
$apps->data = Array(Array());
if ($userData['account_permissions'])
{
@reset($userData['account_permissions']);
while (list($app,$turned_on) = each($userData['account_permissions']))
{
if ($turned_on)
{
$apps->add($app);
/* dont think this is still used -- RalfBecker 2006-06-03
if (!$apps_after[$app])
{
$apps_after[] = $app;
}
*/
}
}
}
$apps->save_repository();
if (!$userData['changepassword'])
{
$GLOBALS['egw']->acl->add_repository('preferences','nopasswordchange',$userData['account_id'],1);
}
$apps->account_apps = array(array());
// $apps_after = array(array());
return $userData['account_id'];
}
}
?>

View File

@ -30,6 +30,10 @@
'set_group_managers' => True
);
/**
* Instance of boaccounts
* @var boaccounts
*/
var $bo;
var $nextmatchs;
var $apps_with_acl = array(
@ -51,7 +55,7 @@
'timesheet' => True
);
function uiaccounts()
function __construct()
{
$this->bo =& CreateObject('admin.boaccounts');
$this->nextmatchs =& CreateObject('phpgwapi.nextmatchs');
@ -131,7 +135,7 @@
unset($GLOBALS['egw_info']['flags']['nonavbar']);
$GLOBALS['egw_info']['flags']['app_header'] = $GLOBALS['egw_info']['apps']['admin']['title'].' - '.
lang('User groups');
$GLOBALS['egw']->common->egw_header();
common::egw_header();
$p =& CreateObject('phpgwapi.Template',EGW_APP_TPL);
$p->set_file(
@ -333,7 +337,7 @@
unset($GLOBALS['egw_info']['flags']['nonavbar']);
$GLOBALS['egw_info']['flags']['app_header'] = $GLOBALS['egw_info']['apps']['admin']['title'].' - '.
lang('User accounts');
$GLOBALS['egw']->common->egw_header();
common::egw_header();
$p =& CreateObject('phpgwapi.Template',EGW_APP_TPL);
@ -370,7 +374,7 @@
$uiaccountsel =& CreateObject('phpgwapi.uiaccountsel');
$p->set_var(array(
'left_next_matchs' => $this->nextmatchs->left('/index.php',$start,$total,$link_data),
'lang_showing' => ($_REQUEST['group_id'] ? $GLOBALS['egw']->common->grab_owner_name($_REQUEST['group_id']).': ' : '').
'lang_showing' => ($_REQUEST['group_id'] ? common::grab_owner_name($_REQUEST['group_id']).': ' : '').
($GLOBALS['query'] ? lang("Search %1 '%2'",lang($uiaccountsel->query_types[$_REQUEST['query_type']]),
html::htmlspecialchars($GLOBALS['query'])).': ' : '')
.$this->nextmatchs->show_hits($total,$start),
@ -458,9 +462,9 @@
$account['account_status'] = '<font color="red">' . lang('Disabled') . '</font>';
}
if (isset($account['account_created']))
$account['account_status'].= '<br>'.$GLOBALS['egw']->common->show_date($account['account_created'],$GLOBALS['egw_info']['user']['preferences']['common']['dateformat']);
$account['account_status'].= '<br>'.common::show_date($account['account_created'],$GLOBALS['egw_info']['user']['preferences']['common']['dateformat']);
if (isset($account['account_modified']))
$account['account_status'].= '<br>'.$GLOBALS['egw']->common->show_date($account['account_modified'],$GLOBALS['egw_info']['user']['preferences']['common']['dateformat']);
$account['account_status'].= '<br>'.common::show_date($account['account_modified'],$GLOBALS['egw_info']['user']['preferences']['common']['dateformat']);
$p->set_var($account);
@ -529,7 +533,7 @@
if(is_array($errors))
{
$this->create_edit_group($group_info,$errors);
$GLOBALS['egw']->common->egw_exit();
common::egw_exit();
}
$GLOBALS['egw']->redirect($GLOBALS['egw']->link('/index.php','menuaction=admin.uiaccounts.list_groups'));
}
@ -547,61 +551,7 @@
function add_user()
{
if ($GLOBALS['egw']->acl->check('account_access',4,'admin'))
{
$this->list_users();
return;
}
if($_POST['submit'])
{
if(!($email = $_POST['account_email']))
{
$email = $GLOBALS['egw']->common->email_address($_POST['account_firstname'],$_POST['account_lastname'],$_POST['account_lid']);
}
$userData = array(
'account_type' => 'u',
'account_lid' => $_POST['account_lid'],
'account_firstname' => $_POST['account_firstname'],
'account_lastname' => $_POST['account_lastname'],
'account_passwd' => $_POST['account_passwd'],
'status' => ($_POST['account_status'] ? 'A' : ''),
'account_status' => ($_POST['account_status'] ? 'A' : ''),
'old_loginid' => ($_GET['old_loginid']?rawurldecode($_GET['old_loginid']):''),
'account_id' => ($_GET['account_id']?$_GET['account_id']:0),
'account_primary_group' => $_POST['account_primary_group'],
'account_passwd_2' => $_POST['account_passwd_2'],
'account_groups' => $_POST['account_groups'],
'anonymous' => $_POST['anonymous'],
'changepassword' => $_POST['changepassword'],
'mustchangepassword' => $_POST['mustchangepassword'],
'account_permissions' => $_POST['account_permissions'],
'homedirectory' => $_POST['homedirectory'],
'loginshell' => $_POST['loginshell'],
'account_expires_never' => $_POST['never_expires'],
'account_email' => $email
/* 'file_space' => $_POST['account_file_space_number'] . "-" . $_POST['account_file_space_type'] */
);
if ($userData['mustchangpassword']) $userData['account_lastpwd_change']=0;
/* when does the account expire */
if ($_POST['expires'] !== '' && !$_POST['never_expires'])
{
$jscal =& CreateObject('phpgwapi.jscalendar',False);
$userData += $jscal->input2date($_POST['expires'],False,'account_expires_day','account_expires_month','account_expires_year');
}
$errors = $this->bo->add_user($userData);
if(is_array($errors))
{
$this->create_edit_user(0,$userData,$errors);
$GLOBALS['egw']->common->egw_exit();
}
$GLOBALS['egw']->redirect($GLOBALS['egw']->link('/index.php','menuaction=admin.uiaccounts.list_users'));
}
else
{
$this->create_edit_user(0);
}
return $this->edit_user('', '', 4);
}
function delete_group()
@ -618,7 +568,7 @@
unset($GLOBALS['egw_info']['flags']['noheader']);
unset($GLOBALS['egw_info']['flags']['nonavbar']);
$GLOBALS['egw']->common->egw_header();
common::egw_header();
$p =& CreateObject('phpgwapi.Template',EGW_APP_TPL);
$p->set_file(
@ -647,7 +597,7 @@
'menuaction' => 'admin.uiaccounts.edit_user',
'account_id' => $id
)
) . '">' . $GLOBALS['egw']->common->grab_owner_name($id) . '</a><br>';
) . '">' . common::grab_owner_name($id) . '</a><br>';
}
$p->set_var('message_display',$user_list);
$p->parse('messages','message_row',True);
@ -695,7 +645,7 @@
unset($GLOBALS['egw_info']['flags']['noheader']);
unset($GLOBALS['egw_info']['flags']['nonavbar']);
$GLOBALS['egw']->common->egw_header();
common::egw_header();
$t =& CreateObject('phpgwapi.Template',EGW_APP_TPL);
$t->set_file(
@ -767,7 +717,7 @@
if(is_array($errors))
{
$this->create_edit_group($group_info,$errors);
$GLOBALS['egw']->common->egw_exit();
common::egw_exit();
}
$GLOBALS['egw']->redirect($GLOBALS['egw']->link('/index.php','menuaction=admin.uiaccounts.list_groups'));
}
@ -838,9 +788,9 @@
//NDEE
}
function edit_user($cd='',$account_id='')
function edit_user($cd='',$account_id='', $required_account_access=16)
{
if($GLOBALS['egw']->acl->check('account_access',16,'admin'))
if($GLOBALS['egw']->acl->check('account_access',$required_account_access,'admin') || isset($_POST['cancel']))
{
$this->list_users();
return False;
@ -850,9 +800,10 @@
{
if(!($email = $_POST['account_email']))
{
$email = $GLOBALS['egw']->common->email_address($_POST['account_firstname'],$_POST['account_lastname'],$_POST['account_lid']);
$email = common::email_address($_POST['account_firstname'],$_POST['account_lastname'],$_POST['account_lid']);
}
$userData = array(
'account_type' => 'u',
'account_lid' => $_POST['account_lid'],
'account_firstname' => $_POST['account_firstname'],
'account_lastname' => $_POST['account_lastname'],
@ -894,10 +845,10 @@
}
if($_POST['expires'] !== '' && !$_POST['never_expires'])
{
$jscal =& CreateObject('phpgwapi.jscalendar',False);
$jscal = new jscalendar(False);
$userData += $jscal->input2date($_POST['expires'],False,'account_expires_day','account_expires_month','account_expires_year');
}
$errors = $this->bo->edit_user($userData);
$errors = $this->bo->edit_user($userData, $required_account_access);
if(!@is_array($errors))
{
@ -939,12 +890,12 @@
// todo
// not needed if i use the same file for new users too
if(!$account_id)
/*if(!$account_id)
{
$this->list_users();
return False;
}
else
else*/
{
$this->create_edit_user($account_id);
}
@ -960,7 +911,7 @@
}
unset($GLOBALS['egw_info']['flags']['noheader']);
unset($GLOBALS['egw_info']['flags']['nonavbar']);
$GLOBALS['egw']->common->egw_header();
common::egw_header();
$t =& CreateObject('phpgwapi.Template',EGW_APP_TPL);
$t->set_unknowns('remove');
@ -1019,14 +970,14 @@
{
$var['account_status'] = '<b>' . lang('Disabled') . '</b>';
}
if (isset($userData['account_created'])) $var['account_status'].= '<br>'.lang('Created').': '.$GLOBALS['egw']->common->show_date($userData['account_created']);
if (isset($userData['account_modified'])) $var['account_status'].= '<br>'.lang('Modified').': '.$GLOBALS['egw']->common->show_date($userData['account_modified']);
if (isset($userData['account_created'])) $var['account_status'].= '<br>'.lang('Created').': '.common::show_date($userData['account_created']);
if (isset($userData['account_modified'])) $var['account_status'].= '<br>'.lang('Modified').': '.common::show_date($userData['account_modified']);
// Last login time
if ($userData['lastlogin'])
{
$var['account_lastlogin'] = $GLOBALS['egw']->common->show_date($userData['lastlogin']);
$var['account_lastlogin'] = common::show_date($userData['lastlogin']);
}
else
{
@ -1046,7 +997,7 @@
// Account expires
if ($userData['expires'] != -1)
{
$var['input_expires'] = $GLOBALS['egw']->common->show_date($userData['expires']);
$var['input_expires'] = common::show_date($userData['expires']);
}
else
{
@ -1169,7 +1120,7 @@
{
unset($GLOBALS['egw_info']['flags']['noheader']);
unset($GLOBALS['egw_info']['flags']['nonavbar']);
$GLOBALS['egw']->common->egw_header();
common::egw_header();
$p =& CreateObject('phpgwapi.Template',EGW_APP_TPL);
$p->set_file(Array('edit' => 'group_form.tpl'));
@ -1188,7 +1139,7 @@
'lang_group_name' => lang('group name'),
'group_name_value' => $group_info['account_name'],
'lang_include_user' => lang('Select users for inclusion'),
'error' => (!$_errors?'':'<center>'.$GLOBALS['egw']->common->error_list($_errors).'</center>'),
'error' => (!$_errors?'':'<center>'.common::error_list($_errors).'</center>'),
'lang_permissions' => lang('Permissions this group has')
);
$p->set_var($var);
@ -1265,7 +1216,7 @@
. '<td><input type="checkbox" name="account_apps['
. $perm_display[$i][0] . ']" value="True"'.($group_info['account_apps'][$app]?' checked':'').'> '
. ($acl_action?'<a href="'.$acl_action.'"'.$options
. '><img src="'.$GLOBALS['egw']->common->image('phpgwapi','edit').'" border="0" hspace="3" align="absmiddle" title="'
. '><img src="'.common::image('phpgwapi','edit').'" border="0" hspace="3" align="absmiddle" title="'
. lang('Grant Access').': '.lang("edit group ACL's").'"></a>':'&nbsp;').'</td>'.($i & 1?'</tr>':'')."\n";
}
if($i & 1)
@ -1330,18 +1281,16 @@
unset($GLOBALS['egw_info']['flags']['noheader']);
unset($GLOBALS['egw_info']['flags']['nonavbar']);
$GLOBALS['egw']->common->egw_header();
common::egw_header();
$t =& CreateObject('phpgwapi.Template',EGW_APP_TPL);
$t->set_unknowns('remove');
if ($GLOBALS['egw_info']['server']['ldap_extra_attributes'] && ($GLOBALS['egw_info']['server']['account_repository'] == 'ldap'))
$t->set_file(array('account' => 'account_form.tpl'));
$t->set_block('account', 'ldap_extra');
if (!$GLOBALS['egw_info']['server']['ldap_extra_attributes'] || $GLOBALS['egw_info']['server']['account_repository'] != 'ldap')
{
$t->set_file(array('account' => 'account_form_ldap.tpl'));
}
else
{
$t->set_file(array('account' => 'account_form.tpl'));
$t->set_var('ldap_extra', '');
}
$t->set_block('account','form','form');
$t->set_block('account','form_passwordinfo','form_passwordinfo');
@ -1356,16 +1305,13 @@
{
$userData = Array();
$userData=$_userData;
// $userData['firstname'] = $userData['account_firstname'];
// $userData['lastname'] = $userData['account_lastname'];
@reset($userData['account_groups']);
while (list($key, $value) = @each($userData['account_groups']))
{
$userGroups[$key]['account_id'] = $value;
}
$account =& CreateObject('phpgwapi.accounts');
$allGroups = $account->get_list('groups');
$allGroups = $GLOBALS['egw']->accounts->get_list('groups');
}
elseif(is_string($_userData) && $_userData=='')
{
@ -1388,7 +1334,6 @@
}
else
{
$account =& CreateObject('phpgwapi.accounts');
$userData = Array();
$userData['status'] = 'A';
$userGroups = Array();
@ -1407,7 +1352,7 @@
$var = Array(
'form_action' => $GLOBALS['egw']->link('/index.php',$page_params),
'error_messages' => (!$_errors?'':'<center>'.$GLOBALS['egw']->common->error_list($_errors).'</center>'),
'error_messages' => (!$_errors?'':'<div style="color: red; font-style: italics">'.common::error_list($_errors).'</div>'),
'th_bg' => $GLOBALS['egw_info']['theme']['th_bg'],
'tr_color1' => $GLOBALS['egw_info']['theme']['row_on'],
'tr_color2' => $GLOBALS['egw_info']['theme']['row_off'],
@ -1427,6 +1372,8 @@
'lang_mustchangepassword'=> lang('Must change password upon next login'),
'lang_button' => ($_account_id?lang('Save'):lang('Add')),
'lang_passwds_unequal' => lang('The two passwords are not the same'),
'lang_cancel' => lang('Cancel'),
'cancel_action' => "document.location='".egw::link('/index.php', array('menuaction' => 'admin.uiaccounts.list_users'))."';",
/* 'lang_file_space' => lang('File Space') */
);
$t->set_var($var);
@ -1496,16 +1443,16 @@
'changepassword' => '<input type="checkbox" name="changepassword" value="1"'.($userData['changepassword'] ? ' checked' : '').'>',
'mustchangepassword' => '<input type="checkbox" name="mustchangepassword" value="1"'.($userData['mustchangepassword'] ? ' checked' : '').'>',
'account_status' => '<input type="checkbox" name="account_status" value="A"'.($userData['status']?' checked':'').'>',
'account_firstname' => '<input id="firstname" onchange="check_account_email(this.id);" name="account_firstname" maxlength="50" value="' . $userData['firstname'] . '">',
'account_lastname' => '<input id="lastname" onchange="check_account_email(this.id);" name="account_lastname" maxlength="50" value="' . $userData['lastname'] . '">',
'account_email' => '<input id="email" onchange="email_set=0; check_account_email(this.id);" name="account_email" size="32" maxlength="100" value="' . $userData['email'] . '">',
'account_firstname' => '<input id="firstname" onchange="check_account_email(this.id);" name="account_firstname" maxlength="50" value="' . $userData['account_firstname'] . '">',
'account_lastname' => '<input id="lastname" onchange="check_account_email(this.id);" name="account_lastname" maxlength="50" value="' . $userData['account_lastname'] . '">',
'account_email' => '<input id="email" onchange="email_set=0; check_account_email(this.id);" name="account_email" size="32" maxlength="100" value="' . $userData['account_email'] . '">',
'account_passwd' => $userData['account_passwd'],
'account_passwd_2' => $userData['account_passwd_2'],
'account_file_space' => $account_file_space,
'account_id' => (int) $userData['account_id']
);
if (isset($userData['account_created'])) $var['account_status'].= '<br>'.lang('Created').': '.$GLOBALS['egw']->common->show_date($userData['account_created']);
if (isset($userData['account_modified'])) $var['account_status'].= '<br>'.lang('Modified').': '.$GLOBALS['egw']->common->show_date($userData['account_modified']);
if (isset($userData['account_created'])) $var['account_status'].= '<br>'.lang('Created').': '.common::show_date($userData['account_created']);
if (isset($userData['account_modified'])) $var['account_status'].= '<br>'.lang('Modified').': '.common::show_date($userData['account_modified']);
if($userData['expires'] == -1)
@ -1576,7 +1523,7 @@
$part[$i&1] = sprintf('<td>%s</td><td><input type="checkbox" name="account_permissions[%s]" value="True"%s>',
$data['title'],$app,$checked).
($acl_action?'<a href="'.$acl_action.'"'.$options
. '><img src="'.$GLOBALS['egw']->common->image('phpgwapi','edit').'" border="0" hspace="3" align="absmiddle" title="'
. '><img src="'.common::image('phpgwapi','edit').'" border="0" hspace="3" align="absmiddle" title="'
. lang('Grant Access').'"></a>':'&nbsp;').'</td>';
if ($i & 1)
@ -1624,7 +1571,7 @@
// $menuClass =& CreateObject('admin.uimenuclass');
// This is now using ExecMethod()
$GLOBALS['account_id'] = $_account_id;
$t->set_var('rows',ExecMethod('admin.uimenuclass.createHTMLCode','edit_user'));
$t->set_var('rows', $_account_id ? ExecMethod('admin.uimenuclass.createHTMLCode','edit_user') : '');
echo $t->fp('out','form');
}
@ -1634,7 +1581,7 @@
$response = new xajaxResponse();
if (!$email)
{
$response->addAssign('email','value',$GLOBALS['egw']->common->email_address($first,$last,$account_lid));
$response->addAssign('email','value',common::email_address($first,$last,$account_lid));
}
$id_account_lid = (int) $GLOBALS['egw']->accounts->name2id($account_lid);
if ($id == 'account' && $id_account_lid && $id_account_lid != (int) $account_id)
@ -1665,13 +1612,13 @@
{
$user_list .= '<option value="' . $entry['account_id'] . '"'
. $group_info['account_managers'][(int)$entry['account_id']] . '>'
. $GLOBALS['egw']->common->grab_owner_name($entry['account_id'])
. common::grab_owner_name($entry['account_id'])
. '</option>'."\n";
}
unset($GLOBALS['egw_info']['flags']['noheader']);
unset($GLOBALS['egw_info']['flags']['nonavbar']);
$GLOBALS['egw']->common->egw_header();
common::egw_header();
$t =& CreateObject('phpgwapi.Template',EGW_APP_TPL);
$t->set_unknowns('remove');
@ -1708,7 +1655,7 @@
if($GLOBALS['egw']->acl->check('group_access',16,'admin') || $_POST['cancel'])
{
$GLOBALS['egw']->redirect_link('/index.php','menuaction=admin.uiaccounts.list_groups');
$GLOBALS['egw']->common->egw_exit();
common::egw_exit();
}
elseif($_POST['submit'])
{
@ -1728,7 +1675,7 @@
}
}
$GLOBALS['egw']->redirect($GLOBALS['egw']->link('/index.php','menuaction=admin.uiaccounts.list_groups'));
$GLOBALS['egw']->common->egw_exit();
common::egw_exit();
}
/**

View File

@ -272,7 +272,6 @@ enter your http proxy server port admin de HTTP-Proxy-Server-Port
enter your smtp server hostname or ip address admin de SMTP-Server Hostname oder IP-Adresse
enter your smtp server port admin de SMTP-Server Port
error canceling timer, maybe there's none set !!! admin de Fehler beim Abbrechen des Test-Jobs, eventuell läuft gar kein Job !!!
error changing the password for % !!! admin de Fehler beim Ändern des Passworts für % !
error changing the password for %1 !!! admin de Fehler beim Ändern des Passworts für %1 !
error deleting log entry! admin de Fehler beim Löschen des Protokolleintrags!
error saving admin de Fehler beim Speichern
@ -296,7 +295,6 @@ file space admin de Speicherplatz
file space must be an integer admin de Speicherplatz muss eine Zahl sein
for the times above admin de für die oben angegebenen Zeiten
for the times below (empty values count as '*', all empty = every minute) admin de für die darunter angegebenen Zeiten (leere Felder zählen als "*", alles leer = jede Minute)
force password strength (1-5, default empty: no check against rules for a strong password)? admin de Erzwinge eine gewisse Qualität der Passwörter im Passwort-Ändern Dialog (1-5, 1:gering, 5=stark; Default=leer kein Check gegen Regeln zur Passwortqualität)
force selectbox admin de Auswahl erzwingen
force users to change their password regularily?(empty for no,number for after that number of days admin de Erzwinge das ändern von Passwörtern durch den Benutzer nach X Tagen. (leer für nein, eine positive Zahl für alle X Tage)
forward also to admin de Zusätzlich weiterleiten an
@ -453,6 +451,8 @@ passthrough admin de durchgehend
password for smtp-authentication admin de Passwort für SMTP Authentifizierung
password updated admin de Passwort aktualisiert
passwords and/or attributes of %1 accounts changed admin de Passwörter und/oder Attribute von %1 Benutzern geändert
passwords require a minimum number of characters admin de Passworte benötigen diese Mindestanzahl Zeichen
passwords requires this number of different character classes admin de Passworte benötigen mindestens soviele Zeichenklassen
path information admin de Pfad-Information
peer server list admin de Liste der Server im Verbund
peer servers admin de Server-Verbund
@ -603,6 +603,7 @@ unknown option %1 admin de Unbekannte Option %1
unwilling to save category with current settings. check for inconsistency: admin de Kategorie kann mit den aktuellen Einstellungen nicht gespeichert werden. Bitte überprüfen sie die Einstellungen auf Ungereimtheiten
up admin de hoch
updated admin de aktualisiert
uppercase, lowercase, number, special char admin de Großbuchstaben, kleine Buchstaben, Zahlen, Sonderzeichen
url of the egroupware installation, eg. http://domain.com/egroupware admin de URL der EGroupware Installation, z.B. http://domain.com/egroupware
usage admin de Einsatz
use cookies to pass sessionid admin de Sitzungs-ID in einem Cookie speichern

View File

@ -273,7 +273,6 @@ enter your http proxy server port admin en Enter your HTTP proxy server port
enter your smtp server hostname or ip address admin en Enter your SMTP server hostname or IP address
enter your smtp server port admin en Enter your SMTP server port
error canceling timer, maybe there's none set !!! admin en Error canceling timer, maybe there's none set!
error changing the password for % !!! admin en Error changing the password for % !
error changing the password for %1 !!! admin en Error changing the password for %1 !
error deleting log entry! admin en Error deleting log entry!
error saving admin en Error saving!
@ -297,7 +296,6 @@ file space admin en File space
file space must be an integer admin en File space must be an integer
for the times above admin en For the times above
for the times below (empty values count as '*', all empty = every minute) admin en For the times below: empty values count as '*', all empty = every minute.
force password strength (1-5, default empty: no check against rules for a strong password)? admin en Set required password strength. 1 = weak, up to 5 = very strong. Default = empty, no password strength checked
force selectbox admin en Force select box
force users to change their password regularily?(empty for no,number for after that number of days admin en Set recurrent forced password change. Set a number of days. Empty = No
forward also to admin en Forward also to
@ -454,6 +452,8 @@ passthrough admin en Passthrough
password for smtp-authentication admin en Password for SMTP authentication
password updated admin en Password updated.
passwords and/or attributes of %1 accounts changed admin en Passwords and/or attributes of %1 accounts changed
passwords require a minimum number of characters admin en Passwords require a minimum number of characters
passwords requires this number of different character classes admin en Passwords requires this number of different character classes
path information admin en Path information
peer server list admin en Peer server list
peer servers admin en Peer servers
@ -604,6 +604,7 @@ unknown option %1 admin en Unknown option %1 !
unwilling to save category with current settings. check for inconsistency: admin en Unable to save category with current settings. Check for inconsistency:
up admin en Up
updated admin en Updated
uppercase, lowercase, number, special char admin en Uppercase, lowercase, number, special char
url of the egroupware installation, eg. http://domain.com/egroupware admin en URL of the EGroupware installation, e.g. http://domain.com/egroupware
usage admin en Usage
use cookies to pass sessionid admin en Use cookies to pass session ID

View File

@ -61,7 +61,14 @@ function check_password(id)
</tr>
{password_fields}
<!-- BEGIN ldap_extra -->
<tr class="row_off">
<td>{lang_homedir}</td>
<td>{homedirectory}&nbsp;</td>
<td>{lang_shell}</td>
<td>{loginshell}&nbsp;</td>
</tr>
<!-- END ldap_extra -->
<tr class="row_on">
<td>{lang_mustchangepassword}</td>
<td>{mustchangepassword}</td>
@ -120,7 +127,10 @@ function check_password(id)
<!-- BEGIN form_buttons_ -->
<tr class="row_off">
<td colspan="4" align="right"><input type="submit" name="submit" value="{lang_button}"></td>
<td colspan="4" align="right">
<input type="submit" name="submit" value="{lang_button}">
<input type="submit" name="cancel" value="{lang_cancel}" onclick="{cancel_action}; return false;">
</td>
</tr>
<!-- END form_buttons_ -->

View File

@ -1,149 +0,0 @@
<!-- BEGIN form -->
{error_messages}
<script>
var email_set=0;
function check_account_email(id)
{
account = document.getElementById('account').value;
firstname = document.getElementById('firstname').value;
lastname = document.getElementById('lastname').value;
email = document.getElementById('email').value;
if (!email || email_set || id == 'account')
{
xajax_doXMLHTTP('admin.uiaccounts.ajax_check_account_email',firstname,lastname,account,{account_id},email_set ? '' : email,id);
email_set = !email || email_set;
}
}
function check_password(id)
{
password = document.getElementById('password').value;
password2 = document.getElementById('password2').value;
if (password && (password2 || id == 'password2') && password != password2)
{
alert('{lang_passwds_unequal}');
document.getElementById('password2').value = '';
document.getElementById('password').select();
document.getElementById('password').focus();
return false;
}
return true;
}
</script>
<form method="POST" action="{form_action}">
<div align="center">
<table border="0" width="95%">
<tr>
<td valign="top">
{rows}
</td>
<td valign="top">
<table border=0 width=100%>
<tr class="th">
<td colspan="4"><b>{lang_action}</b></td>
</tr>
<tr class="row_on">
<td width="25%">{lang_loginid}</td>
<td width="25%">{account_lid}&nbsp;</td>
<td width="25%">{lang_account_active}:</td>
<td width="25%">{account_status}</td>
</tr>
<tr class="row_off">
<td>{lang_firstname}</td>
<td>{account_firstname}&nbsp;</td>
<td>{lang_lastname}</td>
<td>{account_lastname}&nbsp;</td>
</tr>
{password_fields}
<tr class="row_on">
<td>{lang_mustchangepassword}</td>
<td>{mustchangepassword}</td>
<td></td>
<td></td>
</tr>
<tr class="row_off">
<td>{lang_homedir}</td>
<td>{homedirectory}&nbsp;</td>
<td>{lang_shell}</td>
<td>{loginshell}&nbsp;</td>
</tr>
<tr class="row_off">
<td>{lang_expires}</td>
<td>{input_expires}&nbsp;&nbsp;{lang_never}&nbsp;{never_expires}</td>
<td>{lang_email}</td>
<td>{account_email}</td>
</tr>
<tr class="row_on">
<td>{lang_changepassword}</td>
<td>{changepassword}</td>
<td>{lang_anonymous}</td>
<td>{anonymous}</td>
</tr>
<tr class="row_off">
<td>{lang_groups}</td>
<td>{groups_select}&nbsp;</td>
<td>{lang_primary_group}</td>
<td>{primary_group_select}&nbsp;</td>
</tr>
<tr class="th">
<td>{lang_app}</td>
<td>{lang_acl}</td>
<td>{lang_app}</td>
<td>{lang_acl}</td>
</tr>
{permissions_list}
{form_buttons}
</table>
</td>
</tr>
</table>
</div>
</form>
<!-- END form -->
<!-- BEGIN form_passwordinfo -->
<tr class="row_on">
<td>{lang_password}</td>
<td><input type="password" name="account_passwd" value="{account_passwd}" autocomplete="off"></td>
<td>{lang_reenter_password}</td>
<td><input type="password" name="account_passwd_2" value="{account_passwd_2}" autocomplete="off"></td>
</tr>
<!-- END form_passwordinfo -->
<!-- BEGIN form_buttons_ -->
<tr class="row_off">
<td colspan="4" align="right"><input type="submit" name="submit" value="{lang_button}"></td>
</tr>
<!-- END form_buttons_ -->
<!-- BEGIN form_logininfo -->
<tr class="row_on">
<td>{lang_lastlogin}</td>
<td>{account_lastlogin}</td>
<td>{lang_lastloginfrom}</td>
<td>{account_lastloginfrom}</td>
</tr>
<!-- END form_logininfo -->
<!-- BEGIN link_row -->
<tr bgcolor="{tr_color}">
<td>&nbsp;<a href="{row_link}">{row_text}</a></td>
</tr>
<!-- END link_row -->

View File

@ -1,84 +0,0 @@
<!-- BEGIN form -->
<form method="POST" action="{form_action}">
<center>
<table border="0" width="95%">
<tr>
<td valign="top">
{rows}
</td>
<td>
<table border=0 width=100% cellspacing="1" cellpadding="2">
<tr bgcolor="{th_bg}">
<td colspan="2" style="padding-left:10px; text-align: left">
<b>{lang_email_config}<img src="{info_icon}" border="0" onMouseOver="this.T_TITLE='Info:'; this.T_WIDTH=250; return escape('<p>{lang_info_UsageHints}</p>')" /></b>
</td>
<td align="right">
<input type="checkbox" name="accountStatus" {account_checked}>
{lang_emailaccount_active}<img src="{info_icon}" border="0" onMouseOver="this.T_TITLE='Info:'; this.T_WIDTH=250; return escape('<p>{lang_info_AccountActive}</p>')" />
</td>
</tr>
<tr bgcolor="{tr_color1}">
<td style="padding-left:10px; text-align: left">{lang_masterEmailAddress}<img src="{info_icon}" border="0" onMouseOver="this.T_TITLE='Info:'; this.T_WIDTH=250; return escape('<p>{lang_info_masterEmailAddress}</p>')" /></td>
<td colspan="2" style="text-align: left"><input name="mail" value="{mail}" size=35></td>
</tr>
<tr bgcolor="{tr_color2}">
<td rowspan="4" style="padding-left:10px; vertical-align: top; text-align: left;">{lang_mailAliases}<img src="{info_icon}" border="0" onMouseOver="this.T_TITLE='Info:'; this.T_WIDTH=250; return escape('<p>{lang_info_mailAliases}</p>')" /></td>
<td rowspan="4" style="text-align: left">{options_mailAlternateAddress}</td>
<td align="center">
<input type="submit" value="{lang_remove} -->" name="remove_mailAlternateAddress">
</td>
</tr>
<tr bgcolor="{tr_color1}">
<td>
&nbsp;
</td>
</tr>
<tr bgcolor="{tr_color2}">
<td align="center">
<input name="mailAlternateAddressInput" value="" size=35>
</td>
</tr>
<tr bgcolor="{tr_color2}">
<td align="center">
<input type="submit" value="<-- {lang_add}" name="add_mailAlternateAddress">
</td>
</tr>
<tr bgcolor="{tr_color1}">
<td style="padding-left:10px; text-align: left">
{lang_RouteMailsTo}<img src="{info_icon}" border="0" onMouseOver="this.T_TITLE='Info:'; this.T_WIDTH=250; return escape('<p>{lang_info_RouteMailsTo}</p>')" />
</td>
<td colspan="2" style="text-align: left">
<input name="mailForwardingAddress" value="{mailForwardingAddress}" size=35>
</td>
</tr>
<tr>
<td colspan="3">
&nbsp;
</td>
</tr>
<tr>
<td colspan="3">
&nbsp;
</td>
</tr>
</table>
<table border=0 width=100%>
<tr bgcolor="{tr_color1}">
<td align="right" colspan="2">
<input type="submit" name="save" value="{lang_button}">
</td>
</tr>
</table>
</td>
</tr>
</table>
</center>
</form>
<!-- END form -->
<!-- BEGIN link_row -->
<tr bgcolor="{tr_color}">
<td colspan="2">&nbsp;&nbsp;<a href="{row_link}">{row_text}</a></td>
</tr>
<!-- END link_row -->

View File

@ -231,13 +231,34 @@
</tr>
<tr class="row_off">
<td>{lang_Force_password_strength_(1-5,_default_empty: no check against rules for a strong password)?}:</td>
<td>{lang_Passwords_require_a_minimum_number_of_characters}:</td>
<td>
<input name="newsettings[force_pwd_strength]" value="{value_force_pwd_strength}" size="5">
<select name="newsettings[force_pwd_length]">
<option value="">{lang_None}</options>
<option value="6"{selected_force_pwd_length_6}>6</option>
<option value="7"{selected_force_pwd_length_7}>7</option>
<option value="8"{selected_force_pwd_length_8}>8</option>
<option value="10"{selected_force_pwd_length_10}>10</option>
<option value="12"{selected_force_pwd_length_12}>12</option>
<option value="14"{selected_force_pwd_length_14}>14</option>
<option value="16"{selected_force_pwd_length_16}>16</option>
</select>
</td>
</tr>
<tr class="row_on">
<td>{lang_Passwords_requires_this_number_of_different_character_classes}:<br/>({lang_Uppercase,_lowercase,_number,_special_char})</td>
<td>
<select name="newsettings[force_pwd_strength]">
<option value="">{lang_None}</option>
<option value="2"{selected_force_pwd_strength_2}>2</option>
<option value="3"{selected_force_pwd_strength_3}>3</option>
<option value="4"{selected_force_pwd_strength_4}>4</option>
</select>
</td>
</tr>
<tr class="row_off">
<td>{lang_Admin_email_addresses_(comma-separated)_to_be_notified_about_the_blocking_(empty_for_no_notify)}:</td>
<td>
<input name="newsettings[admin_mails]" value="{value_admin_mails}" size="40">
@ -254,7 +275,7 @@
</td>
</tr>
-->
<tr class="row_off">
<tr class="row_on">
<td>{lang_Enable_the_xmlrpc_service} {lang_(default_No,_leave_it_off_if_you_dont_use_it)}:</td>
<td>
<select name="newsettings[xmlrpc_enabled]">
@ -264,7 +285,7 @@
</td>
</tr>
<tr class="row_on">
<tr class="row_off">
<td>{lang_Enable_the_soap_service} {lang_(default_No,_leave_it_off_if_you_dont_use_it)}:</td>
<td>
<select name="newsettings[soap_enabled]">
@ -273,19 +294,19 @@
</select>
</td>
</tr>
<tr class="row_off">
<tr class="row_on">
<td>{lang_How_many_entries_should_non-admins_be_able_to_export_(empty_=_no_limit,_no_=_no_export)}:<br />{lang_This_controls_exports_and_merging.}</td>
<td><input name="newsettings[export_limit]" value="{value_export_limit}" size="5"></td>
</tr>
<tr class="row_on">
<tr class="row_off">
<td>{lang_Group_excepted_from_above_export_limit_(admins_are_always_excepted)}:</td>
<td>{call_bo_merge::hook_export_limit_excepted}</td>
</tr>
<tr class="row_off">
<tr class="row_on">
<td>{lang_Allow_remote_administration_from_following_install_ID's_(comma_separated)}:<br />{lang_Own_install_ID:_}{value_install_id}</td>
<td><input name="newsettings[allow_remote_admin]" value="{value_allow_remote_admin}" size="40"></td>
</tr>
<tr class="row_on">
<tr class="row_off">
<td>{lang_Should_exceptions_contain_a_trace_(including_function_arguments)}:</td>
<td>
<select name="newsettings[exception_show_trace]">
@ -294,7 +315,7 @@
</select>
</td>
</tr>
<tr class="row_off">
<tr class="row_on">
<td>{lang_Disable_minifying_of_javascript_and_CSS_files}:</td>
<td>
<select name="newsettings[debug_minify]">

View File

@ -754,17 +754,19 @@ class accounts_ads
// check if we need to update something
if ($attributes && !($ret = $this->adldap->user()->modify($data['account_lid'], $attributes)))
{
error_log(__METHOD__."(".array2string($data).") adldap->user()->modify('$data[account_lid]', ".array2string($attributes).') returned '.array2string($ret));
error_log(__METHOD__."(".array2string($data).") adldap->user()->modify('$data[account_lid]', ".array2string($attributes).') returned '.array2string($ret).' '.function_backtrace());
return false;
}
//elseif ($attributes) error_log(__METHOD__."(".array2string($data).") adldap->user()->modify('$data[account_lid]', ".array2string($attributes).') returned '.array2string($ret).' '.function_backtrace());
// attributes not (yet) suppored by adldap
if ($ldap && !($ret = @ldap_modify($ds=$this->ldap_connection(), $old['account_dn'], $ldap)))
{
error_log(__METHOD__."(".array2string($data).") ldap_modify($ds, '$old[account_dn]', ".array2string($ldap).') returned '.array2string($ret));
error_log(__METHOD__."(".array2string($data).") ldap_modify($ds, '$old[account_dn]', ".array2string($ldap).') returned '.array2string($ret).' '.function_backtrace());
return false;
}
else error_log(__METHOD__."(".array2string($data).") ldap_modify($ds, '$old[account_dn]', ".array2string($ldap).') returned '.array2string($ret));
//elseif ($ldap) error_log(__METHOD__."(".array2string($data).") ldap_modify($ds, '$old[account_dn]', ".array2string($ldap).') returned '.array2string($ret).' '.function_backtrace());
//error_log(__METHOD__."(".array2string($data).") returning ".array2string($old['account_id']));
return $old['account_id'];
}

View File

@ -215,15 +215,21 @@ class auth
}
/**
* changes password in sql datababse
* Calls crackcheck to enforce password strength (if configured) and changes password
*
* @param string $old_passwd must be cleartext
* @param string $new_passwd must be cleartext
* @param int $account_id account id of user whose passwd should be changed
* @throws egw_exception_wrong_userinput if configured password strength is not meat
* @throws Exception from backends having extra requirements
* @return boolean true if password successful changed, false otherwise
*/
function change_password($old_passwd, $new_passwd, $account_id=0)
{
if (($err = self::crackcheck($new_passwd)))
{
throw new egw_exception_wrong_userinput($err);
}
if (($ret = $this->backend->change_password($old_passwd, $new_passwd, $account_id)) &&
($account_id == $GLOBALS['egw_info']['user']['account_id']))
{
@ -518,28 +524,45 @@ class auth
/**
* Checks if a given password is "safe"
*
* @param string $login
* @abstract atm a simple check in length, #digits, #uppercase and #lowercase
* could be made more safe using e.g. pecl library cracklib
* but as pecl dosn't run on any platform and isn't GPL'd
* i haven't implemented it yet
* Windows compatible check is: 7 char lenth, 1 Up, 1 Low, 1 Num and 1 Special
* atm a simple check in length, #digits, #uppercase and #lowercase
* Could be made more safe using e.g. pecl library cracklib.
* But as pecl dosn't run on any platform and isn't GPL'd, I haven't implemented it yet.
* Windows compatible check is: 7 char length, 1 Up, 1 Low, 1 Num and 1 Special
*
* @param string $password
* @param int $reqstrength=null defaults to whatever set in config for "force_pwd_strength"
* @param int $minlength=null defaults to whatever set in config for "check_save_passwd"
* @author cornelius weiss <egw at von-und-zu-weiss.de>
* @return mixed false if password is considered "safe" or a string $message if "unsafe"
* @return mixed false if password is considered "safe" (or no requirements) or a string $message if "unsafe"
*/
static function crackcheck($passwd,$reqstrength=5)
static function crackcheck($passwd, $reqstrength=null, $minlength=null)
{
if (!preg_match('/.{'. ($noc=7). ',}/',$passwd))
if (!isset($reqstrength)) $reqstrength = $GLOBALS['egw_info']['server']['force_pwd_strength'];
if (!isset($minlength)) $minlength = $GLOBALS['egw_info']['server']['force_pwd_length'];
// check for and if necessary convert old values True and 5 to new separate values for length and char-classes
if ($GLOBALS['egw_info']['server']['check_save_passwd'] || $reqstrength == 5)
{
$message[] = lang('Password must have at least %1 characters',$noc). '<br>';
if (!isset($reqstrength) || $reqstrength == 5)
{
config::save_value('force_pwd_strength', $reqstrength=4, 'phpgwapi');
}
if (!isset($minlength))
{
config::save_value('force_pwd_length', $minlength=7, 'phpgwapi');
}
config::save_value('check_save_passwd', null, 'phpgwapi');
}
else
if (!$reqstrength && !$minlength)
{
$strength++;
return false; // nothing to check
}
$strength = 0;
if(!preg_match('/(.*\d.*){'. ($non=1). ',}/',$passwd))
{
$message[] = lang('Password must contain at least %1 numbers',$non). '<br>';
$message[] = lang('Password must contain at least %1 numbers',$non);
}
else
{
@ -547,7 +570,7 @@ class auth
}
if(!preg_match('/(.*[[:upper:]].*){'. ($nou=1). ',}/',$passwd))
{
$message[] = lang('Password must contain at least %1 uppercase letters',$nou). '<br>';
$message[] = lang('Password must contain at least %1 uppercase letters',$nou);
}
else
{
@ -555,30 +578,32 @@ class auth
}
if(!preg_match('/(.*[[:lower:]].*){'. ($nol=1). ',}/',$passwd))
{
$message[] = lang('Password must contain at least %1 lowercase letters',$nol). '<br>';
$message[] = lang('Password must contain at least %1 lowercase letters',$nol);
}
else
{
$strength++;
}
if(!preg_match('/(.*[\\!"#$%&\'()*+,-.\/:;<=>?@\[\]\^_ {|}~`].*){'. ($nol=1). ',}/',$passwd))
if(!preg_match('/(.*[\\!"#$%&\'()*+,-.\/:;<=>?@\[\]\^_ {|}~`].*){'. ($nos=1). ',}/',$passwd))
{
$message[] = lang('Password must contain at least %1 special characters',$nol). '<br>';
$message[] = lang('Password must contain at least %1 special characters',$nos);
}
else
{
$strength++;
}
if (count($message)>0 && $reqstrength>$strength)
if (!preg_match('/.{'. ($minlength=7). ',}/',$passwd))
{
$outmessage = lang('Your Password does not meet the required strength.<br> You must meet %1 criteria. You met only %2 criteria. <br>Your Password failed the following criteria:',$reqstrength,$strength);
$outmessage .= '<br>'.implode(' ',$message);
$message[] = lang('Password must have at least %1 characters', $minlength);
$strength = 0;
}
else
if ($reqstrength <= $strength)
{
$outmessage =false;
return false;
}
return $outmessage ? $outmessage : false;
return lang('Your password does not have required strength of %1 character classes and minimum length of %2 characters.',
$reqstrength, $minlength).
"<br/>\n- ".implode("<br/>\n- ", $message);
}
/**

View File

@ -101,7 +101,7 @@ class auth_ads implements auth_backend
* @return boolean true if password successful changed, false otherwise
* @throws egw_exception_wrong_userinput
*/
function change_password($old_passwd, $new_passwd, $_account_id=0)
function change_password($old_passwd, $new_passwd, $account_id=0)
{
if (!($adldap = accounts_ads::get_adldap()) || !($adldap->getUseSSL() || $adldap->getUseTLS()))
{
@ -126,11 +126,13 @@ class auth_ads implements auth_backend
return false;
}
try {
return $adldap->user()->password($username, $new_passwd);
$ret = $adldap->user()->password($username, $new_passwd);
//error_log(__METHOD__."('$old_passwd', '$new_passwd', $account_id) admin=$admin adldap->user()->password('$username', '$new_passwd') returned ".array2string($ret));
return $ret;
}
catch (Exception $e) {
// as we cant (todo) detect what the problem is, we do a password strength check and throw it's message, if it fails
if (($error = auth::crackcheck($new_passwd)))
if (($error = auth::crackcheck($new_passwd, 4, 8))) // 4 char classes and 8 chars min
{
throw new egw_exception_wrong_userinput($error);
}

View File

@ -46,7 +46,7 @@ class uipassword
$GLOBALS['egw']->template->set_var('lang_enter_password',lang('Enter your new password'));
$GLOBALS['egw']->template->set_var('lang_reenter_password',lang('Re-enter your password'));
$GLOBALS['egw']->template->set_var('lang_enter_old_password',lang('Enter your old password'));
$GLOBALS['egw']->template->set_var('lang_change',lang('Change'));
$GLOBALS['egw']->template->set_var('lang_change',lang('Change password'));
$GLOBALS['egw']->template->set_var('lang_cancel',lang('Cancel'));
$GLOBALS['egw']->template->set_var('form_action',
$GLOBALS['egw_info']['user']['apps']['preferences'] ?
@ -91,19 +91,8 @@ class uipassword
{
$errors[] = lang('You must enter a password');
}
$strength = ($GLOBALS['egw_info']['server']['force_pwd_strength']?$GLOBALS['egw_info']['server']['force_pwd_strength']:false);
//error_log(__METHOD__.__LINE__.' Strength:'.$strength);
if ($strength && $strength>5) $strength =5;
if ($strength && $strength<0) $strength = false;
if($GLOBALS['egw_info']['server']['check_save_passwd'] && $strength==false) $strength=5;//old behavior
//error_log(__METHOD__.__LINE__.' Strength:'.$strength);
if(($GLOBALS['egw_info']['server']['check_save_passwd'] || $strength) && $error_msg = $GLOBALS['egw']->auth->crackcheck($n_passwd,$strength))
{
$errors[] = $error_msg;
}
// allow auth backends to throw exceptions and display there message
// allow auth backends or configured password strenght to throw exceptions and display there message
try {
$passwd_changed = $this->bo->changepass($o_passwd, $n_passwd);
}

View File

@ -13,6 +13,7 @@ automatically start with this font preferences de Startet automatisch mit dieser
automatically start with this font size preferences de Startet automatisch mit dieser Schriftgröße
br preferences de br
change a user password by passing the old and new passwords. returns true on success, false on failure. preferences de Ändern Sie Ihr Passwort, indem Sie Ihr altes und neues Passwort angeben. Es wird TRUE zurückgegeben für eine erfolgreiche Änderung und FALSE wenn es nicht erfolgreich war.
change password preferences de Passwort ändern
change your password preferences de Passwort ändern
change your profile preferences de Profil ändern
change your settings preferences de Einstellungen ändern

View File

@ -13,6 +13,7 @@ automatically start with this font preferences en Automatically start with this
automatically start with this font size preferences en Automatically start with this font size
br preferences en br
change a user password by passing the old and new passwords. returns true on success, false on failure. preferences en Change a user password by passing the old and new passwords. Returns TRUE on success, FALSE on failure.
change password preferences en Change password
change your password preferences en Change password
change your profile preferences en Change profile
change your settings preferences en Change settings

View File

@ -289,36 +289,6 @@
</tr>
<tr class="row_off">
<td>{lang_Activate_safe_password_check}:</td>
<td>
<select name="newsettings[check_save_passwd]">
<option value="">{lang_No}</option>
<option value="True" {selected_check_save_passwd_True}>{lang_Yes}</option>
</select>
</td>
</tr>
<tr class="row_on">
<td>{lang_Allow_authentication_via_cookie}:</td>
<td>
<select name="newsettings[allow_cookie_auth]">
<option value="">{lang_No}</option>
<option value="True" {selected_allow_cookie_auth_True}>{lang_Yes}</option>
</select>
</td>
</tr>
<tr class="row_off">
<td>{lang_Auto_login_anonymous_user}:</td>
<td>
<select name="newsettings[auto_anon_login]">
<option value="">{lang_No}</option>
<option value="True"{selected_auto_anon_login_True}>{lang_Yes}</option>
</select>
</td>
</tr>
<tr class="row_on">
<td>{lang_Allow_password_migration}:</td>
<td>
<select name="newsettings[pwd_migration_allowed]">
@ -328,27 +298,47 @@
</td>
</tr>
<tr class="row_off">
<tr class="row_on">
<td>{lang_Allowed_migration_types_(comma-separated)}:</td>
<td>
<input name="newsettings[pwd_migration_types]" value="{value_pwd_migration_types}" size="20" />
</td>
</tr>
<tr class="row_off">
<td>{lang_Allow_authentication_via_cookie}:</td>
<td>
<select name="newsettings[allow_cookie_auth]">
<option value="">{lang_No}</option>
<option value="True" {selected_allow_cookie_auth_True}>{lang_Yes}</option>
</select>
</td>
</tr>
<tr class="row_on">
<td>{lang_Auto_login_anonymous_user}:</td>
<td>
<select name="newsettings[auto_anon_login]">
<option value="">{lang_No}</option>
<option value="True"{selected_auto_anon_login_True}>{lang_Yes}</option>
</select>
</td>
</tr>
<tr class="row_off">
<td>{lang_Minimum_account_id_(e.g._500_or_100,_etc.)}:</td>
<td><input name="newsettings[account_min_id]" value="{value_account_min_id}" /></td>
</tr>
<tr class="row_off">
<tr class="row_on">
<td>{lang_Maximum_account_id_(e.g._65535_or_1000000)}:</td>
<td><input name="newsettings[account_max_id]" value="{value_account_max_id}" /></td>
</tr>
<tr class="row_on">
<tr class="row_off">
<td>{lang_User_account_prefix}:</td>
<td><input name="newsettings[account_prefix]" value="{value_account_prefix}" /></td>
</tr>
<tr class="row_off">
<tr class="row_on">
<td>{lang_Usernames_are_casesensitive}:</td>
<td>
<select name="newsettings[case_sensitive_username]">
@ -358,7 +348,7 @@
</td>
</tr>
<tr class="row_on">
<tr class="row_off">
<td>{lang_Auto_create_account_records_for_authenticated_users}:</td>
<td>
<select name="newsettings[auto_create_acct]">
@ -369,7 +359,7 @@
</td>
</tr>
<tr class="row_off">
<tr class="row_on">
<td>{lang_Auto-created_user_accounts_expire}:</td>
<td>
<select name="newsettings[auto_create_expire]">
@ -381,12 +371,12 @@
</td>
</tr>
<tr class="row_on">
<tr class="row_off">
<td>{lang_Add_auto-created_users_to_this_group_('Default'_will_be_attempted_if_this_is_empty.)}:</td>
<td><input name="newsettings[default_group_lid]" value="{value_default_group_lid}" /></td>
</tr>
<tr class="row_off">
<tr class="row_on">
<td>{lang_If_no_ACL_records_for_user_or_any_group_the_user_is_a_member_of}:</td>
<td>
<select name="newsettings[acl_default]">