static NTSTATUS rpc_service_start_internal(const DOM_SID *domain_sid,
					const char *domain_name, 
					struct cli_state *cli,
					struct rpc_pipe_client *pipe_hnd,
					TALLOC_CTX *mem_ctx, 
					int argc,
					const char **argv )
{
	POLICY_HND hSCM, hService;
	WERROR result = WERR_GENERAL_FAILURE;
	fstring servicename;
	uint32 state = 0;
	
	if (argc != 1 ) {
		d_printf("Usage: net rpc service status <service>\n");
		return NT_STATUS_OK;
	}

	fstrcpy( servicename, argv[0] );

	/* Open the Service Control Manager */
	
	result = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE  );
	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
		return werror_to_ntstatus(result);
	}
	
	/* Open the Service */
	
	result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, 
		servicename, SC_RIGHT_SVC_START );

	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
		goto done;
	}
	
	/* get the status */

	result = rpccli_svcctl_start_service(pipe_hnd, mem_ctx, &hService, NULL, 0 );
	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Query status request failed.  [%s]\n", dos_errstr(result));
		goto done;
	}
	
	result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state  );
	
	if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
		d_printf("Successfully started service: %s\n", servicename );
	else
		d_fprintf(stderr, "Failed to start service: %s [%s]\n", servicename, dos_errstr(result) );
	
done:	
	rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService  );
	rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM  );

	return werror_to_ntstatus(result);
}
示例#2
0
static bool test_set_get_includes(struct smbconf_ctx *ctx)
{
	WERROR werr;
	uint32_t count;
	bool ret = false;
	const char *set_includes[] = {
		"/path/to/include1",
		"/path/to/include2"
	};
	uint32_t set_num_includes = 2;
	char **get_includes = NULL;
	uint32_t get_num_includes = 0;
	TALLOC_CTX *mem_ctx = talloc_stackframe();

	printf("test: set_get_includes\n");

	werr = smbconf_set_global_includes(ctx, set_num_includes, set_includes);
	if (!W_ERROR_IS_OK(werr)) {
		printf("failure: get_set_includes (setting includes) - %s\n",
		       dos_errstr(werr));
		goto done;
	}

	werr = smbconf_get_global_includes(ctx, mem_ctx, &get_num_includes,
					   &get_includes);
	if (!W_ERROR_IS_OK(werr)) {
		printf("failure: get_set_includes (getting includes) - %s\n",
		       dos_errstr(werr));
		goto done;
	}

	if (get_num_includes != set_num_includes) {
		printf("failure: get_set_includes - set %d includes, got %d\n",
		       set_num_includes, get_num_includes);
		goto done;
	}

	for (count = 0; count < get_num_includes; count++) {
		if (!strequal(set_includes[count], get_includes[count])) {
			printf("expected: \n");
			print_strings("* ", set_num_includes, set_includes);
			printf("got: \n");
			print_strings("* ", get_num_includes,
				      (const char **)get_includes);
			printf("failure: get_set_includes - data mismatch:\n");
			goto done;
		}
	}

	printf("success: set_includes\n");
	ret = true;

done:
	TALLOC_FREE(mem_ctx);
	return ret;
}
示例#3
0
static bool test_delete_includes(struct smbconf_ctx *ctx)
{
	WERROR werr;
	bool ret = false;
	const char *set_includes[] = {
		"/path/to/include",
	};
	uint32_t set_num_includes = 1;
	char **get_includes = NULL;
	uint32_t get_num_includes = 0;
	TALLOC_CTX *mem_ctx = talloc_stackframe();

	printf("test: delete_includes\n");

	werr = smbconf_set_global_includes(ctx, set_num_includes, set_includes);
	if (!W_ERROR_IS_OK(werr)) {
		printf("failure: delete_includes (setting includes) - %s\n",
		       dos_errstr(werr));
		goto done;
	}

	werr = smbconf_delete_global_includes(ctx);
	if (!W_ERROR_IS_OK(werr)) {
		printf("failure: delete_includes (deleting includes) - %s\n",
		       dos_errstr(werr));
		goto done;
	}

	werr = smbconf_get_global_includes(ctx, mem_ctx, &get_num_includes,
					   &get_includes);
	if (!W_ERROR_IS_OK(werr)) {
		printf("failure: delete_includes (getting includes) - %s\n",
		       dos_errstr(werr));
		goto done;
	}

	if (get_num_includes != 0) {
		printf("failure: delete_includes (not empty after delete)\n");
		goto done;
	}

	werr = smbconf_delete_global_includes(ctx);
	if (!W_ERROR_IS_OK(werr)) {
		printf("failuer: delete_includes (delete empty includes) - "
		       "%s\n", dos_errstr(werr));
		goto done;
	}

	printf("success: delete_includes\n");
	ret = true;

done:
	return ret;
}
static NTSTATUS rpc_service_list_internal(const DOM_SID *domain_sid,
					const char *domain_name, 
					struct cli_state *cli,
					struct rpc_pipe_client *pipe_hnd,
					TALLOC_CTX *mem_ctx, 
					int argc,
					const char **argv )
{
	POLICY_HND hSCM;
	ENUM_SERVICES_STATUS *services;
	WERROR result = WERR_GENERAL_FAILURE;
	fstring servicename;
	fstring displayname;
	uint32 num_services = 0;
	int i;
	
	if (argc != 0 ) {
		d_printf("Usage: net rpc service list\n");
		return NT_STATUS_OK;
	}

	result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE  );
	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
		return werror_to_ntstatus(result);
	}
	
	result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
		SVCCTL_STATE_ALL, &num_services, &services );
	
	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Failed to enumerate services.  [%s]\n", dos_errstr(result));
		goto done;
	}
	
	if ( num_services == 0 )
		d_printf("No services returned\n");
	
	for ( i=0; i<num_services; i++ ) {
		rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
		rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
		
		d_printf("%-20s    \"%s\"\n", servicename, displayname);
	}

