Location: PHPKode > projects > ProNuke. Postnuke To Oracle > postnuke/html/includes/security.php
<?php // File: $Id: security.php,v 1.15 2001/12/07 23:43:11 jgm Exp $
// ----------------------------------------------------------------------
// POST-NUKE Content Management System
// Copyright (C) 2001 by the Post-Nuke Development Team.
// http://www.postnuke.com/
// ----------------------------------------------------------------------
// Based on:
// PHP-NUKE Web Portal System - http://phpnuke.org/
// Thatware - http://thatware.org/
// ----------------------------------------------------------------------
// LICENSE
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License (GPL)
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// To read the license please visit http://www.gnu.org/copyleft/gpl.html
// ----------------------------------------------------------------------
// Original Author of file: Jim McDonald
// Purpose of file: Provide a low-level security access mechanism
// ----------------------------------------------------------------------


/*
 * Notes on security system
 *
 * Special UID and GIDS:
 *  UID -1 corresponds to 'all users', includes unregistered users
 *  GID -1 corresponds to 'all groups', includes unregistered users
 *  UID 0 corresponds to unregistered users
 *  GID 0 corresponds to unregistered users
 *
 */

global $currentlang;

// Language
if (file_exists("language/$currentlang/security.php")) {
    include "language/$currentlang/security.php";
} elseif (file_exists("language/eng/security.php")) {
    include "language/eng/security.php";
}


/*
 * Defines for access levels
 */
define("ACCESS_INVALID", -1);
define("ACCESS_NONE", 0);
define("ACCESS_OVERVIEW", 100);
define("ACCESS_READ", 200);
define("ACCESS_COMMENT", 300);
define("ACCESS_MODERATE", 400);
define("ACCESS_EDIT", 500);
define("ACCESS_ADD", 600);
define("ACCESS_DELETE", 700);
define("ACCESS_ADMIN", 800);

/*
 * Arrays for transformations
 */
global $accessnames;
$accessnames = array(  0 => _ACCESS_NONE,
                     100 => _ACCESS_OVERVIEW,
                     200 => _ACCESS_READ,
                     300 => _ACCESS_COMMENT,
                     400 => _ACCESS_MODERATE,
                     500 => _ACCESS_EDIT,
                     600 => _ACCESS_ADD,
                     700 => _ACCESS_DELETE,
                     800 => _ACCESS_ADMIN);

// Don't think we need this, but leave it around for the moment
global $accesslevels;
$accesslevels = array(_ACCESS_NONE     =>   0,
                      _ACCESS_OVERVIEW => 100,
                      _ACCESS_READ     => 200,
                      _ACCESS_COMMENT  => 300,
                      _ACCESS_MODERATE => 400,
                      _ACCESS_EDIT     => 500,
                      _ACCESS_ADD      => 600,
                      _ACCESS_DELETE   => 700,
                      _ACCESS_ADMIN    => 800);

/*
 * Translation functions - avoids globals in external code
 */

// Translate level -> name
function accesslevelname($level) {
    global $accessnames;

    //FTO Remove Warning
    if (!isset($accessnames[$level])) $accessnames[$level]='';
    
    return $accessnames[$level];
}

// Get all level -> name
function accesslevelnames() {
    global $accessnames;

    return $accessnames;
}

// Translate name -> level
function accessnamelevel($name) {
    global $accesslevels;

    return $accesslevels[$name];
}

// Get all name -> levels
function accessnamelevels() {
    global $accesslevels;

    return $accesslevels;
}

/*
 * schemas - holds all component/instance schemas
 */
$schemas = array();

/*
 * addinstanceschemainfo - register an instance schema with the security
 *                         system
 *
 * Takes two parameters:
 * - a component
 * - an instance schema
 *
 * Will fail if an attempt is made to overwrite an existing schema
 */
function addinstanceschemainfo($component, $schema) {
    global $schemas;

    if (!empty($schemas[$component])) {
       // Duplicate schema
       die("Duplicate schema $component detected");
    }
    $schemas[$component] = $schema;

}

// Get list of schemas
function getinstanceschemainfo() {
    global $schemas;
    static $gotmoduleschemas = 0;

    if ($gotmoduleschemas == 0) {
        getmodulesinstanceschemainfo();
        $gotmoduleschemas = 1;
    }

    return $schemas;
}

