#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)
#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 */
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;
/*
static void sig_usr1(void)
{
received_signal = 1;
- sys_select_signal();
+ sys_select_signal(SIGUSR1);
}
/****************************************************************************
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
{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, "", ""}
};
/****************************************************************************
initialise a privilege list and set the talloc context
****************************************************************************/
+
NTSTATUS privilege_set_init(PRIVILEGE_SET *priv_set)
{
TALLOC_CTX *mem_ctx;
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;
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);
static void sig_term(int sig)
{
got_sig_term = 1;
- sys_select_signal();
+ sys_select_signal(SIGTERM);
}
/**************************************************************************** **
static void sig_hup(int sig)
{
reload_after_sighup = 1;
- sys_select_signal();
+ sys_select_signal(SIGHUP);
}
#if DUMP_CORE
static void termination_handler(int signum)
{
do_sigterm = True;
- sys_select_signal();
+ sys_select_signal(signum);
}
static BOOL do_sigusr2;
static void sigusr2_handler(int signum)
{
do_sigusr2 = True;
- sys_select_signal();
+ sys_select_signal(SIGUSR2);
}
static BOOL do_sighup;
static void sighup_handler(int signum)
{
do_sighup = True;
- sys_select_signal();
+ sys_select_signal(SIGHUP);
}
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*/
Initialize the cache tree
*********************************************************************/
-REGISTRY_HOOK* reghook_cache_find( char *keyname )
+REGISTRY_HOOK* reghook_cache_find( const char *keyname )
{
char *key;
int len;
return (snum < num_services) ? snum : -1;
}
+/*******************************************************************
+ 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;
+}
+
/*******************************************************************
********************************************************************/
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;
}
/********************************************************************
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);
}
/****************************************************************************
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);
}
/****************************************************************************
static void sig_term(void)
{
got_sig_term = 1;
- sys_select_signal();
+ sys_select_signal(SIGTERM);
}
/****************************************************************************
static void sig_hup(int sig)
{
reload_after_sighup = 1;
- sys_select_signal();
+ sys_select_signal(SIGHUP);
}
/****************************************************************************
BlockSignals(True,SIGHUP);
DEBUG(0,("Got SIGHUP\n"));
- sys_select_signal();
+ sys_select_signal(SIGHUP);
reload_after_sighup = True;
BlockSignals(False,SIGHUP);
}