done:	
	rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM  );
		
	return werror_to_ntstatus(result);
}	
示例#5
0
文件: parse_prs.c 项目: jophxy/samba
BOOL prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status)
{
	char *q = prs_mem_get(ps, sizeof(uint32));
	if (q == NULL)
		return False;

	if (UNMARSHALLING(ps)) {
		if (ps->bigendian_data)
			*status = W_ERROR(RIVAL(q,0));
		else
			*status = W_ERROR(IVAL(q,0));
	} else {
		if (ps->bigendian_data)
			RSIVAL(q,0,W_ERROR_V(*status));
		else
			SIVAL(q,0,W_ERROR_V(*status));
	}

	DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth), ps->data_offset, name, 
		 dos_errstr(*status)));

	ps->data_offset += sizeof(uint32);

	return True;
}
static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid,
					const char *domain_name, 
					struct cli_state *cli,
					struct rpc_pipe_client *pipe_hnd,
					TALLOC_CTX *mem_ctx, 
					int argc,
					const char **argv )
{
	POLICY_HND hSCM;
	WERROR result = WERR_GENERAL_FAILURE;
	fstring servicename;
	
	if (argc != 1 ) {
		d_printf("Usage: net rpc service status <service>\n");
		return NT_STATUS_OK;
	}

	fstrcpy( servicename, argv[0] );

	/* Open the Service Control Manager */
	
	result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE  );
	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
		return werror_to_ntstatus(result);
	}
	
	result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, 
		SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
		
	rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM  );
		
	return werror_to_ntstatus(result);
}	
static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
				TALLOC_CTX *mem_ctx, 
				POLICY_HND *hSCM,
				const char *service,
				uint32 *state )
{
	POLICY_HND hService;
	SERVICE_STATUS service_status;
	WERROR result = WERR_GENERAL_FAILURE;
	
	/* now cycle until the status is actually 'watch_state' */
	
	result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService, 
		service, SC_RIGHT_SVC_QUERY_STATUS );

	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
		return result;
	}

	result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status  );
	if ( W_ERROR_IS_OK(result) ) {
		*state = service_status.state;
	}
	
	rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
	
	return result;
}
示例#8
0
static bool test_get_includes(struct smbconf_ctx *ctx)
{
	WERROR werr;
	bool ret = false;
	uint32_t num_includes = 0;
	char **includes = NULL;
	TALLOC_CTX *mem_ctx = talloc_stackframe();

	printf("test: get_includes\n");
	werr = smbconf_get_global_includes(ctx, mem_ctx,
					   &num_includes, &includes);
	if (!W_ERROR_IS_OK(werr)) {
		printf("failure: get_includes - %s\n", dos_errstr(werr));
		goto done;
	}

	printf("got %u includes%s\n", num_includes,
	       (num_includes > 0) ? ":" : ".");
	print_strings("", num_includes, (const char **)includes);

	printf("success: get_includes\n");
	ret = true;

done:
	TALLOC_FREE(mem_ctx);
	return ret;
}
示例#9
0
static bool torture_smbconf_reg(void)
{
	WERROR werr;
	bool ret = true;
	struct smbconf_ctx *conf_ctx = NULL;
	TALLOC_CTX *mem_ctx = talloc_stackframe();

	printf("test: registry backend\n");

	printf("test: init\n");
	werr = smbconf_init_reg(mem_ctx, &conf_ctx, NULL);
	if (!W_ERROR_IS_OK(werr)) {
		printf("failure: init failed: %s\n", dos_errstr(werr));
		ret = false;
		goto done;
	}
	printf("success: init\n");

	ret &= test_get_includes(conf_ctx);
	ret &= test_set_get_includes(conf_ctx);
	ret &= test_delete_includes(conf_ctx);

	smbconf_shutdown(conf_ctx);

	printf("%s: registry backend\n", ret ? "success" : "failure");

done:
	TALLOC_FREE(mem_ctx);
	return ret;
}
示例#10
0
文件: cmd_netlogon.c 项目: aosm/samba
static WERROR cmd_netlogon_dsr_getdcnameex2(struct rpc_pipe_client *cli,
					    TALLOC_CTX *mem_ctx, int argc,
					    const char **argv)
{
	WERROR result;
	uint32 flags = DS_RETURN_DNS_NAME;
	const char *server_name = cli->cli->desthost;
	const char *domain_name;
	const char *client_account = NULL;
	uint32 mask = 0;
	const char *site_name = NULL;
	struct GUID domain_guid = GUID_zero();
	struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;

	if (argc < 2) {
		fprintf(stderr, "Usage: %s [domainname] [client_account] [acb_mask] [domain_name] [domain_guid] [site_name] [flags]\n", argv[0]);
		return WERR_OK;
	}

	if (argc >= 2)
		client_account = argv[1];

	if (argc >= 3)
		mask = atoi(argv[2]);
	
	if (argc >= 4)
		domain_name = argv[3];

	if (argc >= 5) {
		if (!NT_STATUS_IS_OK(GUID_from_string(argv[4], &domain_guid))) {
			return WERR_NOMEM;
		}
	}

	if (argc >= 6)
		site_name = argv[5];

	if (argc >= 7)
		sscanf(argv[6], "%x", &flags);

	result = rpccli_netlogon_dsr_getdcnameex2(cli, mem_ctx, server_name, 
						  client_account, mask,
						  domain_name, &domain_guid,
						  site_name, flags,
						  &info);

	if (W_ERROR_IS_OK(result)) {
		d_printf("DsGetDcNameEx2 gave\n");
		display_ds_domain_controller_info(mem_ctx, info);
		return WERR_OK;
	}

	printf("rpccli_netlogon_dsr_getdcnameex2 returned %s\n",
	       dos_errstr(result));

	return result;
}
示例#11
0
static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
				TALLOC_CTX *mem_ctx, 
				POLICY_HND *hSCM,
				const char *service, 
				uint32 control,
				uint32 watch_state )
{
	POLICY_HND hService;
	WERROR result = WERR_GENERAL_FAILURE;
	SERVICE_STATUS service_status;
	uint32 state = 0;
	
	/* Open the Service */
	
	result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService, 
		service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) );

	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
		goto done;
	}
	
	/* get the status */

	result = rpccli_svcctl_control_service(pipe_hnd, mem_ctx, &hService, 
		control, &service_status  );
		
	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Control service request failed.  [%s]\n", dos_errstr(result));
		goto done;
	}
	
	/* loop -- checking the state until we are where we want to be */
	
	result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
		
	d_printf("%s service is %s.\n", service, svc_status_string(state));

