From 6090601c8b6abde1642906351d1dd9bb41e576b6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 14 Jun 2007 11:29:35 +0000 Subject: 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) --- source3/lib/privileges.c | 505 ++------------------------------------- source3/lib/privileges_basic.c | 519 +++++++++++++++++++++++++++++++++++++++++ source3/lib/util_nttoken.c | 70 ++++++ source3/lib/util_reg.c | 117 +--------- source3/lib/util_reg_api.c | 136 +++++++++++ source3/lib/util_reg_smbconf.c | 83 +++++++ 6 files changed, 828 insertions(+), 602 deletions(-) create mode 100644 source3/lib/privileges_basic.c create mode 100644 source3/lib/util_nttoken.c create mode 100644 source3/lib/util_reg_api.c create mode 100644 source3/lib/util_reg_smbconf.c (limited to 'source3/lib') 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; imask[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; imask[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; imask[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; ilow == 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; icount; 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; imask[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; imask[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 +****************************************************************************/ + +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; imask[i] )); + } + + DEBUGADDC( dbg_cl, dbg_lvl, ("\n")); +} + +/**************************************************************************** + check if the privilege is in the privilege list +****************************************************************************/ + +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 ); +} + +/********************************************************************* + 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; +} + +/**************************************************************************** + initialise a privilege list and set the talloc context + ****************************************************************************/ + +/**************************************************************************** + 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 ); +} + +/******************************************************************* + 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; +} + + +/********************************************************************* + 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; +} + +/**************************************************************************** + 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; +} + + +/**************************************************************************** + 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; +} + +/******************************************************************* +*******************************************************************/ + +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; ilow == 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; icount; 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; +} + diff --git a/source3/lib/util_nttoken.c b/source3/lib/util_nttoken.c new file mode 100644 index 0000000000..9cb981f74f --- /dev/null +++ b/source3/lib/util_nttoken.c @@ -0,0 +1,70 @@ +/* + * Unix SMB/CIFS implementation. + * Authentication utility functions + * Copyright (C) Andrew Tridgell 1992-1998 + * Copyright (C) Andrew Bartlett 2001 + * Copyright (C) Jeremy Allison 2000-2001 + * Copyright (C) Rafal Szczesniak 2002 + * Copyright (C) Volker Lendecke 2006 + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* function(s) moved from auth/auth_util.c to minimize linker deps */ + +#include "includes.h" + +/**************************************************************************** + Duplicate a SID token. +****************************************************************************/ + +NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, const NT_USER_TOKEN *ptoken) +{ + NT_USER_TOKEN *token; + + if (!ptoken) + return NULL; + + token = TALLOC_P(mem_ctx, NT_USER_TOKEN); + if (token == NULL) { + DEBUG(0, ("talloc failed\n")); + return NULL; + } + + ZERO_STRUCTP(token); + + if (ptoken->user_sids && ptoken->num_sids) { + token->user_sids = (DOM_SID *)talloc_memdup( + token, ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids ); + + if (token->user_sids == NULL) { + DEBUG(0, ("talloc_memdup failed\n")); + TALLOC_FREE(token); + return NULL; + } + token->num_sids = ptoken->num_sids; + } + + /* copy the privileges; don't consider failure to be critical here */ + + if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) { + DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. " + "Continuing with 0 privileges assigned.\n")); + } + + return token; +} + diff --git a/source3/lib/util_reg.c b/source3/lib/util_reg.c index 9f9cd40331..e75d72ac24 100644 --- a/source3/lib/util_reg.c +++ b/source3/lib/util_reg.c @@ -20,6 +20,8 @@ #include "includes.h" +extern REGISTRY_OPS smbconf_reg_ops; + const char *reg_type_lookup(enum winreg_Type type) { const char *result; @@ -108,118 +110,3 @@ WERROR reg_pull_multi_sz(TALLOC_CTX *mem_ctx, const void *buf, size_t len, return WERR_OK; } - -WERROR registry_pull_value(TALLOC_CTX *mem_ctx, - struct registry_value **pvalue, - enum winreg_Type type, uint8 *data, - uint32 size, uint32 length) -{ - struct registry_value *value; - WERROR err; - - if (!(value = TALLOC_ZERO_P(mem_ctx, struct registry_value))) { - return WERR_NOMEM; - } - - value->type = type; - - switch (type) { - case REG_DWORD: - if ((size != 4) || (length != 4)) { - err = WERR_INVALID_PARAM; - goto error; - } - value->v.dword = IVAL(data, 0); - break; - case REG_SZ: - case REG_EXPAND_SZ: - { - /* - * Make sure we get a NULL terminated string for - * convert_string_talloc(). - */ - - smb_ucs2_t *tmp; - uint32 num_ucs2 = length / 2; - - if ((length % 2) != 0) { - err = WERR_INVALID_PARAM; - goto error; - } - - if (!(tmp = SMB_MALLOC_ARRAY(smb_ucs2_t, num_ucs2+1))) { - err = WERR_NOMEM; - goto error; - } - - memcpy((void *)tmp, (const void *)data, length); - tmp[num_ucs2] = 0; - - value->v.sz.len = convert_string_talloc( - value, CH_UTF16LE, CH_UNIX, tmp, length+2, - &value->v.sz.str, False); - - SAFE_FREE(tmp); - - if (value->v.sz.len == (size_t)-1) { - err = WERR_INVALID_PARAM; - goto error; - } - break; - } - case REG_MULTI_SZ: - err = reg_pull_multi_sz(value, (void *)data, length, - &value->v.multi_sz.num_strings, - &value->v.multi_sz.strings); - if (!(W_ERROR_IS_OK(err))) { - goto error; - } - break; - case REG_BINARY: - value->v.binary.data = talloc_move(value, &data); - value->v.binary.length = length; - break; - default: - err = WERR_INVALID_PARAM; - goto error; - } - - *pvalue = value; - return WERR_OK; - - error: - TALLOC_FREE(value); - return err; -} - -WERROR registry_push_value(TALLOC_CTX *mem_ctx, - const struct registry_value *value, - DATA_BLOB *presult) -{ - switch (value->type) { - case REG_DWORD: { - char buf[4]; - SIVAL(buf, 0, value->v.dword); - *presult = data_blob_talloc(mem_ctx, (void *)buf, 4); - if (presult->data == NULL) { - return WERR_NOMEM; - } - break; - } - case REG_SZ: - case REG_EXPAND_SZ: { - presult->length = convert_string_talloc( - mem_ctx, CH_UNIX, CH_UTF16LE, value->v.sz.str, - MIN(value->v.sz.len, strlen(value->v.sz.str)+1), - (void *)&(presult->data), False); - if (presult->length == (size_t)-1) { - return WERR_NOMEM; - } - break; - } - default: - return WERR_INVALID_PARAM; - } - - return WERR_OK; -} diff --git a/source3/lib/util_reg_api.c b/source3/lib/util_reg_api.c new file mode 100644 index 0000000000..aad53e8e7c --- /dev/null +++ b/source3/lib/util_reg_api.c @@ -0,0 +1,136 @@ +/* + * Unix SMB/CIFS implementation. + * Registry helper routines + * Copyright (C) Volker Lendecke 2006 + * + * 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 the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 675 + * Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +WERROR registry_pull_value(TALLOC_CTX *mem_ctx, + struct registry_value **pvalue, + enum winreg_Type type, uint8 *data, + uint32 size, uint32 length) +{ + struct registry_value *value; + WERROR err; + + if (!(value = TALLOC_ZERO_P(mem_ctx, struct registry_value))) { + return WERR_NOMEM; + } + + value->type = type; + + switch (type) { + case REG_DWORD: + if ((size != 4) || (length != 4)) { + err = WERR_INVALID_PARAM; + goto error; + } + value->v.dword = IVAL(data, 0); + break; + case REG_SZ: + case REG_EXPAND_SZ: + { + /* + * Make sure we get a NULL terminated string for + * convert_string_talloc(). + */ + + smb_ucs2_t *tmp; + uint32 num_ucs2 = length / 2; + + if ((length % 2) != 0) { + err = WERR_INVALID_PARAM; + goto error; + } + + if (!(tmp = SMB_MALLOC_ARRAY(smb_ucs2_t, num_ucs2+1))) { + err = WERR_NOMEM; + goto error; + } + + memcpy((void *)tmp, (const void *)data, length); + tmp[num_ucs2] = 0; + + value->v.sz.len = convert_string_talloc( + value, CH_UTF16LE, CH_UNIX, tmp, length+2, + &value->v.sz.str, False); + + SAFE_FREE(tmp); + + if (value->v.sz.len == (size_t)-1) { + err = WERR_INVALID_PARAM; + goto error; + } + break; + } + case REG_MULTI_SZ: + err = reg_pull_multi_sz(value, (void *)data, length, + &value->v.multi_sz.num_strings, + &value->v.multi_sz.strings); + if (!(W_ERROR_IS_OK(err))) { + goto error; + } + break; + case REG_BINARY: + value->v.binary.data = talloc_move(value, &data); + value->v.binary.length = length; + break; + default: + err = WERR_INVALID_PARAM; + goto error; + } + + *pvalue = value; + return WERR_OK; + + error: + TALLOC_FREE(value); + return err; +} + +WERROR registry_push_value(TALLOC_CTX *mem_ctx, + const struct registry_value *value, + DATA_BLOB *presult) +{ + switch (value->type) { + case REG_DWORD: { + char buf[4]; + SIVAL(buf, 0, value->v.dword); + *presult = data_blob_talloc(mem_ctx, (void *)buf, 4); + if (presult->data == NULL) { + return WERR_NOMEM; + } + break; + } + case REG_SZ: + case REG_EXPAND_SZ: { + presult->length = convert_string_talloc( + mem_ctx, CH_UNIX, CH_UTF16LE, value->v.sz.str, + MIN(value->v.sz.len, strlen(value->v.sz.str)+1), + (void *)&(presult->data), False); + if (presult->length == (size_t)-1) { + return WERR_NOMEM; + } + break; + } + default: + return WERR_INVALID_PARAM; + } + + return WERR_OK; +} diff --git a/source3/lib/util_reg_smbconf.c b/source3/lib/util_reg_smbconf.c new file mode 100644 index 0000000000..8fe6b4e0b6 --- /dev/null +++ b/source3/lib/util_reg_smbconf.c @@ -0,0 +1,83 @@ +/* + * Unix SMB/CIFS implementation. + * Registry helper routines + * 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 the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 675 + * Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +extern REGISTRY_OPS smbconf_reg_ops; + +/* + * create a fake token just with enough rights to + * locally access the registry. + */ +NT_USER_TOKEN *registry_create_admin_token(TALLOC_CTX *mem_ctx) +{ + NT_USER_TOKEN *token = NULL; + + /* fake a user token: builtin administrators sid and the + * disk operators privilege is all we need to access the + * registry... */ + if (!(token = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) { + DEBUG(1, ("talloc failed\n")); + goto done; + } + token->privileges = se_disk_operators; + if (!add_sid_to_array(token, &global_sid_Builtin_Administrators, + &token->user_sids, &token->num_sids)) { + DEBUG(1, ("Error adding builtin administrators sid " + "to fake token.\n")); + goto done; + } +done: + return token; +} + +/* + * init the smbconf portion of the registry. + * for use in places where not the whole registry is needed, + * e.g. utils/net_conf.c and loadparm.c + */ +BOOL registry_init_regdb(void) +{ + BOOL ret = False; + int saved_errno = 0; + static REGISTRY_HOOK smbconf_reg_hook = {KEY_SMBCONF, &smbconf_reg_ops}; + + DEBUG(10, ("registry_init_regdb called\n")); + + if (!regdb_init()) { + saved_errno = errno; + DEBUG(1, ("Can't open the registry")); + if (saved_errno) { + DEBUGADD(1, (": %s", strerror(saved_errno))); + } + DEBUGADD(1, (".\n")); + goto done; + } + reghook_cache_init(); + if (!reghook_cache_add(&smbconf_reg_hook)) { + DEBUG(1, ("Error adding smbconf reghooks to reghook cache.\n")); + goto done; + } + + ret = True; + +done: + return ret; +} -- cgit