Beispiel #1
0
static NTSTATUS rpc_service_create_internal(struct net_context *c,
					    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)
{
	struct policy_handle hSCM, hService;
	WERROR result = WERR_GENERAL_FAILURE;
	NTSTATUS status;
	const char *ServiceName;
	const char *DisplayName;
	const char *binary_path;

	if (argc != 3) {
		d_printf(_("Usage: net rpc service create <service> "
			   "<displayname> <binarypath>\n"));
		return NT_STATUS_OK;
	}

	/* Open the Service Control Manager */
	status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
					      pipe_hnd->srv_name_slash,
					      NULL,
					      SC_RIGHT_MGR_CREATE_SERVICE,
					      &hSCM,
					      &result);
	if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
		d_fprintf(stderr,
			_("Failed to open Service Control Manager.  [%s]\n"),
			win_errstr(result));
		return werror_to_ntstatus(result);
	}

	/* Create the service */

	ServiceName = argv[0];
	DisplayName = argv[1];
	binary_path = argv[2];

	status = rpccli_svcctl_CreateServiceW(pipe_hnd, mem_ctx,
					      &hSCM,
					      ServiceName,
					      DisplayName,
					      SERVICE_ALL_ACCESS,
					      SERVICE_TYPE_WIN32_OWN_PROCESS,
					      SVCCTL_DEMAND_START,
					      SVCCTL_SVC_ERROR_NORMAL,
					      binary_path,
					      NULL, /* LoadOrderGroupKey */
					      NULL, /* TagId */
					      NULL, /* dependencies */
					      0, /* dependencies_size */
					      NULL, /* service_start_name */
					      NULL, /* password */
					      0, /* password_size */
					      &hService,
					      &result);

	if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, _("Create service request failed.  [%s]\n"),
			win_errstr(result));
		goto done;
	}

	d_printf(_("Successfully created Service: %s\n"), argv[0]);

 done:
	if (is_valid_policy_hnd(&hService)) {
		rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
	}
	if (is_valid_policy_hnd(&hSCM)) {
		rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
	}

	return werror_to_ntstatus(result);
}
Beispiel #2
0
static WERROR cmd_drsuapi_getdcinfo(struct rpc_pipe_client *cli,
				    TALLOC_CTX *mem_ctx, int argc,
				    const char **argv)
{
	NTSTATUS status;
	WERROR werr;

	struct GUID bind_guid;
	struct policy_handle bind_handle;
	struct dcerpc_binding_handle *b = cli->binding_handle;

	const char *domain = NULL;
	int32_t level = 1;
	int32_t level_out;
	union drsuapi_DsGetDCInfoRequest req;
	union drsuapi_DsGetDCInfoCtr ctr;

	if (argc < 2) {
		printf("usage: %s domain [level]\n", argv[0]);
		return WERR_OK;
	}

	domain = argv[1];
	if (argc >= 3) {
		level = atoi(argv[2]);
	}

	GUID_from_string(DRSUAPI_DS_BIND_GUID, &bind_guid);

	status = dcerpc_drsuapi_DsBind(b, mem_ctx,
				       &bind_guid,
				       NULL,
				       &bind_handle,
				       &werr);

	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	if (!W_ERROR_IS_OK(werr)) {
		return werr;
	}

	req.req1.domain_name = domain;
	req.req1.level = level;

	status = dcerpc_drsuapi_DsGetDomainControllerInfo(b, mem_ctx,
							  &bind_handle,
							  1,
							  &req,
							  &level_out,
							  &ctr,
							  &werr);
	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto out;
	}

	if (!W_ERROR_IS_OK(werr)) {
		goto out;
	}

	display_domain_controller_info(level_out, &ctr);
 out:
	if (is_valid_policy_hnd(&bind_handle)) {
		WERROR _werr;
		dcerpc_drsuapi_DsUnbind(b, mem_ctx, &bind_handle, &_werr);
	}

	return werr;
}
Beispiel #3
0
static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
				       TALLOC_CTX *mem_ctx,
				       uint32_t num_sids,
				       const struct dom_sid *sids,
				       uint32_t *pnum_aliases,
				       uint32_t **palias_rids)
{
	struct rpc_pipe_client *samr_pipe;
	struct policy_handle dom_pol;
	uint32_t num_aliases = 0;
	uint32_t *alias_rids = NULL;
	TALLOC_CTX *tmp_ctx;
	NTSTATUS status, result;
	struct dcerpc_binding_handle *b = NULL;

	DEBUG(3,("sam_lookup_useraliases\n"));

	ZERO_STRUCT(dom_pol);

	if (pnum_aliases) {
		*pnum_aliases = 0;
	}

	tmp_ctx = talloc_stackframe();
	if (tmp_ctx == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	b = samr_pipe->binding_handle;

	status = rpc_lookup_useraliases(tmp_ctx,
					samr_pipe,
					&dom_pol,
					num_sids,
					sids,
					&num_aliases,
					&alias_rids);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	if (pnum_aliases) {
		*pnum_aliases = num_aliases;
	}

	if (palias_rids) {
		*palias_rids = talloc_move(mem_ctx, &alias_rids);
	}

done:
	if (b && is_valid_policy_hnd(&dom_pol)) {
		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
	}

	TALLOC_FREE(tmp_ctx);
	return status;
}
Beispiel #4
0
static NTSTATUS rpc_service_delete_internal(struct net_context *c,
					    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)
{
	struct policy_handle hSCM, hService;
	WERROR result = WERR_GENERAL_FAILURE;
	NTSTATUS status;

	if (argc != 1 ) {
		d_printf(_("Usage: net rpc service delete <service>\n"));
		return NT_STATUS_OK;
	}

	/* Open the Service Control Manager */
	status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
					      pipe_hnd->srv_name_slash,
					      NULL,
					      SC_RIGHT_MGR_ENUMERATE_SERVICE,
					      &hSCM,
					      &result);
	if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
		d_fprintf(stderr,
			_("Failed to open Service Control Manager.  [%s]\n"),
			win_errstr(result));
		return werror_to_ntstatus(result);
	}

	/* Open the Service */

	status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
					    &hSCM,
					    argv[0],
					    SERVICE_ALL_ACCESS,
					    &hService,
					    &result);

	if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, _("Failed to open service.  [%s]\n"),
			win_errstr(result));
		goto done;
	}

	/* Delete the Service */

	status = rpccli_svcctl_DeleteService(pipe_hnd, mem_ctx,
					     &hService,
					     &result);

	if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
		d_fprintf(stderr, _("Delete service request failed.  [%s]\n"),
			win_errstr(result));
		goto done;
	}

	d_printf(_("Successfully deleted Service: %s\n"), argv[0]);

 done:
	if (is_valid_policy_hnd(&hService)) {
		rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
	}
	if (is_valid_policy_hnd(&hSCM)) {
		rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
	}

	return werror_to_ntstatus(result);
}
Beispiel #5
0
static bool sync_eventlog_params(TALLOC_CTX *mem_ctx,
				 struct messaging_context *msg_ctx,
				 EVENTLOG_INFO *info)
{
	struct dcerpc_binding_handle *h = NULL;
	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	struct policy_handle hive_hnd, key_hnd;
	uint32_t uiMaxSize = 0;
	uint32_t uiRetention = 0;
	char *path = NULL;
	NTSTATUS status;
	WERROR wresult = WERR_OK;
	char *elogname = info->logname;
	TALLOC_CTX *ctx;
	bool ret = false;

	ctx = talloc_stackframe();
	if (ctx == NULL) {
		return false;
	}

	DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );

	if ( !info->etdb ) {
		DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
		goto done;
	}
	/* set resonable defaults.  512Kb on size and 1 week on time */

	uiMaxSize = 0x80000;
	uiRetention = 604800;

	/* the general idea is to internally open the registry
	   key and retrieve the values.  That way we can continue
	   to use the same fetch/store api that we use in
	   srv_reg_nt.c */
	path = talloc_asprintf(ctx, "%s\\%s", TOP_LEVEL_EVENTLOG_KEY, elogname);
	if (!path) {
		goto done;
	}

	status = dcerpc_winreg_int_hklm_openkey(ctx,
						get_session_info_system(),
						msg_ctx,
						&h,
						path,
						false,
						access_mask,
						&hive_hnd,
						&key_hnd,
						&wresult);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(4,("sync_eventlog_params: Failed to open key [%s] (%s)\n",
			 path, nt_errstr(status)));
		goto done;
	}
	if ( !W_ERROR_IS_OK( wresult ) ) {
		DEBUG( 4,
		       ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
			 path, win_errstr( wresult ) ) );
		goto done;
	}

	status = dcerpc_winreg_query_dword(ctx,
					   h,
					   &key_hnd,
					   "Retention",
					   &uiRetention,
					   &wresult);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(4, ("Failed to query value \"Retention\": %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(wresult)) {
		DEBUG(4, ("Failed to query value \"Retention\": %s\n",
			  win_errstr(wresult)));
		goto done;
	}

	status = dcerpc_winreg_query_dword(ctx,
					   h,
					   &key_hnd,
					   "MaxSize",
					   &uiMaxSize,
					   &wresult);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(4, ("Failed to query value \"Retention\": %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(wresult)) {
		DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
			  win_errstr(wresult)));
		goto done;
	}

	tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
	tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );

	ret = true;