done:	
	rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService  );
		
	return result;
}	
示例#12
0
enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
					     struct winbindd_cli_state *state)
{
	fstring dcname_slash;
	char *p;
	struct rpc_pipe_client *netlogon_pipe;
	NTSTATUS result;
	WERROR werr;
	unsigned int orig_timeout;

	state->request.domain_name
		[sizeof(state->request.domain_name)-1] = '\0';

	DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid,
		  state->request.domain_name));

	result = cm_connect_netlogon(domain, &netlogon_pipe);

	if (!NT_STATUS_IS_OK(result)) {
		DEBUG(1, ("Can't contact the NETLOGON pipe\n"));
		return WINBINDD_ERROR;
	}

	/* This call can take a long time - allow the server to time out.
	   35 seconds should do it. */

	orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);

	werr = rpccli_netlogon_getanydcname(netlogon_pipe, state->mem_ctx, domain->dcname,
					    state->request.domain_name,
					    dcname_slash);
	/* And restore our original timeout. */
	cli_set_timeout(netlogon_pipe->cli, orig_timeout);

	if (!W_ERROR_IS_OK(werr)) {
		DEBUG(5, ("Error requesting DCname: %s\n", dos_errstr(werr)));
		return WINBINDD_ERROR;
	}

	p = dcname_slash;
	if (*p == '\\') {
		p+=1;
	}
	if (*p == '\\') {
		p+=1;
	}

	fstrcpy(state->response.data.dc_name, p);
	return WINBINDD_OK;
}
示例#13
0
static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid,
						const char *domain_name, 
						struct cli_state *cli,
						struct rpc_pipe_client *pipe_hnd,
						TALLOC_CTX *mem_ctx, 
						int argc,
						const char **argv )
{
	POLICY_HND hSCM, hService;
	WERROR result = WERR_GENERAL_FAILURE;
	fstring servicename;
	SERVICE_STATUS service_status;
	SERVICE_CONFIG config;
	fstring ascii_string;
	
	if (argc != 1 ) {
		d_printf("Usage: net rpc service status <service>\n");
		return NT_STATUS_OK;
	}

	fstrcpy( servicename, argv[0] );

	/* Open the Service Control Manager */
	
	result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE  );
	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
		return werror_to_ntstatus(result);
	}
	
	/* Open the Service */
	
	result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, servicename, 
		(SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG) );

	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
		goto done;
	}
	
	/* get the status */

	result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status  );
	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Query status request failed.  [%s]\n", dos_errstr(result));
		goto done;
	}
	
	d_printf("%s service is %s.\n", servicename, svc_status_string(service_status.state));

	/* get the config */

	result = rpccli_svcctl_query_config(pipe_hnd, mem_ctx, &hService, &config  );
	if ( !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, "Query config request failed.  [%s]\n", dos_errstr(result));
		goto done;
	}

	/* print out the configuration information for the service */

	d_printf("Configuration details:\n");
	d_printf("\tControls Accepted    = 0x%x\n", service_status.controls_accepted);
	d_printf("\tService Type         = 0x%x\n", config.service_type);
	d_printf("\tStart Type           = 0x%x\n", config.start_type);
	d_printf("\tError Control        = 0x%x\n", config.error_control);
	d_printf("\tTag ID               = 0x%x\n", config.tag_id);

	if ( config.executablepath ) {
		rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
		d_printf("\tExecutable Path      = %s\n", ascii_string);
	}

	if ( config.loadordergroup ) {
		rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
		d_printf("\tLoad Order Group     = %s\n", ascii_string);
	}

	if ( config.dependencies ) {
		rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
		d_printf("\tDependencies         = %s\n", ascii_string);
	}

	if ( config.startname ) {
		rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
		d_printf("\tStart Name           = %s\n", ascii_string);
	}

	if ( config.displayname ) {
		rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
		d_printf("\tDisplay Name         = %s\n", ascii_string);
	}

