// Privilege handler (/secure/handlers/privilege.c)
// Coded by Donky - 25/09/96
// Modified for use here by Shaydz 14/10/2000
#define SECURITY geteuid(PO)
#define SAVE_FILE "/secure/save/handlers/privilege"
#include <access.h>
mapping privileges;
void save_me() { unguarded( (: save_object, SAVE_FILE :) ); }
void create() {
string privilege, *people, person;
int i;
unguarded( (: restore_object , SAVE_FILE :) );
if( !mapp(privileges) ) {
privileges = ([ ]);
} else {
foreach( privilege, people in privileges )
foreach( person in people )
if( !creatorp( person ) ) {
privileges[privilege] -= ({ person });
i = 1;
}
if( i )
save_me();
}
} /* create() */
int query_privilege( string privilege, string privileged ) {
int flag;
string *bits, *dirs;
// TCRE("shaydz",sprintf("privilege=%s, privileged=%s\n",privilege,privileged));
if( adminp(privileged) )
return 1;
// must be at least 2 fields
if( sizeof( bits = explode( privilege, ".") ) < 2 )
return 0;
// allow domain leaders to add & remove members from their domains
// domain.<domain name>.member.add
// domain.<domain name>.member.remove
// allow the leader(s) of the Learning domain to promote creators
switch( bits[0] ) {
case "permission":
// permission.<mask>.<path>.[grant|revoke]
// e.g. permission.1./secure.add
// TCRE("shaydz",sprintf("privilege=%s, privileged=%s\n",privilege,privileged));
if( sizeof(bits) < 4 )
return 0;
if( sscanf( bits[1], "%d", flag ) != 1 )
return 0;
if( bits[<1] != "grant" && bits[<1] != "revoke")
return 0;
dirs = explode( bits[2], "/");
// TCRE("shaydz",sprintf("flag=%d, dirs=%O\n",flag,dirs));
// Only admin can grant grant access.
if( flag & GRANT_MASK )
return 0;
if( sizeof(dirs) > 1 ) {
// A domain leader can grant read and write access to his
// domain directories, but not grant access.
if( dirs[0] == "d" &&
DOMAIN_H->query_leader( dirs[1], privileged ) )
return 1;
// A project leader can grant read or write access to his
// project directories, but not grant access.
if( dirs[0] == "p" &&
PROJECT_H->query_leader( dirs[1], privileged ) )
return 1;
// A creator can grant read or write access to his home
// directory but not grant access.
if( dirs[0] == "w" && dirs[1] == privileged )
return 1;
}
// To grant access of any form, you need to have grant access
// to the given directory.
if( master()->valid_grant( privileged, bits[2], to_int(bits[1]) ) )
return 1;
return 0;
case "domain":
if( bits[2] == "member") {
if( DOMAIN_H->query_leader( bits[1], privileged ) )
return 1;
if( bits[1] == "learning" && lordp(privileged) )
return 1;
}
if( bits[2] == "senior" &&
DOMAIN_H->query_leader( bits[1], privileged ) )
return 1;
break;
case "project":
if( bits[2] == "member" &&
PROJECT_H->query_leader( bits[1], privileged ) )
return 1;
if( bits[2] == "senior" &&
PROJECT_H->query_leader( bits[1], privileged ) )
return 1;
break;
case "creator":
if( ( bits[1] == "add" || bits[1] == "remove" ) &&
DOMAIN_H->query_leader("learning", privileged ) )
return 1;
break; // The following doesn't work yet.
if( bits[2] == "p")
flag = PROJECT_H->query_leader( bits[3], privileged ) ||
DOMAIN_H->query_leader("project", privileged );
else if( bits[2] == "w")
flag = ( bits[3] == privileged && creatorp(bits[3]) );
switch( bits[<1] ) {
case "add":
case "remove":
case "modify":
if( flag )
return 1;
break;
}
break;
}
// If the person is allowed for that privilege, return 1.
if( arrayp(privileges[privilege]) )
return member_array( privileged, privileges[privilege] ) != -1;
} /* query_privilege() */
string *query_privileges( string privileged ) {
string *ret = ({ });
string privilege, *privilegeds;
foreach( privilege, privilegeds in privileges )
if( member_array( privileged, privilegeds ) != -1 )
ret += ({ privilege });
return ret;
} /* query_privileges() */
string add_privilege( string privilege, string privileged ) {
if( !query_privilege("privilege.add", SECURITY) )
return "Insufficient privilege to grant privileges.";
if( !arrayp(privileges[privilege]) )
return "Privilege does not exist.";
if( query_privilege( privilege, privileged ) )
return CAP(privileged)+" already has the "+privilege+" privilege.";
if( !creatorp(privileged) )
return CAP(privileged) +" is not a creator.";
privileges[privilege] += ({ privileged });
save_me();
return 0;
} /* add_privilege() */
string remove_privilege( string privilege, string privileged ) {
if( !query_privilege("privilege.remove", SECURITY) )
return "Insufficient privilege to revoke privileges.";
if( adminp(privileged) )
return "You cannot revoke privileges from an admin.";
if( !arrayp(privileges[privilege]) )
return "Privilege does not exist.";
if( member_array( privileged, privileges[privilege] ) == -1 )
return CAP(privileged)+" does not have the "+privilege+" privilege.";
privileges[privilege] -= ({ privileged });
save_me();
return 0;
} /* remove_privilege() */
string add_privilege_type( string privilege ) {
if( !query_privilege("privilege.type.add", SECURITY) )
return "Insufficient privilege to add a privilege type.";
if( sizeof( explode( privilege, ".") ) < 2 )
return "Invalid number of fields in privilege name (minimum of 2).";
if( arrayp(privileges[privilege]) )
return "Privilege "+ privilege +" already exists.";
privileges[privilege] = ({ });
save_me();
return 0;
} /* add_privilege_type() */
string remove_privilege_type( string privilege ) {
if( !query_privilege("privilege.type.remove", SECURITY) )
return "Insufficient privilege to remove a privilege type.";
if( !arrayp(privileges[privilege]) )
return "Privilege "+privilege+" does not exist.";
map_delete( privileges, privilege );
save_me();
return 0;
} /* remove_privilege_type() */
string *query_privilege_types() { return keys(privileges); }
nomask void dwep() {
object my_ob = TO;
if( my_ob )
destruct(my_ob);
} /* dwep() */
void dest_me() { dwep(); }