done:
	if (h != NULL) {
		WERROR ignore;

		if (is_valid_policy_hnd(&key_hnd)) {
			dcerpc_winreg_CloseKey(h, ctx, &key_hnd, &ignore);
		}
		if (is_valid_policy_hnd(&hive_hnd)) {
			dcerpc_winreg_CloseKey(h, ctx, &hive_hnd, &ignore);
		}
	}

	TALLOC_FREE(ctx);
	return ret;
}
Beispiel #6
0
static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
				  TALLOC_CTX *mem_ctx,
				  const struct dom_sid *domain_sid,
				  uint32 *rids,
				  size_t num_rids,
				  char **pdomain_name,
				  char ***pnames,
				  enum lsa_SidType **ptypes)
{
	struct rpc_pipe_client *lsa_pipe;
	struct policy_handle lsa_policy;
	enum lsa_SidType *types = NULL;
	char *domain_name = NULL;
	char **names = NULL;
	TALLOC_CTX *tmp_ctx;
	NTSTATUS status, result;
	struct dcerpc_binding_handle *b = NULL;

	DEBUG(3,("sam_rids_to_names for %s\n", domain->name));

	ZERO_STRUCT(lsa_policy);

	/* Paranoia check */
	if (!sid_check_is_builtin(domain_sid) &&
	    !sid_check_is_domain(domain_sid) &&
	    !sid_check_is_unix_users(domain_sid) &&
	    !sid_check_is_unix_groups(domain_sid) &&
	    !sid_check_is_in_wellknown_domain(domain_sid)) {
		DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
			  "lookup SID %s\n", sid_string_dbg(domain_sid)));
		return NT_STATUS_NONE_MAPPED;
	}

	tmp_ctx = talloc_stackframe();
	if (tmp_ctx == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	b = lsa_pipe->binding_handle;

	status = rpc_rids_to_names(tmp_ctx,
				   lsa_pipe,
				   &lsa_policy,
				   domain,
				   domain_sid,
				   rids,
				   num_rids,
				   &domain_name,
				   &names,
				   &types);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	if (pdomain_name) {
		*pdomain_name = talloc_move(mem_ctx, &domain_name);
	}

	if (ptypes) {
		*ptypes = talloc_move(mem_ctx, &types);
	}

	if (pnames) {
		*pnames = talloc_move(mem_ctx, &names);
	}

done:
	if (b && is_valid_policy_hnd(&lsa_policy)) {
		dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
	}

	TALLOC_FREE(tmp_ctx);
	return status;
}
Beispiel #7
0
WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
			  struct NetLocalGroupDel *r)
{
	struct rpc_pipe_client *pipe_cli = NULL;
	NTSTATUS status, result;
	WERROR werr;
	struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
	struct dom_sid2 *domain_sid = NULL;
	struct dcerpc_binding_handle *b = NULL;

	if (!r->in.group_name) {
		return WERR_INVALID_PARAM;
	}

	ZERO_STRUCT(connect_handle);
	ZERO_STRUCT(builtin_handle);
	ZERO_STRUCT(domain_handle);
	ZERO_STRUCT(alias_handle);

	werr = libnetapi_open_pipe(ctx, r->in.server_name,
				   &ndr_table_samr,
				   &pipe_cli);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	b = pipe_cli->binding_handle;

	werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
						  SAMR_ACCESS_LOOKUP_DOMAIN |
						  SAMR_ACCESS_ENUM_DOMAINS,
						  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
						  &connect_handle,
						  &builtin_handle);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
						      &builtin_handle,
						      r->in.group_name,
						      SEC_STD_DELETE,
						      &alias_handle);

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
	}

	if (NT_STATUS_IS_OK(status)) {
		goto delete_alias;
	}

	werr = libnetapi_samr_open_domain(ctx, pipe_cli,
					  SAMR_ACCESS_ENUM_DOMAINS |
					  SAMR_ACCESS_LOOKUP_DOMAIN,
					  SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
					  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
					  &connect_handle,
					  &domain_handle,
					  &domain_sid);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
						      &domain_handle,
						      r->in.group_name,
						      SEC_STD_DELETE,
						      &alias_handle);

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_domain_handle(ctx, &domain_handle);
	}

	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto done;
	}


 delete_alias:
	status = dcerpc_samr_DeleteDomAlias(b, talloc_tos(),
					    &alias_handle,
					    &result);
	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto done;
	}
	if (!NT_STATUS_IS_OK(result)) {
		werr = ntstatus_to_werror(result);
		goto done;
	}

	ZERO_STRUCT(alias_handle);

	werr = WERR_OK;

 done:
	if (is_valid_policy_hnd(&alias_handle)) {
		dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
	}

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_domain_handle(ctx, &domain_handle);
		libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
		libnetapi_samr_close_connect_handle(ctx, &connect_handle);
	}

	return werr;
}
Beispiel #8
0
static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli,
				     TALLOC_CTX *mem_ctx, int argc,
				     const char **argv)
{
	NTSTATUS status;
	struct policy_handle handle, sec_handle;
	struct lsa_String name;
	struct lsa_DATA_BUF_PTR new_val;
	NTTIME new_mtime = 0;
	struct lsa_DATA_BUF_PTR old_val;
	NTTIME old_mtime = 0;
	DATA_BLOB session_key;
	DATA_BLOB new_blob = data_blob_null;
	DATA_BLOB old_blob = data_blob_null;
	char *new_secret, *old_secret;

	if (argc < 2) {
		printf("Usage: %s name\n", argv[0]);
		return NT_STATUS_OK;
	}

	status = rpccli_lsa_open_policy2(cli, mem_ctx,
					 true,
					 SEC_FLAG_MAXIMUM_ALLOWED,
					 &handle);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	init_lsa_String(&name, argv[1]);

	status = rpccli_lsa_OpenSecret(cli, mem_ctx,
				       &handle,
				       name,
				       SEC_FLAG_MAXIMUM_ALLOWED,
				       &sec_handle);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	ZERO_STRUCT(new_val);
	ZERO_STRUCT(old_val);

	status = rpccli_lsa_QuerySecret(cli, mem_ctx,
					&sec_handle,
					&new_val,
					&new_mtime,
					&old_val,
					&old_mtime);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	status = cli_get_session_key(mem_ctx, cli, &session_key);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	if (new_val.buf) {
		new_blob = data_blob_const(new_val.buf->data, new_val.buf->length);
	}
	if (old_val.buf) {
		old_blob = data_blob_const(old_val.buf->data, old_val.buf->length);
	}

	new_secret = sess_decrypt_string(mem_ctx, &new_blob, &session_key);
	old_secret = sess_decrypt_string(mem_ctx, &old_blob, &session_key);
	if (new_secret) {
		d_printf("new secret: %s\n", new_secret);
	}
	if (old_secret) {
		d_printf("old secret: %s\n", old_secret);
	}

 done:
	if (is_valid_policy_hnd(&sec_handle)) {
		rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
	}
	if (is_valid_policy_hnd(&handle)) {
		rpccli_lsa_Close(cli, mem_ctx, &handle);
	}

	return status;
}
Beispiel #9
0
static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
					   struct NetLocalGroupAddMembers *add,
					   struct NetLocalGroupDelMembers *del,
					   struct NetLocalGroupSetMembers *set)
{
	struct NetLocalGroupAddMembers *r = NULL;

	struct rpc_pipe_client *pipe_cli = NULL;
	struct rpc_pipe_client *lsa_pipe = NULL;
	NTSTATUS status, result;
	WERROR werr;
	struct lsa_String lsa_account_name;
	struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
	struct dom_sid2 *domain_sid = NULL;
	struct dom_sid *member_sids = NULL;
	int i = 0, k = 0;

	struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
	struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;

	struct dom_sid *add_sids = NULL;
	struct dom_sid *del_sids = NULL;
	uint32_t num_add_sids = 0;
	uint32_t num_del_sids = 0;
	struct dcerpc_binding_handle *b = NULL;

	if ((!add && !del && !set) || (add && del && set)) {
		return WERR_INVALID_PARAM;
	}

	if (add) {
		r = add;
	}

	if (del) {
		r = (struct NetLocalGroupAddMembers *)del;
	}

	if (set) {
		r = (struct NetLocalGroupAddMembers *)set;
	}

	if (!r->in.group_name) {
		return WERR_INVALID_PARAM;
	}

	switch (r->in.level) {
		case 0:
		case 3:
			break;
		default:
			return WERR_UNKNOWN_LEVEL;
	}

	if (r->in.total_entries == 0 || !r->in.buffer) {
		return WERR_INVALID_PARAM;
	}

	ZERO_STRUCT(connect_handle);
	ZERO_STRUCT(builtin_handle);
	ZERO_STRUCT(domain_handle);
	ZERO_STRUCT(alias_handle);

	member_sids = talloc_zero_array(ctx, struct dom_sid,
					r->in.total_entries);
	W_ERROR_HAVE_NO_MEMORY(member_sids);

	switch (r->in.level) {
		case 0:
			info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
			for (i=0; i < r->in.total_entries; i++) {
				sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
			}
			break;
		case 3:
			info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
			break;
		default:
			break;
	}

