1 /* Copyright (C) 2000-2006  Thomas Bopp, Thorsten Hampel, Ludger Merkens
     3  *  This program is free software; you can redistribute it and/or modify
     4  *  it under the terms of the GNU General Public License as published by
     5  *  the Free Software Foundation; either version 2 of the License, or
     6  *  (at your option) any later version.
     8  *  This program is distributed in the hope that it will be useful,
     9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  *  GNU General Public License for more details.
    13  *  You should have received a copy of the GNU General Public License
    14  *  along with this program; if not, write to the Free Software
    15  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    17  * $Id: security.pike,v 1.3 2009/06/19 16:13:59 astra Exp $
    19 inherit "/kernel/module";
    23 #include <attributes.h>
    28 //! The security module handles all security issues in sTeam. It
    29 //! listens to almost any event globally and tries to block events
    30 //! if permission checks fail.
    31 class security : public module{
    40 private  array sRegisteredPermissions;
    41 private  mapping       mValidObjects = ([ ]);
    42 private  object                security_cache;
    44 #define CACHE_AVAILABLE (objectp(security_cache) && objectp(obj))
    47  * Load this security module and add all global events which
    48  * are relevant for security. E.g. should have callback functions
    52 void post_load_module()
    54   security_cache = get_module("Security:cache");
    60     add_global_event(EVENT_MOVE, access_move, PHASE_BLOCK);
    61     add_global_event(EVENT_GET_INVENTORY, access_read, PHASE_BLOCK);
    62     add_global_event(EVENT_ATTRIBUTES_CHANGE, access_attribute_change, 
    64     add_global_event(EVENT_ATTRIBUTES_ACQUIRE, access_attribute_acquire,
    66     add_global_event(EVENT_ATTRIBUTES_LOCK, access_attribute_lock,
    68     add_global_event(EVENT_DOWNLOAD, access_read, PHASE_BLOCK);
    69     add_global_event(EVENT_DUPLICATE, access_read, PHASE_BLOCK);
    70     add_global_event(EVENT_UPLOAD, access_write, PHASE_BLOCK);
    71     add_global_event(EVENT_LOCK, access_write, PHASE_BLOCK);
    72     add_global_event(EVENT_UNLOCK, access_write, PHASE_BLOCK);
    73     add_global_event(EVENT_ATTRIBUTES_QUERY,access_read_attribute,PHASE_BLOCK);
    74     add_global_event(EVENT_DELETE, access_delete, PHASE_BLOCK);
    75     add_global_event(EVENT_REGISTER_ATTRIBUTE, access_register_attribute, 
    77     add_global_event(EVENT_EXECUTE, access_execute, PHASE_BLOCK);
    78     add_global_event(EVENT_REMOVE_MEMBER, access_group_remove_member, 
    80     add_global_event(EVENT_ADD_MEMBER, access_group_add_member, PHASE_BLOCK);
    81     add_global_event(EVENT_GRP_ADD_PERMISSION, access_group_add_permission,
    83     add_global_event(EVENT_GRP_ADDMUTUAL, access_group_addmutual, PHASE_BLOCK);
    84     add_global_event(EVENT_USER_CHANGE_PW, access_change_password, 
    86     add_global_event(EVENT_SANCTION, access_sanction_object, PHASE_BLOCK);
    87     add_global_event(EVENT_SANCTION_META, access_sanction_object_meta, 
    89     add_global_event(EVENT_ANNOTATE, access_annotate, PHASE_BLOCK);
    90     add_global_event(EVENT_ARRANGE_OBJECT, access_arrange, PHASE_BLOCK);
    92     sRegisteredPermissions = allocate(16);
    93     for ( int i = 0; i < 16; i++ )
    94    sRegisteredPermissions[i] = "free";
    95     sRegisteredPermissions[8] = "sanction";
    96     sRegisteredPermissions[0] = "read";
    97     sRegisteredPermissions[1] = "execute";
    98     sRegisteredPermissions[2] = "move";
    99     sRegisteredPermissions[3] = "write";
   100     sRegisteredPermissions[4] = "insert";
   101     sRegisteredPermissions[5] = "annotate";
   107  * This is a callback function called from the master() object when this
   108  * module is upgraded. The master() object is a concept of the pike 
   109  * programming language. Upgrading is a key concept of sTeam.
   114     if ( CALLER != master() ) 
   116     remove_global_events();
   119  program pAccess = (program)"/base/access.pike";
   120  program pUser = (program)"/net/coal/login.pike";
   122 int is_valid(object obj)
   124   function|program prg = object_program(obj);
   125   if ( functionp(prg) )
   127   if ( Program.inherits(prg, pAccess) || Program.inherits(prg, pUser) )
   132 object get_valid_caller(object obj, mixed bt)
   139     for ( ; sz >= 0; sz-- ) {
   140    if ( functionp(bt[sz][2]) ) {
   141        function f = bt[sz][2];
   142        caller = function_object(f);
   143        if ( caller == obj ) {
   146        else if ( foundobj ) {
   147          if ( IS_SOCKET(caller) )
   148            return caller->get_user_object();
   149          if ( is_valid(caller) ) 
   154     steam_error(sprintf("No valid object found for %O in \n%O\n",
   160  * check if the given object is a valid proxy
   162  * @param obj - the object to check
   163  * @return if valid or not
   168 bool valid_proxy(object obj)
   172     if ( obj == 0 || !functionp(obj->get_object) )
   175     o = obj->get_object();
   179     return o->trust(obj);
   183  * check if the given object is a valid user
   185  * @param obj - the object to check
   186  * @return if object is valid user or not
   191 bool valid_user(object obj)
   193     if ( valid_proxy(obj) )
   194    obj = obj->get_object();
   196     program pUser = (program)"/classes/User.pike"; // cache User
   198     if ( object_program(obj) == pUser ) {
   199    SECURITY_LOG("[%s] is valid user !", obj->get_identifier());
   206  * check if the object is a valid object, that is inherits access.pike
   208  * @param obj - the object to check
   209  * @return true or false
   214 bool valid_object(object obj)
   216     program pObject, pAccess;
   217     function|program     prg;
   219     if ( !objectp(obj) ) {
   220       werror("valid_object(0) by %O\n", backtrace());
   223     if ( valid_proxy(obj) ) {
   224    obj = obj->get_object();
   229     prg = object_program(obj);
   230     if ( functionp(prg) )
   231       prg = function_program(prg);
   233     if ( !programp(prg) ) 
   234       werror("Warning prg is not a valid prorgram: %O for object: %O\n", prg, obj);
   236     if ( mValidObjects[prg] )
   239     pObject = (program)"/classes/Object.pike";
   240     pAccess = (program)"/base/access.pike";
   241     /* see if it inherits the access object to make sure
   242      * access functions are from the right place
   243      * or if the object is /classes/Object.pike clone itself */
   244     if ( Program.inherits(prg, pAccess) || Program.inherits(prg, pUser) ||
   247    mValidObjects[prg] = true;
   254  * see if the object is a valid group, that is clone of Group.pike
   256  * @param obj - the object to check
   257  * @return true or false
   262 bool valid_group(object obj)
   264     if ( valid_proxy(obj) ) obj = obj->get_object();
   265     program pGroup = (program)"/classes/Group.pike";
   266     if ( object_program(obj) == pGroup )
   274  * check role permission of user groups recursively
   276  * @param grp - the group that wants to write
   277  * @param accessRole - the role that the group must feature
   278  * @return if successfull or not
   279  * @see try_access_object
   282 check_role_permission(object grp, int roleBit, void|mixed ctx)
   286     if ( roleBit == 0 ) // no special role permission granted
   289     grp = grp->get_object();
   293     ASSERTINFO(valid_group(grp), "Group:" + grp->get_identifier() +
   294           " is not a valid group");
   295     SECURITY_LOG("Checking role permissions on %s" + 
   296             "(permission="+grp->get_permission()+")",
   297             grp->get_identifier()  );
   299     if ( grp->features(roleBit, ctx) ) 
   300    return true; // group has permission itself
   302     array grp_groups = grp->get_groups();
   303     foreach( grp_groups, object member ) {
   304    LOG("Accessing indirectly by " + member->get_identifier());
   305    if ( objectp(member) && valid_group(member) ) {
   306        if ( check_role_permission(member, roleBit, ctx) )
   310     /* check the parent group for permission otherwise */
   315  * try to access an object by one of the users groups
   317  * @param obj - the object accessed
   318  * @param user - the active user
   319  * @param accessBit - the access Bit used
   320  * @return true or false
   325 check_access_user(object obj, object user, int accBit, int roleBit,bool meta,void|RoleContext ctx)
   330     int userAcc  = ACCESS_GRANTED;
   331     int groupAcc = ACCESS_GRANTED;
   333     SECURITY_LOG("check_access_user(%s %s,"+
   334             accBit + ","+ roleBit+","+ meta+")",
   335                     (objectp(obj) ? obj->get_identifier() + 
   336              "["+obj->get_object_id()+"]," : "null,"),
   337             user->get_identifier());
   339     if ( CACHE_AVAILABLE && !meta ) {
   340    if ( security_cache->get_permission(obj, user) & 
   341         (accBit<<SANCTION_SHIFT_DENY) ) 
   343    else if ( security_cache->get_permission(obj, user) & accBit ) {
   344        SECURITY_LOG("Cache hit: true !")
   350    userAcc = obj->try_access_object(user, accBit, meta);
   351    if ( userAcc == ACCESS_GRANTED ) {
   352        if ( CACHE_AVAILABLE ) {
   353            security_cache->add_permission(obj, user, accBit);
   359     groups = user->get_groups();
   361     SECURITY_LOG("Checking access for " + sizeof(groups) + 
   362             " groups (accessbit="+accBit+",rolebit="+roleBit+")!");
   363     /* go through all groups and see if the general roleBit works
   364      * or if the group is able to access the object */
   365     for ( i = sizeof(groups) - 1; i >= 0; i-- ) {
   366    if ( !objectp(groups[i]) ) 
   367        THROW("User is in 0-group - this should not happen !", E_ERROR);
   370        if ( check_role_permission(groups[i], roleBit, ctx) ) {
   371            SECURITY_LOG("Role permission success !");
   372            if ( CACHE_AVAILABLE && !meta )
   373                security_cache->add_permission(obj, user, accBit);
   377    /* if user/group access is once blocked only the above role
   378     * permission might work
   379     * this is to still have the admin groups do everything
   381    if ( accBit > 0 && userAcc != ACCESS_BLOCKED )
   383        groupAcc = obj->try_access_object_group(groups[i], accBit, meta);
   384        if ( groupAcc == ACCESS_GRANTED ) {
   385            if ( CACHE_AVAILABLE && !meta )
   386                security_cache->add_permission(obj, user, accBit);
   387            SECURITY_LOG("Group direct access !");
   392     if ( CACHE_AVAILABLE && !meta )
   393       security_cache->add_permission(obj,user,accBit<<SANCTION_SHIFT_DENY);
   400 private  mapping join_permissions(mapping p1, mapping p2)
   402   array sanctioned = indices(p1) | indices(p2);
   403   mapping permissions = ([ ]);
   404   foreach(sanctioned, object s) {
   405     permissions[s] = p1[s] | p2[s];
   412 mapping|int get_permissions(object obj, void|object grp) 
   415   if ( objectp(grp) ) {
   416     mapping permissions = get_permissions(obj);
   417     int p = permissions[grp];
   418     foreach(grp->get_groups(), object g) {
   420       object pgroup = g->get_parent();
   421       while (objectp(pgroup)) {
   422    p |= permissions[pgroup];
   423    pgroup = pgroup->get_parent();
   429   mapping permission = obj->get_sanction();
   430   mixed acquire = obj->get_acquire();
   431   // function or object
   432   if (functionp(acquire)) 
   434   // if acquire is set we get the acquired permissions
   435   if (objectp(acquire)) 
   436     permission = join_permissions(permission, get_permissions(acquire));
   438   object creator = obj->get_creator() || USER("root");
   439   permission[creator] = SANCTION_ALL;
   446  * check on some accessBit/roleBit. Object can be null when just 
   447  * the roleBit of an user should be checked.
   449  * @param obj - the object accessed (must be proxy)
   450  * @param caller - the calling object (must be the proxy or socket)
   451  * @param accessBit - the bit used for access
   452  * @return true or false
   453  * @see check_access_group
   456 check_access(object obj,object caller,int accessBit,int roleBit,bool meta, void|mixed data)
   462     sanctions = " for (ROLE="+roleBit+"), ";
   463     for ( i = 0; i <= 8; i++ )
   464    if ( accessBit & (1<<i) )
   465        sanctions += sRegisteredPermissions[i] + ",";
   467     SECURITY_LOG("----------------------------------------------------------"+
   468             "\n--- "+(meta?"META":"")+" Access checking "+
   470             function_name(backtrace()[-3][2]) + "() on " +ctime(time()));
   471     SECURITY_LOG("params: %O %O", obj, caller);
   473    SECURITY_LOG("Checking access on [%O, %d]", 
   474                 obj->get_identifier(),
   475                 obj->get_object_id());
   478    return true;    // some objects are allowed to do everything
   479     SECURITY_LOG("CALLER: %O", caller);
   481     SECURITY_LOG("EUID: %s",(objectp(geteuid()) ? geteuid()->get_identifier() :
   484     // access for world-user-group, no login required
   485     object grp = _WORLDUSER;
   486     if ( objectp(obj) && objectp(grp) &&
   487     obj->try_access_object(grp, accessBit, meta) ) 
   489    SECURITY_LOG("Access granted################################\n");
   493     object euid = geteuid();
   497       read_user = this_user();
   498     if ( !objectp(read_user) ) {
   499       SECURITY_LOG("Access Granted - no active user object #####\n");
   500       return true; // the server is rebooting, so no active user
   503     SECURITY_LOG("ACTIVE:" + master()->stupid_describe(read_user, 255)+",%O",
   504             read_user->get_identifier());
   507     RoleContext ctx = RoleContext(obj, data);
   509     if ( check_access_user(obj, read_user, accessBit, roleBit, meta, ctx) )
   512     SECURITY_LOG("** Access denied **");
   513     THROW(sprintf("Access denied for user %O(%O) accessing %O using %d called by %O",
   514              this_user(), read_user, obj, accessBit, caller),
   520  * check for read access
   522  * @param obj - the object accessed
   523  * @param caller - the calling object
   524  * @return true or false
   527 bool access_read(int e, object obj, object caller)
   530     err = catch(check_access(obj, caller,SANCTION_READ,ROLE_READ_ALL,false));
   532       if (objectp(obj) && functionp(obj->get_identifier) ) {
   533         string message = sprintf("\nNo READ access on %O for %O (%O)", 
   534                             (objectp(obj)?obj->get_identifier():"none"),
   535                             this_user(), geteuid());
   536         if ( objectp(err) && functionp(err->set_message) )
   537           err->set_message(err->message()+"\n"+message);
   538         else if ( arrayp(err) )
   547  * check for write access
   549  * @param obj - the object accessed
   550  * @param caller - the calling object
   551  * @return true or false
   554 bool access_write(int e, object obj, object caller)
   557     err = catch(check_access(obj,caller,SANCTION_WRITE, ROLE_WRITE_ALL,false));
   559       if ( objectp(obj) ) {
   560         string message = sprintf("\nNo WRITE access on %O for %O (%O)", 
   561                     (objectp(obj)?obj->get_identifier():"none"),
   562                             this_user(), geteuid());
   563         if ( objectp(err) && functionp(err->set_message) )
   564           err->set_message(err->message()+"\n"+message);
   565         else if ( arrayp(err) )
   574  * Check whether an object is able to set the creator of object obj.
   575  * Usually the creator is only set when the object is created, but
   576  * export/import functionality requires to change such values.
   578  * @param object obj - the object with a new creator
   579  * @param object caller - the calling object
   580  * @return true or throws an error.
   582 bool access_set_creator(int e, object obj, object caller)
   584     if ( _Server->is_a_factory(CALLER) )
   586     return check_access(obj, caller, SANCTION_ALL, ROLE_ALL_ROLES, true);
   590  * check access for deleting objects. Same as write access currently.
   593 bool access_delete(int e, object obj, object caller)
   595     return check_access(obj, caller, SANCTION_WRITE, ROLE_WRITE_ALL, false);
   599  * check access for deleting objects. Same as write access currently.
   602 bool access_register_module(int e, object obj, object caller)
   604     return check_access(0, caller, 0, ROLE_REGISTER_MODULES, false);
   607  * check access for deleting objects. Same as write access currently.
   613 bool access_register_class(int e, object obj, object caller)
   615     return check_access(0, caller, 0, ROLE_REGISTER_CLASSES, false);
   621  * @param obj - the object accessed
   622  * @param caller - the calling object
   623  * @param dest - destination of movement
   624  * @return true or false
   627 bool access_move(int e, object obj, object caller, object from, object dest)
   630     if ( caller == obj->get_environment() )
   634     /* if the caller is the object, then the user moves herself !
   635      * otherwise check insert access */
   636     LOG("CALLER is user ?:"+valid_user(caller));
   638     if ( !valid_user(obj) ) {
   639       // Inserting objects into a room requires insert permissions
   640       if (!check_access(dest, caller, SANCTION_INSERT, ROLE_INSERT_ALL, false))
   643     else if ( objectp(dest) ) {
   644       // moving the user somewhere only requires permissions for the user
   645       if (!check_access(dest, obj, SANCTION_READ, ROLE_READ_ALL, false))
   649     object env = obj->get_environment();
   653     // if the user/caller is able to move the room, she can move the 
   654     // object in the container/room too
   655     if ( objectp(env) ) {
   656         // catch this block - access failure is no problem
   658        if ( check_access(env, caller,SANCTION_MOVE,ROLE_MOVE_ALL,false) ) {
   659            if ( CACHE_AVAILABLE ) {
   660                security_cache->remove_permission(obj);
   667     err = catch(check_access(obj, caller, SANCTION_MOVE,ROLE_MOVE_ALL,false));
   669       if ( objectp(obj) ) {
   670    string message = sprintf("\n%s %s\n", 
   671                     "No access to MOVE", obj->get_identifier());
   672         if ( objectp(err) && functionp(err->set_message) )
   673           err->set_message(err->message()+"\n"+message);
   674         else if ( arrayp(err) )
   681     if ( CACHE_AVAILABLE )
   682    security_cache->remove_permission(obj);
   687  * Check if a user/object is able to annotated an object.
   689  * @param object obj - the object to annotate
   690  * @param object caller - the calling object
   691  * @param annotation - the added annotation
   692  * @return true or throws an error
   694 bool access_annotate(int e, object obj, object caller, object annotation)
   696     if ( _Server->is_a_factory(caller) ) // trust any factory for creation
   697    return true; // ok, for any factory
   699     mixed err = catch(check_access(obj, caller, SANCTION_ANNOTATE, 
   700                         ROLE_ANNOTATE_ALL, false));
   702       if ( objectp(obj) ) {
   703    string message = sprintf("\n%s %s\n", 
   704                      "No access to ANNOTATE", obj->get_identifier());
   705         if ( objectp(err) && functionp(err->set_message) )
   706           err->set_message(message+"\n"+err->message());
   707         else if ( arrayp(err) )
   716  * Check if arranging an object is allowed.
   718  * @param object obj - the object to arrange
   719  * @param object caller - the calling object
   720  * @param float x - the new x position
   721  * @param float y - the new y position
   722  * @param float z - the new z position
   723  * @param bool locked - is the position already locked (returns false)
   724  * @return true or false or throws an error
   726 bool access_arrange(int e, object obj, object caller, float x, float y, float z, 
   729     if ( locked ) return false;
   731     if ( !check_access(obj, caller, SANCTION_WRITE, ROLE_WRITE_ALL, false) )
   737  * check access for creating an object
   739  * @param caller - the calling object
   740  * @return true or false 
   741  * @see access_create_group
   743 bool access_create_object(int e, object caller)
   745     if ( _Server->is_a_factory(caller) ) // trust any factory for creation
   746    return true; // ok, for any factory
   747     if ( caller->get_object_class() & CLASS_DOCLPC ) {
   748    // in general means its a factory,but only for the object to be created
   749    if ( object_program(CALLER) == caller->get_program() )
   750        if ( check_access(caller, caller, SANCTION_EXECUTE, ROLE_EXECUTE_ALL, false) )
   751            return true; // need access on the DocLPC in this case !
   753     object factory = _Server->get_factory(caller->get_object_class());
   754     if ( !objectp(factory) ) 
   755    factory = _Server->get_factory(CLASS_DOCUMENT);
   756     if ( !check_access(factory, caller, SANCTION_EXECUTE, ROLE_EXECUTE_ALL, false) )
   762  * Check if its valid to add an object to the group grp.
   764  * @param grp - the group to add someone to
   765  * @param caller - the calling object
   766  * @param add - the group/user to add
   767  * @param bool pw - group password check was done and successfull
   768  * @return true or false or throws an error
   770 bool access_group_add_member(int e, object grp, object caller, object add, bool pw)
   773    if ( security_cache )
   774        security_cache->remove_permission_user(add);
   778     if ( _Server->is_a_factory(caller) || _Server->is_module(caller) ) {
   779    if ( security_cache )
   780        security_cache->remove_permission_user(add);
   784     if ( !check_access(grp, caller, SANCTION_INSERT, ROLE_INSERT_ALL, false) )
   786     if ( security_cache )
   787    security_cache->remove_permission_user(add);
   793  * Check if a user is allowed to add users to all groups in a
   794  * mutual exclusive group cluster.
   796  * @param grp - the group to add "add" to
   797  * @param caller - the calling object
   798  * @add   add - the group to add to "grp"
   799  * @return true - access is granted
   800  *         false - access denied
   801  *         throws an error according to check_access
   804 bool access_group_addmutual(int e, object grp, object caller, object add)
   806     if (!valid_group(grp) || !valid_group(add))
   808     array need_access = grp->get_mutual_list();
   810     foreach(need_access, object g)
   811         if (!check_access(g, caller, SANCTION_INSERT,
   812                           ROLE_INSERT_ALL, true))
   814     return check_access(add, caller, SANCTION_INSERT, ROLE_INSERT_ALL, true);
   818  * Check if the calling object and the current user are
   819  * allowed to create a new group.
   821  * @param object caller - the calling object
   822  * @return true or false or throws an access error
   824 bool access_create_group(int e, object caller)
   826     if ( _Server->is_a_factory(caller) )
   828     object factory = _Server->get_factory(CLASS_GROUP);
   829     if ( !check_access(factory, caller, SANCTION_EXECUTE, ROLE_EXECUTE_ALL, false))
   835  * Check whether a calling object and the current user 
   836  * are able to create a new user. Usually this is allowed since 
   837  * people are able to register their user themself.
   839  * @param object caller - the calling object
   840  * @return true or false or throws access error
   842 bool access_create_user(int e, object caller)
   844     if ( _Server->is_a_factory(caller) )
   846     object factory = _Server->get_factory(CLASS_USER);
   847     if ( !check_access(factory, caller, SANCTION_EXECUTE, ROLE_EXECUTE_ALL , false))
   853  * Check if the calling object is allowed to create a new document.
   855  * @param object caller - the calling object
   856  * @return true or false or throws an access error.
   858 bool access_create_document(int e, object caller)
   860     if ( _Server->is_a_factory(caller) )
   862     object factory = _Server->get_factory(CLASS_DOCUMENT);
   863     if ( !check_access(factory, caller, SANCTION_EXECUTE, ROLE_EXECUTE_ALL , false))
   869  * Check if meta sanction is changeable by caller.
   871  * @param object obj - the object to change meta sanction access
   872  * @param object caller - the calling object
   873  * @param object grp - the group to sanction
   874  * @param int p - the meta access persmissions
   876  * @return true, false or throw access
   878 bool access_sanction_object_meta(int e, object obj, object caller, object grp, int p)
   880     if ( _Server->is_a_factory(caller) )
   882     check_access(obj, caller, p, ROLE_SANCTION_ALL, false);
   883     check_access(obj, caller, SANCTION_SANCTION, ROLE_SANCTION_ALL, true);
   884     check_access(obj, caller, p, ROLE_SANCTION_ALL, true);
   888  * Check if caller has permissions to sanction group grp with access
   891  * @param object obj - the object to change meta sanction access
   892  * @param object caller - the calling object
   893  * @param object grp - the group to sanction
   894  * @param int p - the access persmissions
   895  * @return true or false or throw access error
   897 bool access_sanction_object(int e, object obj, object caller, object grp, int p)
   899     if ( _Server->is_a_factory(caller) )
   902     check_access(obj, caller, p|SANCTION_SANCTION, ROLE_SANCTION_ALL, true);
   903     check_access(obj, caller, p|SANCTION_SANCTION, ROLE_SANCTION_ALL, false);
   904     if ( CACHE_AVAILABLE )
   905    security_cache->remove_permission(obj);
   910  * Check if the calling object has permission to listen to events on obj.
   912  * @param obj - the object accessed
   913  * @param caller - the calling object
   914  * @return true or false
   917 bool access_event_listen(int e, object obj, object caller)
   919     return check_access(obj, caller, SANCTION_READ, ROLE_READ_ALL, false);
   923  * Check if calling object is able to change data in object 'obj'. This
   924  * usually means changing a documents content.
   926  * @param obj - the object accessed
   927  * @param caller - the calling object
   928  * @return true or false
   931 bool access_data_change(int e, object obj, object caller, mixed id, mixed data)
   933     if ( _Server->is_a_factory(caller) ) // trust any factory for creation
   934    return true; // ok, for any factory
   936     if ( !access_write(e, obj, caller) )
   937    THROW("No Access to change data !", E_ACCESS);
   942  * Check if caller is able to change attributes in object 'obj'.
   944  * @param object obj - the object to change an attribute.
   945  * @param object caller - the calling object.
   946  * @param attr - the attribute to change
   947  * @return true or false or throw access error
   950 access_attribute_change(int e, object obj, object caller, mixed attr)
   952     //    LOG("Access for changing the attribute ?");
   953     if ( _Server->is_a_factory(caller) ) // trust any factory for creation
   954    return true; // ok, for any factory
   955     //    LOG("not a factory ");
   957     if ( !access_write(e, obj, caller) )
   958    THROW("No Access to change attributes !", E_ACCESS);
   963  * Check whether an object has permissions to lock attributes in object 'obj'.
   965  * @param object obj - the object to lock attributes in.
   966  * @param object caller - the calling object.
   967  * @param bool l_or_ul - lock or unlock attributes.
   968  * @return true or false or throw an access error.
   970 bool access_attribute_lock(int e, object obj, object caller, bool l_or_ul)
   972     if ( _Server->is_a_factory(caller) ) // trust any factory for creation
   973    return true; // ok, for any factory
   974     if ( !access_write(e, obj, caller) )
   975    THROW("No Access to lock/unlock attributes !", E_ACCESS);
   980  * Check if caller is able to change acquiring setting for an attribute.
   982  * @param object obj - the object.
   983  * @param object caller - the calling object.
   984  * @param mixed key - the attribute to change acquiring for.
   985  * @param mixed acquire - new acquiring setting.
   986  * @return true or false or throw access error.
   989 access_attribute_acquire(int e, object obj, object caller, mixed key, mixed acquire)
   991     if ( objectp(acquire) && !valid_proxy(acquire) )
   992    THROW("Acquring must point to proxy !", E_ERROR);
   994     if ( _Server->is_a_factory(caller) ) // trust any factory for creation
   995    return true; // ok, for any factory
   996     if ( _Server->is_module(caller) )
   999     if ( !access_write(e, obj, caller) )
  1000    THROW("No Access to write data !", E_ACCESS);
  1005  * Check if the caller is able to read an attribute.
  1007  * @param object obj - the object to read.
  1008  * @param object caller - the calling object.
  1009  * @param mixed key - the attribute to read.
  1010  * @return true or false or throw access denied.
  1013 access_read_attribute(int e, object obj, object caller, mixed key)
  1015   if ( !check_access(obj, caller, SANCTION_READ, ROLE_READ_ALL, false, key) )
  1016     THROW("No Access to read data !", E_ACCESS);
  1021  * Check whether the calling object is able to register attributes.
  1023  * @param object obj - the object to register an attribute.
  1024  * @param object caller - the calling object.
  1025  * @param mixed key - the attribute to register.
  1026  * @return true or false or throw access denied.
  1029 access_register_attribute(int e, object obj, object caller, mixed key)
  1031     object factory = _Server->get_factory(obj->get_object_class());
  1032     if ( caller == factory ) return true;
  1034     if ( !access_write(e, obj, caller) )
  1035    THROW("No Access to register data !", E_ACCESS);
  1042  * @param obj - the object accessed
  1043  * @param caller - the calling object
  1044  * @return true or false
  1047 bool access_execute(int e, object obj, object caller)
  1049     if ( _Server->is_a_factory(caller) ) // trust any factory for creation
  1050    return true; // ok, for any factory
  1053       catch(check_access(obj,caller,SANCTION_EXECUTE,ROLE_EXECUTE_ALL,false));
  1055       if ( objectp(obj) ) {
  1056    FATAL("Access error: %O", err);
  1057    string message = sprintf("%s %s",
  1058                     "No access to EXECUTE", obj->get_identifier());
  1059         if ( objectp(err) && functionp(err->set_message) )
  1060           err->set_message(message+"\n"+err->message());
  1061         else if ( arrayp(err) )
  1069  * Check if the caller is able to add permissions to the group 'grp'.
  1071  * @param object grp - the group to add permissions.
  1072  * @param object caller - the calling object.
  1073  * @param int permission - permissions to add.
  1074  * @return true or false or throw access denied.
  1077 access_group_add_permission(int e, object grp, object caller, int permission)
  1079     ASSERTINFO(valid_group(grp), "No valid group in group_add_permission()");
  1080     if ( !check_access(0, caller, 0, ROLE_GIVE_ROLES, false) )
  1082     if ( !check_access(grp, caller, SANCTION_WRITE, ROLE_WRITE_ALL, false) )
  1088  * add a user or list of users to a group
  1090  * @param object grp - the group to remove a member
  1091  * @param object caller - the calling object.
  1092  * @param object user - the user or group to remove.
  1093  * @return number of users successfully added
  1095 bool access_group_remove_member(int e, object grp, object caller, object user)
  1097   if ( user == this_user() )
  1099   if ( !check_access(grp, caller, SANCTION_INSERT, ROLE_INSERT_ALL, false) )
  1101   if ( security_cache )
  1102     security_cache->remove_permission_user(user);
  1107  * set acquiring object for object "obj"
  1109  * @param obj - the object that acquires
  1110  * @param from - the object to acquire from
  1111  * @return successfully or not
  1113 bool access_acquire(int e, object obj, object caller, object from)
  1115     if ( _Server->is_a_factory(caller) )
  1117     if ( !check_access(obj,caller,SANCTION_WRITE, ROLE_WRITE_ALL,true) )
  1119     if ( !check_access(obj,caller,SANCTION_SANCTION, ROLE_SANCTION_ALL,true) )
  1121     if ( CACHE_AVAILABLE )
  1122    security_cache->remove_permission(obj);
  1128  * Check if caller has permissions to change password for user.
  1130  * @param object user - the user object.
  1131  * @param object caller - the calling object.
  1132  * @return true or false or throw access denied.
  1134 bool access_change_password(int e, object user, object caller)
  1136     object factory = _Server->get_factory(user->get_object_class());
  1137     LOG("Caller:"+master()->describe_object(caller) + ", Factory:"+
  1138    master()->describe_object(factory));
  1139     if ( caller == factory ) return true;
  1141     if ( caller != user && 
  1142     (!IS_SOCKET(caller) || user != caller->get_user_object()) && 
  1143     !check_access(user, caller, 0, ROLE_CHANGE_PWS, false) )
  1149  * Get the identifier string for this module.
  1151  * @return The module identifier.
  1153 string get_identifier()
  1159  * The function returns if some object is especially trusted.
  1161  * @param object obj - the object to check.
  1162  * @return true or false.
  1164 final bool trust(object obj)
  1166     if ( obj == this_object() ) return true;
  1167     if ( ::trust(obj) ) return true;
  1168     if ( obj == master() ) return true;
  1169     if ( obj == _Database ) return true;
  1170     if ( obj == _Persistence ) return true;
  1171     if ( obj == _Server ) return true;
  1172     if ( obj == _FILEPATH ) return true;
  1177  * Check if a user is allowed to access the given objects.
  1179  * @param array objs - an array of objects to check access for.
  1180  * @return Mapping with object:permissions of current user.
  1190     foreach(objs, object obj) {
  1192    for ( i = sizeof(sRegisteredPermissions) - 1 ; i >= 0; i-- ) {
  1200  * Check access for a given user for accessBit and roleBit.
  1202  * @param object obj - the object to check.
  1203  * @param object user - the user to check access for.
  1204  * @param int accBit - the access bit to check.
  1205  * @param int roleBit - the roleBit to check.
  1206  * @param bool meta - if normal or meta permissions are to check.
  1207  * @return true or false or throw an access error.
  1210 check_user_access(object obj, object user, int accBit, int roleBit, bool meta)
  1212     if ( !objectp(user) )
  1213    THROW("User undefined !", E_ACCESS);
  1214     object grp = _WORLDUSER;
  1215     if ( objectp(obj) && objectp(grp) &&
  1216     obj->try_access_object(grp, accBit, meta) ) 
  1219     if ( accBit >= (1<<16) )
  1220       steam_error("Wrong accBit check for check_access_user(), only 16 Bits "+
  1224       roleBit = accBit; // use corresponding roleBit
  1230  * Get the meta access of object 'obj' for user 'user'.
  1232  * @param object obj - the object to get meta access for.
  1233  * @param object user - the user to get meta access for.
  1234  * @return the meta access bit string.
  1236 int get_meta_access(object obj, object user)
  1238     int meta = obj->query_meta_sanction(user);
  1239     for ( int i = 0; i < 16; i++ )
  1240    if ( check_user_access(obj, user, 1<<i,1<<i, true) )
  1248  * Get an array of string descriptions for permissions.
  1250  * @return array of string descriptions.
  1252 array get_sanction_strings()
  1254     return sRegisteredPermissions;
  1258  * Get the user permissions for object 'obj' and user 'user' with
  1259  * access mask 'mask'.
  1261  * @param object obj - the object to get user permissions for.
  1262  * @param object user - object user.
  1263  * @param int mask - the access mask.
  1264  * @return user permission bit string.
  1266 int get_user_permissions(object obj, object user, int mask)
  1268     int res = security_cache->get_permission(obj, user);
  1270     if ( !objectp(obj) || !objectp(user) )
  1274     b = (res & ( mask<<SANCTION_SHIFT_DENY)) >> SANCTION_SHIFT_DENY;
  1279     // not all permissions are cached here !
  1280     for ( int i = 0; i < SANCTION_SHIFT_DENY; i++ ) {
  1281    if ( ((1<<i) & mask) && !(r & (1<<i)) )
  1283     return security_cache->get_permission(obj, user) & mask;
  1287  mapping get_acq_permissions(mixed acq)
  1293   if ( functionp(acq) ) {
  1295     if ( objectp(obj) ) {
  1296       res = obj->get_sanction();
  1297       ares =  get_acq_permissions(obj->get_acquire());
  1300   else if ( objectp(acq) ) {
  1301     res = acq->get_sanction();
  1302     ares = get_acq_permissions(acq->get_acquire());
  1307   foreach(indices(ares), mixed idx) {
  1309       res[idx] |= ares[idx];
  1311       res[idx] = ares[idx];
  1318 mapping get_inherited_permissions(object obj)
  1321   mixed acq = obj->get_acquire();
  1322   res = get_acq_permissions(acq);