diff options
| -rw-r--r-- | source3/Makefile.in | 1 | ||||
| -rw-r--r-- | source3/librpc/gen_ndr/cli_wbint.c | 161 | ||||
| -rw-r--r-- | source3/librpc/gen_ndr/cli_wbint.h | 12 | ||||
| -rw-r--r-- | source3/librpc/gen_ndr/ndr_wbint.c | 87 | ||||
| -rw-r--r-- | source3/librpc/gen_ndr/ndr_wbint.h | 5 | ||||
| -rw-r--r-- | source3/librpc/gen_ndr/srv_wbint.c | 93 | ||||
| -rw-r--r-- | source3/librpc/gen_ndr/srv_wbint.h | 2 | ||||
| -rw-r--r-- | source3/librpc/gen_ndr/wbint.h | 13 | ||||
| -rw-r--r-- | source3/librpc/idl/wbint.idl | 5 | ||||
| -rw-r--r-- | source3/winbindd/winbindd.c | 6 | ||||
| -rw-r--r-- | source3/winbindd/winbindd_async.c | 58 | ||||
| -rw-r--r-- | source3/winbindd/winbindd_domain.c | 4 | ||||
| -rw-r--r-- | source3/winbindd/winbindd_dual_srv.c | 40 | ||||
| -rw-r--r-- | source3/winbindd/winbindd_lookuprids.c | 197 | ||||
| -rw-r--r-- | source3/winbindd/winbindd_proto.h | 9 | ||||
| -rw-r--r-- | source3/winbindd/winbindd_sid.c | 30 | 
16 files changed, 623 insertions, 100 deletions
| diff --git a/source3/Makefile.in b/source3/Makefile.in index ac1b705b62..6febc971a1 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1199,6 +1199,7 @@ WINBINDD_OBJ1 = \  		winbindd/winbindd_getgrgid.o \  		winbindd/winbindd_getgrnam.o \  		winbindd/winbindd_getusersids.o \ +		winbindd/winbindd_lookuprids.o \  		winbindd/winbindd_setpwent.o \  		winbindd/winbindd_getpwent.o \  		winbindd/winbindd_endpwent.o \ diff --git a/source3/librpc/gen_ndr/cli_wbint.c b/source3/librpc/gen_ndr/cli_wbint.c index 3b38a4d43d..55f3b3a5f7 100644 --- a/source3/librpc/gen_ndr/cli_wbint.c +++ b/source3/librpc/gen_ndr/cli_wbint.c @@ -2297,3 +2297,164 @@ NTSTATUS rpccli_wbint_DsGetDcName(struct rpc_pipe_client *cli,  	return r.out.result;  } +struct rpccli_wbint_LookupRids_state { +	struct wbint_LookupRids orig; +	struct wbint_LookupRids tmp; +	TALLOC_CTX *out_mem_ctx; +	NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx); +}; + +static void rpccli_wbint_LookupRids_done(struct tevent_req *subreq); + +struct tevent_req *rpccli_wbint_LookupRids_send(TALLOC_CTX *mem_ctx, +						struct tevent_context *ev, +						struct rpc_pipe_client *cli, +						struct wbint_RidArray *_rids /* [in] [ref] */, +						struct wbint_Principals *_names /* [out] [ref] */) +{ +	struct tevent_req *req; +	struct rpccli_wbint_LookupRids_state *state; +	struct tevent_req *subreq; + +	req = tevent_req_create(mem_ctx, &state, +				struct rpccli_wbint_LookupRids_state); +	if (req == NULL) { +		return NULL; +	} +	state->out_mem_ctx = NULL; +	state->dispatch_recv = cli->dispatch_recv; + +	/* In parameters */ +	state->orig.in.rids = _rids; + +	/* Out parameters */ +	state->orig.out.names = _names; + +	/* Result */ +	ZERO_STRUCT(state->orig.out.result); + +	if (DEBUGLEVEL >= 10) { +		NDR_PRINT_IN_DEBUG(wbint_LookupRids, &state->orig); +	} + +	state->out_mem_ctx = talloc_named_const(state, 0, +			     "rpccli_wbint_LookupRids_out_memory"); +	if (tevent_req_nomem(state->out_mem_ctx, req)) { +		return tevent_req_post(req, ev); +	} + +	/* make a temporary copy, that we pass to the dispatch function */ +	state->tmp = state->orig; + +	subreq = cli->dispatch_send(state, ev, cli, +				    &ndr_table_wbint, +				    NDR_WBINT_LOOKUPRIDS, +				    &state->tmp); +	if (tevent_req_nomem(subreq, req)) { +		return tevent_req_post(req, ev); +	} +	tevent_req_set_callback(subreq, rpccli_wbint_LookupRids_done, req); +	return req; +} + +static void rpccli_wbint_LookupRids_done(struct tevent_req *subreq) +{ +	struct tevent_req *req = tevent_req_callback_data( +		subreq, struct tevent_req); +	struct rpccli_wbint_LookupRids_state *state = tevent_req_data( +		req, struct rpccli_wbint_LookupRids_state); +	NTSTATUS status; +	TALLOC_CTX *mem_ctx; + +	if (state->out_mem_ctx) { +		mem_ctx = state->out_mem_ctx; +	} else { +		mem_ctx = state; +	} + +	status = state->dispatch_recv(subreq, mem_ctx); +	TALLOC_FREE(subreq); +	if (!NT_STATUS_IS_OK(status)) { +		tevent_req_nterror(req, status); +		return; +	} + +	/* Copy out parameters */ +	*state->orig.out.names = *state->tmp.out.names; + +	/* Copy result */ +	state->orig.out.result = state->tmp.out.result; + +	/* Reset temporary structure */ +	ZERO_STRUCT(state->tmp); + +	if (DEBUGLEVEL >= 10) { +		NDR_PRINT_OUT_DEBUG(wbint_LookupRids, &state->orig); +	} + +	tevent_req_done(req); +} + +NTSTATUS rpccli_wbint_LookupRids_recv(struct tevent_req *req, +				      TALLOC_CTX *mem_ctx, +				      NTSTATUS *result) +{ +	struct rpccli_wbint_LookupRids_state *state = tevent_req_data( +		req, struct rpccli_wbint_LookupRids_state); +	NTSTATUS status; + +	if (tevent_req_is_nterror(req, &status)) { +		tevent_req_received(req); +		return status; +	} + +	/* Steal possbile out parameters to the callers context */ +	talloc_steal(mem_ctx, state->out_mem_ctx); + +	/* Return result */ +	*result = state->orig.out.result; + +	tevent_req_received(req); +	return NT_STATUS_OK; +} + +NTSTATUS rpccli_wbint_LookupRids(struct rpc_pipe_client *cli, +				 TALLOC_CTX *mem_ctx, +				 struct wbint_RidArray *rids /* [in] [ref] */, +				 struct wbint_Principals *names /* [out] [ref] */) +{ +	struct wbint_LookupRids r; +	NTSTATUS status; + +	/* In parameters */ +	r.in.rids = rids; + +	if (DEBUGLEVEL >= 10) { +		NDR_PRINT_IN_DEBUG(wbint_LookupRids, &r); +	} + +	status = cli->dispatch(cli, +				mem_ctx, +				&ndr_table_wbint, +				NDR_WBINT_LOOKUPRIDS, +				&r); + +	if (!NT_STATUS_IS_OK(status)) { +		return status; +	} + +	if (DEBUGLEVEL >= 10) { +		NDR_PRINT_OUT_DEBUG(wbint_LookupRids, &r); +	} + +	if (NT_STATUS_IS_ERR(status)) { +		return status; +	} + +	/* Return variables */ +	*names = *r.out.names; + +	/* Return result */ +	return r.out.result; +} + diff --git a/source3/librpc/gen_ndr/cli_wbint.h b/source3/librpc/gen_ndr/cli_wbint.h index 148870dcf0..7f8cb12edd 100644 --- a/source3/librpc/gen_ndr/cli_wbint.h +++ b/source3/librpc/gen_ndr/cli_wbint.h @@ -190,4 +190,16 @@ NTSTATUS rpccli_wbint_DsGetDcName(struct rpc_pipe_client *cli,  				  const char *site_name /* [in] [unique,charset(UTF8)] */,  				  uint32_t flags /* [in]  */,  				  struct netr_DsRGetDCNameInfo **dc_info /* [out] [ref] */); +struct tevent_req *rpccli_wbint_LookupRids_send(TALLOC_CTX *mem_ctx, +						struct tevent_context *ev, +						struct rpc_pipe_client *cli, +						struct wbint_RidArray *_rids /* [in] [ref] */, +						struct wbint_Principals *_names /* [out] [ref] */); +NTSTATUS rpccli_wbint_LookupRids_recv(struct tevent_req *req, +				      TALLOC_CTX *mem_ctx, +				      NTSTATUS *result); +NTSTATUS rpccli_wbint_LookupRids(struct rpc_pipe_client *cli, +				 TALLOC_CTX *mem_ctx, +				 struct wbint_RidArray *rids /* [in] [ref] */, +				 struct wbint_Principals *names /* [out] [ref] */);  #endif /* __CLI_WBINT__ */ diff --git a/source3/librpc/gen_ndr/ndr_wbint.c b/source3/librpc/gen_ndr/ndr_wbint.c index 8f07349d7a..681d1da492 100644 --- a/source3/librpc/gen_ndr/ndr_wbint.c +++ b/source3/librpc/gen_ndr/ndr_wbint.c @@ -1851,6 +1851,83 @@ _PUBLIC_ void ndr_print_wbint_DsGetDcName(struct ndr_print *ndr, const char *nam  	ndr->depth--;  } +static enum ndr_err_code ndr_push_wbint_LookupRids(struct ndr_push *ndr, int flags, const struct wbint_LookupRids *r) +{ +	if (flags & NDR_IN) { +		if (r->in.rids == NULL) { +			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); +		} +		NDR_CHECK(ndr_push_wbint_RidArray(ndr, NDR_SCALARS, r->in.rids)); +	} +	if (flags & NDR_OUT) { +		if (r->out.names == NULL) { +			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); +		} +		NDR_CHECK(ndr_push_wbint_Principals(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.names)); +		NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); +	} +	return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_wbint_LookupRids(struct ndr_pull *ndr, int flags, struct wbint_LookupRids *r) +{ +	TALLOC_CTX *_mem_save_rids_0; +	TALLOC_CTX *_mem_save_names_0; +	if (flags & NDR_IN) { +		ZERO_STRUCT(r->out); + +		if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { +			NDR_PULL_ALLOC(ndr, r->in.rids); +		} +		_mem_save_rids_0 = NDR_PULL_GET_MEM_CTX(ndr); +		NDR_PULL_SET_MEM_CTX(ndr, r->in.rids, LIBNDR_FLAG_REF_ALLOC); +		NDR_CHECK(ndr_pull_wbint_RidArray(ndr, NDR_SCALARS, r->in.rids)); +		NDR_PULL_SET_MEM_CTX(ndr, _mem_save_rids_0, LIBNDR_FLAG_REF_ALLOC); +		NDR_PULL_ALLOC(ndr, r->out.names); +		ZERO_STRUCTP(r->out.names); +	} +	if (flags & NDR_OUT) { +		if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { +			NDR_PULL_ALLOC(ndr, r->out.names); +		} +		_mem_save_names_0 = NDR_PULL_GET_MEM_CTX(ndr); +		NDR_PULL_SET_MEM_CTX(ndr, r->out.names, LIBNDR_FLAG_REF_ALLOC); +		NDR_CHECK(ndr_pull_wbint_Principals(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.names)); +		NDR_PULL_SET_MEM_CTX(ndr, _mem_save_names_0, LIBNDR_FLAG_REF_ALLOC); +		NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); +	} +	return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_wbint_LookupRids(struct ndr_print *ndr, const char *name, int flags, const struct wbint_LookupRids *r) +{ +	ndr_print_struct(ndr, name, "wbint_LookupRids"); +	ndr->depth++; +	if (flags & NDR_SET_VALUES) { +		ndr->flags |= LIBNDR_PRINT_SET_VALUES; +	} +	if (flags & NDR_IN) { +		ndr_print_struct(ndr, "in", "wbint_LookupRids"); +		ndr->depth++; +		ndr_print_ptr(ndr, "rids", r->in.rids); +		ndr->depth++; +		ndr_print_wbint_RidArray(ndr, "rids", r->in.rids); +		ndr->depth--; +		ndr->depth--; +	} +	if (flags & NDR_OUT) { +		ndr_print_struct(ndr, "out", "wbint_LookupRids"); +		ndr->depth++; +		ndr_print_ptr(ndr, "names", r->out.names); +		ndr->depth++; +		ndr_print_wbint_Principals(ndr, "names", r->out.names); +		ndr->depth--; +		ndr_print_NTSTATUS(ndr, "result", r->out.result); +		ndr->depth--; +	} +	ndr->depth--; +} +  static const struct ndr_interface_call wbint_calls[] = {  	{  		"wbint_Ping", @@ -1964,6 +2041,14 @@ static const struct ndr_interface_call wbint_calls[] = {  		(ndr_print_function_t) ndr_print_wbint_DsGetDcName,  		false,  	}, +	{ +		"wbint_LookupRids", +		sizeof(struct wbint_LookupRids), +		(ndr_push_flags_fn_t) ndr_push_wbint_LookupRids, +		(ndr_pull_flags_fn_t) ndr_pull_wbint_LookupRids, +		(ndr_print_function_t) ndr_print_wbint_LookupRids, +		false, +	},  	{ NULL, 0, NULL, NULL, NULL, false }  }; @@ -1993,7 +2078,7 @@ const struct ndr_interface_table ndr_table_wbint = {  		NDR_WBINT_VERSION  	},  	.helpstring	= NDR_WBINT_HELPSTRING, -	.num_calls	= 14, +	.num_calls	= 15,  	.calls		= wbint_calls,  	.endpoints	= &wbint_endpoints,  	.authservices	= &wbint_authservices diff --git a/source3/librpc/gen_ndr/ndr_wbint.h b/source3/librpc/gen_ndr/ndr_wbint.h index 4b3096cb57..d183e348e6 100644 --- a/source3/librpc/gen_ndr/ndr_wbint.h +++ b/source3/librpc/gen_ndr/ndr_wbint.h @@ -39,7 +39,9 @@ extern const struct ndr_interface_table ndr_table_wbint;  #define NDR_WBINT_DSGETDCNAME (0x0d) -#define NDR_WBINT_CALL_COUNT (14) +#define NDR_WBINT_LOOKUPRIDS (0x0e) + +#define NDR_WBINT_CALL_COUNT (15)  enum ndr_err_code ndr_push_wbint_userinfo(struct ndr_push *ndr, int ndr_flags, const struct wbint_userinfo *r);  enum ndr_err_code ndr_pull_wbint_userinfo(struct ndr_pull *ndr, int ndr_flags, struct wbint_userinfo *r);  void ndr_print_wbint_userinfo(struct ndr_print *ndr, const char *name, const struct wbint_userinfo *r); @@ -72,4 +74,5 @@ void ndr_print_wbint_QuerySequenceNumber(struct ndr_print *ndr, const char *name  void ndr_print_wbint_LookupGroupMembers(struct ndr_print *ndr, const char *name, int flags, const struct wbint_LookupGroupMembers *r);  void ndr_print_wbint_QueryUserList(struct ndr_print *ndr, const char *name, int flags, const struct wbint_QueryUserList *r);  void ndr_print_wbint_DsGetDcName(struct ndr_print *ndr, const char *name, int flags, const struct wbint_DsGetDcName *r); +void ndr_print_wbint_LookupRids(struct ndr_print *ndr, const char *name, int flags, const struct wbint_LookupRids *r);  #endif /* _HEADER_NDR_wbint */ diff --git a/source3/librpc/gen_ndr/srv_wbint.c b/source3/librpc/gen_ndr/srv_wbint.c index 5dbd6474b6..2cc750c4b5 100644 --- a/source3/librpc/gen_ndr/srv_wbint.c +++ b/source3/librpc/gen_ndr/srv_wbint.c @@ -1144,6 +1144,86 @@ static bool api_wbint_DsGetDcName(pipes_struct *p)  	return true;  } +static bool api_wbint_LookupRids(pipes_struct *p) +{ +	const struct ndr_interface_call *call; +	struct ndr_pull *pull; +	struct ndr_push *push; +	enum ndr_err_code ndr_err; +	DATA_BLOB blob; +	struct wbint_LookupRids *r; + +	call = &ndr_table_wbint.calls[NDR_WBINT_LOOKUPRIDS]; + +	r = talloc(talloc_tos(), struct wbint_LookupRids); +	if (r == NULL) { +		return false; +	} + +	if (!prs_data_blob(&p->in_data.data, &blob, r)) { +		talloc_free(r); +		return false; +	} + +	pull = ndr_pull_init_blob(&blob, r, NULL); +	if (pull == NULL) { +		talloc_free(r); +		return false; +	} + +	pull->flags |= LIBNDR_FLAG_REF_ALLOC; +	ndr_err = call->ndr_pull(pull, NDR_IN, r); +	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +		talloc_free(r); +		return false; +	} + +	if (DEBUGLEVEL >= 10) { +		NDR_PRINT_IN_DEBUG(wbint_LookupRids, r); +	} + +	ZERO_STRUCT(r->out); +	r->out.names = talloc_zero(r, struct wbint_Principals); +	if (r->out.names == NULL) { +		talloc_free(r); +		return false; +	} + +	r->out.result = _wbint_LookupRids(p, r); + +	if (p->rng_fault_state) { +		talloc_free(r); +		/* Return true here, srv_pipe_hnd.c will take care */ +		return true; +	} + +	if (DEBUGLEVEL >= 10) { +		NDR_PRINT_OUT_DEBUG(wbint_LookupRids, r); +	} + +	push = ndr_push_init_ctx(r, NULL); +	if (push == NULL) { +		talloc_free(r); +		return false; +	} + +	ndr_err = call->ndr_push(push, NDR_OUT, r); +	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +		talloc_free(r); +		return false; +	} + +	blob = ndr_push_blob(push); +	if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { +		talloc_free(r); +		return false; +	} + +	talloc_free(r); + +	return true; +} +  /* Tables */  static struct api_struct api_wbint_cmds[] = @@ -1162,6 +1242,7 @@ static struct api_struct api_wbint_cmds[] =  	{"WBINT_LOOKUPGROUPMEMBERS", NDR_WBINT_LOOKUPGROUPMEMBERS, api_wbint_LookupGroupMembers},  	{"WBINT_QUERYUSERLIST", NDR_WBINT_QUERYUSERLIST, api_wbint_QueryUserList},  	{"WBINT_DSGETDCNAME", NDR_WBINT_DSGETDCNAME, api_wbint_DsGetDcName}, +	{"WBINT_LOOKUPRIDS", NDR_WBINT_LOOKUPRIDS, api_wbint_LookupRids},  };  void wbint_get_pipe_fns(struct api_struct **fns, int *n_fns) @@ -1361,6 +1442,18 @@ NTSTATUS rpc_wbint_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, co  			return NT_STATUS_OK;  		} +		case NDR_WBINT_LOOKUPRIDS: { +			struct wbint_LookupRids *r = (struct wbint_LookupRids *)_r; +			ZERO_STRUCT(r->out); +			r->out.names = talloc_zero(mem_ctx, struct wbint_Principals); +			if (r->out.names == NULL) { +			return NT_STATUS_NO_MEMORY; +			} + +			r->out.result = _wbint_LookupRids(cli->pipes_struct, r); +			return NT_STATUS_OK; +		} +  		default:  			return NT_STATUS_NOT_IMPLEMENTED;  	} diff --git a/source3/librpc/gen_ndr/srv_wbint.h b/source3/librpc/gen_ndr/srv_wbint.h index a6dbd40265..1203a3f26e 100644 --- a/source3/librpc/gen_ndr/srv_wbint.h +++ b/source3/librpc/gen_ndr/srv_wbint.h @@ -15,6 +15,7 @@ NTSTATUS _wbint_QuerySequenceNumber(pipes_struct *p, struct wbint_QuerySequenceN  NTSTATUS _wbint_LookupGroupMembers(pipes_struct *p, struct wbint_LookupGroupMembers *r);  NTSTATUS _wbint_QueryUserList(pipes_struct *p, struct wbint_QueryUserList *r);  NTSTATUS _wbint_DsGetDcName(pipes_struct *p, struct wbint_DsGetDcName *r); +NTSTATUS _wbint_LookupRids(pipes_struct *p, struct wbint_LookupRids *r);  void wbint_get_pipe_fns(struct api_struct **fns, int *n_fns);  NTSTATUS rpc_wbint_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *r);  void _wbint_Ping(pipes_struct *p, struct wbint_Ping *r); @@ -31,5 +32,6 @@ NTSTATUS _wbint_QuerySequenceNumber(pipes_struct *p, struct wbint_QuerySequenceN  NTSTATUS _wbint_LookupGroupMembers(pipes_struct *p, struct wbint_LookupGroupMembers *r);  NTSTATUS _wbint_QueryUserList(pipes_struct *p, struct wbint_QueryUserList *r);  NTSTATUS _wbint_DsGetDcName(pipes_struct *p, struct wbint_DsGetDcName *r); +NTSTATUS _wbint_LookupRids(pipes_struct *p, struct wbint_LookupRids *r);  NTSTATUS rpc_wbint_init(void);  #endif /* __SRV_WBINT__ */ diff --git a/source3/librpc/gen_ndr/wbint.h b/source3/librpc/gen_ndr/wbint.h index 31eaae2645..ddea95b7fe 100644 --- a/source3/librpc/gen_ndr/wbint.h +++ b/source3/librpc/gen_ndr/wbint.h @@ -230,4 +230,17 @@ struct wbint_DsGetDcName {  }; + +struct wbint_LookupRids { +	struct { +		struct wbint_RidArray *rids;/* [ref] */ +	} in; + +	struct { +		struct wbint_Principals *names;/* [ref] */ +		NTSTATUS result; +	} out; + +}; +  #endif /* _HEADER_wbint */ diff --git a/source3/librpc/idl/wbint.idl b/source3/librpc/idl/wbint.idl index fbbe5ef118..ab258c5832 100644 --- a/source3/librpc/idl/wbint.idl +++ b/source3/librpc/idl/wbint.idl @@ -126,4 +126,9 @@ interface wbint  	[in]					uint32 flags,  	[out] 					netr_DsRGetDCNameInfo **dc_info  	); + +    NTSTATUS wbint_LookupRids( +	[in] wbint_RidArray *rids, +	[out] wbint_Principals *names +	);  }
\ No newline at end of file diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index a57412ab14..10538d3f21 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -447,10 +447,6 @@ static struct winbindd_dispatch_table {  	{ WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,  	  "LIST_TRUSTDOM" }, -	/* SID related functions */ - -	{ WINBINDD_LOOKUPRIDS, winbindd_lookuprids, "LOOKUPRIDS" }, -  	/* Lookup related functions */  	{ WINBINDD_ALLOCATE_UID, winbindd_allocate_uid, "ALLOCATE_UID" }, @@ -530,6 +526,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {  	  winbindd_getgrnam_send, winbindd_getgrnam_recv },  	{ WINBINDD_GETUSERSIDS, "GETUSERSIDS",  	  winbindd_getusersids_send, winbindd_getusersids_recv }, +	{ WINBINDD_LOOKUPRIDS, "LOOKUPRIDS", +	  winbindd_lookuprids_send, winbindd_lookuprids_recv },  	{ WINBINDD_SETPWENT, "SETPWENT",  	  winbindd_setpwent_send, winbindd_setpwent_recv },  	{ WINBINDD_GETPWENT, "GETPWENT", diff --git a/source3/winbindd/winbindd_async.c b/source3/winbindd/winbindd_async.c index d16a1f8288..1e63ed1fec 100644 --- a/source3/winbindd/winbindd_async.c +++ b/source3/winbindd/winbindd_async.c @@ -694,64 +694,6 @@ static bool parse_ridlist(TALLOC_CTX *mem_ctx, char *ridstr,  	return True;  } -enum winbindd_result winbindd_dual_lookuprids(struct winbindd_domain *domain, -					      struct winbindd_cli_state *state) -{ -	uint32 *rids = NULL; -	size_t i, buflen, num_rids = 0; -	ssize_t len; -	DOM_SID domain_sid; -	char *domain_name; -	char **names; -	enum lsa_SidType *types; -	NTSTATUS status; -	char *result; - -	DEBUG(10, ("Looking up RIDs for domain %s (%s)\n", -		   state->request->domain_name, -		   state->request->data.sid)); - -	if (!parse_ridlist(state->mem_ctx, state->request->extra_data.data, -			   &rids, &num_rids)) { -		DEBUG(5, ("Could not parse ridlist\n")); -		return WINBINDD_ERROR; -	} - -	if (!string_to_sid(&domain_sid, state->request->data.sid)) { -		DEBUG(5, ("Could not parse domain sid %s\n", -			  state->request->data.sid)); -		return WINBINDD_ERROR; -	} - -	status = domain->methods->rids_to_names(domain, state->mem_ctx, -						&domain_sid, rids, num_rids, -						&domain_name, -						&names, &types); - -	if (!NT_STATUS_IS_OK(status) && -	    !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) { -		return WINBINDD_ERROR; -	} - -	len = 0; -	buflen = 0; -	result = NULL; - -	for (i=0; i<num_rids; i++) { -		sprintf_append(state->mem_ctx, &result, &len, &buflen, -			       "%d %s\n", types[i], names[i]); -	} - -	fstrcpy(state->response->data.domain_name, domain_name); - -	if (result != NULL) { -		state->response->extra_data.data = result; -		state->response->length += len+1; -	} - -	return WINBINDD_OK; -} -  static void getsidaliases_recv(TALLOC_CTX *mem_ctx, bool success,  			       struct winbindd_response *response,  			       void *c, void *private_data) diff --git a/source3/winbindd/winbindd_domain.c b/source3/winbindd/winbindd_domain.c index eb4e131259..14376c62bf 100644 --- a/source3/winbindd/winbindd_domain.c +++ b/source3/winbindd/winbindd_domain.c @@ -50,10 +50,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {  		.struct_cmd	= WINBINDD_LOOKUPNAME,  		.struct_fn	= winbindd_dual_lookupname,  	},{ -		.name		= "LOOKUPRIDS", -		.struct_cmd	= WINBINDD_LOOKUPRIDS, -		.struct_fn	= winbindd_dual_lookuprids, -	},{  		.name		= "LIST_USERS",  		.struct_cmd	= WINBINDD_LIST_USERS,  		.struct_fn	= winbindd_dual_list_users, diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 6b1a4b3615..b46b3d511e 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -289,3 +289,43 @@ done:  	return status;  } + +NTSTATUS _wbint_LookupRids(pipes_struct *p, struct wbint_LookupRids *r) +{ +	struct winbindd_domain *domain = wb_child_domain(); +	char *domain_name; +	char **names; +	enum lsa_SidType *types; +	struct wbint_Principal *result; +	NTSTATUS status; +	int i; + +	if (domain == NULL) { +		return NT_STATUS_REQUEST_NOT_ACCEPTED; +	} + +	status = domain->methods->rids_to_names( +		domain, talloc_tos(), &domain->sid, r->in.rids->rids, +		r->in.rids->num_rids, &domain_name, &names, &types); +	if (!NT_STATUS_IS_OK(status)) { +		return status; +	} + +	result = talloc_array(p->mem_ctx, struct wbint_Principal, +			      r->in.rids->num_rids); +	if (result == NULL) { +		return NT_STATUS_NO_MEMORY; +	} + +	for (i=0; i<r->in.rids->num_rids; i++) { +		sid_compose(&result[i].sid, &domain->sid, r->in.rids->rids[i]); +		result[i].type = types[i]; +		result[i].name = talloc_move(result, &names[i]); +	} +	TALLOC_FREE(types); +	TALLOC_FREE(names); + +	r->out.names->num_principals = r->in.rids->num_rids; +	r->out.names->principals = result; +	return NT_STATUS_OK; +} diff --git a/source3/winbindd/winbindd_lookuprids.c b/source3/winbindd/winbindd_lookuprids.c new file mode 100644 index 0000000000..f2cb8793eb --- /dev/null +++ b/source3/winbindd/winbindd_lookuprids.c @@ -0,0 +1,197 @@ +/* +   Unix SMB/CIFS implementation. +   async implementation of WINBINDD_LOOKUPRIDS +   Copyright (C) Volker Lendecke 2009 + +   This program is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published by +   the Free Software Foundation; either version 3 of the License, or +   (at your option) any later version. + +   This program is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "winbindd.h" +#include "librpc/gen_ndr/cli_wbint.h" + +struct winbindd_lookuprids_state { +	struct tevent_context *ev; +	const char *domain_name; +	struct wbint_RidArray rids; +	struct wbint_Principals names; +}; + +static bool parse_ridlist(TALLOC_CTX *mem_ctx, char *ridstr, +			  uint32_t **prids, uint32_t *pnum_rids); + +static void winbindd_lookuprids_done(struct tevent_req *subreq); + +struct tevent_req *winbindd_lookuprids_send(TALLOC_CTX *mem_ctx, +					    struct tevent_context *ev, +					    struct winbindd_cli_state *cli, +					    struct winbindd_request *request) +{ +	struct tevent_req *req, *subreq; +	struct winbindd_lookuprids_state *state; +	struct winbindd_domain *domain; +	struct dom_sid sid; + +	req = tevent_req_create(mem_ctx, &state, +				struct winbindd_lookuprids_state); +	if (req == NULL) { +		return NULL; +	} +	state->ev = ev; + +	/* Ensure null termination */ +	request->data.sid[sizeof(request->data.sid)-1]='\0'; + +	DEBUG(3, ("lookuprids (%s)\n", request->data.sid)); + +	if (!string_to_sid(&sid, request->data.sid)) { +		DEBUG(5, ("%s not a SID\n", request->data.sid)); +		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); +		return tevent_req_post(req, ev); +	} + +	domain = find_domain_from_sid_noinit(&sid); +	if (domain == NULL) { +		DEBUG(5, ("Domain for sid %s not found\n", +			  sid_string_dbg(&sid))); +		tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN); +		return tevent_req_post(req, ev); +	} + +	if (request->extra_data.data[request->extra_len-1] != '\0') { +		DEBUG(5, ("extra_data not 0-terminated\n")); +		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); +		return tevent_req_post(req, ev); +	} + +	if (!parse_ridlist(state, request->extra_data.data, +			   &state->rids.rids, &state->rids.num_rids)) { +		DEBUG(5, ("parse_ridlist failed\n")); +		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); +		return tevent_req_post(req, ev); +	} + +	subreq = rpccli_wbint_LookupRids_send( +		state, ev, domain->child.rpccli, &state->rids, &state->names); +	if (tevent_req_nomem(subreq, req)) { +		return tevent_req_post(req, ev); +	} +	tevent_req_set_callback(subreq, winbindd_lookuprids_done, req); +	return req; +} + +static void winbindd_lookuprids_done(struct tevent_req *subreq) +{ +	struct tevent_req *req = tevent_req_callback_data( +		subreq, struct tevent_req); +	struct winbindd_lookuprids_state *state = tevent_req_data( +		req, struct winbindd_lookuprids_state); +	NTSTATUS status, result; + +	status = rpccli_wbint_LookupRids_recv(subreq, state, &result); +	TALLOC_FREE(subreq); +	if (!NT_STATUS_IS_OK(status)) { +		tevent_req_nterror(req, status); +		return; +	} +	if (!NT_STATUS_IS_OK(result)) { +		tevent_req_nterror(req, result); +		return; +	} +	tevent_req_done(req); +} + +NTSTATUS winbindd_lookuprids_recv(struct tevent_req *req, +				  struct winbindd_response *response) +{ +	struct winbindd_lookuprids_state *state = tevent_req_data( +		req, struct winbindd_lookuprids_state); +	NTSTATUS status; +	char *result; +	int i; + +	if (tevent_req_is_nterror(req, &status)) { +		DEBUG(5, ("Lookuprids failed: %s\n",nt_errstr(status))); +		return status; +	} + +	result = talloc_strdup(response, ""); +	if (result == NULL) { +		return NT_STATUS_NO_MEMORY; +	} + +	for (i=0; i<state->names.num_principals; i++) { +		struct wbint_Principal *p = &state->names.principals[i]; + +		result = talloc_asprintf_append_buffer( +			result, "%d %s\n", (int)p->type, p->name); +		if (result == NULL) { +			return NT_STATUS_NO_MEMORY; +		} +	} + +	fstrcpy(response->data.domain_name, state->domain_name); +	response->extra_data.data = result; +	response->length += talloc_get_size(result); +	return NT_STATUS_OK; +} + +static bool parse_ridlist(TALLOC_CTX *mem_ctx, char *ridstr, +			  uint32_t **prids, uint32_t *pnum_rids) +{ +	uint32_t i, num_rids; +	uint32_t *rids; +	char *p; + +	if (ridstr == NULL) { +		return false; +	} + +	p = ridstr; +	num_rids = 0; + +	/* count rids */ + +	while ((p = strchr(p, '\n')) != NULL) { +		p += 1; +		num_rids += 1; +	} + +	if (num_rids == 0) { +		*pnum_rids = 0; +		*prids = NULL; +		return true; +	} + +	rids = talloc_array(mem_ctx, uint32_t, num_rids); +	if (rids == NULL) { +		return false; +	} + +	p = ridstr; + +	for (i=0; i<num_rids; i++) { +		char *q; +		rids[i] = strtoul(p, &q, 10); +		if (*q != '\n') { +			DEBUG(0, ("Got invalid ridstr: %s\n", p)); +			return false; +		} +		p = q+1; +	} + +	*pnum_rids = num_rids; +	*prids = rids; +	return true; +} diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 930d48b458..bebfc9d9e4 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -102,8 +102,6 @@ bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,  		   size_t num_sids, char **result, ssize_t *len);  bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,  		   DOM_SID **sids, size_t *num_sids); -enum winbindd_result winbindd_dual_lookuprids(struct winbindd_domain *domain, -					      struct winbindd_cli_state *state);  void winbindd_getsidaliases_async(struct winbindd_domain *domain,  				  TALLOC_CTX *mem_ctx,  				  const DOM_SID *sids, size_t num_sids, @@ -848,6 +846,13 @@ struct tevent_req *winbindd_getusersids_send(TALLOC_CTX *mem_ctx,  NTSTATUS winbindd_getusersids_recv(struct tevent_req *req,  				   struct winbindd_response *response); +struct tevent_req *winbindd_lookuprids_send(TALLOC_CTX *mem_ctx, +					    struct tevent_context *ev, +					    struct winbindd_cli_state *cli, +					    struct winbindd_request *request); +NTSTATUS winbindd_lookuprids_recv(struct tevent_req *req, +				  struct winbindd_response *response); +  struct tevent_req *wb_query_user_list_send(TALLOC_CTX *mem_ctx,  					   struct tevent_context *ev,  					   struct winbindd_domain *domain); diff --git a/source3/winbindd/winbindd_sid.c b/source3/winbindd/winbindd_sid.c index db000682ae..8f09d5f7eb 100644 --- a/source3/winbindd/winbindd_sid.c +++ b/source3/winbindd/winbindd_sid.c @@ -25,36 +25,6 @@  #undef DBGC_CLASS  #define DBGC_CLASS DBGC_WINBIND -/* Convert a string  */ - -void winbindd_lookuprids(struct winbindd_cli_state *state) -{ -	struct winbindd_domain *domain; -	DOM_SID domain_sid; -	 -	/* Ensure null termination */ -	state->request->data.sid[sizeof(state->request->data.sid)-1]='\0'; - -	DEBUG(10, ("lookup_rids: %s\n", state->request->data.sid)); - -	if (!string_to_sid(&domain_sid, state->request->data.sid)) { -		DEBUG(5, ("Could not convert %s to SID\n", -			  state->request->data.sid)); -		request_error(state); -		return; -	} - -	domain = find_lookup_domain_from_sid(&domain_sid); -	if (domain == NULL) { -		DEBUG(10, ("Could not find domain for name %s\n", -			   state->request->domain_name)); -		request_error(state); -		return; -	} - -	sendto_domain(state, domain); -} -  static void set_mapping_recv(void *private_data, bool success)  {  	struct winbindd_cli_state *state = | 