	if (r->in.level == 3) {
		werr = libnetapi_open_pipe(ctx, r->in.server_name,
					   &ndr_table_lsarpc,
					   &lsa_pipe);
		if (!W_ERROR_IS_OK(werr)) {
			goto done;
		}

		for (i=0; i < r->in.total_entries; i++) {
			status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
							     info3[i].lgrmi3_domainandname,
							     &member_sids[i]);
			if (!NT_STATUS_IS_OK(status)) {
				werr = ntstatus_to_werror(status);
				goto done;
			}
		}
		TALLOC_FREE(lsa_pipe);
	}

	werr = libnetapi_open_pipe(ctx, r->in.server_name,
				   &ndr_table_samr,
				   &pipe_cli);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	b = pipe_cli->binding_handle;

	werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
						  SAMR_ACCESS_LOOKUP_DOMAIN |
						  SAMR_ACCESS_ENUM_DOMAINS,
						  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
						  &connect_handle,
						  &builtin_handle);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	init_lsa_String(&lsa_account_name, r->in.group_name);

	status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
						      &builtin_handle,
						      r->in.group_name,
						      SAMR_ALIAS_ACCESS_ADD_MEMBER |
						      SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
						      SAMR_ALIAS_ACCESS_GET_MEMBERS |
						      SAMR_ALIAS_ACCESS_LOOKUP_INFO,
						      &alias_handle);

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
	}

	if (NT_STATUS_IS_OK(status)) {
		goto modify_membership;
	}

	werr = libnetapi_samr_open_domain(ctx, pipe_cli,
					  SAMR_ACCESS_ENUM_DOMAINS |
					  SAMR_ACCESS_LOOKUP_DOMAIN,
					  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
					  &connect_handle,
					  &domain_handle,
					  &domain_sid);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
						      &domain_handle,
						      r->in.group_name,
						      SAMR_ALIAS_ACCESS_ADD_MEMBER |
						      SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
						      SAMR_ALIAS_ACCESS_GET_MEMBERS |
						      SAMR_ALIAS_ACCESS_LOOKUP_INFO,
						      &alias_handle);
	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto done;
	}

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_domain_handle(ctx, &domain_handle);
	}

 modify_membership:

	if (add) {
		for (i=0; i < r->in.total_entries; i++) {
			status = add_sid_to_array_unique(ctx, &member_sids[i],
							 &add_sids,
							 &num_add_sids);
			if (!NT_STATUS_IS_OK(status)) {
				werr = ntstatus_to_werror(status);
				goto done;
			}
		}
	}

	if (del) {
		for (i=0; i < r->in.total_entries; i++) {
			status = add_sid_to_array_unique(ctx, &member_sids[i],
							 &del_sids,
							 &num_del_sids);
			if (!NT_STATUS_IS_OK(status)) {
				werr = ntstatus_to_werror(status);
				goto done;
			}
		}
	}

	if (set) {

		struct lsa_SidArray current_sids;

		status = dcerpc_samr_GetMembersInAlias(b, talloc_tos(),
						       &alias_handle,
						       &current_sids,
						       &result);
		if (!NT_STATUS_IS_OK(status)) {
			werr = ntstatus_to_werror(status);
			goto done;
		}
		if (!NT_STATUS_IS_OK(result)) {
			werr = ntstatus_to_werror(result);
			goto done;
		}

		/* add list */

		for (i=0; i < r->in.total_entries; i++) {
			bool already_member = false;
			for (k=0; k < current_sids.num_sids; k++) {
				if (dom_sid_equal(&member_sids[i],
					      current_sids.sids[k].sid)) {
					already_member = true;
					break;
				}
			}
			if (!already_member) {
				status = add_sid_to_array_unique(ctx,
					&member_sids[i],
					&add_sids, &num_add_sids);
				if (!NT_STATUS_IS_OK(status)) {
					werr = ntstatus_to_werror(status);
					goto done;
				}
			}
		}

		/* del list */

		for (k=0; k < current_sids.num_sids; k++) {
			bool keep_member = false;
			for (i=0; i < r->in.total_entries; i++) {
				if (dom_sid_equal(&member_sids[i],
					      current_sids.sids[k].sid)) {
					keep_member = true;
					break;
				}
			}
			if (!keep_member) {
				status = add_sid_to_array_unique(ctx,
						current_sids.sids[k].sid,
						&del_sids, &num_del_sids);
				if (!NT_STATUS_IS_OK(status)) {
					werr = ntstatus_to_werror(status);
					goto done;
				}
			}
		}
	}

	/* add list */

	for (i=0; i < num_add_sids; i++) {
		status = dcerpc_samr_AddAliasMember(b, talloc_tos(),
						    &alias_handle,
						    &add_sids[i],
						    &result);
		if (!NT_STATUS_IS_OK(status)) {
			werr = ntstatus_to_werror(status);
			goto done;
		}
		if (!NT_STATUS_IS_OK(result)) {
			werr = ntstatus_to_werror(result);
			goto done;
		}
	}

	/* del list */

	for (i=0; i < num_del_sids; i++) {
		status = dcerpc_samr_DeleteAliasMember(b, talloc_tos(),
						       &alias_handle,
						       &del_sids[i],
						       &result);
		if (!NT_STATUS_IS_OK(status)) {
			werr = ntstatus_to_werror(status);
			goto done;
		}
		if (!NT_STATUS_IS_OK(result)) {
			werr = ntstatus_to_werror(result);
			goto done;
		}
	}

	werr = WERR_OK;

 done:
	if (b && is_valid_policy_hnd(&alias_handle)) {
		dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
	}

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_domain_handle(ctx, &domain_handle);
		libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
		libnetapi_samr_close_connect_handle(ctx, &connect_handle);
	}

	return werr;
}
Beispiel #10
0
WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
			  struct NetLocalGroupAdd *r)
{
	struct rpc_pipe_client *pipe_cli = NULL;
	NTSTATUS status, result;
	WERROR werr;
	struct lsa_String lsa_account_name;
	struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
	struct dom_sid2 *domain_sid = NULL;
	uint32_t rid;
	struct dcerpc_binding_handle *b = NULL;

	struct LOCALGROUP_INFO_0 *info0 = NULL;
	struct LOCALGROUP_INFO_1 *info1 = NULL;

	const char *alias_name = NULL;

	if (!r->in.buffer) {
		return WERR_INVALID_PARAM;
	}

	ZERO_STRUCT(connect_handle);
	ZERO_STRUCT(builtin_handle);
	ZERO_STRUCT(domain_handle);
	ZERO_STRUCT(alias_handle);

	switch (r->in.level) {
		case 0:
			info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
			alias_name = info0->lgrpi0_name;
			break;
		case 1:
			info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
			alias_name = info1->lgrpi1_name;
			break;
		default:
			werr = WERR_UNKNOWN_LEVEL;
			goto done;
	}

	werr = libnetapi_open_pipe(ctx, r->in.server_name,
				   &ndr_table_samr,
				   &pipe_cli);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	b = pipe_cli->binding_handle;

	werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
						  SAMR_ACCESS_LOOKUP_DOMAIN |
						  SAMR_ACCESS_ENUM_DOMAINS,
						  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
						  &connect_handle,
						  &builtin_handle);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
						      &builtin_handle,
						      alias_name,
						      SAMR_ALIAS_ACCESS_LOOKUP_INFO,
						      &alias_handle);
	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
	}

	if (NT_STATUS_IS_OK(status)) {
		werr = WERR_ALIAS_EXISTS;
		goto done;
	}

	werr = libnetapi_samr_open_domain(ctx, pipe_cli,
					  SAMR_ACCESS_ENUM_DOMAINS |
					  SAMR_ACCESS_LOOKUP_DOMAIN,
					  SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
					  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
					  &connect_handle,
					  &domain_handle,
					  &domain_sid);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	init_lsa_String(&lsa_account_name, alias_name);

	status = dcerpc_samr_CreateDomAlias(b, talloc_tos(),
					    &domain_handle,
					    &lsa_account_name,
					    SEC_STD_DELETE |
					    SAMR_ALIAS_ACCESS_SET_INFO,
					    &alias_handle,
					    &rid,
					    &result);
	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto done;
	}
	if (!NT_STATUS_IS_OK(result)) {
		werr = ntstatus_to_werror(result);
		goto done;
	}


	if (r->in.level == 1 && info1->lgrpi1_comment) {

		union samr_AliasInfo alias_info;

		init_lsa_String(&alias_info.description, info1->lgrpi1_comment);

		status = dcerpc_samr_SetAliasInfo(b, talloc_tos(),
						  &alias_handle,
						  ALIASINFODESCRIPTION,
						  &alias_info,
						  &result);
		if (!NT_STATUS_IS_OK(status)) {
			werr = ntstatus_to_werror(status);
			goto done;
		}
		if (!NT_STATUS_IS_OK(result)) {
			werr = ntstatus_to_werror(result);
			goto done;
		}
	}

	werr = WERR_OK;

 done:
	if (is_valid_policy_hnd(&alias_handle)) {
		dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
	}

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_domain_handle(ctx, &domain_handle);
		libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
		libnetapi_samr_close_connect_handle(ctx, &connect_handle);
	}

	return werr;
}
WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
			      struct NetLocalGroupGetInfo *r)
{
	struct cli_state *cli = NULL;
	struct rpc_pipe_client *pipe_cli = NULL;
	NTSTATUS status;
	WERROR werr;
	struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
	struct dom_sid2 *domain_sid = NULL;
	union samr_AliasInfo *alias_info = NULL;
	uint32_t entries_read = 0;

	if (!r->in.group_name) {
		return WERR_INVALID_PARAM;
	}

	switch (r->in.level) {
		case 0:
		case 1:
		case 1002:
			break;
		default:
			return WERR_UNKNOWN_LEVEL;
	}

	ZERO_STRUCT(connect_handle);
	ZERO_STRUCT(builtin_handle);
	ZERO_STRUCT(domain_handle);
	ZERO_STRUCT(alias_handle);

	werr = libnetapi_open_pipe(ctx, r->in.server_name,
				   &ndr_table_samr.syntax_id,
				   &cli,
				   &pipe_cli);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
						  SAMR_ACCESS_LOOKUP_DOMAIN |
						  SAMR_ACCESS_ENUM_DOMAINS,
						  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
						  &connect_handle,
						  &builtin_handle);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
						      &builtin_handle,
						      r->in.group_name,
						      SAMR_ALIAS_ACCESS_LOOKUP_INFO,
						      &alias_handle);

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
	}

	if (NT_STATUS_IS_OK(status)) {
		goto query_alias;
	}

	werr = libnetapi_samr_open_domain(ctx, pipe_cli,
					  SAMR_ACCESS_ENUM_DOMAINS |
					  SAMR_ACCESS_LOOKUP_DOMAIN,
					  SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
					  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
					  &connect_handle,
					  &domain_handle,
					  &domain_sid);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
						      &domain_handle,
						      r->in.group_name,
						      SAMR_ALIAS_ACCESS_LOOKUP_INFO,
						      &alias_handle);

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_domain_handle(ctx, &domain_handle);
	}

	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto done;
	}

 query_alias:
	status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx,
					    &alias_handle,
					    ALIASINFOALL,
					    &alias_info);
	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto done;
	}

	werr = map_alias_info_to_buffer(ctx,
					r->in.group_name,
					&alias_info->all,
					r->in.level, &entries_read,
					r->out.buffer);

 done:
	if (!cli) {
		return werr;
	}

	if (is_valid_policy_hnd(&alias_handle)) {
		rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
	}

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_domain_handle(ctx, &domain_handle);
		libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
		libnetapi_samr_close_connect_handle(ctx, &connect_handle);
	}

	return werr;
}
Beispiel #12
0
bool svcctl_init_winreg(struct messaging_context *msg_ctx)
{
	struct dcerpc_binding_handle *h = NULL;
	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	struct policy_handle hive_hnd, key_hnd;
	const char **service_list = lp_svcctl_list();
	const char **subkeys = NULL;
	uint32_t num_subkeys = 0;
	char *key = NULL;
	uint32_t i;
	NTSTATUS status;
	WERROR result = WERR_OK;
	bool ok = false;
	TALLOC_CTX *tmp_ctx;

	tmp_ctx = talloc_stackframe();
	if (tmp_ctx == NULL) {
		return false;
	}

	DEBUG(3, ("Initialise the svcctl registry keys if needed.\n"));

	ZERO_STRUCT(hive_hnd);
	ZERO_STRUCT(key_hnd);

	key = talloc_strdup(tmp_ctx, TOP_LEVEL_SERVICES_KEY);
	if (key == NULL) {
		goto done;
	}

	result = regdb_open();
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(10, ("regdb_open failed: %s\n",
			   win_errstr(result)));
		goto done;
	}
	result = regdb_transaction_start();
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(10, ("regdb_transaction_start failed: %s\n",
			   win_errstr(result)));
		goto done;
	}

	status = dcerpc_winreg_int_hklm_openkey(tmp_ctx,
						get_session_info_system(),
						msg_ctx,
						&h,
						key,
						false,
						access_mask,
						&hive_hnd,
						&key_hnd,
						&result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg: Could not open %s - %s\n",
			  key, nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg: Could not open %s - %s\n",
			  key, win_errstr(result)));
		goto done;
	}

	/* get all subkeys */
	status = dcerpc_winreg_enum_keys(tmp_ctx,
					 h,
					 &key_hnd,
					 &num_subkeys,
					 &subkeys,
					 &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg: Could enum keys at %s - %s\n",
			  key, nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg: Could enum keys at %s - %s\n",
			  key, win_errstr(result)));
		goto done;
	}

	for (i = 0; builtin_svcs[i].servicename != NULL; i++) {
		uint32_t j;
		bool skip = false;

		for (j = 0; j < num_subkeys; j++) {
			if (strequal(subkeys[i], builtin_svcs[i].servicename)) {
				skip = true;
			}
		}

		if (skip) {
			continue;
		}

		ok = svcctl_add_service(tmp_ctx,
					h,
					&hive_hnd,
					key,
					access_mask,
					builtin_svcs[i].servicename);
		if (!ok) {
			goto done;
		}
	}

	for (i = 0; service_list && service_list[i]; i++) {
		uint32_t j;
		bool skip = false;

		for (j = 0; j < num_subkeys; j++) {
			if (strequal(subkeys[i], service_list[i])) {
				skip = true;
			}
		}

		if (skip) {
			continue;
		}

		ok = svcctl_add_service(tmp_ctx,
					h,
					&hive_hnd,
					key,
					access_mask,
					service_list[i]);
		if (is_valid_policy_hnd(&key_hnd)) {
			dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
		}
		ZERO_STRUCT(key_hnd);

		if (!ok) {
			goto done;
		}
	}

