<?php if (!defined('PmWiki')) exit(); /* The ExternAuth module assumes that (for whatever reason), authentication is being handled outside of PmWiki. Whatever authentication mechanism is being used, it is assumed that the php $_SESSION variable is set. In the author's case, the wiki is for a University, ans the following variables are set in the $_SESSION variable: $_SESSION['authenticated'] - a BOOLEAN $_SESSION['username'] - the username of the authenticated user $_SESSION['groups'] - an array of groups for which the user is a member. These are set in the ExternAuthGroups variable later in the file. This file changes the AuthFunction to ExternAuth, which uses the SESSION variables to validate a page based on the externauth variables set for the page and group. Much of this file is simply copies of functions from PmWiki with slight modifications for the extern authentication. ExternAuth sets variables on pages where the variable name is: externauth_{level}_{mode} where the level is the action level requested - read, edit, attr, etc. and the mode is one of allow, group, or user. The allow variable is a boolean that allows access to anyone. The group variable contains the different groups that can access the page, and the user variable contains the different users that can access the page. Therefore, pages are granted access based on the settings. Access is given to all, any number of groups, or any number of users. There is currently no capability for authentication exceptions (like everyone except fred). If nothing is specified, the ExternAuth module has an ExternAuthAttribute function set for each attribute. These can be set to pass the authentication on to the underlying PmWiki Auth functions, or do whatever the user might want to do based on other $_SESSION variables. */ // Change the default AuthFunction to ExternAuth $AuthFunction = 'ExternAuth'; // The following are the attributes for which we will allow // external authorization. // When a page is being checked, extern_auth variables are checked on the // page as well as group variables. If they are specified, these variable // determine who is authenticated for a given attribute. // However, if no variables exist, what should the system do? // The ExternAuthAttribute is used to cover this situation. // For each attribute, the argument is a function to call if the page // or group has no extern_auth specifications for the given attribute. // The administrator can write their own functions - I use an EApass function // that passes the authentication to the underlying auth module for // read and edit. // For the other attrbutes , I have tighter restrictions. SDV($ExternAuthAttributes{'read'},'EApass'); SDV($ExternAuthAttributes{'edit'},'EApass'); SDV($ExternAuthAttributes{'attr'},'EAadmins'); SDV($ExternAuthAttributes{'upload'},'EAadmins'); SDV($ExternAuthAttributes{'rename'},'EAwebadmin'); // Here are the default pass and fail functions function EApass() { return true; } function EAfail() { return false; } // This is an example of how to use the function arguments // to do a specialized function. In my case, I want the attributes // to fail unless the person is in the staff, faculty, or webadmin group. // The _SESSION group variable is set by the external authentication // mechanism. function EAadmins() { if (in_array('staff', $_SESSION['groups'])) return true; if (in_array('faculty', $_SESSION['groups'])) return true; if (in_array('webadmin', $_SESSION['groups'])) return true; return false; } function EAwebadmin() { if (in_array('webadmin', $_SESSION['groups'])) return true; return false; } // This variable is used to form the attribute page so that users can check // boxes rather than fill in text fields. I suppose that if I were more clever // I could read this from my LDAP or external mechanism. I am not that clever. // This was easier. SDV($ExternAuthGroups, array( 'webadmin' => 'students and staff responsible for web administration', 'faculty' => 'faculty members', 'staff' => 'staff members including faculty', 'adjunct' => 'adjunct professors', 'employee' => 'student employees', 'student' => 'current engineering students', 'alumni' => 'graduates of the engineering program', 'user' => 'users who do not fit into any other category', )); // Clear the PageAttributes so that the only page by page attributes are // the externauth ones. This isn't essential, I just don't use the other // ones and they would confuse my users. Yes, my users are pathetic. unset($PageAttributes); // Add some attributes to the page ... // Two attributes for each level, // one for the allowed groups // one for the allowed users foreach(array_keys($ExternAuthAttributes) as $level) { $allowvar = 'externauth_' . $level . '_allow'; $PageAttributes[$allowvar] = '$[' . $level . ' allow:]'; $uservar = 'externauth_' . $level . '_user'; $PageAttributes[$uservar] = '$[' . $level . ' users:]'; $groupvar = 'externauth_' . $level . '_group'; $PageAttributes[$groupvar] = '$[' . $level . ' groups:]'; } // I am adding in a condition to make conditional inclusion easier // Now I can simply say (:if authenticated :) stuff ... (:ifend:) // or (:if authenticated level:) stuff ... (:ifend:) // (where level is one of the ExternAuthAttributes $Conditions['authenticated'] = 'conditional_authenticate(trim($condparm))'; // The conditional_authenticate is used by the Site.PageActions which set's the // tabs that are viewable. This is a bit of a problem. hmmmm. // What I want to know, is not whether or not the Site.PageActions // attributes are // set, but whether or not the attributes are set on the page that is // being displayed. So, I save the referring page being viewed in the // ExternAuthReferrerPage global and used this // for the conditional_authenticate. // This way, whatever conditionals are used on a page // or subsequent included pages, get the value of the referrer page. // To use the referrer page attributes (like the Site.PageActions), // (:if authenticated read referrer:) // (:if authenticated any referrer:) // To do a conditional inclusion based on the attibutes of the present page // (for instance, you want to put some secret stuff in a particular page) // (:if authenticated read:) // (:if authenticated:) - which is the same as (:if authenticated any:) function conditional_authenticate($condparam) { global $ExternAuthReferrerPage; global $ExternAuthCurrentPage; // echo "condparam=$condparam<br>"; $args = ParseArgs($condparam); $level = $args[''][0]; $type = $args[''][1]; // Give the user a way to do an authenticated on any auth with an referrer // Problem being that (:if authenticated referrer :) will use referrer as the // level and not the type. if ($level == 'any') $level = ''; //echo "level=$level, type = $type<br>"; // The ExternAuthReferrerPage is set as a global - // when the page is read the first time in, // it is saved so that subsequent calls for authentication can use it. // This is necessary for the Site.PageActions template. // The ExternAuthCurrentPage is the last page that was read in // i.e. the one that spawned this conditional // if ($type == 'referrer') { //echo "Returning the ReferrerPage<br>"; return extern_authenticate($level, &$ExternAuthReferrerPage); } return extern_authenticate($level, &$ExternAuthCurrentPage); } ///////////////////////////////////////////////////////////////// // The extern_authenticate function assumes that there has // been prior authentication done by some external element. // The results of the authentication are stored in $_SESSION. // // Of interest are the following variables: // $_SESSION['authenticated'] - 1 if the user has authenticated, 0 otherwise // $_SESSION['username'] - The users username - a scalar // $_SESSION['groups'] - an array of the users groups // // The authenticate functions performs the following algorithm: // If there is no level to authenticate, simply return the // users authentication status. // If the level is one of the attributes that we check // and there are no attribute entries, consider the match successful. // Compare the user groups to the authorized group array // Return TRUE if there is a match. // Compare the username to the authorized username array // Return TRUE if there is a match. // If this fails, then return FALSE // // OK - one more problem. Of all of the actions, read doesn't have a default // password. What happens if the page has a read value and we // don't authenticate? // We fail, and it goes back to the general authentication system. // This means that a read failure defaults to the global system read status. // This is generally open. So, what we need to do is go see if there // is a specification on one of the levels that we are checking, and if so, // we need to ensure that the page password is set to something - // if it isn't set, we need to set it to the admin password. function extern_authenticate($level, &$page) { global $ExternAuthAttributes,$DefaultPasswords; global $ExternAuthGroupAttributes; //echo "page (keys)= "; print_r(array_keys($page)); //echo "page (vals)= "; print_r(array_values($page)); //echo "authlevel = $level <br>"; $pagename = $page['name']; $pagegroup = FmtPageName('$Group',$pagename); //echo "pagegroup = $pagegroup<br>"; // This variable counts the number of specified elements in // each group If it is nonzero, there is a restriction $allowvar = 'externauth_' . $level . '_allow'; $uservar = 'externauth_' . $level . '_user'; $groupvar = 'externauth_' . $level . '_group'; // Here we are setting the Users and Groups variables from the page // If the page wants to allow the level, allow it. if ($page[$allowvar]) return true; //echo "Checking $uservar which is " . $page[$uservar] . "<br>"; if ($page[$uservar]) //echo "Found $uservar<br>"; $usercount = count($Users = explode(',',$page[$uservar])); if ($page[$groupvar]) $groupcount = count($Groups = explode(',',$page[$groupvar])); //echo "Users = " . print_r(array_values($Users)) . "<br>"; // Now we need to check for any PmWikiGroup variables // This allows the user to set default attribute permissions for an // entire group // Group Variables are NOT checked if the level has page variables // If there are no corresponding page variables, we set the Groups // and Users variables from the Group defaults. $uservar = $ExternAuthGroupAttributes{$pagegroup}{$level . '_user'}; $groupvar = $ExternAuthGroupAttributes{$pagegroup}{$level . '_group'}; $allowvar = $ExternAuthGroupAttributes{$pagegroup}{$level . '_allow'}; // This variable says that there is a restriction // Somewhere in the page settings $SettingsSet = $usercount + $groupcount; // If the page hasn't set anything on this, and the group allowvar is set, // allow it. if ($allowvar && ! $SettingsSet) { return true; } if (! $usercount) { //echo "Page $pagename, Level $level, Checking uservar = $uservar<br>"; if ($uservar) { $usercount = count($Users = explode(',',$uservar)); //echo "Setting usercount to $usercount<br>"; } } if (! $groupcount) { //echo "Page $pagename, Level $level, Checking groupvar = $groupvar<br>"; if ($groupvar) { $groupcount = count($Groups = explode(',',$groupvar)); //echo "Setting groupcount to $groupcount<br>"; } } // Update the SettingsSet with the Group variable count $SettingsSet = $usercount + $groupcount; //echo "Checking $level<BR>"; //echo "SettingsSet = " . $SettingsSet . "<br>"; //echo "Groups = "; print_r(array_values($Groups)); echo "<br>"; //echo "Users = "; print_r(array_values($Users)); echo "<br>"; if ($_SESSION['authenticated']) { // only return a true if we are authenticated // If we are authenticated and there is no level, call it good if (! $level) { //echo "$level is authenticated (0)<br>"; return true; } // If there is a * in the user field, return true if the user is authenticated if (strstr(implode(',',$Users),'*')) { //echo "Got the big pig for $level<br>"; return true; } // If there are no specifications, consider it a match if it is one of // the variables for which we have attributes. if (! $SettingsSet) { if (isset($ExternAuthAttributes[$level])) { //echo "Getting ready to call " . $ExternAuthAttributes[$level] . "<br>"; return($ExternAuthAttributes[$level]()); } } // If we have specifications, see if they match if ((array_intersect($_SESSION['groups'],$Groups)) || (in_array($_SESSION['username'],$Users))) { //echo "$level is authenticated(2)<br>"; return true; } } // Before returning the failure, ensure that the appropriate password is set. // If the settings haven't been set, then we just go through and let the // system do its defaults. // However, if we have set something, and we have failed, then we need // to ensure that the system defaults is going to be a deny. We do this // by setting the page password to be the admin password for the wiki. // this means that the wiki admin can get everywhere from the web // without using our authentications. if ($SettingsSet) { if (! $DefaultPasswords[$level]) { //$DefaultPasswords[$level] = $DefaultPasswords['admin']; //echo "DefaultPasswords[$level] = $DefaultPasswords[$level]<br>"; $page["passwd$level"] = $DefaultPasswords['admin']; //echo "page[passwd$level] = " . $page["passwd$level"] . "<br>"; //echo "pagename = " . $page[name] . "; "; //echo "page[passwd$level] = " . $page["passwd$level"] . "<br>"; } } //echo "$level is NOT authenticated<br>"; return false; } ///////////////////////////////////////////////////////////////// // The ExternAuth function is a copy of PmWikiAuth with a simple // modifications to check for external authorizations. // The only addition are the lines ... /* SDV($ExternAuthReferrerPage,$page); $ExternAuthCurrentPage = $page; if (extern_authenticate($level,&$page)) { return $page; } */ // Which call the extern_authenticate function before passing control to // the standard function. The assumption is that all functions are // nailed down with passwords so that anything beyond what is // allowed by the authenticate function requires a password. // function ExternAuth($pagename, $level, $authprompt=true, $since=0) { //echo "Calling ExternAuth on $pagename, level = $level, authprompt=$authprompt, since = $since<br>"; global $DefaultPasswords, $AllowPassword, $GroupAttributesFmt, $ExternAuthReferrerPage,$ExternAuthCurrentPage, $AuthCascade, $FmtV, $AuthPromptFmt, $PageStartFmt, $PageEndFmt, $AuthId; static $grouppasswd, $authpw; SDV($GroupAttributesFmt,'$Group/GroupAttributes'); SDV($AllowPassword,'nopass'); $page = ReadPage($pagename, $since); if (!$page) { return false; } ////////////////////////////////////////////////// // I need to save the page when it is found so that the attributes for this // page are available to subsequent authorization checks. // For example, which tabs I put on top (edit, attr) are dependent not on // the attributes of the template page, but on the attributes of this page // The ExternAuthReferrerPage saves the referrer page that started everything // ExternAuthCurrentPage saves the current page (from which this auth call came // These are both used for conditional inclusion SDV($ExternAuthReferrerPage,$page); $ExternAuthCurrentPage = $page; ////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// // So, here I authenticate. // If the user is authenticated, return the page //echo "Checking page " . $page[name] . " at level $level"; if (extern_authenticate($level,&$page)) { //echo "- it is AUTHENTICATED<br>"; return $page; } //echo "- it is NOT AUTHENTICATED "; // But if they aren't, what do we do? // We assume that the site is configured with default passwords on everything // except read - so just pass it on ... /////////////////////////////////////////////////////////////////// $groupattr = FmtPageName($GroupAttributesFmt, $pagename); if (!isset($grouppasswd[$groupattr])) { $grouppasswd[$groupattr] = array(); $gp = ReadPage($groupattr, READPAGE_CURRENT); foreach($DefaultPasswords as $k=>$v) if (isset($gp["passwd$k"])) $grouppasswd[$groupattr][$k] = explode(' ', $gp["passwd$k"]); } foreach ($DefaultPasswords as $k=>$v) { if (isset($page["passwd$k"])) { $passwd[$k] = explode(' ', $page["passwd$k"]); $page['=pwsource'][$k] = 'page'; } else if (isset($grouppasswd[$groupattr][$k])) { $passwd[$k] = $grouppasswd[$groupattr][$k]; $page['=pwsource'][$k] = 'group'; } else { $passwd[$k] = $v; if ($v) $page['=pwsource'][$k] = 'site'; } } $page['=passwd'] = $passwd; foreach($AuthCascade as $k => $t) { if (!$passwd[$k] && $passwd[$t]) { $passwd[$k] = $passwd[$t]; $page['=pwsource'][$k] = "cascade:$t"; } } if (!isset($authpw)) { $sid = session_id(); @session_start(); if (@$_POST['authpw']) @$_SESSION['authpw'][$_POST['authpw']]++; $authpw = array_keys((array)@$_SESSION['authpw']); if (!isset($AuthId)) $AuthId = @$_SESSION['authid']; if (!$sid) session_write_close(); } foreach($passwd as $lv => $a) { if (!$a) { $page['=auth'][$lv]++; continue; } foreach((array)$a as $pwchal) { if ($AuthId && strncmp($pwchal, 'id:', 3) == 0) { $idlist = explode(',', substr($pwchal, 3)); foreach($idlist as $id) { if ($id == $AuthId || $id == '*') { $page['=auth'][$lv]++; continue 3; } if ($id == "-$AuthId") { continue 3; } } } if ($pwchal == '' || crypt($AllowPassword, $pwchal) == $pwchal) { $page['=auth'][$lv]++; continue 2; } foreach ($authpw as $pwresp) if (crypt($pwresp, $pwchal) == $pwchal) { $page['=auth'][$lv]++; continue 3; } } } if ($page['=auth']['admin']) foreach($passwd as $lv=>$a) $page['=auth'][$lv]++; if ($page['=auth'][$level]) { //echo "The page is being allowed<br>"; return $page; } //echo "The page is NOT being allowed<br>"; if (!$authprompt) return false; PCache($pagename, $page); $postvars = ''; foreach($_POST as $k=>$v) { if ($k == 'authpw') continue; $v = str_replace('$', '$', htmlspecialchars(stripmagic($v), ENT_COMPAT)); $postvars .= "<input type='hidden' name='$k' value=\"$v\" />\n"; } $FmtV['$PostVars'] = $postvars; SDV($AuthPromptFmt,array(&$PageStartFmt, "<p><b>Please authenticate to view this page</b></p> <p>Use the login box on the left</p> <br> <p>If you are the Wiki administrator, you may the Wiki password here</p> <form name='authform' action='{$_SERVER['REQUEST_URI']}' method='post'> Password: <input tabindex='1' type='password' name='authpw' value='' /> <input type='submit' value='OK' />\$PostVars</form> <script language='javascript'><!-- document.authform.authpw.focus() //--></script>", &$PageEndFmt)); PrintFmt($pagename,$AuthPromptFmt); exit; } ///////////////////////////////////////////////////////////////////// // // The following are copies of pmwiki functions with simple changes // ///////////////////////////////////////////////////////////////////// // This is the HandlAuth array from pmwiki.php // I want to change this so that the source action // has the permissions of edit and not read. // There isn't any reason to be looking at the source // if you can't change it. And there may be things // that I want to hide in the source. $HandleAuth = array( 'browse' => 'read', 'source' => 'edit', 'diff' => 'edit','rename' => 'rename', 'edit' => 'edit', 'attr' => 'attr', 'postattr' => 'attr', 'comment' => 'edit', 'logout' => 'read', 'login' => 'login'); // This is the HandlActions array from pmwiki.php // I want to change this so that the it used my ExternAuthHandleAttr function // where I changed the message /* $HandleActions = array( 'browse' => 'HandleBrowse', 'edit' => 'HandleEdit', 'source' => 'HandleSource', 'attr' => 'ExternAuthHandleAttr', 'postattr' => 'ExternAuthHandlePostAttr', 'logout' => 'HandleLogoutA', 'login' => 'HandleLoginA'); */ $HandleActions['attr'] = 'ExternAuthHandleAttr'; $HandleActions['postattr'] = 'ExternAuthHandlePostAttr'; // This is a copy of the function in pmwiki.php. I just wanted to change the message. // function ExternAuthHandleAttr($pagename, $auth = 'attr') { global $PageAttrFmt,$PageStartFmt,$PageEndFmt; $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT); if (!$page) { Abort("?unable to read $pagename"); } PCache($pagename,$page); XLSDV('en', array('EnterAttributes' => "<p>From the attributes pages you can set who has access to various actions that operate on this page. The actions that you can control include who can read the page, who can edit the page, who can rename the page, who can set these attributes, and who can upload files to a WikiGroup from this page. There are Group Defaults for an entire WikiGroup. These are set by the Wiki administrator. Each page can also have its own unique Page Settings. If any value is set in these Page Settings, the Group Defaults for that attribute will be ignored and the Page Settings values will be used instead. </p><br><p> For each of the actions, you can enable specific users or groups of users. To enable a specific user, enter the username in the appropriate text field. If you want to enable multiple users, enter a comma-separated list of usernames (e.g. gehrig,ruth,mantle). To allow any authenticated user, place an asterisk (*) in the field. </p><br><p> Access can also be restricted to groups. Check the appopriate boxes to enable individual groups. The action will be allowed if the authenticated username is explicitly set in the appropriate action OR if the user is in a group that is enabled for the action. </p><br> Finally, if you want to simply ensure that ANYONE can perform the action, check the anyone box in the action allow checkbox. </p><br> <br>")); SDV($PageAttrFmt,"<div class='wikiattr'> <h2 class='wikiaction'>$[{\$FullName} Attributes]</h2> <p>$[EnterAttributes]</p></div>"); SDV($HandleAttrFmt,array(&$PageStartFmt,&$PageAttrFmt, 'function:EAPrintAttrForm',&$PageEndFmt)); PrintFmt($pagename,$HandleAttrFmt); } function EAPrintAttrForm($pagename) { global $PageAttributes, $PCache, $FmtV, $ExternAuthGroups, $ExternAuthGroupAttributes; $allow_color = '#ffcccc'; $group_color = '#ccccff'; echo ("<H2>Group Defaults</H2><br>"); echo "In the abscence of group defaults or page specific settings, the read action will be allowed for any visitor to the website. The edit and action is restricted to authenticated users, and the upload, rename and attribute actions are restricted to members of the faculty, staff, and webadmin groups."; echo ("<table border=2 cellspacing=5>"); $page = $PCache[$pagename]; $groupname = FmtPageName('$Group',$pagename); $group_columns = 8; // Let's print out the group defaults foreach($ExternAuthGroupAttributes[$groupname] as $attr=>$p) { $setting = $p; $value = $p; $prompt = ereg_replace('_',' ',$attr) . 's:'; $colcount = 0; if (strstr($attr, 'group')) { echo "<tr bgcolor=$group_color><td>$prompt</td>"; foreach($ExternAuthGroups as $group=>$descr) { //echo "group=$group, descr=$descr<br>"; $cbox_value=''; //echo "Looking for $group in $setting<br>"; if (strstr($setting,$group)) { $cbox_value='checked'; } $name = $attr . '_' . $group . 'jojo'; //echo "Setting the name to $name with cbox_value $cbox_value<br>"; if ($colcount >= $group_columns) { $colcount = 0; echo "</tr><tr bgcolor=$group_color><td></td>"; } echo "<td align='right'>$group <input type='checkbox' name=$name $cbox_value DISABLED/></td>"; $colcount = $colcount + 1; } echo "</tr>"; } else { $spansize = count($ExternAuthGroups); echo "<tr><td>$prompt</td> <td colspan=$spansize><input type='text' name='$attr' value='$value' READONLY/></td> <td>$setting</td></tr>"; } } echo FmtPageName("</table><br><br></form>", $pagename); echo ("<H2>Page Settings</H2><br>"); echo FmtPageName("<form action='\$PageUrl' method='post'> <input type='hidden' name='action' value='postattr' /> <input type='hidden' name='n' value='\$FullName' /> <table border=2 cellspacing=5>",$pagename); $page = $PCache[$pagename]; /* This goes through the PageAttributes vars to build up stuff */ $colcount=0; foreach($PageAttributes as $attr=>$p) { if (!$p) continue; $setting = @$page[$attr]; $value = @$page[$attr]; $prompt = FmtPageName($p,$pagename); $colcount = 0; if (strstr($attr, 'group')) { echo "<tr bgcolor=$group_color><td>$prompt</td>"; foreach($ExternAuthGroups as $group=>$descr) { //echo "group=$group, descr=$descr<br>"; $cbox_value=''; //echo "Looking for $group in $setting<br>"; if (strstr($setting,$group)) { $cbox_value='checked'; } $name = $attr . '_' . $group; //echo "Setting the name to $name with cbox_value $cbox_value<br>"; if ($colcount >= $group_columns) { $colcount = 0; echo "</tr><tr bgcolor=$group_color><td></td>"; } echo "<td align='right'>$group <input type='checkbox' name=$name $cbox_value /></td>"; $colcount = $colcount + 1; } echo "</tr>"; } elseif (strstr($attr, 'allow')) { $prompt = ereg_replace('_',' ',$attr) ; $prompt = ereg_replace('externauth ','',$prompt) ; echo "<tr bgcolor=$allow_color><td>$prompt</td>"; $setting = @$page[$attr]; $cbox_value=''; if ($setting) { $cbox_value='checked'; } $name = $attr; //echo "Setting the name to $name with cbox_value $cbox_value<br>"; echo "<td align='right'>anyone <input type='checkbox' name=$name $cbox_value /></td>"; echo "</tr>"; } else { $spansize = count($ExternAuthGroups); echo "<tr bgcolor=#ffffff><td>$prompt</td> <td colspan=$spansize><input type='text' name='$attr' value='$value' /></td> <td>$setting</td></tr>"; } } echo FmtPageName("</table><br><input type='submit' value='$[Save]' /></form>", $pagename); echo "<hr>"; } function ExternAuthHandlePostAttr($pagename, $auth = 'attr') { global $PageAttributes, $EnablePostAttrClearSession, $ExternAuthGroups; Lock(2); $page = RetrieveAuthPage($pagename, $auth, true); if (!$page) { Abort("?unable to read $pagename"); } // We are going to have to do more than get the page attributes here, // we need to also get the tacked on group attributes. // maybe we should do that first, turn it into a page attribute, // and then go from there ... // For each of the page attributes foreach($PageAttributes as $attr=>$p) { //echo "Looking for group in $attr<br>"; if (strstr($attr,'group')) { // Clear the group array $group_array = array(); // For each of the groups foreach($ExternAuthGroups as $group=>$desc) { //Form the groupvar $groupvar = $attr . '_' . $group; //See if the groupvar is set if ($_POST[$groupvar] != '') { //if so, push it onto an array array_push($group_array,$group); } } // Set the POST attribute as though I had done it via a string $_POST[$attr] = implode(',',$group_array); } } foreach($PageAttributes as $attr=>$p) { //echo "Looking at $attr = $p <br>"; // Clear any of the group Page Attributes as we will set them from the post //if (strstr($attr,'group')) { unset($page[$attr]); //} $v = stripmagic(@$_POST[$attr]); //echo "V = $v<br>"; if ($v == '') continue; //if ($v=='clear') unset($page[$attr]); else if (strncmp($attr, 'passwd', 6) != 0) $page[$attr] = $v; else { $a = array(); preg_match_all('/"[^"]*"|\'[^\']*\'|\\S+/', $v, $match); foreach($match[0] as $pw) $a[] = preg_match('/^(@|\\w+:)/', $pw) ? $pw : crypt(preg_replace('/^([\'"])(.*)\\1$/', '$2', $pw)); if ($a) $page[$attr] = implode(' ',$a); } } WritePage($pagename,$page); Lock(0); if (IsEnabled($EnablePostAttrClearSession, 1)) { @session_start(); unset($_SESSION['authid']); unset($_SESSION['authlist']); $_SESSION['authpw'] = array(); } Redirect($pagename); exit; } ?>