?php /* @file * Synchronize users password and htpasswd file * * HTPasswd Sync module duplicates all users changes in the configured htpasswd * file. Password a hashed with the crypt function. The htgroup file contains * roles as groups. */ /** * return htpasswd file name * * @return * full filname of the htpasswd */ function _htpasswdsync_passfilename() { return variable_get('htpasswdsync_htpasswd', "/etc/httpd/htpasswd"); } /** * return htgroup file name * * @return * full filname of the htgroup file */ function _htpasswdsync_grpfilename() { return variable_get('htpasswdsync_htgroup', "/etc/httpd/htgroup"); } /** * return role to put in htgroup * * return the roles selectionned in the admin page to put into * the htgroup file. * * @return * array of role id */ function _htpasswdsync_roles() { return variable_get('htpasswdsync_roles', array()); } /** * read an htfile * * read an htfile, format is key: value, one key per row * * @param &$arr * array to read to * @param $file * file to read * @return * none */ function _htpasswdsync_read_htfile(&$arr, $file) { $f = fopen($file, "r"); while ($l = fgets($f)) { list($u, $p) = split(":", rtrim($l), 2); if ($u != "") { $arr[$u] = $p; } } fclose($f); } /** * write an htfile * * write an array to an htfile, format is key: value, one key per row * * @param &$arr * array to write * @param $file * file to write to * @return * none */ function _htpasswdsync_write_htfile(&$arr, $file) { $f = fopen($file, "w"); foreach ($arr as $u => $p) { if ($u != "" && $p != "") { fputs($f, $u .":". $p ."\n"); } } fclose($f); } /* generate the htgroup content * * for each role configured (htpasswdsync_roles array), list users * and update the htgroup accordingly * * @param * @return */ function _htpasswdsync_updategroup() { $file = _htpasswdsync_grpfilename(); $groups = array(); _htpasswdsync_read_htfile($groups, $file); foreach (_htpasswdsync_roles() as $rid) { // get role name $res = db_fetch_object(db_query('SELECT name FROM {role} WHERE rid = %d', $rid)); $name = $res->name; //empty group $groups[$name] = ""; // add members to the group $res = db_query('SELECT name FROM {users} u, {users_roles} ur WHERE ur.rid = %d AND ur.uid = u.uid', $rid); while ($r = db_fetch_object($res)) { $groups[$name] .= " ". $r->name; } } _htpasswdsync_write_htfile($groups, $file); } /* generate the htpasswd content from the database * * update the htpasswd file from the table htpasswdsync_passwd * * @param * @return */ function _htpasswdsync_updatepasswd() { $file = _htpasswdsync_passfilename(); $passwords = array(); _htpasswdsync_read_htfile($passwords, $file); //get all users $res = db_query('SELECT username, passwd FROM {htpasswdsync_passwd}'); while ($r = db_fetch_object($res)) { if ($r->passwd == "****DELETED") { unset($passwords[$r->username]); } else { $passwords[$r->username] = $r->passwd; } } _htpasswdsync_write_htfile($passwords, $file); } /* update htpassword with the new password of the user * * @param $account * account of the user to update * @return */ function _htpasswdsync_update($account) { // read current file $f = _htpasswdsync_passfilename(); $passwds = array(); _htpasswdsync_read_htfile($passwds, $f); // update with the $account information received // password crypted with the standard crypt (not MD5) function $user = $account['name']; $pass = crypt($account['pass'], chr(rand(65, 122)) . chr(rand(65, 122))); $passwds[$user] = $pass; //save file _htpasswdsync_write_htfile($passwds, $f); //update table db_query("DELETE FROM {htpasswdsync_passwd} WHERE username = '%s'", $user); db_query("INSERT INTO {htpasswdsync_passwd} (username, passwd) VALUES('%s', '%s')", $user, $pass); } /* remove the user for the htpassword file * * @param $account * array of account to delete * @return */ function _htpasswdsync_delete($account) { $f = _htpasswdsync_passfilename(); $passwds = array(); _htpasswdsync_read_htfile($passwds, $f); foreach ($account['accounts'] as $a) { $r = db_query("SELECT name FROM {users} WHERE uid = %d", $a); $user = db_fetch_object($r); unset($passwds[$user->name]); db_query("DELETE FROM {htpasswdsync_passwd} WHERE username = '%s'", $user->name); db_query("INSERT INTO {htpasswdsync_passwd} (username, passwd) VALUES('%s', '%s')", $user->name, "****DELETED"); } _htpasswdsync_write_htfile($passwds, $f); _htpasswdsync_updategroup(); } /** * Display help and module information * @param path which path of the site we're displaying help * @param arg array that holds the current path as would be returned from arg() function * @return help text for the path */ function htpasswdsync_help($path, $arg) { $output = ''; //declare your output variable switch ($path) { case "admin/help#htpasswdsync": $output = '

'. t("synchronize password with a htpasswd file") .'

'; break; } return $output; } // function htpasswdsync_help /** * Valid permissions for this module * @return array An array of valid permissions for the htpasswdsync module */ function htpasswdsync_perm() { return array('administer htpasswdsync'); } // function htpasswdsync_perm() /* * Implementation of hook_user() */ function htpasswdsync_user($op, &$edit, &$account, $category = NULL) { switch ($op) { case "delete": _htpasswdsync_delete($edit); break; case "insert": _htpasswdsync_update($edit); break; case "update": _htpasswdsync_update($edit); break; } } // function htpasswdsync_user() function htpasswdsync_admin() { $form['htpasswdsync_htpasswd'] = array( '#type' => 'textfield', '#title' => t('htpasswd file'), '#default_value' => _htpasswdsync_passfilename(), '#size' => 100, '#maxlength' => 200, '#description' => t("Where is stored the !file file we want to synchronize with.", array('!file' => 'htpasswd')), '#required' => TRUE, ); $form['htpasswdsync_htgroup'] = array( '#type' => 'textfield', '#title' => t('htgroup file'), '#default_value' => _htpasswdsync_grpfilename(), '#size' => 100, '#maxlength' => 200, '#description' => t("Where is stored the !file file we want to synchronize with.", array('!file' => 'htgroup')), '#required' => TRUE, ); $form['htpasswdsync_roles'] = array( '#type' => 'checkboxes', '#title' => t('Roles to be exported in htgroup'), '#default_value' => _htpasswdsync_roles(), '#options' => user_roles(TRUE), ); return system_settings_form($form); } /* Test if a file exist and is writable * * @param $filename * name of the file * @return * return false on success, otherwise an error message */ function _htpasswdsync_check_file($file) { $f = @fopen($file, "r"); if (!$f) { return t("File '!file' does not exists, you should create it.", array('!file' => $file)); } else { fclose($f); $f = @fopen($file, "a"); if (!$f) { return t("cannot write to file '!file'.", array('!file' => $file)); } else { fclose($f); } } return FALSE; } function htpasswdsync_admin_validate($form, &$form_state) { $file = $form_state['values']['htpasswdsync_htpasswd']; if ($msg = _htpasswdsync_check_file($file)) { form_set_error('htpasswdsync_htpasswd', $msg); } $file = $form_state['values']['htpasswdsync_htgroup']; if ($msg = _htpasswdsync_check_file($file)) { form_set_error('htpasswdsync_htpasswd', $msg); } } function htpasswdsync_menu() { $items = array(); $items['admin/user/htpasswdsync'] = array( 'title' => 'HTPassword Sync', 'description' => 'Preferences for the HTPasswd Sync module', 'page callback' => 'drupal_get_form', 'page arguments' => array('htpasswdsync_admin'), 'access arguments' => array('access administration pages'), 'type' => MENU_NORMAL_ITEM, ); return $items; } function htpasswdsync_requirements($phase) { $requirements = array(); // if not runtime query, exit if ($phase != 'runtime') { return $requirements; } $htpasswd_status_msg = _htpasswdsync_check_file(_htpasswdsync_passfilename()); $htpasswd_status_val = REQUIREMENT_ERROR; if (!$htpasswd_status_msg) { $htpasswd_status_msg = t('!file file is available', array('!file' => 'htpasswd')); $htpasswd_status_val = REQUIREMENT_OK; } $htgroup_status_msg = _htpasswdsync_check_file(_htpasswdsync_grpfilename()); $htgroup_status_val = REQUIREMENT_ERROR; if (!$htgroup_status_msg) { $htgroup_status_msg = t('!file file is available', array('!file' => 'htgroup')); $htgroup_status_val = REQUIREMENT_OK; } $status = $htpasswd_status_val > $htgroup_status_val ? $htpasswd_status_val : $htgroup_status_val; $requirements['htpasswdsync_status'] = array( 'title' => t('HTPasswd Sync Status'), 'value' => $htpasswd_status_msg ."
". $htgroup_status_msg ."
". t('last update !time ago.', array( '!time' => format_interval(time()-variable_get('htpasswdsync_cron_time', 0)))), 'severity' => $status, ); if ($status != REQUIREMENT_OK) { $requirements['htpasswdsync_status']['description'] = t('Cannot access files, please check configuration.', array('!url' => url('admin/user/htpasswdsync'))); } return $requirements; } function htpasswdsync_cron() { $time = variable_get('htpasswdsync_cron_time', 0); _htpasswdsync_updatepasswd(); _htpasswdsync_updategroup(); variable_set('htpasswdsync_cron_time', time()); }