diff options
-rw-r--r-- | source3/include/doserr.h | 3 | ||||
-rw-r--r-- | source3/include/privileges.h | 4 | ||||
-rw-r--r-- | source3/lib/messages.c | 2 | ||||
-rw-r--r-- | source3/lib/privileges.c | 5 | ||||
-rw-r--r-- | source3/lib/select.c | 7 | ||||
-rw-r--r-- | source3/nmbd/nmbd.c | 4 | ||||
-rw-r--r-- | source3/nsswitch/winbindd.c | 8 | ||||
-rw-r--r-- | source3/registry/reg_cachehook.c | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg_nt.c | 116 | ||||
-rw-r--r-- | source3/smbd/notify_kernel.c | 2 | ||||
-rw-r--r-- | source3/smbd/oplock_linux.c | 2 | ||||
-rw-r--r-- | source3/smbd/server.c | 4 | ||||
-rw-r--r-- | source3/wrepld/server.c | 2 |
13 files changed, 142 insertions, 19 deletions
diff --git a/source3/include/doserr.h b/source3/include/doserr.h index 60a3c335ec..38cd87515e 100644 --- a/source3/include/doserr.h +++ b/source3/include/doserr.h @@ -185,6 +185,9 @@ #define WERR_INVALID_OWNER W_ERROR(1307) #define WERR_IO_PENDING W_ERROR(997) #define WERR_CAN_NOT_COMPLETE W_ERROR(1003) +#define WERR_REG_CORRUPT W_ERROR(1015) +#define WERR_REG_IO_FAILURE W_ERROR(1016) +#define WERR_REG_FILE_INVALID W_ERROR(1017) #define WERR_NO_SUCH_SERVICE W_ERROR(1060) #define WERR_INVALID_SERVICE_CONTROL W_ERROR(1052) #define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338) diff --git a/source3/include/privileges.h b/source3/include/privileges.h index c7a9b0560d..38edee84e8 100644 --- a/source3/include/privileges.h +++ b/source3/include/privileges.h @@ -57,6 +57,9 @@ typedef struct { #define SE_ADD_USERS { { 0x00000040, 0x00000000, 0x00000000, 0x00000000 } } #define SE_DISK_OPERATOR { { 0x00000080, 0x00000000, 0x00000000, 0x00000000 } } #define SE_REMOTE_SHUTDOWN { { 0x00000100, 0x00000000, 0x00000000, 0x00000000 } } +#define SE_BACKUP { { 0x00000200, 0x00000000, 0x00000000, 0x00000000 } } +#define SE_RESTORE { { 0x00000400, 0x00000000, 0x00000000, 0x00000000 } } +#define SE_TAKE_OWNERSHIP { { 0x00000800, 0x00000000, 0x00000000, 0x00000000 } } /* defined in lib/privilegs.c */ @@ -66,6 +69,7 @@ extern const SE_PRIV se_print_operator; extern const SE_PRIV se_add_users; extern const SE_PRIV se_disk_operators; extern const SE_PRIV se_remote_shutdown; +extern const SE_PRIV se_restore; /* diff --git a/source3/lib/messages.c b/source3/lib/messages.c index dca4b94844..21b5531c89 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -76,7 +76,7 @@ static struct dispatch_fns { static void sig_usr1(void) { received_signal = 1; - sys_select_signal(); + sys_select_signal(SIGUSR1); } /**************************************************************************** diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c index e01561de06..ae98d8940f 100644 --- a/source3/lib/privileges.c +++ b/source3/lib/privileges.c @@ -39,6 +39,7 @@ 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; /******************************************************************** This is a list of privileges reported by a WIndows 2000 SP4 AD DC @@ -91,6 +92,9 @@ PRIVS privs[] = { {SE_ADD_USERS, "SeAddUsersPrivilege", "Add users and groups to the domain"}, {SE_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Force shutdown from a remote system"}, {SE_DISK_OPERATOR, "SeDiskOperatorPrivilege", "Manage disk shares"}, + {SE_BACKUP, "SeBackupPrivilege", "Back up files and directories"}, + {SE_RESTORE, "SeRestorePrivilege", "Restore files and directories"}, + {SE_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege", "Take ownership of files or other objects"}, {SE_END, "", ""} }; @@ -636,6 +640,7 @@ NTSTATUS privilege_create_account(const DOM_SID *sid ) /**************************************************************************** initialise a privilege list and set the talloc context ****************************************************************************/ + NTSTATUS privilege_set_init(PRIVILEGE_SET *priv_set) { TALLOC_CTX *mem_ctx; diff --git a/source3/lib/select.c b/source3/lib/select.c index 2e55f9753d..f63221f7cf 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -38,9 +38,8 @@ static VOLATILE unsigned pipe_written, pipe_read; nasty signal race condition. ********************************************************************/ -void sys_select_signal(void) +void sys_select_signal(char c) { - char c = 1; if (!initialised) return; if (pipe_written > pipe_read+256) return; @@ -111,6 +110,10 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s byte in the pipe and lose the signal. JRA. */ ret = -1; +#if 0 + /* JRA - we can use this to debug the signal messaging... */ + DEBUG(0,("select got %u signal\n", (unsigned int)c)); +#endif errno = EINTR; } else { FD_CLR(select_pipe[0], readfds2); diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index af93bf5197..97e22943b1 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -90,7 +90,7 @@ static SIG_ATOMIC_T got_sig_term; static void sig_term(int sig) { got_sig_term = 1; - sys_select_signal(); + sys_select_signal(SIGTERM); } /**************************************************************************** ** @@ -102,7 +102,7 @@ static SIG_ATOMIC_T reload_after_sighup; static void sig_hup(int sig) { reload_after_sighup = 1; - sys_select_signal(); + sys_select_signal(SIGHUP); } #if DUMP_CORE diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index f083dfe44a..c3a27a7deb 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -183,7 +183,7 @@ static BOOL do_sigterm; static void termination_handler(int signum) { do_sigterm = True; - sys_select_signal(); + sys_select_signal(signum); } static BOOL do_sigusr2; @@ -191,7 +191,7 @@ static BOOL do_sigusr2; static void sigusr2_handler(int signum) { do_sigusr2 = True; - sys_select_signal(); + sys_select_signal(SIGUSR2); } static BOOL do_sighup; @@ -199,7 +199,7 @@ static BOOL do_sighup; static void sighup_handler(int signum) { do_sighup = True; - sys_select_signal(); + sys_select_signal(SIGHUP); } static BOOL do_sigchld; @@ -207,7 +207,7 @@ static BOOL do_sigchld; static void sigchld_handler(int signum) { do_sigchld = True; - sys_select_signal(); + sys_select_signal(SIGCHLD); } /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/ diff --git a/source3/registry/reg_cachehook.c b/source3/registry/reg_cachehook.c index 4b03a69acf..c8a23777be 100644 --- a/source3/registry/reg_cachehook.c +++ b/source3/registry/reg_cachehook.c @@ -67,7 +67,7 @@ BOOL reghook_cache_add( REGISTRY_HOOK *hook ) Initialize the cache tree *********************************************************************/ -REGISTRY_HOOK* reghook_cache_find( char *keyname ) +REGISTRY_HOOK* reghook_cache_find( const char *keyname ) { char *key; int len; diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index 4211e9b9f4..9792592c19 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -763,6 +763,113 @@ static int validate_reg_filename( pstring fname ) } /******************************************************************* + Note: topkeypaty is the *full* path that this *key will be + loaded into (including the name of the key) + ********************************************************************/ + +static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath, + REGF_NK_REC *key ) +{ + REGF_NK_REC *subkey; + REGISTRY_KEY registry_key; + REGVAL_CTR values; + REGSUBKEY_CTR subkeys; + int i; + pstring path; + WERROR result = WERR_OK; + + /* initialize the REGISTRY_KEY structure */ + + if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) { + DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n", + topkeypath )); + return WERR_BADFILE; + } + pstrcpy( registry_key.name, topkeypath ); + + /* now start parsing the values and subkeys */ + + ZERO_STRUCT( values ); + ZERO_STRUCT( subkeys ); + + regsubkey_ctr_init( &subkeys ); + regval_ctr_init( &values ); + + /* copy values into the REGVAL_CTR */ + + for ( i=0; i<key->num_values; i++ ) { + regval_ctr_addvalue( &values, key->values[i].valuename, key->values[i].type, + key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) ); + } + + /* copy subkeys into the REGSUBKEY_CTR */ + + key->subkey_index = 0; + while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { + regsubkey_ctr_addkey( &subkeys, subkey->keyname ); + } + + /* write this key and values out */ + + if ( !store_reg_values( ®istry_key, &values ) + || !store_reg_keys( ®istry_key, &subkeys ) ) + { + DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath)); + result = WERR_REG_IO_FAILURE; + } + + regval_ctr_destroy( &values ); + regsubkey_ctr_destroy( &subkeys ); + + if ( !W_ERROR_IS_OK(result) ) + return result; + + /* now continue to load each subkey registry tree */ + + key->subkey_index = 0; + while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { + pstr_sprintf( path, "%s%s%s", topkeypath, "\\", subkey->keyname ); + result = reg_load_tree( regfile, path, subkey ); + if ( !W_ERROR_IS_OK(result) ) + break; + } + + return result; +} + +/******************************************************************* + ********************************************************************/ + +static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname ) +{ + REGF_FILE *regfile; + REGF_NK_REC *rootkey; + WERROR result; + + /* open the registry file....fail if the file already exists */ + + if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) { + DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", + fname, strerror(errno) )); + return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); + } + + /* get the rootkey from the regf file and then load the tree + via recursive calls */ + + if ( !(rootkey = regfio_rootkey( regfile )) ) + return WERR_REG_FILE_INVALID; + + result = reg_load_tree( regfile, krecord->name, rootkey ); + + /* cleanup */ + + regfio_close( regfile ); + + return result; +} + +/******************************************************************* ********************************************************************/ WERROR _reg_restore_key(pipes_struct *p, REG_Q_RESTORE_KEY *q_u, REG_R_RESTORE_KEY *r_u) @@ -783,13 +890,14 @@ WERROR _reg_restore_key(pipes_struct *p, REG_Q_RESTORE_KEY *q_u, REG_R_RESTORE_ if ( (snum = validate_reg_filename( filename )) == -1 ) return WERR_OBJECT_PATH_INVALID; + /* user must posses SeRestorePrivilege for this this proceed */ + + if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) ) + return WERR_ACCESS_DENIED; + DEBUG(2,("_reg_restore_key: Restoring [%s] from %s in share %s\n", regkey->name, filename, lp_servicename(snum) )); -#if 0 return restore_registry_key( regkey, filename ); -#endif - - return WERR_OK; } /******************************************************************** diff --git a/source3/smbd/notify_kernel.c b/source3/smbd/notify_kernel.c index 6d1f550241..02abe0b4b6 100644 --- a/source3/smbd/notify_kernel.c +++ b/source3/smbd/notify_kernel.c @@ -74,7 +74,7 @@ static void signal_handler(int sig, siginfo_t *info, void *unused) fd_pending_array[signals_received] = (SIG_ATOMIC_T)info->si_fd; signals_received++; } /* Else signal is lost. */ - sys_select_signal(); + sys_select_signal(RT_SIGNAL_NOTIFY); } /**************************************************************************** diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c index 6d1bc64ce1..78dc260939 100644 --- a/source3/smbd/oplock_linux.c +++ b/source3/smbd/oplock_linux.c @@ -72,7 +72,7 @@ static void signal_handler(int sig, siginfo_t *info, void *unused) fd_pending_array[signals_received] = (SIG_ATOMIC_T)info->si_fd; signals_received++; } /* Else signal is lost. */ - sys_select_signal(); + sys_select_signal(RT_SIGNAL_LEASE); } /**************************************************************************** diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 301534d750..01515a5726 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -66,7 +66,7 @@ static void smbd_set_server_fd(int fd) static void sig_term(void) { got_sig_term = 1; - sys_select_signal(); + sys_select_signal(SIGTERM); } /**************************************************************************** @@ -76,7 +76,7 @@ static void sig_term(void) static void sig_hup(int sig) { reload_after_sighup = 1; - sys_select_signal(); + sys_select_signal(SIGHUP); } /**************************************************************************** diff --git a/source3/wrepld/server.c b/source3/wrepld/server.c index 9d035a6cbf..06fab1ab1a 100644 --- a/source3/wrepld/server.c +++ b/source3/wrepld/server.c @@ -89,7 +89,7 @@ static void sig_hup(int sig) BlockSignals(True,SIGHUP); DEBUG(0,("Got SIGHUP\n")); - sys_select_signal(); + sys_select_signal(SIGHUP); reload_after_sighup = True; BlockSignals(False,SIGHUP); } |