done:
	if (is_valid_policy_hnd(&key_hnd)) {
		dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
	}

	if (ok) {
		result = regdb_transaction_commit();
		if (!W_ERROR_IS_OK(result)) {
			DEBUG(10, ("regdb_transaction_commit failed: %s\n",
				   win_errstr(result)));
		}
	} else {
		result = regdb_transaction_cancel();
		if (!W_ERROR_IS_OK(result)) {
			DEBUG(10, ("regdb_transaction_cancel failed: %s\n",
				   win_errstr(result)));
		}
	}
	regdb_close();
	talloc_free(tmp_ctx);
	return ok;
}
Beispiel #13
0
static bool svcctl_add_service(TALLOC_CTX *mem_ctx,
			       struct dcerpc_binding_handle *h,
			       struct policy_handle *hive_hnd,
			       const char *key,
			       uint32_t access_mask,
			       const char *name)
{
	enum winreg_CreateAction action = REG_ACTION_NONE;
	struct security_descriptor *sd = NULL;
	struct policy_handle key_hnd;
	struct winreg_String wkey;
	struct winreg_String wkeyclass;
	char *description = NULL;
	char *dname = NULL;
	char *ipath = NULL;
	bool ok = false;
	uint32_t i;
	NTSTATUS status;
	WERROR result = WERR_OK;

	ZERO_STRUCT(key_hnd);

	ZERO_STRUCT(wkey);
	wkey.name = talloc_asprintf(mem_ctx, "%s\\%s", key, name);
	if (wkey.name == NULL) {
		goto done;
	}

	ZERO_STRUCT(wkeyclass);
	wkeyclass.name = "";

	status = dcerpc_winreg_CreateKey(h,
					 mem_ctx,
					 hive_hnd,
					 wkey,
					 wkeyclass,
					 0,
					 access_mask,
					 NULL,
					 &key_hnd,
					 &action,
					 &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n",
			wkey.name, nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n",
			wkey.name, win_errstr(result)));
		goto done;
	}

	/* These values are hardcoded in all QueryServiceConfig() replies.
	   I'm just storing them here for cosmetic purposes */
	status = dcerpc_winreg_set_dword(mem_ctx,
					 h,
					 &key_hnd,
					 "Start",
					 SVCCTL_AUTO_START,
					 &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  win_errstr(result)));
		goto done;
	}

	status = dcerpc_winreg_set_dword(mem_ctx,
					 h,
					 &key_hnd,
					 "Type",
					 SERVICE_TYPE_WIN32_OWN_PROCESS,
					 &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  win_errstr(result)));
		goto done;
	}

	status = dcerpc_winreg_set_dword(mem_ctx,
					 h,
					 &key_hnd,
					 "ErrorControl",
					 SVCCTL_SVC_ERROR_NORMAL,
					 &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  win_errstr(result)));
		goto done;
	}

	status = dcerpc_winreg_set_sz(mem_ctx,
				      h,
				      &key_hnd,
				      "ObjectName",
				      "LocalSystem",
				      &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  win_errstr(result)));
		goto done;
	}

	/*
	 * Special considerations for internal services and the DisplayName
	 * value.
	 */
	for (i = 0; builtin_svcs[i].servicename; i++) {
		if (strequal(name, builtin_svcs[i].servicename)) {
			ipath = talloc_asprintf(mem_ctx,
						"%s/%s/%s",
						get_dyn_MODULESDIR(),
						SVCCTL_SCRIPT_DIR,
						builtin_svcs[i].daemon);
			description = talloc_strdup(mem_ctx, builtin_svcs[i].description);
			dname = talloc_strdup(mem_ctx, builtin_svcs[i].dispname);
			break;
		}
	}

	/* Default to an external service if we haven't found a match */
	if (builtin_svcs[i].servicename == NULL) {
		struct rcinit_file_information *init_info = NULL;
		char *dispname = NULL;

		ipath = talloc_asprintf(mem_ctx,
					"%s/%s/%s",
					get_dyn_MODULESDIR(),
					SVCCTL_SCRIPT_DIR,
					name);

		/* lookup common unix display names */
		dispname = svcctl_get_common_service_dispname(mem_ctx, name);
		dname = talloc_strdup(mem_ctx, dispname ? dispname : "");

		/* get info from init file itself */
		if (read_init_file(mem_ctx, name, &init_info)) {
			description = talloc_strdup(mem_ctx,
						    init_info->description);
		} else {
			description = talloc_strdup(mem_ctx,
						    "External Unix Service");
		}
	}

	if (ipath == NULL || dname == NULL || description == NULL) {
		goto done;
	}

	status = dcerpc_winreg_set_sz(mem_ctx,
				      h,
				      &key_hnd,
				      "DisplayName",
				      dname,
				      &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  win_errstr(result)));
		goto done;
	}

	status = dcerpc_winreg_set_sz(mem_ctx,
				      h,
				      &key_hnd,
				      "ImagePath",
				      ipath,
				      &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  win_errstr(result)));
		goto done;
	}

	status = dcerpc_winreg_set_sz(mem_ctx,
				      h,
				      &key_hnd,
				      "Description",
				      description,
				      &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  win_errstr(result)));
		goto done;
	}

	sd = svcctl_gen_service_sd(mem_ctx);
	if (sd == NULL) {
		DEBUG(0, ("add_new_svc_name: Failed to create default "
			  "sec_desc!\n"));
		goto done;
	}

	if (is_valid_policy_hnd(&key_hnd)) {
		dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &result);
	}
	ZERO_STRUCT(key_hnd);

	ZERO_STRUCT(wkey);
	wkey.name = talloc_asprintf(mem_ctx, "%s\\%s\\Security", key, name);
	if (wkey.name == NULL) {
		result = WERR_NOMEM;
		goto done;
	}

	ZERO_STRUCT(wkeyclass);
	wkeyclass.name = "";

	status = dcerpc_winreg_CreateKey(h,
					 mem_ctx,
					 hive_hnd,
					 wkey,
					 wkeyclass,
					 0,
					 access_mask,
					 NULL,
					 &key_hnd,
					 &action,
					 &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n",
			wkey.name, nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n",
			wkey.name, win_errstr(result)));
		goto done;
	}

	status = dcerpc_winreg_set_sd(mem_ctx,
				      h,
				      &key_hnd,
				      "Security",
				      sd,
				      &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
			  win_errstr(result)));
		goto done;
	}

	ok = true;
