/** * Check the username / password against the PAM system */ function SQUID_PAM_check($username, $password) { global $c; $script = $c->authenticate_hook['config']['script']; if (empty($script)) { $script = $c->authenticate_hook['config']['path']; } $cmd = sprintf('echo %s %s | %s -n common-auth', escapeshellarg($username), escapeshellarg($password), $script); $auth_result = exec($cmd); if ($auth_result == "OK") { dbg_error_log('pwauth', 'User %s successfully authenticated', $username); $principal = new Principal('username', $username); if (!$principal->Exists()) { dbg_error_log('pwauth', 'User %s does not exist in local db, creating', $username); $pwent = posix_getpwnam($username); $gecos = explode(',', $pwent['gecos']); $fullname = $gecos[0]; $principal->Create(array('username' => $username, 'user_active' => 't', 'email' => sprintf('%s@%s', $username, $email_base), 'fullname' => $fullname)); if (!$principal->Exists()) { dbg_error_log("PAM", "Unable to create local principal for '%s'", $username); return false; } CreateHomeCalendar($username); } return $principal; } else { dbg_error_log("PAM", "User %s is not a valid username (or password was wrong)", $username); return false; } }
/** * Check the username / password against the PAM system */ function IMAP_PAM_check($username, $password) { global $c; $imap_username = $username; if (function_exists('mb_convert_encoding')) { $imap_username = mb_convert_encoding($imap_username, "UTF7-IMAP", mb_detect_encoding($imap_username)); } else { $imap_username = imap_utf7_encode($imap_username); } //$imap_url = '{localhost:143/imap/notls}'; //$imap_url = '{localhost:993/imap/ssl/novalidate-cert}'; $imap_url = $c->authenticate_hook['config']['imap_url']; $auth_result = "ERR"; $imap_stream = @imap_open($imap_url, $imap_username, $password, OP_HALFOPEN); //print_r(imap_errors()); if ($imap_stream) { // disconnect imap_close($imap_stream); // login ok $auth_result = "OK"; } if ($auth_result == "OK") { $principal = new Principal('username', $username); if (!$principal->Exists()) { dbg_error_log("PAM", "Principal '%s' doesn't exist in local DB, we need to create it", $username); $cmd = "getent passwd '{$username}'"; $getent_res = exec($cmd); $getent_arr = explode(":", $getent_res); $fullname = $getent_arr[4]; if (empty($fullname)) { $fullname = $username; } $principal->Create(array('username' => $username, 'user_active' => true, 'email' => $username . "@" . $c->authenticate_hook['config']['email_base'], 'modified' => date('c'), 'fullname' => $fullname)); if (!$principal->Exists()) { dbg_error_log("PAM", "Unable to create local principal for '%s'", $username); return false; } CreateHomeCalendar($username); } return $principal; } else { dbg_error_log("PAM", "User %s is not a valid username (or password was wrong)", $username); return false; } }
/** * Update the local cache of the remote user details * @param object $usr The user details we read from the remote. */ function UpdateUserFromExternal(&$usr) { global $c; /** * When we're doing the create we will usually need to generate a user number */ if (!isset($usr->user_no) || intval($usr->user_no) == 0) { $qry = new AwlQuery("SELECT nextval('usr_user_no_seq');"); $qry->Exec('Login', __LINE__, __FILE__); $sequence_value = $qry->Fetch(true); // Fetch as an array $usr->user_no = $sequence_value[0]; } $qry = new AwlQuery('SELECT * FROM usr WHERE user_no = :user_no', array(':user_no' => $usr->user_no)); if ($qry->Exec('Login', __LINE__, __FILE__) && $qry->rows() == 1) { $type = "UPDATE"; if ($old = $qry->Fetch()) { $changes = false; foreach ($usr as $k => $v) { if ($old->{$k} != $v) { $changes = true; dbg_error_log("Login", "User '%s' field '%s' changed from '%s' to '%s'", $usr->username, $k, $old->{$k}, $v); break; } } if (!$changes) { dbg_error_log("Login", "No changes to user record for '%s' - leaving as-is.", $usr->username); if (isset($usr->active) && $usr->active == 'f') { return false; } return; // Normal case, if there are no changes } else { dbg_error_log("Login", "Changes to user record for '%s' - updating.", $usr->username); } } } else { $type = "INSERT"; } $params = array(); if ($type != 'INSERT') { $params[':user_no'] = $usr->user_no; } $qry = new AwlQuery(sql_from_object($usr, $type, 'usr', 'WHERE user_no= :user_no'), $params); $qry->Exec('Login', __LINE__, __FILE__); /** * We disallow login by inactive users _after_ we have updated the local copy */ if (isset($usr->active) && ($usr->active === 'f' || $usr->active === false)) { return false; } if ($type == 'INSERT') { $qry = new AwlQuery('INSERT INTO principal( type_id, user_no, displayname, default_privileges) SELECT 1, user_no, fullname, :privs::INT::BIT(24) FROM usr WHERE username=:username', array(':privs' => privilege_to_bits($c->default_privileges), ':username' => $usr->username)); $qry->Exec('Login', __LINE__, __FILE__); CreateHomeCalendar($usr->username); } else { if ($usr->fullname != $old->{'fullname'}) { // Also update the displayname if the fullname has been updated. $qry->QDo('UPDATE principal SET displayname=:new_display WHERE user_no=:user_no', array(':new_display' => $usr->fullname, ':user_no' => $usr->user_no)); } } }
function principal_editor() { global $id, $can_write_principal, $session; $editor = new Editor(translate('Principal'), 'dav_principal'); $editor->SetLookup('date_format_type', "SELECT 'E', 'European' UNION SELECT 'U', 'US Format' UNION SELECT 'I', 'ISO Format'"); $editor->SetLookup('type_id', 'SELECT principal_type_id, principal_type_desc FROM principal_type ORDER BY principal_type_id'); $editor->SetLookup('locale', 'SELECT \'\', \'' . translate("*** Default Locale ***") . '\' UNION SELECT locale, locale_name_locale FROM supported_locales ORDER BY 1 ASC'); $editor->AddAttribute('locale', 'title', translate("The preferred language for this person.")); $editor->AddAttribute('fullname', 'title', translate("The full name for this person, group or other type of principal.")); $editor->SetWhere('principal_id=' . $id); $editor->AddField('is_admin', 'EXISTS( SELECT 1 FROM role_member WHERE role_no = 1 AND role_member.user_no = dav_principal.user_no )'); $editor->AddAttribute('is_admin', 'title', translate('An "Administrator" user has full rights to the whole DAViCal System')); $post_values = false; if (isset($_POST['xxxxusername'])) { $_POST['xxxxusername'] = trim(str_replace('/', '', $_POST['xxxxusername'])); if ($_POST['xxxxusername'] == '') { $c->messages[] = i18n("The username must not be blank, and may not contain a slash"); $can_write_principal = false; } } if (isset($_POST['fullname']) && trim($_POST['fullname']) == '') { $c->messages[] = i18n("The full name must not be blank."); $can_write_principal = false; } if (isset($_POST['email']) && trim($_POST['email']) == '') { $c->messages[] = i18n("The email address really should not be blank."); } $pwstars = '@@@@@@@@@@'; if ($can_write_principal && $editor->IsSubmit()) { $editor->WhereNewRecord("principal_id=(SELECT CURRVAL('dav_id_seq'))"); if (!$session->AllowedTo('Admin')) { unset($_POST['admin_role']); unset($_POST['user_active']); } unset($_POST['password']); if ($_POST['newpass1'] != '' && $_POST['newpass1'] != $pwstars) { if ($_POST['newpass1'] == $_POST['newpass2']) { $_POST['password'] = $_POST['newpass1']; } else { $c->messages[] = "Password not updated. The supplied passwords do not match."; } } if (isset($_POST['fullname']) && !isset($_POST['displayname'])) { $_POST['displayname'] = $_POST['fullname']; } if (isset($_POST['default_privileges'])) { $privilege_bitpos = array_flip($privilege_names); $priv_names = array_keys($_POST['default_privileges']); $privs = privilege_to_bits($priv_names); $_POST['default_privileges'] = sprintf('%024s', decbin($privs)); $editor->Assign('default_privileges', $privs_dec); } if ($editor->IsCreate()) { $c->messages[] = i18n("Creating new Principal record."); } else { $c->messages[] = i18n("Updating Principal record."); } $editor->Write(); if ($_POST['type_id'] != 3 && $editor->IsCreate()) { /** We only add the default calendar if it isn't a group, and this is a create action */ require_once 'auth-functions.php'; CreateHomeCalendar($editor->Value('username')); } if ($session->AllowedTo('Admin')) { if ($_POST['is_admin'] == 'on') { $sql = 'INSERT INTO role_member (role_no, user_no) SELECT 1, dav_principal.user_no FROM dav_principal WHERE user_no = :user_no AND NOT EXISTS(SELECT 1 FROM role_member rm WHERE rm.role_no = 1 AND rm.user_no = dav_principal.user_no )'; $editor->Assign('is_admin', 't'); } else { $sql = 'DELETE FROM role_member WHERE role_no = 1 AND user_no = :user_no'; $editor->Assign('is_admin', 'f'); } $params[':user_no'] = $editor->Value('user_no'); $qry = new AwlQuery($sql, $params); $qry->Exec('admin-principal-edit'); } } else { if (isset($id) && $id > 0) { $editor->GetRecord(); if ($editor->IsSubmit()) { $c->messages[] = i18n('You do not have permission to modify this record.'); } } } if ($editor->Available()) { $c->page_title = $editor->Title(translate('Principal') . ': ' . $editor->Value('fullname')); } else { $c->page_title = $editor->Title(translate('Create New Principal')); $privs = decbin(privilege_to_bits($c->default_privileges)); $editor->Assign('default_privileges', $privs); $editor->Assign('user_active', 't'); foreach ($c->template_usr as $k => $v) { $editor->Assign($k, $v); } } if ($post_values) { $editor->PostToValues(); if (isset($_POST['default_privileges'])) { $privilege_bitpos = array_flip($privilege_names); $priv_names = array_keys($_POST['default_privileges']); $privs = privilege_to_bits($priv_names); $_POST['default_privileges'] = sprintf('%024s', decbin($privs)); $editor->Assign('default_privileges', $_POST['default_privileges']); } } $prompt_principal_id = translate('Principal ID'); $value_id = $editor->Available() ? '##principal_id.hidden####principal_id.value##' : translate('New Principal'); $prompt_username = translate('Username'); $prompt_password_1 = translate('Change Password'); $prompt_password_2 = translate('Confirm Password'); $prompt_fullname = translate('Fullname'); $prompt_displayname = translate('Display Name'); $prompt_email = translate('Email Address'); $prompt_date_format = translate('Date Format Style'); $prompt_admin = translate('Administrator'); $prompt_active = translate('Active'); $prompt_locale = translate('Locale'); $prompt_type = translate('Principal Type'); $prompt_privileges = translate('Privileges granted to All Users'); $privs_html = build_privileges_html($editor, 'default_privileges'); $admin_row_entry = ''; $delete_principal_button = ''; if ($session->AllowedTo('Admin')) { $admin_row_entry = ' <tr> <th class="right">' . $prompt_admin . ':</th><td class="left">##is_admin.checkbox##</td> </tr>'; $admin_row_entry .= ' <tr> <th class="right">' . $prompt_active . ':</th><td class="left">##user_active.checkbox##</td> </tr>'; if (isset($id)) { $delete_principal_button = '<a href="' . $c->base_url . '/admin.php?action=edit&t=principal&subaction=delete_principal&id=' . $id . '" class="submit">' . translate("Delete Principal") . '</a>'; } } $id = $editor->Value('principal_id'); $template = <<<EOTEMPLATE ##form## <script language="javascript"> function toggle_privileges() { var argv = toggle_privileges.arguments; var argc = argv.length; if ( argc < 2 ) { return; } var match_me = argv[0]; var set_to = -1; if ( argv[1] == 'all' ) { var form = document.getElementById(argv[2]); var fieldcount = form.elements.length; var matching = '/^' + match_me + '/'; for (var i = 0; i < fieldcount; i++) { var fieldname = form.elements[i].name; if ( fieldname.match( match_me ) ) { if ( set_to == -1 ) { set_to = ( form.elements[i].checked ? 0 : 1 ); } form.elements[i].checked = set_to; } } } else { for (var i = 1; i < argc; i++) { var f = document.getElementById( match_me + '_' + argv[i]); if ( set_to == -1 ) { set_to = ( f.checked ? 0 : 1 ); } f.checked = set_to; } } } </script> <style> th.right, label.privilege { white-space:nowrap; } label.privilege { margin:0.2em 1em 0.2em 0.1em; padding:0 0.2em; line-height:1.6em; font-size:87%; } </style> <table> <tr> <th class="right">{$prompt_principal_id}:</th><td class="left"> <table width="100%" class="form_inner"><tr> <td>{$value_id}</td> <td align="right">{$delete_principal_button}</td> </tr></table> </td></tr> <tr> <th class="right">{$prompt_username}:</th> <td class="left">##xxxxusername.input.50##</td> </tr> <tr> <th class="right">{$prompt_password_1}:</th> <td class="left">##newpass1.password.{$pwstars}##</td> </tr> <tr> <th class="right">{$prompt_password_2}:</th> <td class="left">##newpass2.password.{$pwstars}##</td> </tr> <tr> <th class="right">{$prompt_fullname}:</th> <td class="left">##fullname.input.50##</td> </tr> <tr> <th class="right">{$prompt_email}:</th> <td class="left">##email.input.50##</td> </tr> <tr> <th class="right">{$prompt_locale}:</th> <td class="left">##locale.select##</td> </tr> <tr> <th class="right">{$prompt_date_format}:</th> <td class="left">##date_format_type.select##</td> </tr> <tr> <th class="right">{$prompt_type}:</th> <td class="left">##type_id.select##</td> </tr> {$admin_row_entry} <tr> <th class="right" style="white-space:normal;">{$prompt_privileges}:</th><td class="left">{$privs_html}</td> </tr> <tr> <th class="right"></th> <td class="left" colspan="2">##submit##</td> </tr> </table> </form> EOTEMPLATE; $editor->SetTemplate($template); return $editor; }
/** * Check the username / password against the PAM system */ function PWAUTH_PAM_check($username, $password) { global $c; $program = $c->authenticate_hook['config']['path']; $email_base = $c->authenticate_hook['config']['email_base']; $pipe = popen(escapeshellarg($program), 'w'); $authinfo = sprintf("%s\n%s\n", $username, $password); $written = fwrite($pipe, $authinfo); dbg_error_log('pwauth', 'Bytes written: %d of %d', $written, strlen($authinfo)); $return_status = pclose($pipe); switch ($return_status) { case 0: // STATUS_OK: Authentication succeeded. dbg_error_log('pwauth', 'User %s successfully authenticated', $username); $principal = new Principal('username', $username); if (!$principal->Exists()) { dbg_error_log('pwauth', 'User %s does not exist in local db, creating', $username); $pwent = posix_getpwnam($username); $gecos = explode(',', $pwent['gecos']); $fullname = $gecos[0]; $principal->Create(array('username' => $username, 'user_active' => 't', 'email' => sprintf('%s@%s', $username, $email_base), 'fullname' => $fullname)); if (!$principal->Exists()) { dbg_error_log("PAM", "Unable to create local principal for '%s'", $username); return false; } CreateHomeCalendar($username); } return $principal; break; /* * Note that for system configurations using PAM instead of * reading the password database directly, if PAM is unable to * read the password database, pwauth will return status 1. */ /* * Note that for system configurations using PAM instead of * reading the password database directly, if PAM is unable to * read the password database, pwauth will return status 1. */ case 1: case 2: // (1) STATUS_UNKNOWN: Invalid username or password. // (2) STATUS_INVALID: Invalid password. dbg_error_log('pwauth', 'Invalid username or password (username: %s)', $username); break; case 3: // STATUS_BLOCKED: UID for username is < pwauth's MIN_UNIX_UID dbg_error_log('pwauth', 'UID for username %s is < pwauth MIN_UNIX_UID', $username); break; case 4: // STATUS_EXPIRED: The user account has expired. dbg_error_log('pwauth', 'The account for %s has expired', $username); break; case 5: // STATUS_PW_EXPIRED: The user account's password has expired. dbg_error_log('pwauth', 'The account password for user %s has expired', $username); break; case 6: // STATUS_NOLOGIN: Logins to the system are administratively disabled. dbg_error_log('pwauth', 'Logins administratively disabled (%s)', $username); break; case 7: // STATUS_MANYFAILS: Too many login failures for user account. dbg_error_log('pwauth', 'Login rejected for %s, too many failures', $username); break; case 50: // STATUS_INT_USER: Configuration error, Web server cannot use pwauth dbg_error_log('pwauth', 'config error: see pwauth man page (%s)', 'STATUS_INT_USER'); break; case 51: // STATUS_INT_ARGS: pwauth received no username/passwd to check dbg_error_log('pwauth', 'error: pwauth received no username/password'); break; case 52: // STATUS_INT_ERR: unknown error dbg_error_log('pwauth', 'error: see pwauth man page (%s)', 'STATUS_INT_ERR'); break; case 53: // STATUS_INT_NOROOT: pwauth could not read the password database dbg_error_log('pwauth', 'config error: cannot read password database (%s)', 'STATUS_INT_NOROOT'); break; default: // Unknown error code. dbg_error_log('pwauth', 'An unknown error (%d) has occurred', $return_status); } return FALSE; }