// Get instance information from modules
function getmodulesinstanceschemainfo() {

    $moddir = opendir('modules/');
    while ($modname = readdir($moddir)) {
        if (@file_exists("modules/$modname/Version.php")) {
            include "modules/$modname/Version.php";
            if (!empty($modversion['securityschema'])) {
                foreach ($modversion['securityschema'] as $component => $instance) {
                    addinstanceschemainfo($component, $instance);
                }
            }
            $modversion['securityschema'] = '';
        }
    }
    closedir($moddir);
}

/*
 * authorised - see if a user is authorised to view a particular element
 * Takes four parameters:
 * - the realm
 * - the component
 * - the instance
 * - the level of access required
 *
 * Returns 1 if authorised, 0 if not
 */
function authorised($testrealm, $testcomponent, $testinstance, $testlevel)
{

    static $authinfogathered = 0;
    static $userperms, $groupperms;
    global $pntable, $dbconn;

    if ($authinfogathered == 0) {
        // First time here - get auth info
        list($userperms, $groupperms) = gatherAuthInfo();

        $authinfogathered = 1;
    }

    // Confirm this is a valid component
    // Not yet active, might never be
//    if (!authValidComponent($testcomponent)) {
//        die("Invalid test component $testcomponent");
//        exit;
//    }

    // Get group access level
    $grouplevel = getLevel($groupperms, $testrealm, $testcomponent, $testinstance);

    // Get user access level
    $userlevel = getLevel($userperms, $testrealm, $testcomponent, $testinstance);

    // Assume no access
    $retval = 0;

    // Group level access, if it exists
    if ($grouplevel >= $testlevel) {
        $retval = 1;
    }

    // User access level is over-ride, so return that if it exists
    if ($userlevel > ACCESS_INVALID) {
        if ($userlevel >= $testlevel) {
            $retval = 1;
        } else {
            $retval = 0;
        }
    }

    return($retval);
}