done:
	if (is_valid_policy_hnd(&key_hnd)) {
		dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &result);
	}

	return ok;
}
Beispiel #14
0
static WERROR cmd_drsuapi_writeaccountspn(struct rpc_pipe_client *cli,
					  TALLOC_CTX *mem_ctx, int argc,
					  const char **argv)
{
	NTSTATUS status;
	WERROR werr;

	struct GUID bind_guid;
	struct policy_handle bind_handle;
	struct dcerpc_binding_handle *b = cli->binding_handle;
	struct drsuapi_DsNameString *spn_names = NULL;

	int i = 0;
	uint32_t level_out;
	union drsuapi_DsWriteAccountSpnRequest req;
	union drsuapi_DsWriteAccountSpnResult result;

	if (argc < 4) {
		printf("usage: %s [add|replace|delete] dn [spn_names]+\n", argv[0]);
		return WERR_OK;
	}

	req.req1.unknown1 = 0;  /* Unused, must be 0 */
	req.req1.object_dn = argv[2];
	req.req1.count = argc - 3;

	if (strcmp(argv[1], "add") == 0) {
		req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
	} else if (strcmp(argv[1], "replace") == 0) {
		req.req1.operation = DRSUAPI_DS_SPN_OPERATION_REPLACE;
	} else if (strcmp(argv[1], "delete") == 0) {
		req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
	} else {
		printf("usage: %s [add|replace|delete] dn [spn_names]+\n", argv[0]);
		return WERR_OK;
	}

	spn_names = talloc_zero_array(mem_ctx,
				      struct drsuapi_DsNameString,
				      req.req1.count);
	W_ERROR_HAVE_NO_MEMORY(spn_names);

	for (i=0; i<req.req1.count; i++) {
		spn_names[i].str = argv[i + 3];
	}

	req.req1.spn_names = spn_names;

	GUID_from_string(DRSUAPI_DS_BIND_GUID, &bind_guid);

	status = dcerpc_drsuapi_DsBind(b, mem_ctx,
				       &bind_guid,
				       NULL,
				       &bind_handle,
				       &werr);

	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	if (!W_ERROR_IS_OK(werr)) {
		return werr;
	}

	status = dcerpc_drsuapi_DsWriteAccountSpn(b, mem_ctx,
						  &bind_handle,
						  1,
						  &req,
						  &level_out,
						  &result,
						  &werr);

	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto out;
	}

	if (!W_ERROR_IS_OK(werr)) {
		goto out;
	}

 out:
	if (is_valid_policy_hnd(&bind_handle)) {
		WERROR _werr;
		dcerpc_drsuapi_DsUnbind(b, mem_ctx, &bind_handle, &_werr);
	}

	return werr;
}
Beispiel #15
0
WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
			      struct NetLocalGroupSetInfo *r)
{
	struct rpc_pipe_client *pipe_cli = NULL;
	NTSTATUS status, result;
	WERROR werr;
	struct lsa_String lsa_account_name;
	struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
	struct dom_sid2 *domain_sid = NULL;
	enum samr_AliasInfoEnum alias_level = 0;
	union samr_AliasInfo *alias_info = NULL;
	struct dcerpc_binding_handle *b = NULL;

	if (!r->in.group_name) {
		return WERR_INVALID_PARAM;
	}

	switch (r->in.level) {
		case 0:
		case 1:
		case 1002:
			break;
		default:
			return WERR_UNKNOWN_LEVEL;
	}

	ZERO_STRUCT(connect_handle);
	ZERO_STRUCT(builtin_handle);
	ZERO_STRUCT(domain_handle);
	ZERO_STRUCT(alias_handle);

	werr = libnetapi_open_pipe(ctx, r->in.server_name,
				   &ndr_table_samr,
				   &pipe_cli);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	b = pipe_cli->binding_handle;

	werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
						  SAMR_ACCESS_LOOKUP_DOMAIN |
						  SAMR_ACCESS_ENUM_DOMAINS,
						  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
						  &connect_handle,
						  &builtin_handle);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	init_lsa_String(&lsa_account_name, r->in.group_name);

	status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
						      &builtin_handle,
						      r->in.group_name,
						      SAMR_ALIAS_ACCESS_SET_INFO,
						      &alias_handle);

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
	}

	if (NT_STATUS_IS_OK(status)) {
		goto set_alias;
	}

	werr = libnetapi_samr_open_domain(ctx, pipe_cli,
					  SAMR_ACCESS_ENUM_DOMAINS |
					  SAMR_ACCESS_LOOKUP_DOMAIN,
					  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
					  &connect_handle,
					  &domain_handle,
					  &domain_sid);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
						      &domain_handle,
						      r->in.group_name,
						      SAMR_ALIAS_ACCESS_SET_INFO,
						      &alias_handle);
	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto done;
	}

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_domain_handle(ctx, &domain_handle);
	}

 set_alias:

	werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
					&alias_level, &alias_info);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	status = dcerpc_samr_SetAliasInfo(b, talloc_tos(),
					  &alias_handle,
					  alias_level,
					  alias_info,
					  &result);
	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto done;
	}
	if (!NT_STATUS_IS_OK(result)) {
		werr = ntstatus_to_werror(result);
		goto done;
	}

	werr = WERR_OK;

 done:
	if (is_valid_policy_hnd(&alias_handle)) {
		dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
	}

	if (ctx->disable_policy_handle_cache) {
		libnetapi_samr_close_domain_handle(ctx, &domain_handle);
		libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
		libnetapi_samr_close_connect_handle(ctx, &connect_handle);
	}

	return werr;
}
Beispiel #16
0
static WERROR cmd_drsuapi_cracknames(struct rpc_pipe_client *cli,
				     TALLOC_CTX *mem_ctx, int argc,
				     const char **argv)
{
	NTSTATUS status;
	WERROR werr;
	int i;

	struct GUID bind_guid;
	struct policy_handle bind_handle;
	struct dcerpc_binding_handle *b = cli->binding_handle;

	union drsuapi_DsNameCtr ctr;

	if (argc < 2) {
		printf("usage: %s name\n", argv[0]);
		return WERR_OK;
	}

	GUID_from_string(DRSUAPI_DS_BIND_GUID, &bind_guid);

	status = dcerpc_drsuapi_DsBind(b, mem_ctx,
				       &bind_guid,
				       NULL,
				       &bind_handle,
				       &werr);

	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	if (!W_ERROR_IS_OK(werr)) {
		return werr;
	}

	werr = cracknames(cli, mem_ctx,
			  &bind_handle,
			  DRSUAPI_DS_NAME_FORMAT_UNKNOWN,
			  DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
			  1,
			  argv+1,
			  &ctr);

	if (!W_ERROR_IS_OK(werr)) {
		goto out;
	}

	for (i=0; i < ctr.ctr1->count; i++) {
		printf("status: %d\n",
			ctr.ctr1->array[i].status);
		printf("dns_domain_name: %s\n",
			ctr.ctr1->array[i].dns_domain_name);
		printf("result_name: %s\n",
			ctr.ctr1->array[i].result_name);
	}

 out:
	if (is_valid_policy_hnd(&bind_handle)) {
		WERROR _werr;
		dcerpc_drsuapi_DsUnbind(b, mem_ctx, &bind_handle, &_werr);
	}

	return werr;
}
Beispiel #17
0
/* Lookup group membership given a rid.   */
static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
				    TALLOC_CTX *mem_ctx,
				    const struct dom_sid *group_sid,
				    enum lsa_SidType type,
				    uint32_t *pnum_names,
				    struct dom_sid **psid_mem,
				    char ***pnames,
				    uint32_t **pname_types)
{
	struct rpc_pipe_client *samr_pipe;
	struct policy_handle dom_pol;

	uint32_t num_names = 0;
	struct dom_sid *sid_mem = NULL;
	char **names = NULL;
	uint32_t *name_types = NULL;

	TALLOC_CTX *tmp_ctx;
	NTSTATUS status, result;
	struct dcerpc_binding_handle *b = NULL;

	DEBUG(3,("sam_lookup_groupmem\n"));

	ZERO_STRUCT(dom_pol);

	/* Paranoia check */
	if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
		/* There's no groups, only aliases in BUILTIN */
		return NT_STATUS_NO_SUCH_GROUP;
	}

	if (pnum_names) {
		pnum_names = 0;
	}

	tmp_ctx = talloc_stackframe();
	if (tmp_ctx == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	b = samr_pipe->binding_handle;

	status = rpc_lookup_groupmem(tmp_ctx,
				     samr_pipe,
				     &dom_pol,
				     domain->name,
				     &domain->sid,
				     group_sid,
				     type,
				     &num_names,
				     &sid_mem,
				     &names,
				     &name_types);

	if (pnum_names) {
		*pnum_names = num_names;
	}

	if (pnames) {
		*pnames = talloc_move(mem_ctx, &names);
	}

	if (pname_types) {
		*pname_types = talloc_move(mem_ctx, &name_types);
	}

	if (psid_mem) {
		*psid_mem = talloc_move(mem_ctx, &sid_mem);
	}

done:
	if (b && is_valid_policy_hnd(&dom_pol)) {
		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
	}

	TALLOC_FREE(tmp_ctx);
	return status;
}
Beispiel #18
0
static NTSTATUS cmd_lsa_set_secret(struct rpc_pipe_client *cli,
				   TALLOC_CTX *mem_ctx, int argc,
				   const char **argv)
{
	NTSTATUS status;
	struct policy_handle handle, sec_handle;
	struct lsa_String name;
	struct lsa_DATA_BUF new_val;
	struct lsa_DATA_BUF old_val;
	DATA_BLOB enc_key;
	DATA_BLOB session_key;

	if (argc < 3) {
		printf("Usage: %s name secret\n", argv[0]);
		return NT_STATUS_OK;
	}

	status = rpccli_lsa_open_policy2(cli, mem_ctx,
					 true,
					 SEC_FLAG_MAXIMUM_ALLOWED,
					 &handle);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	init_lsa_String(&name, argv[1]);

	status = rpccli_lsa_OpenSecret(cli, mem_ctx,
				       &handle,
				       name,
				       SEC_FLAG_MAXIMUM_ALLOWED,
				       &sec_handle);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	ZERO_STRUCT(new_val);
	ZERO_STRUCT(old_val);

	status = cli_get_session_key(mem_ctx, cli, &session_key);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	enc_key = sess_encrypt_string(argv[2], &session_key);

	new_val.length = enc_key.length;
	new_val.size = enc_key.length;
	new_val.data = enc_key.data;

	status = rpccli_lsa_SetSecret(cli, mem_ctx,
				      &sec_handle,
				      &new_val,
				      NULL);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

 done:
	if (is_valid_policy_hnd(&sec_handle)) {
		rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
	}
	if (is_valid_policy_hnd(&handle)) {
		rpccli_lsa_Close(cli, mem_ctx, &handle);
	}

	return status;
}
Beispiel #19
0
bool svcctl_set_secdesc(struct messaging_context *msg_ctx,
			const struct auth_session_info *session_info,
			const char *name,
			struct security_descriptor *sd)
{
	struct dcerpc_binding_handle *h = NULL;
	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	struct policy_handle hive_hnd;
	struct policy_handle key_hnd = { 0, };
	char *key = NULL;
	bool ok = false;
	TALLOC_CTX *tmp_ctx;
	NTSTATUS status;
	WERROR result = WERR_OK;

	tmp_ctx = talloc_stackframe();
	if (tmp_ctx == NULL) {
		return false;
	}

	key = talloc_asprintf(tmp_ctx, "%s\\%s", TOP_LEVEL_SERVICES_KEY, name);
	if (key == NULL) {
		goto done;
	}

	status = dcerpc_winreg_int_hklm_openkey(tmp_ctx,
						session_info,
						msg_ctx,
						&h,
						key,
						false,
						access_mask,
						&hive_hnd,
						&key_hnd,
						&result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
			  key, nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(result)) {
		DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
			  key, win_errstr(result)));
		goto done;
	}

	if (is_valid_policy_hnd(&key_hnd)) {
		dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
	}

	{
		enum winreg_CreateAction action = REG_ACTION_NONE;
		struct winreg_String wkey = { 0, };
		struct winreg_String wkeyclass;

		wkey.name = talloc_asprintf(tmp_ctx, "%s\\Security", key);
		if (wkey.name == NULL) {
			result = WERR_NOT_ENOUGH_MEMORY;
			goto done;
		}

		ZERO_STRUCT(wkeyclass);
		wkeyclass.name = "";

		status = dcerpc_winreg_CreateKey(h,
						 tmp_ctx,
						 &hive_hnd,
						 wkey,
						 wkeyclass,
						 0,
						 access_mask,
						 NULL,
						 &key_hnd,
						 &action,
						 &result);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(2, ("svcctl_set_secdesc: Could not create key %s: %s\n",
				wkey.name, nt_errstr(status)));
			goto done;
		}
		if (!W_ERROR_IS_OK(result)) {
			DEBUG(2, ("svcctl_set_secdesc: Could not create key %s: %s\n",
				wkey.name, win_errstr(result)));
			goto done;
		}

		status = dcerpc_winreg_set_sd(tmp_ctx,
					      h,
					      &key_hnd,
					      "Security",
					      sd,
					      &result);
		if (!NT_STATUS_IS_OK(status)) {
			goto done;
		}
		if (!W_ERROR_IS_OK(result)) {
			goto done;
		}
	}

	ok = true;

done:
	if (is_valid_policy_hnd(&key_hnd)) {
		dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
	}

	talloc_free(tmp_ctx);
	return ok;
}