diff options
author | Michael Adam <obnox@samba.org> | 2007-06-14 11:29:35 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:23:21 -0500 |
commit | 6090601c8b6abde1642906351d1dd9bb41e576b6 (patch) | |
tree | f610144465f0c402b7ee2f56e2319d0bf41697d7 /source3/lib/privileges.c | |
parent | 0b86e4030604bfbaca66df9f699a68bbf6db0824 (diff) | |
download | samba-6090601c8b6abde1642906351d1dd9bb41e576b6.tar.gz samba-6090601c8b6abde1642906351d1dd9bb41e576b6.tar.bz2 samba-6090601c8b6abde1642906351d1dd9bb41e576b6.zip |
r23485: This checkin consists mostly of refactorings in preparation of the
activation of global registry options in loadparm.c, mainly to
extract functionality from net_conf.c to be made availabel elsewhere
and to minimize linker dependencies.
In detail:
* move functions registry_push/pull_value from lib/util_reg.c to new file
lib/util_reg_api.c
* create a fake user token consisting of builtin administrators sid and
se_disk_operators privilege by hand instead of using get_root_nt_token()
to minimize linker deps for bin/net.
+ new function registry_create_admin_token() in new lib/util_reg_smbconf.c
+ move dup_nt_token from auth/token_util.c to new file lib/util_nttoken.c
+ adapt net_conf.c and Makefile.in accordingly.
* split lib/profiles.c into two parts: new file lib/profiles_basic.c
takes all the low level mask manipulation and format conversion functions
(se_priv, privset, luid). the privs array is completely hidden from
profiles.c by adding some access-functions. some mask-functions are not
static anymore.
Generally, SID- and LUID-related stuff that has more dependencies
is kept in lib/profiles.c
* Move initialization of regdb from net_conf.c into a function
registry_init_regdb() in lib/util_reg_smbconf.c.
Michael
(This used to be commit efd3e2bfb756ac5c4df7984791c67e7ae20a582e)
Diffstat (limited to 'source3/lib/privileges.c')
-rw-r--r-- | source3/lib/privileges.c | 505 |
1 files changed, 18 insertions, 487 deletions
diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c index cd6494d1ed..3714a906de 100644 --- a/source3/lib/privileges.c +++ b/source3/lib/privileges.c @@ -4,6 +4,7 @@ Copyright (C) Jean François Micouleau 1998-2001 Copyright (C) Simo Sorce 2002-2003 Copyright (C) Gerald (Jerry) Carter 2005 + Copyright (C) Michael Adam 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,84 +26,6 @@ #define PRIVPREFIX "PRIV_" -static const SE_PRIV se_priv_all = SE_ALL_PRIVS; -static const SE_PRIV se_priv_end = SE_END; - -/* Define variables for all privileges so we can use the - SE_PRIV* in the various se_priv_XXX() functions */ - -const SE_PRIV se_priv_none = SE_NONE; -const SE_PRIV se_machine_account = SE_MACHINE_ACCOUNT; -const SE_PRIV se_print_operator = SE_PRINT_OPERATOR; -const SE_PRIV se_add_users = SE_ADD_USERS; -const SE_PRIV se_disk_operators = SE_DISK_OPERATOR; -const SE_PRIV se_remote_shutdown = SE_REMOTE_SHUTDOWN; -const SE_PRIV se_restore = SE_RESTORE; -const SE_PRIV se_take_ownership = SE_TAKE_OWNERSHIP; - -/******************************************************************** - This is a list of privileges reported by a WIndows 2000 SP4 AD DC - just for reference purposes (and I know the LUID is not guaranteed - across reboots): - - SeCreateTokenPrivilege Create a token object ( 0x0, 0x2 ) - SeAssignPrimaryTokenPrivilege Replace a process level token ( 0x0, 0x3 ) - SeLockMemoryPrivilege Lock pages in memory ( 0x0, 0x4 ) - SeIncreaseQuotaPrivilege Increase quotas ( 0x0, 0x5 ) - SeMachineAccountPrivilege Add workstations to domain ( 0x0, 0x6 ) - SeTcbPrivilege Act as part of the operating system ( 0x0, 0x7 ) - SeSecurityPrivilege Manage auditing and security log ( 0x0, 0x8 ) - SeTakeOwnershipPrivilege Take ownership of files or other objects ( 0x0, 0x9 ) - SeLoadDriverPrivilege Load and unload device drivers ( 0x0, 0xa ) - SeSystemProfilePrivilege Profile system performance ( 0x0, 0xb ) - SeSystemtimePrivilege Change the system time ( 0x0, 0xc ) - SeProfileSingleProcessPrivilege Profile single process ( 0x0, 0xd ) - SeIncreaseBasePriorityPrivilege Increase scheduling priority ( 0x0, 0xe ) - SeCreatePagefilePrivilege Create a pagefile ( 0x0, 0xf ) - SeCreatePermanentPrivilege Create permanent shared objects ( 0x0, 0x10 ) - SeBackupPrivilege Back up files and directories ( 0x0, 0x11 ) - SeRestorePrivilege Restore files and directories ( 0x0, 0x12 ) - SeShutdownPrivilege Shut down the system ( 0x0, 0x13 ) - SeDebugPrivilege Debug programs ( 0x0, 0x14 ) - SeAuditPrivilege Generate security audits ( 0x0, 0x15 ) - SeSystemEnvironmentPrivilege Modify firmware environment values ( 0x0, 0x16 ) - SeChangeNotifyPrivilege Bypass traverse checking ( 0x0, 0x17 ) - SeRemoteShutdownPrivilege Force shutdown from a remote system ( 0x0, 0x18 ) - SeUndockPrivilege Remove computer from docking station ( 0x0, 0x19 ) - SeSyncAgentPrivilege Synchronize directory service data ( 0x0, 0x1a ) - SeEnableDelegationPrivilege Enable computer and user accounts to be trusted for delegation ( 0x0, 0x1b ) - SeManageVolumePrivilege Perform volume maintenance tasks ( 0x0, 0x1c ) - SeImpersonatePrivilege Impersonate a client after authentication ( 0x0, 0x1d ) - SeCreateGlobalPrivilege Create global objects ( 0x0, 0x1e ) - - ********************************************************************/ - -/* we have to define the LUID here due to a horrible check by printmig.exe - that requires the SeBackupPrivilege match what is in Windows. So match - those that we implement and start Samba privileges at 0x1001 */ - -PRIVS privs[] = { -#if 0 /* usrmgr will display these twice if you include them. We don't - use them but we'll keep the bitmasks reserved in privileges.h anyways */ - - {SE_NETWORK_LOGON, "SeNetworkLogonRight", "Access this computer from network", { 0x0, 0x0 }}, - {SE_INTERACTIVE_LOGON, "SeInteractiveLogonRight", "Log on locally", { 0x0, 0x0 }}, - {SE_BATCH_LOGON, "SeBatchLogonRight", "Log on as a batch job", { 0x0, 0x0 }}, - {SE_SERVICE_LOGON, "SeServiceLogonRight", "Log on as a service", { 0x0, 0x0 }}, -#endif - {SE_MACHINE_ACCOUNT, "SeMachineAccountPrivilege", "Add machines to domain", { 0x0, 0x0006 }}, - {SE_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege", "Take ownership of files or other objects",{ 0x0, 0x0009 }}, - {SE_BACKUP, "SeBackupPrivilege", "Back up files and directories", { 0x0, 0x0011 }}, - {SE_RESTORE, "SeRestorePrivilege", "Restore files and directories", { 0x0, 0x0012 }}, - {SE_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Force shutdown from a remote system", { 0x0, 0x0018 }}, - - {SE_PRINT_OPERATOR, "SePrintOperatorPrivilege", "Manage printers", { 0x0, 0x1001 }}, - {SE_ADD_USERS, "SeAddUsersPrivilege", "Add users and groups to the domain", { 0x0, 0x1002 }}, - {SE_DISK_OPERATOR, "SeDiskOperatorPrivilege", "Manage disk shares", { 0x0, 0x1003 }}, - - {SE_END, "", "", { 0x0, 0x0 }} -}; - typedef struct { size_t count; DOM_SID *list; @@ -113,125 +36,6 @@ typedef struct { SID_LIST sids; } PRIV_SID_LIST; -/*************************************************************************** - copy an SE_PRIV structure -****************************************************************************/ - -BOOL se_priv_copy( SE_PRIV *dst, const SE_PRIV *src ) -{ - if ( !dst || !src ) - return False; - - memcpy( dst, src, sizeof(SE_PRIV) ); - - return True; -} - -/*************************************************************************** - combine 2 SE_PRIV structures and store the resulting set in mew_mask -****************************************************************************/ - -void se_priv_add( SE_PRIV *mask, const SE_PRIV *addpriv ) -{ - int i; - - for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { - mask->mask[i] |= addpriv->mask[i]; - } -} - -/*************************************************************************** - remove one SE_PRIV sytucture from another and store the resulting set - in mew_mask -****************************************************************************/ - -void se_priv_remove( SE_PRIV *mask, const SE_PRIV *removepriv ) -{ - int i; - - for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { - mask->mask[i] &= ~removepriv->mask[i]; - } -} - -/*************************************************************************** - invert a given SE_PRIV and store the set in new_mask -****************************************************************************/ - -static void se_priv_invert( SE_PRIV *new_mask, const SE_PRIV *mask ) -{ - SE_PRIV allprivs; - - se_priv_copy( &allprivs, &se_priv_all ); - se_priv_remove( &allprivs, mask ); - se_priv_copy( new_mask, &allprivs ); -} - -/*************************************************************************** - check if 2 SE_PRIV structure are equal -****************************************************************************/ - -static BOOL se_priv_equal( const SE_PRIV *mask1, const SE_PRIV *mask2 ) -{ - return ( memcmp(mask1, mask2, sizeof(SE_PRIV)) == 0 ); -} - -/*************************************************************************** - check if a SE_PRIV has any assigned privileges -****************************************************************************/ - -static BOOL se_priv_empty( const SE_PRIV *mask ) -{ - SE_PRIV p1; - int i; - - se_priv_copy( &p1, mask ); - - for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { - p1.mask[i] &= se_priv_all.mask[i]; - } - - return se_priv_equal( &p1, &se_priv_none ); -} - -/********************************************************************* - Lookup the SE_PRIV value for a privilege name -*********************************************************************/ - -BOOL se_priv_from_name( const char *name, SE_PRIV *mask ) -{ - int i; - - for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { - if ( strequal( privs[i].name, name ) ) { - se_priv_copy( mask, &privs[i].se_priv ); - return True; - } - } - - return False; -} - -/*************************************************************************** - dump an SE_PRIV structure to the log files -****************************************************************************/ - -void dump_se_priv( int dbg_cl, int dbg_lvl, const SE_PRIV *mask ) -{ - int i; - - DEBUGADDC( dbg_cl, dbg_lvl,("SE_PRIV ")); - - for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { - DEBUGADDC( dbg_cl, dbg_lvl,(" 0x%x", mask->mask[i] )); - } - - DEBUGADDC( dbg_cl, dbg_lvl, ("\n")); -} - -/*************************************************************************** - Retrieve the privilege mask (set) for a given SID -****************************************************************************/ static BOOL get_privileges( const DOM_SID *sid, SE_PRIV *mask ) { @@ -301,139 +105,6 @@ static BOOL set_privileges( const DOM_SID *sid, SE_PRIV *mask ) return ( tdb_store_bystring(tdb, keystr, data, TDB_REPLACE) != -1 ); } -/**************************************************************************** - check if the privilege is in the privilege list -****************************************************************************/ - -static BOOL is_privilege_assigned( const SE_PRIV *privileges, - const SE_PRIV *check ) -{ - SE_PRIV p1, p2; - - if ( !privileges || !check ) - return False; - - /* everyone has privileges if you aren't checking for any */ - - if ( se_priv_empty( check ) ) { - DEBUG(1,("is_privilege_assigned: no privileges in check_mask!\n")); - return True; - } - - se_priv_copy( &p1, check ); - - /* invert the SE_PRIV we want to check for and remove that from the - original set. If we are left with the SE_PRIV we are checking - for then return True */ - - se_priv_invert( &p1, check ); - se_priv_copy( &p2, privileges ); - se_priv_remove( &p2, &p1 ); - - return se_priv_equal( &p2, check ); -} - -/**************************************************************************** - check if the privilege is in the privilege list -****************************************************************************/ - -static BOOL is_any_privilege_assigned( SE_PRIV *privileges, const SE_PRIV *check ) -{ - SE_PRIV p1, p2; - - if ( !privileges || !check ) - return False; - - /* everyone has privileges if you aren't checking for any */ - - if ( se_priv_empty( check ) ) { - DEBUG(1,("is_any_privilege_assigned: no privileges in check_mask!\n")); - return True; - } - - se_priv_copy( &p1, check ); - - /* invert the SE_PRIV we want to check for and remove that from the - original set. If we are left with the SE_PRIV we are checking - for then return True */ - - se_priv_invert( &p1, check ); - se_priv_copy( &p2, privileges ); - se_priv_remove( &p2, &p1 ); - - /* see if we have any bits left */ - - return !se_priv_empty( &p2 ); -} - -/**************************************************************************** - add a privilege to a privilege array - ****************************************************************************/ - -static BOOL privilege_set_add(PRIVILEGE_SET *priv_set, LUID_ATTR set) -{ - LUID_ATTR *new_set; - - /* we can allocate memory to add the new privilege */ - - new_set = TALLOC_REALLOC_ARRAY(priv_set->mem_ctx, priv_set->set, LUID_ATTR, priv_set->count + 1); - if ( !new_set ) { - DEBUG(0,("privilege_set_add: failed to allocate memory!\n")); - return False; - } - - new_set[priv_set->count].luid.high = set.luid.high; - new_set[priv_set->count].luid.low = set.luid.low; - new_set[priv_set->count].attr = set.attr; - - priv_set->count++; - priv_set->set = new_set; - - return True; -} - -/********************************************************************* - Generate the LUID_ATTR structure based on a bitmask - The assumption here is that the privilege has already been validated - so we are guaranteed to find it in the list. -*********************************************************************/ - -LUID_ATTR get_privilege_luid( SE_PRIV *mask ) -{ - LUID_ATTR priv_luid; - int i; - - ZERO_STRUCT( priv_luid ); - - for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { - - if ( se_priv_equal( &privs[i].se_priv, mask ) ) { - priv_luid.luid = privs[i].luid; - break; - } - } - - return priv_luid; -} - -/********************************************************************* - Generate the LUID_ATTR structure based on a bitmask -*********************************************************************/ - -const char* get_privilege_dispname( const char *name ) -{ - int i; - - for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { - - if ( strequal( privs[i].name, name ) ) { - return privs[i].description; - } - } - - return NULL; -} - /********************************************************************* get a list of all privleges for all sids the in list *********************************************************************/ @@ -582,17 +253,15 @@ BOOL grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask) BOOL grant_privilege_by_name(DOM_SID *sid, const char *name) { - int i; - - for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { - if ( strequal(privs[i].name, name) ) { - return grant_privilege( sid, &privs[i].se_priv ); - } - } + SE_PRIV mask; - DEBUG(3, ("grant_privilege_by_name: No Such Privilege Found (%s)\n", name)); + if (! se_priv_from_name(name, &mask)) { + DEBUG(3, ("grant_privilege_by_name: " + "No Such Privilege Found (%s)\n", name)); + return False; + } - return False; + return grant_privilege( sid, &mask ); } /*************************************************************************** @@ -636,17 +305,16 @@ BOOL revoke_all_privileges( DOM_SID *sid ) BOOL revoke_privilege_by_name(DOM_SID *sid, const char *name) { - int i; + SE_PRIV mask; - for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { - if ( strequal(privs[i].name, name) ) { - return revoke_privilege( sid, &privs[i].se_priv ); - } - } + if (! se_priv_from_name(name, &mask)) { + DEBUG(3, ("revoke_privilege_by_name: " + "No Such Privilege Found (%s)\n", name)); + return False; + } - DEBUG(3, ("revoke_privilege_by_name: No Such Privilege Found (%s)\n", name)); + return revoke_privilege(sid, &mask); - return False; } /*************************************************************************** @@ -738,139 +406,6 @@ NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_l return NT_STATUS_OK; } -/**************************************************************************** - Does the user have the specified privilege ? We only deal with one privilege - at a time here. -*****************************************************************************/ - -BOOL user_has_privileges(const NT_USER_TOKEN *token, const SE_PRIV *privilege) -{ - if ( !token ) - return False; - - return is_privilege_assigned( &token->privileges, privilege ); -} - -/**************************************************************************** - Does the user have any of the specified privileges ? We only deal with one privilege - at a time here. -*****************************************************************************/ - -BOOL user_has_any_privilege(NT_USER_TOKEN *token, const SE_PRIV *privilege) -{ - if ( !token ) - return False; - - return is_any_privilege_assigned( &token->privileges, privilege ); -} - -/**************************************************************************** - Convert a LUID to a named string -****************************************************************************/ - -char* luid_to_privilege_name(const LUID *set) -{ - static fstring name; - int i; - - if (set->high != 0) - return NULL; - - for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { - if ( set->low == privs[i].luid.low ) { - fstrcpy( name, privs[i].name ); - return name; - } - } - - return NULL; -} - -/******************************************************************* - return the number of elements in the privlege array -*******************************************************************/ - -int count_all_privileges( void ) -{ - static int count; - - if ( count ) - return count; - - /* loop over the array and count it */ - for ( count=0; !se_priv_equal(&privs[count].se_priv, &se_priv_end); count++ ) ; - - return count; -} - -/******************************************************************* -*******************************************************************/ - -BOOL se_priv_to_privilege_set( PRIVILEGE_SET *set, SE_PRIV *mask ) -{ - int i; - uint32 num_privs = count_all_privileges(); - LUID_ATTR luid; - - luid.attr = 0; - luid.luid.high = 0; - - for ( i=0; i<num_privs; i++ ) { - if ( !is_privilege_assigned(mask, &privs[i].se_priv) ) - continue; - - luid.luid = privs[i].luid; - - if ( !privilege_set_add( set, luid ) ) - return False; - } - - return True; -} - -/******************************************************************* -*******************************************************************/ - -static BOOL luid_to_se_priv( LUID *luid, SE_PRIV *mask ) -{ - int i; - uint32 num_privs = count_all_privileges(); - - for ( i=0; i<num_privs; i++ ) { - if ( luid->low == privs[i].luid.low ) { - se_priv_copy( mask, &privs[i].se_priv ); - return True; - } - } - - return False; -} - -/******************************************************************* -*******************************************************************/ - -BOOL privilege_set_to_se_priv( SE_PRIV *mask, PRIVILEGE_SET *privset ) -{ - int i; - - ZERO_STRUCTP( mask ); - - for ( i=0; i<privset->count; i++ ) { - SE_PRIV r; - - /* sanity check for invalid privilege. we really - only care about the low 32 bits */ - - if ( privset->set[i].luid.high != 0 ) - return False; - - if ( luid_to_se_priv( &privset->set[i].luid, &r ) ) - se_priv_add( mask, &r ); - } - - return True; -} - /******************************************************************* *******************************************************************/ @@ -886,15 +421,11 @@ BOOL is_privileged_sid( const DOM_SID *sid ) BOOL grant_all_privileges( const DOM_SID *sid ) { - int i; SE_PRIV mask; - uint32 num_privs = count_all_privileges(); - se_priv_copy( &mask, &se_priv_none ); - - for ( i=0; i<num_privs; i++ ) { - se_priv_add(&mask, &privs[i].se_priv); + if (!se_priv_put_all_privileges(&mask)) { + return False; } - + return grant_privilege( sid, &mask ); } |