function gatherAuthInfo()
{
    global $pntable, $dbconn, $user;

    // Tables we use
    $userpermtable = $pntable['user_perms'];
    $userpermcolumn = &$pntable['user_perms_column'];

    $groupmembershiptable = $pntable['group_membership'];
    $groupmembershipcolumn = &$pntable['group_membership_column'];

    $grouppermtable = $pntable['group_perms'];
    $grouppermcolumn = &$pntable['group_perms_column'];

    $realmtable = $pntable['realms'];
    $realmcolumn = &$pntable['realms_column'];

    // Empty arrays
    $userperms = array();
    $groupperms = array();

    $uids[] = -1;
    // Get user ID
    if (empty($user)) {
       // Unregistered UID
       $uids[] = 0;
    } else {
        if (!is_user($user)) {
            return array($userperms, $groupperms);
        }
        $uinfo = base64_decode($user);
        $uinfo = explode(':', $uinfo);
        $uids[] = $uinfo[0];
    }
    $uids = implode(",", $uids);

    // ===FTO. USe the PNTABLES defines from the where clause.
    // ORACLEDONE

    // Get user permissions

    $query = "SELECT $userpermcolumn[realm],
                     $userpermcolumn[component],
                     $userpermcolumn[instance],
                     $userpermcolumn[level]
              FROM $userpermtable
              WHERE $userpermcolumn[uid] IN ($uids)
              ORDER by $userpermcolumn[sequence]";
              
    $result = $dbconn->Execute($query);

//FTO : Rewrite the condition loop clearly to test EOF

    if (!$result) {
        PN_DBMsgError($dbconn, __FILE__, __LINE__, "An error ocurred");
        die();
    }
    while(! $result->EOF) {

        list($realm, $component, $instance, $level) = $result->fields;
        
        // Fix component and instance to auto-insert '.*'
        $component = preg_replace('/^$/', '.*', $component);
        $component = preg_replace('/^:/', '.*:', $component);
        $component = preg_replace('/::/', ':.*:', $component);
        $component = preg_replace('/:$/', ':.*', $component);
        $instance = preg_replace('/^$/', '.*', $instance);
        $instance = preg_replace('/^:/', '.*:', $instance);
        $instance = preg_replace('/::/', ':.*:', $instance);
        $instance = preg_replace('/:$/', ':.*', $instance);

        $userperms[] = array("realm"     => $realm,
                             "component" => $component,
                             "instance"  => $instance,
                             "level"     => $level);

        $result->MoveNext();
    }

    // Get all groups that user is in
    $query = "SELECT $groupmembershipcolumn[gid]
              FROM $groupmembershiptable
              WHERE $groupmembershipcolumn[uid] IN ($uids)";

    $result = $dbconn->Execute($query);
    $usergroups[] = -1;
    if (empty($user)) {
       // Unregistered GID
       $usergroups[] = 0;
    }

//FTO : Rewrite the condition loop clearly to test EOF

    if (!$result) {
        PN_DBMsgError($dbconn, __FILE__, __LINE__, "An error ocurred");
        die();
    }
    while(! $result->EOF ) {

        list($gid) = $result->fields;
        $usergroups[] = $gid;
        $result->MoveNext();
    }

    $usergroups = implode(",", $usergroups);

//FTO : SOFT CODED GID. USE PNTABLES DEFINES

// Get all group permissions

    $query = "SELECT $grouppermcolumn[realm],
                     $grouppermcolumn[component],
                     $grouppermcolumn[instance],
                     $grouppermcolumn[level]
              FROM $grouppermtable
              WHERE $grouppermcolumn[gid] IN ($usergroups)
              ORDER by $grouppermcolumn[sequence]";
    $result = $dbconn->Execute($query);

//FTO : Rewrite the condition loop clearly to test EOF

    if (!$result) {
        PN_DBMsgError($dbconn, __FILE__, __LINE__, "An error ocurred");
        die();
    }

    while(! $result->EOF) {

        list($realm, $component, $instance, $level) = $result->fields;
        
        // Fix component and instance to auto-insert '.*' where
        // there is nothing there
        $component = preg_replace('/^$/', '.*', $component);
        $component = preg_replace('/^:/', '.*:', $component);
        $component = preg_replace('/::/', ':.*:', $component);
        $component = preg_replace('/:$/', ':.*', $component);
        $instance = preg_replace('/^$/', '.*', $instance);
        $instance = preg_replace('/^:/', '.*:', $instance);
        $instance = preg_replace('/::/', ':.*:', $instance);
        $instance = preg_replace('/:$/', ':.*', $instance);

        $groupperms[] = array("realm"     => $realm,
                              "component" => $component,
                              "instance"  => $instance,
                              "level"     => $level);
        $result->MoveNext();
    }

    return array($userperms, $groupperms);
}

function getLevel($perms, $testrealm, $testcomponent, $testinstance)
{
    $level = ACCESS_INVALID;

    // If we get a test component or instance purely consisting of ':' signs
    // then it counts as blank
    $testcomponent = preg_replace('/^:*$/', '', $testcomponent);
    $testinstance = preg_replace('/^:*$/', '', $testinstance);

    foreach ($perms as $perm) {

        // Confirm generic realm, or this particular realm
        if (($perm['realm'] != 0) && ($perm['realm'] != $testrealm)) {
            continue;
        }

        if (($testcomponent != '') && ($testinstance != '')) {
            // Confirm that component and instance match
            if (!((ereg("^$perm[component]$", $testcomponent)) &&
                  (ereg("^$perm[instance]$", $testinstance)))) {
                continue;
            }
        } elseif (($testcomponent != '') && ($testinstance == '')) {
            // Confirm that component matches
            if (!ereg("^$perm[component]$", $testcomponent)) {
              continue;
            }
        } elseif (($testcomponent == '') && ($testinstance != '')) {
            // Confirm that instance matches
            if (!ereg("^$perm[instance]$", $testinstance)) {
                continue;
            }
        }

        // We have a match - set the level and quit
        $level = $perm['level'];
        break;

    }
    return($level);
}

/*
 * Confirm that we have a schema for this component
 */
function authValidComponent($testcomponent)
{
    global $schemas;

    list($sc1, $sc2, $sc3) = explode(":", $testcomponent);
    if (!empty($schemas["$sc1::$sc3"])) {
        return 1;
    } else {
        return 0;
    }
}

?>
Return current item: ProNuke. Postnuke To Oracle