done:	
	rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService  );
	rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM  );

	return werror_to_ntstatus(result);
}	
示例#14
0
WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli,
        TALLOC_CTX *mem_ctx,
        ADS_MODLIST *mods,
        const char *printer)
{
    WERROR result;
    char *printername, *servername;
    REGVAL_CTR *dsdriver_ctr, *dsspooler_ctr;
    uint32 i;
    POLICY_HND pol;

    asprintf(&servername, "\\\\%s", cli->cli->desthost);
    asprintf(&printername, "%s\\%s", servername, printer);
    if (!servername || !printername) {
        DEBUG(3, ("Insufficient memory\n"));
        return WERR_NOMEM;
    }

    result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
                                            "", MAXIMUM_ALLOWED_ACCESS,
                                            servername, cli->cli->user_name, &pol);
    if (!W_ERROR_IS_OK(result)) {
        DEBUG(3, ("Unable to open printer %s, error is %s.\n",
                  printername, dos_errstr(result)));
        SAFE_FREE(printername);
        return result;
    }

    if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) {
        SAFE_FREE(printername);
        return WERR_NOMEM;
    }

    result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);

    if (!W_ERROR_IS_OK(result)) {
        DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
                  printername, dos_errstr(result)));
    } else {
        uint32 num_values = regval_ctr_numvals( dsdriver_ctr );

        /* Have the data we need now, so start building */
        for (i=0; i < num_values; i++) {
            map_regval_to_ads(mem_ctx, mods, dsdriver_ctr->values[i]);
        }
    }

    if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) {
        SAFE_FREE(printername);
        return WERR_NOMEM;
    }

    result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);

    if (!W_ERROR_IS_OK(result)) {
        DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
                  printername, dos_errstr(result)));
    } else {
        uint32 num_values = regval_ctr_numvals( dsspooler_ctr );

        for (i=0; i<num_values; i++) {
            map_regval_to_ads(mem_ctx, mods, dsspooler_ctr->values[i]);
        }
    }

    ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);

    TALLOC_FREE( dsdriver_ctr );
    TALLOC_FREE( dsspooler_ctr );

    rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
    SAFE_FREE(printername);

    return result;
}
WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
			 uint32_t flags,
			 const DOM_SID *sid,
			 struct GROUP_POLICY_OBJECT **gpo_list)
{
	struct gp_registry_context *reg_ctx = NULL;
	WERROR werr = WERR_GENERAL_FAILURE;
	const char *subkeyname = NULL;
	struct GROUP_POLICY_OBJECT *gpo = NULL;
	int count = 0;
	struct registry_key *key = NULL;
	const char *path = NULL;
	const char *gp_state_path = NULL;

