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 | |
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)
-rw-r--r-- | source3/Makefile.in | 50 | ||||
-rw-r--r-- | source3/auth/token_util.c | 41 | ||||
-rw-r--r-- | source3/include/privileges.h | 4 | ||||
-rw-r--r-- | source3/lib/privileges.c | 505 | ||||
-rw-r--r-- | source3/lib/privileges_basic.c | 519 | ||||
-rw-r--r-- | source3/lib/util_nttoken.c | 70 | ||||
-rw-r--r-- | source3/lib/util_reg.c | 117 | ||||
-rw-r--r-- | source3/lib/util_reg_api.c | 136 | ||||
-rw-r--r-- | source3/lib/util_reg_smbconf.c | 83 | ||||
-rw-r--r-- | source3/utils/net_conf.c | 29 |
10 files changed, 874 insertions, 680 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 7d1337cff5..75eed9e6c6 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -281,7 +281,7 @@ LIB_WITH_PROTO_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \ lib/ufc.o lib/genrand.o lib/username.o \ lib/util_pw.o lib/access.o lib/smbrun.o \ lib/bitmap.o lib/crc32.o lib/dprintf.o \ - lib/xfile.o lib/wins_srv.o lib/util_reg.o \ + lib/xfile.o lib/wins_srv.o $(UTIL_REG_OBJ) \ lib/util_str.o lib/clobber.o lib/util_sid.o lib/util_uuid.o \ lib/util_unistr.o lib/util_file.o lib/data_blob.o \ lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \ @@ -369,7 +369,8 @@ REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_pri registry/reg_db.o registry/reg_eventlog.o registry/reg_shares.o \ registry/reg_util.o registry/reg_dynamic.o registry/reg_perfcount.o \ registry/reg_smbconf.o registry/reg_api.o \ - registry/reg_frontend_hilvl.o + registry/reg_frontend_hilvl.o \ + $(UTIL_REG_API_OBJ) $(UTIL_REG_SMBCONF_OBJ) RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o @@ -430,7 +431,8 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ passdb/util_wellknown.o passdb/util_builtin.o passdb/pdb_compat.o \ passdb/util_unixsids.o passdb/lookup_sid.o \ passdb/login_cache.o @PDB_STATIC@ \ - lib/account_pol.o lib/privileges.o lib/util_nscd.o + lib/account_pol.o lib/privileges.o lib/privileges_basic.o \ + lib/util_nscd.o DEVEL_HELP_WEIRD_OBJ = modules/weird.o CP850_OBJ = modules/CP850.o @@ -494,6 +496,7 @@ AUTH_WINBIND_OBJ = auth/auth_winbind.o AUTH_SCRIPT_OBJ = auth/auth_script.o AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/token_util.o \ + lib/util_nttoken.o \ auth/auth_compat.o auth/auth_ntlmssp.o \ $(PLAINTEXT_AUTH_OBJ) $(SLCACHE_OBJ) $(DCUTIL_OBJ) @@ -584,7 +587,7 @@ SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \ rpc_client/cli_pipe.o $(RPC_PARSE_OBJ2) \ $(RPC_CLIENT_OBJ1) \ $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(LDB_OBJ) $(GROUPDB_OBJ) \ - $(LIBMSRPC_GEN_OBJ) + $(LIBMSRPC_GEN_OBJ) TESTPARM_OBJ = utils/testparm.o \ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ @@ -663,18 +666,15 @@ TOOL_OBJ = client/smbctool.o client/clitar.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ $(READLINE_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) \ $(DISPLAY_SEC_OBJ) -NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_domain.o utils/net_help.o \ - utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \ - utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \ - utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \ - utils/net_status.o utils/net_rpc_printer.o utils/net_rpc_rights.o \ - utils/net_rpc_service.o utils/net_rpc_registry.o utils/net_usershare.o \ - utils/netlookup.o utils/net_sam.o utils/net_rpc_shell.o \ - utils/net_util.o utils/net_rpc_sh_acct.o utils/net_rpc_audit.o \ - $(PASSWD_UTIL_OBJ) utils/net_dns.o utils/net_ads_gpo.o \ - utils/net_conf.o +UTIL_REG_OBJ = lib/util_reg.o +UTIL_REG_API_OBJ = lib/util_reg_api.o +UTIL_REG_SMBCONF_OBJ = lib/util_reg_smbconf.o +UTIL_REG_ALL_OBJ = $(UTIL_REG_OBJ) $(UTIL_REG_API_OBJ) $(UTIL_REG_SMBCONF_OBJ) -NET_REG_OBJ = registry/reg_api.o \ +# objects to be used when not all of the registry code should be +# loaded but only the portion needed by reg_api, typically for +# using smbconf (registry) +REG_API_OBJ = registry/reg_api.o \ registry/reg_frontend_hilvl.o \ registry/reg_smbconf.o \ registry/reg_db.o \ @@ -685,8 +685,21 @@ NET_REG_OBJ = registry/reg_api.o \ registry/reg_perfcount.o \ registry/reg_dynamic.o \ \ - auth/token_util.o - + lib/util_nttoken.o \ + $(UTIL_REG_API_OBJ) \ + $(UTIL_REG_SMBCONF_OBJ) + +NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_domain.o utils/net_help.o \ + utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \ + utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \ + utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \ + utils/net_status.o utils/net_rpc_printer.o utils/net_rpc_rights.o \ + utils/net_rpc_service.o utils/net_rpc_registry.o utils/net_usershare.o \ + utils/netlookup.o utils/net_sam.o utils/net_rpc_shell.o \ + utils/net_util.o utils/net_rpc_sh_acct.o utils/net_rpc_audit.o \ + $(PASSWD_UTIL_OBJ) utils/net_dns.o utils/net_ads_gpo.o \ + utils/net_conf.o + NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(LIBADDNS_OBJ0) \ @@ -694,7 +707,8 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \ $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \ $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(REGFIO_OBJ) $(READLINE_OBJ) \ - $(LDB_OBJ) $(LIBGPO_OBJ) @BUILD_INIPARSER@ $(DISPLAY_SEC_OBJ) $(NET_REG_OBJ) + $(LDB_OBJ) $(LIBGPO_OBJ) @BUILD_INIPARSER@ $(DISPLAY_SEC_OBJ) \ + $(REG_API_OBJ) CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ) diff --git a/source3/auth/token_util.c b/source3/auth/token_util.c index d68f44cbf1..57db0d193f 100644 --- a/source3/auth/token_util.c +++ b/source3/auth/token_util.c @@ -28,47 +28,6 @@ #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; -} - -/**************************************************************************** Check for a SID in an NT_USER_TOKEN ****************************************************************************/ diff --git a/source3/include/privileges.h b/source3/include/privileges.h index eac42e0ba9..72b2c91324 100644 --- a/source3/include/privileges.h +++ b/source3/include/privileges.h @@ -61,7 +61,9 @@ typedef struct { #define SE_RESTORE { { 0x00000400, 0x00000000, 0x00000000, 0x00000000 } } #define SE_TAKE_OWNERSHIP { { 0x00000800, 0x00000000, 0x00000000, 0x00000000 } } -/* defined in lib/privilegs.c */ +/* defined in lib/privilegs_basic.c */ + +extern const SE_PRIV se_priv_all; extern const SE_PRIV se_priv_none; extern const SE_PRIV se_machine_account; 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 ); } diff --git a/source3/lib/privileges_basic.c b/source3/lib/privileges_basic.c new file mode 100644 index 0000000000..b1ca1765d5 --- /dev/null +++ b/source3/lib/privileges_basic.c @@ -0,0 +1,519 @@ +/* + Unix SMB/CIFS implementation. + Privileges handling functions + 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 + 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. +*/ + +/* + * Basic privileges functions (mask-operations and conversion + * functions between the different formats (se_priv, privset, luid) + * moved here * from lib/privileges.c to minimize linker deps. + * + * generally SID- and LUID-related code is left in lib/privileges.c + * + * some extra functions to hide privs array from lib/privileges.c + */ + +#include "includes.h" + +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 }} +}; + +/*************************************************************************** + 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; +} + +/*************************************************************************** + put all privileges into a mask +****************************************************************************/ + +BOOL se_priv_put_all_privileges(SE_PRIV *mask) +{ + int i; + uint32 num_privs = count_all_privileges(); + + if (!se_priv_copy(mask, &se_priv_none)) { + return False; + } + for ( i=0; i<num_privs; i++ ) { + se_priv_add(mask, &privs[i].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 +****************************************************************************/ + +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")); +} + +/**************************************************************************** + 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; 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; +} + 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; +} diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c index 7d8849a99a..605ad3fdd2 100644 --- a/source3/utils/net_conf.c +++ b/source3/utils/net_conf.c @@ -38,8 +38,6 @@ #include "includes.h" #include "utils/net.h" -extern REGISTRY_OPS smbconf_reg_ops; - /* * usage functions */ @@ -138,7 +136,7 @@ static char *format_value(TALLOC_CTX *mem_ctx, struct registry_value *value) } break; } - case REG_BINARY: + case REG_BINARY: result = talloc_asprintf(mem_ctx, "binary (%d bytes)", (int)value->v.binary.length); break; @@ -198,6 +196,12 @@ static WERROR smbconf_open_path_q(TALLOC_CTX *ctx, const char *subkeyname, { WERROR werr = WERR_OK; char *path = NULL; + NT_USER_TOKEN *token; + + if (!(token = registry_create_admin_token(ctx))) { + DEBUG(1, ("Error creating admin token\n")); + goto done; + } if (subkeyname == NULL) { path = talloc_strdup(ctx, KEY_SMBCONF); @@ -207,8 +211,9 @@ static WERROR smbconf_open_path_q(TALLOC_CTX *ctx, const char *subkeyname, } werr = reg_open_path(ctx, path, desired_access, - get_root_nt_token(), key); + token, key); +done: TALLOC_FREE(path); return werr; } @@ -1068,7 +1073,6 @@ done: int net_conf(int argc, const char **argv) { int ret = -1; - int saved_errno = 0; struct functable2 func[] = { {"list", net_conf_list, "Dump the complete configuration in smb.conf like format."}, @@ -1091,21 +1095,10 @@ int net_conf(int argc, const char **argv) {NULL, NULL, NULL} }; - REGISTRY_HOOK smbconf_reg_hook = {KEY_SMBCONF, &smbconf_reg_ops}; - - if (!regdb_init()) { - saved_errno = errno; - d_fprintf(stderr, "Can't open the registry"); - if (saved_errno) { - d_fprintf(stderr, ": %s\n", strerror(saved_errno)); - } - else { - d_fprintf(stderr, "!\n"); - } + if (!registry_init_regdb()) { + d_fprintf(stderr, "Error initializing the registry!\n"); goto done; } - reghook_cache_init(); - reghook_cache_add(&smbconf_reg_hook); ret = net_run_function2(argc, argv, "net conf", func); |