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);