	if (!gpo_list) {
		return WERR_INVALID_PARAM;
	}

	ZERO_STRUCTP(gpo_list);

	gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
	if (!gp_state_path) {
		werr = WERR_NOMEM;
		goto done;
	}

	path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
			       KEY_GROUP_POLICY,
			       gp_state_path,
			       "GPO-List");
	if (!path) {
		werr = WERR_NOMEM;
		goto done;
	}

	werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, &reg_ctx);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	while (1) {

		subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
		if (!subkeyname) {
			werr = WERR_NOMEM;
			goto done;
		}

		werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
		if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
			werr = WERR_OK;
			break;
		}
		if (!W_ERROR_IS_OK(werr)) {
			DEBUG(0,("gp_reg_state_read: "
				"gp_read_reg_subkey gave: %s\n",
				dos_errstr(werr)));
			goto done;
		}

		werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
		if (!W_ERROR_IS_OK(werr)) {
			goto done;
		}

		DLIST_ADD(*gpo_list, gpo);
	}

 done:
	gp_free_reg_ctx(reg_ctx);
	return werr;
}
WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
			  uint32_t flags,
			  const char *dn,
			  const struct nt_user_token *token,
			  struct GROUP_POLICY_OBJECT *gpo_list)
{
	struct gp_registry_context *reg_ctx = NULL;
	WERROR werr = WERR_GENERAL_FAILURE;
	const char *subkeyname = NULL;
	struct GROUP_POLICY_OBJECT *gpo;
	int count = 0;
	struct registry_key *key;

	werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
			       token, &reg_ctx);
	W_ERROR_NOT_OK_RETURN(werr);

	werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
			     &token->user_sids[0]);
	if (!W_ERROR_IS_OK(werr)) {
		DEBUG(0,("failed to secure key: %s\n", dos_errstr(werr)));
		goto done;
	}

	werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
	if (!W_ERROR_IS_OK(werr)) {
		DEBUG(0,("failed to store group membership: %s\n", dos_errstr(werr)));
		goto done;
	}

	subkeyname = gp_req_state_path(mem_ctx, &token->user_sids[0], flags);
	if (!subkeyname) {
		werr = WERR_NOMEM;
		goto done;
	}

	werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
	if (!W_ERROR_IS_OK(werr)) {
		DEBUG(0,("failed to delete old state: %s\n", dos_errstr(werr)));
		/* goto done; */
	}

	werr = gp_store_reg_subkey(mem_ctx, subkeyname,
				   reg_ctx->curr_key, &reg_ctx->curr_key);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
				   "Distinguished-Name", dn);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	/* store link list */

	werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
				   reg_ctx->curr_key, &key);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	/* store gpo list */

	werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
				   reg_ctx->curr_key, &reg_ctx->curr_key);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	for (gpo = gpo_list; gpo; gpo = gpo->next) {

		subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
		if (!subkeyname) {
			werr = WERR_NOMEM;
			goto done;
		}

		werr = gp_store_reg_subkey(mem_ctx, subkeyname,
					   reg_ctx->curr_key, &key);
		if (!W_ERROR_IS_OK(werr)) {
			goto done;
		}

		werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
		if (!W_ERROR_IS_OK(werr)) {
			DEBUG(0,("gp_reg_state_store: "
				"gpo_store_reg_gpovals failed for %s: %s\n",
				gpo->display_name, dos_errstr(werr)));
			goto done;
		}
	}
 done:
	gp_free_reg_ctx(reg_ctx);
	return werr;
}