r23485: This checkin consists mostly of refactorings in preparation of the
authorMichael Adam <obnox@samba.org>
Thu, 14 Jun 2007 11:29:35 +0000 (11:29 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:23:21 +0000 (12:23 -0500)
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

source/Makefile.in
source/auth/token_util.c
source/include/privileges.h
source/lib/privileges.c
source/lib/privileges_basic.c [new file with mode: 0644]
source/lib/util_nttoken.c [new file with mode: 0644]
source/lib/util_reg.c
source/lib/util_reg_api.c [new file with mode: 0644]
source/lib/util_reg_smbconf.c [new file with mode: 0644]
source/utils/net_conf.c

index 7d1337cff5b78ea9023ce409737a776fb5444cde..75eed9e6c68b53e2c8f356bd2ff53187e0f06919 100644 (file)
@@ -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)
index d68f44cbf1b2416fe7a76a7aef07866ed9cbfc1e..57db0d193fdaaedb174bea2c705d98885060fcbd 100644 (file)
 
 #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
 ****************************************************************************/
index eac42e0ba937a9763355e856a1a7889dab607327..72b2c913245825ce3f04db3a35102de174667ad1 100644 (file)
@@ -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;
index cd6494d1ed19fd4211ebfec2b474bd740de41aa5..3714a906deff05ad952e12c8164caf1ee033c01b 100644 (file)
@@ -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
 
 #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/source/lib/privileges_basic.c b/source/lib/privileges_basic.c
new file mode 100644 (file)
index 0000000..b1ca176
--- /dev/null
@@ -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/source/lib/util_nttoken.c b/source/lib/util_nttoken.c
new file mode 100644 (file)
index 0000000..9cb981f
--- /dev/null
@@ -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;
+}
+
index 9f9cd403319cf06e017dfe651ed0d1343db74c8d..e75d72ac2496ad54739add3cfbc6c2b516b6b75e 100644 (file)
@@ -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/source/lib/util_reg_api.c b/source/lib/util_reg_api.c
new file mode 100644 (file)
index 0000000..aad53e8
--- /dev/null
@@ -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/source/lib/util_reg_smbconf.c b/source/lib/util_reg_smbconf.c
new file mode 100644 (file)
index 0000000..8fe6b4e
--- /dev/null
@@ -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;
+}
index 7d8849a99a513989e18ce30b6245a8bc5dde7e97..605ad3fdd2bcc6743fbe64af832450fce1b6baaa 100644 (file)
@@ -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);