s4:winbind: implement calls for allowing getent groups
[Samba/nascimento.git] / source4 / winbind / wb_samba3_cmd.c
blob2c846c4f15cd0f30e5c6776c4ab4350196440f63
1 /*
2 Unix SMB/CIFS implementation.
3 Main winbindd samba3 server routines
5 Copyright (C) Stefan Metzmacher 2005
6 Copyright (C) Volker Lendecke 2005
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
8 Copyright (C) Kai Blin 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "winbind/wb_server.h"
26 #include "param/param.h"
27 #include "winbind/wb_helper.h"
28 #include "libcli/composite/composite.h"
29 #include "version.h"
30 #include "librpc/gen_ndr/ndr_netlogon.h"
31 #include "libcli/security/security.h"
32 #include "auth/ntlm/pam_errors.h"
33 #include "auth/credentials/credentials.h"
34 #include "smbd/service_task.h"
37 support the old Samba3 TXT form of the info3
39 static NTSTATUS wb_samba3_append_info3_as_txt(TALLOC_CTX *mem_ctx,
40 struct wbsrv_samba3_call *s3call,
41 DATA_BLOB info3b)
43 struct netr_SamInfo3 *info3;
44 char *ex;
45 uint32_t i;
46 enum ndr_err_code ndr_err;
48 info3 = talloc(mem_ctx, struct netr_SamInfo3);
49 NT_STATUS_HAVE_NO_MEMORY(info3);
51 /* The Samba3 protocol has a redundent 4 bytes at the start */
52 info3b.data += 4;
53 info3b.length -= 4;
55 ndr_err = ndr_pull_struct_blob(&info3b,
56 mem_ctx,
57 lp_iconv_convenience(s3call->wbconn->lp_ctx),
58 info3,
59 (ndr_pull_flags_fn_t)ndr_pull_netr_SamInfo3);
60 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
61 return ndr_map_error2ntstatus(ndr_err);
64 s3call->response.data.auth.info3.logon_time =
65 nt_time_to_unix(info3->base.last_logon);
66 s3call->response.data.auth.info3.logoff_time =
67 nt_time_to_unix(info3->base.last_logoff);
68 s3call->response.data.auth.info3.kickoff_time =
69 nt_time_to_unix(info3->base.acct_expiry);
70 s3call->response.data.auth.info3.pass_last_set_time =
71 nt_time_to_unix(info3->base.last_password_change);
72 s3call->response.data.auth.info3.pass_can_change_time =
73 nt_time_to_unix(info3->base.allow_password_change);
74 s3call->response.data.auth.info3.pass_must_change_time =
75 nt_time_to_unix(info3->base.force_password_change);
77 s3call->response.data.auth.info3.logon_count = info3->base.logon_count;
78 s3call->response.data.auth.info3.bad_pw_count = info3->base.bad_password_count;
80 s3call->response.data.auth.info3.user_rid = info3->base.rid;
81 s3call->response.data.auth.info3.group_rid = info3->base.primary_gid;
82 fstrcpy(s3call->response.data.auth.info3.dom_sid, dom_sid_string(mem_ctx, info3->base.domain_sid));
84 s3call->response.data.auth.info3.num_groups = info3->base.groups.count;
85 s3call->response.data.auth.info3.user_flgs = info3->base.user_flags;
87 s3call->response.data.auth.info3.acct_flags = info3->base.acct_flags;
88 s3call->response.data.auth.info3.num_other_sids = info3->sidcount;
90 fstrcpy(s3call->response.data.auth.info3.user_name,
91 info3->base.account_name.string);
92 fstrcpy(s3call->response.data.auth.info3.full_name,
93 info3->base.full_name.string);
94 fstrcpy(s3call->response.data.auth.info3.logon_script,
95 info3->base.logon_script.string);
96 fstrcpy(s3call->response.data.auth.info3.profile_path,
97 info3->base.profile_path.string);
98 fstrcpy(s3call->response.data.auth.info3.home_dir,
99 info3->base.home_directory.string);
100 fstrcpy(s3call->response.data.auth.info3.dir_drive,
101 info3->base.home_drive.string);
103 fstrcpy(s3call->response.data.auth.info3.logon_srv,
104 info3->base.logon_server.string);
105 fstrcpy(s3call->response.data.auth.info3.logon_dom,
106 info3->base.domain.string);
108 ex = talloc_strdup(mem_ctx, "");
109 NT_STATUS_HAVE_NO_MEMORY(ex);
111 for (i=0; i < info3->base.groups.count; i++) {
112 ex = talloc_asprintf_append_buffer(ex, "0x%08X:0x%08X\n",
113 info3->base.groups.rids[i].rid,
114 info3->base.groups.rids[i].attributes);
115 NT_STATUS_HAVE_NO_MEMORY(ex);
118 for (i=0; i < info3->sidcount; i++) {
119 char *sid;
121 sid = dom_sid_string(mem_ctx, info3->sids[i].sid);
122 NT_STATUS_HAVE_NO_MEMORY(sid);
124 ex = talloc_asprintf_append_buffer(ex, "%s:0x%08X\n",
125 sid,
126 info3->sids[i].attributes);
127 NT_STATUS_HAVE_NO_MEMORY(ex);
129 talloc_free(sid);
132 s3call->response.extra_data.data = ex;
133 s3call->response.length += talloc_get_size(ex);
135 return NT_STATUS_OK;
139 Send off the reply to an async Samba3 query, handling filling in the PAM, NTSTATUS and string errors.
142 static void wbsrv_samba3_async_auth_epilogue(NTSTATUS status,
143 struct wbsrv_samba3_call *s3call)
145 struct winbindd_response *resp = &s3call->response;
146 if (!NT_STATUS_IS_OK(status)) {
147 resp->result = WINBINDD_ERROR;
148 } else {
149 resp->result = WINBINDD_OK;
152 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
153 nt_errstr(status));
154 WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
155 get_friendly_nt_error_msg(status));
157 resp->data.auth.pam_error = nt_status_to_pam(status);
158 resp->data.auth.nt_status = NT_STATUS_V(status);
160 wbsrv_samba3_send_reply(s3call);
164 Send of a generic reply to a Samba3 query
167 static void wbsrv_samba3_async_epilogue(NTSTATUS status,
168 struct wbsrv_samba3_call *s3call)
170 struct winbindd_response *resp = &s3call->response;
171 if (NT_STATUS_IS_OK(status)) {
172 resp->result = WINBINDD_OK;
173 } else {
174 resp->result = WINBINDD_ERROR;
177 wbsrv_samba3_send_reply(s3call);
181 Boilerplate commands, simple queries without network traffic
184 NTSTATUS wbsrv_samba3_interface_version(struct wbsrv_samba3_call *s3call)
186 s3call->response.result = WINBINDD_OK;
187 s3call->response.data.interface_version = WINBIND_INTERFACE_VERSION;
188 return NT_STATUS_OK;
191 NTSTATUS wbsrv_samba3_info(struct wbsrv_samba3_call *s3call)
193 s3call->response.result = WINBINDD_OK;
194 s3call->response.data.info.winbind_separator = *lp_winbind_separator(s3call->wbconn->lp_ctx);
195 WBSRV_SAMBA3_SET_STRING(s3call->response.data.info.samba_version,
196 SAMBA_VERSION_STRING);
197 return NT_STATUS_OK;
200 NTSTATUS wbsrv_samba3_domain_name(struct wbsrv_samba3_call *s3call)
202 s3call->response.result = WINBINDD_OK;
203 WBSRV_SAMBA3_SET_STRING(s3call->response.data.domain_name,
204 lp_workgroup(s3call->wbconn->lp_ctx));
205 return NT_STATUS_OK;
208 NTSTATUS wbsrv_samba3_netbios_name(struct wbsrv_samba3_call *s3call)
210 s3call->response.result = WINBINDD_OK;
211 WBSRV_SAMBA3_SET_STRING(s3call->response.data.netbios_name,
212 lp_netbios_name(s3call->wbconn->lp_ctx));
213 return NT_STATUS_OK;
216 NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
218 const char *path = s3call->wbconn->listen_socket->service->priv_socket_path;
219 s3call->response.result = WINBINDD_OK;
220 s3call->response.extra_data.data = discard_const(path);
222 s3call->response.length += strlen(path) + 1;
223 return NT_STATUS_OK;
226 NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
228 s3call->response.result = WINBINDD_OK;
229 return NT_STATUS_OK;
232 NTSTATUS wbsrv_samba3_domain_info(struct wbsrv_samba3_call *s3call)
234 DEBUG(5, ("wbsrv_samba3_domain_info called, stub\n"));
235 s3call->response.result = WINBINDD_OK;
236 fstrcpy(s3call->response.data.domain_info.name,
237 s3call->request.domain_name);
238 fstrcpy(s3call->response.data.domain_info.alt_name,
239 s3call->request.domain_name);
240 fstrcpy(s3call->response.data.domain_info.sid, "S-1-2-3-4");
241 s3call->response.data.domain_info.native_mode = false;
242 s3call->response.data.domain_info.active_directory = false;
243 s3call->response.data.domain_info.primary = false;
245 return NT_STATUS_OK;
248 /* Plaintext authentication
250 This interface is used by ntlm_auth in it's 'basic' authentication
251 mode, as well as by pam_winbind to authenticate users where we are
252 given a plaintext password.
255 static void check_machacc_recv(struct composite_context *ctx);
257 NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
259 NTSTATUS status;
260 struct cli_credentials *creds;
261 struct composite_context *ctx;
262 struct wbsrv_service *service =
263 s3call->wbconn->listen_socket->service;
265 /* Create a credentials structure */
266 creds = cli_credentials_init(s3call);
267 if (creds == NULL) {
268 return NT_STATUS_NO_MEMORY;
271 cli_credentials_set_conf(creds, service->task->lp_ctx);
273 /* Connect the machine account to the credentials */
274 status = cli_credentials_set_machine_account(creds, service->task->lp_ctx);
275 if (!NT_STATUS_IS_OK(status)) {
276 talloc_free(creds);
277 return status;
280 ctx = wb_cmd_pam_auth_send(s3call, service, creds);
282 if (!ctx) {
283 talloc_free(creds);
284 return NT_STATUS_NO_MEMORY;
287 ctx->async.fn = check_machacc_recv;
288 ctx->async.private_data = s3call;
289 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
290 return NT_STATUS_OK;
293 static void check_machacc_recv(struct composite_context *ctx)
295 struct wbsrv_samba3_call *s3call =
296 talloc_get_type(ctx->async.private_data,
297 struct wbsrv_samba3_call);
298 NTSTATUS status;
300 status = wb_cmd_pam_auth_recv(ctx, s3call, NULL, NULL, NULL, NULL);
302 if (!NT_STATUS_IS_OK(status)) goto done;
304 done:
305 wbsrv_samba3_async_auth_epilogue(status, s3call);
309 Find the name of a suitable domain controller, by query on the
310 netlogon pipe to the DC.
313 static void getdcname_recv_dc(struct composite_context *ctx);
315 NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
317 struct composite_context *ctx;
318 struct wbsrv_service *service =
319 s3call->wbconn->listen_socket->service;
321 DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
323 ctx = wb_cmd_getdcname_send(s3call, service,
324 s3call->request.domain_name);
325 NT_STATUS_HAVE_NO_MEMORY(ctx);
327 ctx->async.fn = getdcname_recv_dc;
328 ctx->async.private_data = s3call;
329 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
330 return NT_STATUS_OK;
333 static void getdcname_recv_dc(struct composite_context *ctx)
335 struct wbsrv_samba3_call *s3call =
336 talloc_get_type(ctx->async.private_data,
337 struct wbsrv_samba3_call);
338 const char *dcname;
339 NTSTATUS status;
341 status = wb_cmd_getdcname_recv(ctx, s3call, &dcname);
342 if (!NT_STATUS_IS_OK(status)) goto done;
344 s3call->response.result = WINBINDD_OK;
345 WBSRV_SAMBA3_SET_STRING(s3call->response.data.dc_name, dcname);
347 done:
348 wbsrv_samba3_async_epilogue(status, s3call);
352 Lookup a user's domain groups
355 static void userdomgroups_recv_groups(struct composite_context *ctx);
357 NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
359 struct composite_context *ctx;
360 struct dom_sid *sid;
362 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
364 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
365 if (sid == NULL) {
366 DEBUG(5, ("Could not parse sid %s\n",
367 s3call->request.data.sid));
368 return NT_STATUS_NO_MEMORY;
371 ctx = wb_cmd_userdomgroups_send(
372 s3call, s3call->wbconn->listen_socket->service, sid);
373 NT_STATUS_HAVE_NO_MEMORY(ctx);
375 ctx->async.fn = userdomgroups_recv_groups;
376 ctx->async.private_data = s3call;
377 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
378 return NT_STATUS_OK;
381 static void userdomgroups_recv_groups(struct composite_context *ctx)
383 struct wbsrv_samba3_call *s3call =
384 talloc_get_type(ctx->async.private_data,
385 struct wbsrv_samba3_call);
386 int i, num_sids;
387 struct dom_sid **sids;
388 char *sids_string;
389 NTSTATUS status;
391 status = wb_cmd_userdomgroups_recv(ctx, s3call, &num_sids, &sids);
392 if (!NT_STATUS_IS_OK(status)) goto done;
394 sids_string = talloc_strdup(s3call, "");
395 if (sids_string == NULL) {
396 status = NT_STATUS_NO_MEMORY;
397 goto done;
400 for (i=0; i<num_sids; i++) {
401 sids_string = talloc_asprintf_append_buffer(
402 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
405 if (sids_string == NULL) {
406 status = NT_STATUS_NO_MEMORY;
407 goto done;
410 s3call->response.result = WINBINDD_OK;
411 s3call->response.extra_data.data = sids_string;
412 s3call->response.length += strlen(sids_string)+1;
413 s3call->response.data.num_entries = num_sids;
415 done:
416 wbsrv_samba3_async_epilogue(status, s3call);
420 Lookup the list of SIDs for a user
422 static void usersids_recv_sids(struct composite_context *ctx);
424 NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call)
426 struct composite_context *ctx;
427 struct dom_sid *sid;
429 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
431 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
432 if (sid == NULL) {
433 DEBUG(5, ("Could not parse sid %s\n",
434 s3call->request.data.sid));
435 return NT_STATUS_NO_MEMORY;
438 ctx = wb_cmd_usersids_send(
439 s3call, s3call->wbconn->listen_socket->service, sid);
440 NT_STATUS_HAVE_NO_MEMORY(ctx);
442 ctx->async.fn = usersids_recv_sids;
443 ctx->async.private_data = s3call;
444 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
445 return NT_STATUS_OK;
448 static void usersids_recv_sids(struct composite_context *ctx)
450 struct wbsrv_samba3_call *s3call =
451 talloc_get_type(ctx->async.private_data,
452 struct wbsrv_samba3_call);
453 int i, num_sids;
454 struct dom_sid **sids;
455 char *sids_string;
456 NTSTATUS status;
458 status = wb_cmd_usersids_recv(ctx, s3call, &num_sids, &sids);
459 if (!NT_STATUS_IS_OK(status)) goto done;
461 sids_string = talloc_strdup(s3call, "");
462 if (sids_string == NULL) {
463 status = NT_STATUS_NO_MEMORY;
464 goto done;
467 for (i=0; i<num_sids; i++) {
468 sids_string = talloc_asprintf_append_buffer(
469 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
470 if (sids_string == NULL) {
471 status = NT_STATUS_NO_MEMORY;
472 goto done;
476 s3call->response.result = WINBINDD_OK;
477 s3call->response.extra_data.data = sids_string;
478 s3call->response.length += strlen(sids_string);
479 s3call->response.data.num_entries = num_sids;
481 /* Hmmmm. Nasty protocol -- who invented the zeros between the
482 * SIDs? Hmmm. Could have been me -- vl */
484 while (*sids_string != '\0') {
485 if ((*sids_string) == '\n') {
486 *sids_string = '\0';
488 sids_string += 1;
491 done:
492 wbsrv_samba3_async_epilogue(status, s3call);
496 Lookup a DOMAIN\\user style name, and return a SID
499 static void lookupname_recv_sid(struct composite_context *ctx);
501 NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
503 struct composite_context *ctx;
504 struct wbsrv_service *service =
505 s3call->wbconn->listen_socket->service;
507 DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
509 ctx = wb_cmd_lookupname_send(s3call, service,
510 s3call->request.data.name.dom_name,
511 s3call->request.data.name.name);
512 NT_STATUS_HAVE_NO_MEMORY(ctx);
514 /* setup the callbacks */
515 ctx->async.fn = lookupname_recv_sid;
516 ctx->async.private_data = s3call;
517 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
518 return NT_STATUS_OK;
521 static void lookupname_recv_sid(struct composite_context *ctx)
523 struct wbsrv_samba3_call *s3call =
524 talloc_get_type(ctx->async.private_data,
525 struct wbsrv_samba3_call);
526 struct wb_sid_object *sid;
527 NTSTATUS status;
529 status = wb_cmd_lookupname_recv(ctx, s3call, &sid);
530 if (!NT_STATUS_IS_OK(status)) goto done;
532 s3call->response.result = WINBINDD_OK;
533 s3call->response.data.sid.type = sid->type;
534 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid,
535 dom_sid_string(s3call, sid->sid));
537 done:
538 wbsrv_samba3_async_epilogue(status, s3call);
542 Lookup a SID, and return a DOMAIN\\user style name
545 static void lookupsid_recv_name(struct composite_context *ctx);
547 NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
549 struct composite_context *ctx;
550 struct wbsrv_service *service =
551 s3call->wbconn->listen_socket->service;
552 struct dom_sid *sid;
554 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
556 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
557 if (sid == NULL) {
558 DEBUG(5, ("Could not parse sid %s\n",
559 s3call->request.data.sid));
560 return NT_STATUS_NO_MEMORY;
563 ctx = wb_cmd_lookupsid_send(s3call, service, sid);
564 NT_STATUS_HAVE_NO_MEMORY(ctx);
566 /* setup the callbacks */
567 ctx->async.fn = lookupsid_recv_name;
568 ctx->async.private_data = s3call;
569 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
570 return NT_STATUS_OK;
573 static void lookupsid_recv_name(struct composite_context *ctx)
575 struct wbsrv_samba3_call *s3call =
576 talloc_get_type(ctx->async.private_data,
577 struct wbsrv_samba3_call);
578 struct wb_sid_object *sid;
579 NTSTATUS status;
581 status = wb_cmd_lookupsid_recv(ctx, s3call, &sid);
582 if (!NT_STATUS_IS_OK(status)) goto done;
584 s3call->response.result = WINBINDD_OK;
585 s3call->response.data.name.type = sid->type;
586 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.dom_name,
587 sid->domain);
588 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.name, sid->name);
590 done:
591 wbsrv_samba3_async_epilogue(status, s3call);
595 Challenge-response authentication. This interface is used by
596 ntlm_auth and the smbd auth subsystem to pass NTLM authentication
597 requests along a common pipe to the domain controller.
599 The return value (in the async reply) may include the 'info3'
600 (effectivly most things you would want to know about the user), or
601 the NT and LM session keys seperated.
604 static void pam_auth_crap_recv(struct composite_context *ctx);
606 NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
608 struct composite_context *ctx;
609 struct wbsrv_service *service =
610 s3call->wbconn->listen_socket->service;
611 DATA_BLOB chal, nt_resp, lm_resp;
613 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
615 chal.data = s3call->request.data.auth_crap.chal;
616 chal.length = sizeof(s3call->request.data.auth_crap.chal);
617 nt_resp.data = (uint8_t *)s3call->request.data.auth_crap.nt_resp;
618 nt_resp.length = s3call->request.data.auth_crap.nt_resp_len;
619 lm_resp.data = (uint8_t *)s3call->request.data.auth_crap.lm_resp;
620 lm_resp.length = s3call->request.data.auth_crap.lm_resp_len;
622 ctx = wb_cmd_pam_auth_crap_send(
623 s3call, service,
624 s3call->request.data.auth_crap.logon_parameters,
625 s3call->request.data.auth_crap.domain,
626 s3call->request.data.auth_crap.user,
627 s3call->request.data.auth_crap.workstation,
628 chal, nt_resp, lm_resp);
629 NT_STATUS_HAVE_NO_MEMORY(ctx);
631 ctx->async.fn = pam_auth_crap_recv;
632 ctx->async.private_data = s3call;
633 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
634 return NT_STATUS_OK;
637 static void pam_auth_crap_recv(struct composite_context *ctx)
639 struct wbsrv_samba3_call *s3call =
640 talloc_get_type(ctx->async.private_data,
641 struct wbsrv_samba3_call);
642 NTSTATUS status;
643 DATA_BLOB info3;
644 struct netr_UserSessionKey user_session_key;
645 struct netr_LMSessionKey lm_key;
646 char *unix_username;
648 status = wb_cmd_pam_auth_crap_recv(ctx, s3call, &info3,
649 &user_session_key, &lm_key, &unix_username);
650 if (!NT_STATUS_IS_OK(status)) goto done;
652 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
653 memcpy(s3call->response.data.auth.user_session_key,
654 &user_session_key.key,
655 sizeof(s3call->response.data.auth.user_session_key));
658 if (s3call->request.flags & WBFLAG_PAM_INFO3_TEXT) {
659 status = wb_samba3_append_info3_as_txt(ctx, s3call, info3);
660 if (!NT_STATUS_IS_OK(status)) {
661 DEBUG(10,("Failed to append INFO3 (TXT): %s\n",
662 nt_errstr(status)));
663 goto done;
667 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
668 s3call->response.extra_data.data = info3.data;
669 s3call->response.length += info3.length;
672 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
673 memcpy(s3call->response.data.auth.first_8_lm_hash,
674 lm_key.key,
675 sizeof(s3call->response.data.auth.first_8_lm_hash));
678 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
679 s3call->response.extra_data.data = unix_username;
680 s3call->response.length += strlen(unix_username)+1;
683 done:
684 wbsrv_samba3_async_auth_epilogue(status, s3call);
687 /* Plaintext authentication
689 This interface is used by ntlm_auth in it's 'basic' authentication
690 mode, as well as by pam_winbind to authenticate users where we are
691 given a plaintext password.
694 static void pam_auth_recv(struct composite_context *ctx);
696 NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
698 struct composite_context *ctx;
699 struct wbsrv_service *service =
700 s3call->wbconn->listen_socket->service;
701 struct cli_credentials *credentials;
702 char *user, *domain;
704 if (!wb_samba3_split_username(s3call, s3call->wbconn->lp_ctx,
705 s3call->request.data.auth.user,
706 &domain, &user)) {
707 return NT_STATUS_NO_SUCH_USER;
710 credentials = cli_credentials_init(s3call);
711 if (!credentials) {
712 return NT_STATUS_NO_MEMORY;
714 cli_credentials_set_conf(credentials, service->task->lp_ctx);
715 cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
716 cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
718 cli_credentials_set_password(credentials, s3call->request.data.auth.pass, CRED_SPECIFIED);
720 ctx = wb_cmd_pam_auth_send(s3call, service, credentials);
721 NT_STATUS_HAVE_NO_MEMORY(ctx);
723 ctx->async.fn = pam_auth_recv;
724 ctx->async.private_data = s3call;
725 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
726 return NT_STATUS_OK;
729 static void pam_auth_recv(struct composite_context *ctx)
731 struct wbsrv_samba3_call *s3call =
732 talloc_get_type(ctx->async.private_data,
733 struct wbsrv_samba3_call);
734 NTSTATUS status;
735 DATA_BLOB info3;
736 struct netr_UserSessionKey user_session_key;
737 struct netr_LMSessionKey lm_key;
738 char *unix_username;
740 status = wb_cmd_pam_auth_recv(ctx, s3call, &info3,
741 &user_session_key, &lm_key, &unix_username);
743 if (!NT_STATUS_IS_OK(status)) goto done;
745 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
746 memcpy(s3call->response.data.auth.user_session_key,
747 &user_session_key.key,
748 sizeof(s3call->response.data.auth.user_session_key));
751 if (s3call->request.flags & WBFLAG_PAM_INFO3_TEXT) {
752 status = wb_samba3_append_info3_as_txt(ctx, s3call, info3);
753 if (!NT_STATUS_IS_OK(status)) {
754 DEBUG(10,("Failed to append INFO3 (TXT): %s\n",
755 nt_errstr(status)));
756 goto done;
760 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
761 s3call->response.extra_data.data = info3.data;
762 s3call->response.length += info3.length;
765 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
766 memcpy(s3call->response.data.auth.first_8_lm_hash,
767 lm_key.key,
768 sizeof(s3call->response.data.auth.first_8_lm_hash));
771 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
772 s3call->response.extra_data.data = unix_username;
773 s3call->response.length += strlen(unix_username)+1;
777 done:
778 wbsrv_samba3_async_auth_epilogue(status, s3call);
782 List trusted domains
785 static void list_trustdom_recv_doms(struct composite_context *ctx);
787 NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
789 struct composite_context *ctx;
790 struct wbsrv_service *service =
791 s3call->wbconn->listen_socket->service;
793 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
795 ctx = wb_cmd_list_trustdoms_send(s3call, service);
796 NT_STATUS_HAVE_NO_MEMORY(ctx);
798 ctx->async.fn = list_trustdom_recv_doms;
799 ctx->async.private_data = s3call;
800 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
801 return NT_STATUS_OK;
804 static void list_trustdom_recv_doms(struct composite_context *ctx)
806 struct wbsrv_samba3_call *s3call =
807 talloc_get_type(ctx->async.private_data,
808 struct wbsrv_samba3_call);
809 int i, num_domains;
810 struct wb_dom_info **domains;
811 NTSTATUS status;
812 char *result;
814 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
815 &domains);
816 if (!NT_STATUS_IS_OK(status)) goto done;
818 result = talloc_strdup(s3call, "");
819 if (result == NULL) {
820 status = NT_STATUS_NO_MEMORY;
821 goto done;
824 for (i=0; i<num_domains; i++) {
825 result = talloc_asprintf_append_buffer(
826 result, "%s\\%s\\%s",
827 domains[i]->name, domains[i]->name,
828 dom_sid_string(s3call, domains[i]->sid));
831 if (result == NULL) {
832 status = NT_STATUS_NO_MEMORY;
833 goto done;
836 s3call->response.result = WINBINDD_OK;
837 if (num_domains > 0) {
838 s3call->response.extra_data.data = result;
839 s3call->response.length += strlen(result)+1;
842 done:
843 wbsrv_samba3_async_epilogue(status, s3call);
846 /* list groups */
847 static void list_groups_recv(struct composite_context *ctx);
849 NTSTATUS wbsrv_samba3_list_groups(struct wbsrv_samba3_call *s3call)
851 struct composite_context *ctx;
852 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
854 DEBUG(5, ("wbsrv_samba4_list_groups called\n"));
856 ctx = wb_cmd_list_groups_send(s3call, service,
857 s3call->request.domain_name);
858 NT_STATUS_HAVE_NO_MEMORY(ctx);
860 ctx->async.fn = list_groups_recv;
861 ctx->async.private_data = s3call;
862 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
863 return NT_STATUS_OK;
866 static void list_groups_recv(struct composite_context *ctx)
868 struct wbsrv_samba3_call *s3call = talloc_get_type_abort(
869 ctx->async.private_data,
870 struct wbsrv_samba3_call);
871 uint32_t extra_data_len;
872 char *extra_data;
873 NTSTATUS status;
875 DEBUG(5, ("list_groups_recv called\n"));
877 status = wb_cmd_list_groups_recv(ctx, s3call, &extra_data_len,
878 &extra_data);
880 if (NT_STATUS_IS_OK(status)) {
881 s3call->response.extra_data.data = extra_data;
882 s3call->response.length += extra_data_len;
883 if (extra_data) {
884 s3call->response.length += 1;
888 wbsrv_samba3_async_epilogue(status, s3call);
891 /* List users */
893 static void list_users_recv(struct composite_context *ctx);
895 NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
897 struct composite_context *ctx;
898 struct wbsrv_service *service =
899 s3call->wbconn->listen_socket->service;
901 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
903 ctx = wb_cmd_list_users_send(s3call, service,
904 s3call->request.domain_name);
905 NT_STATUS_HAVE_NO_MEMORY(ctx);
907 ctx->async.fn = list_users_recv;
908 ctx->async.private_data = s3call;
909 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
910 return NT_STATUS_OK;
913 static void list_users_recv(struct composite_context *ctx)
915 struct wbsrv_samba3_call *s3call =
916 talloc_get_type(ctx->async.private_data,
917 struct wbsrv_samba3_call);
918 uint32_t extra_data_len;
919 char *extra_data;
920 NTSTATUS status;
922 DEBUG(5, ("list_users_recv called\n"));
924 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
925 &extra_data);
927 if (NT_STATUS_IS_OK(status)) {
928 s3call->response.extra_data.data = extra_data;
929 s3call->response.length += extra_data_len;
930 if (extra_data) {
931 s3call->response.length += 1;
935 wbsrv_samba3_async_epilogue(status, s3call);
938 /* NSS calls */
940 static void getpwnam_recv(struct composite_context *ctx);
942 NTSTATUS wbsrv_samba3_getpwnam(struct wbsrv_samba3_call *s3call)
944 struct composite_context *ctx;
945 struct wbsrv_service *service =
946 s3call->wbconn->listen_socket->service;
948 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
950 ctx = wb_cmd_getpwnam_send(s3call, service,
951 s3call->request.data.username);
952 NT_STATUS_HAVE_NO_MEMORY(ctx);
954 ctx->async.fn = getpwnam_recv;
955 ctx->async.private_data = s3call;
956 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
957 return NT_STATUS_OK;
960 static void getpwnam_recv(struct composite_context *ctx)
962 struct wbsrv_samba3_call *s3call =
963 talloc_get_type(ctx->async.private_data,
964 struct wbsrv_samba3_call);
965 NTSTATUS status;
966 struct winbindd_pw *pw;
968 DEBUG(5, ("getpwnam_recv called\n"));
970 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
971 if(NT_STATUS_IS_OK(status))
972 s3call->response.data.pw = *pw;
974 wbsrv_samba3_async_epilogue(status, s3call);
977 static void getpwuid_recv(struct composite_context *ctx);
979 NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
981 struct composite_context *ctx;
982 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
984 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
986 ctx = wb_cmd_getpwuid_send(s3call, service,
987 s3call->request.data.uid);
988 NT_STATUS_HAVE_NO_MEMORY(ctx);
990 ctx->async.fn = getpwuid_recv;
991 ctx->async.private_data = s3call;
992 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
993 return NT_STATUS_OK;
996 static void getpwuid_recv(struct composite_context *ctx)
998 struct wbsrv_samba3_call *s3call =
999 talloc_get_type(ctx->async.private_data,
1000 struct wbsrv_samba3_call);
1001 NTSTATUS status;
1002 struct winbindd_pw *pw;
1004 DEBUG(5, ("getpwuid_recv called\n"));
1006 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
1007 if (NT_STATUS_IS_OK(status))
1008 s3call->response.data.pw = *pw;
1010 wbsrv_samba3_async_epilogue(status, s3call);
1013 static void setpwent_recv(struct composite_context *ctx);
1015 NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
1017 struct composite_context *ctx;
1018 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1020 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
1022 ctx = wb_cmd_setpwent_send(s3call, service);
1023 NT_STATUS_HAVE_NO_MEMORY(ctx);
1025 ctx->async.fn = setpwent_recv;
1026 ctx->async.private_data = s3call;
1027 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1028 return NT_STATUS_OK;
1031 static void setpwent_recv(struct composite_context *ctx)
1033 struct wbsrv_samba3_call *s3call =
1034 talloc_get_type(ctx->async.private_data,
1035 struct wbsrv_samba3_call);
1036 NTSTATUS status;
1037 struct wbsrv_pwent *pwent;
1039 DEBUG(5, ("setpwent_recv called\n"));
1041 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
1042 if (NT_STATUS_IS_OK(status)) {
1043 s3call->wbconn->protocol_private_data = pwent;
1046 wbsrv_samba3_async_epilogue(status, s3call);
1049 static void getpwent_recv(struct composite_context *ctx);
1051 NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
1053 struct composite_context *ctx;
1054 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1055 struct wbsrv_pwent *pwent;
1057 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
1059 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
1061 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
1062 struct wbsrv_pwent);
1063 NT_STATUS_HAVE_NO_MEMORY(pwent);
1065 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
1066 s3call->request.data.num_entries);
1067 NT_STATUS_HAVE_NO_MEMORY(ctx);
1069 ctx->async.fn = getpwent_recv;
1070 ctx->async.private_data = s3call;
1071 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1072 return NT_STATUS_OK;
1075 static void getpwent_recv(struct composite_context *ctx)
1077 struct wbsrv_samba3_call *s3call =
1078 talloc_get_type(ctx->async.private_data,
1079 struct wbsrv_samba3_call);
1080 NTSTATUS status;
1081 struct winbindd_pw *pw;
1082 uint32_t num_users;
1084 DEBUG(5, ("getpwent_recv called\n"));
1086 status = wb_cmd_getpwent_recv(ctx, s3call, &pw, &num_users);
1087 if (NT_STATUS_IS_OK(status)) {
1088 uint32_t extra_len = sizeof(struct winbindd_pw) * num_users;
1090 s3call->response.data.num_entries = num_users;
1091 s3call->response.extra_data.data = pw;
1092 s3call->response.length += extra_len;
1095 wbsrv_samba3_async_epilogue(status, s3call);
1098 NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
1100 struct wbsrv_pwent *pwent =
1101 talloc_get_type(s3call->wbconn->protocol_private_data,
1102 struct wbsrv_pwent);
1103 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
1105 talloc_free(pwent);
1107 s3call->wbconn->protocol_private_data = NULL;
1108 s3call->response.result = WINBINDD_OK;
1109 return NT_STATUS_OK;
1113 static void getgrnam_recv(struct composite_context *ctx);
1115 NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
1117 struct composite_context *ctx;
1118 struct wbsrv_service *service =
1119 s3call->wbconn->listen_socket->service;
1121 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
1123 ctx = wb_cmd_getgrnam_send(s3call, service,
1124 s3call->request.data.groupname);
1125 NT_STATUS_HAVE_NO_MEMORY(ctx);
1127 ctx->async.fn = getgrnam_recv;
1128 ctx->async.private_data = s3call;
1129 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1130 return NT_STATUS_OK;
1133 static void getgrnam_recv(struct composite_context *ctx)
1135 struct wbsrv_samba3_call *s3call =
1136 talloc_get_type(ctx->async.private_data,
1137 struct wbsrv_samba3_call);
1138 NTSTATUS status;
1139 struct winbindd_gr *gr;
1141 DEBUG(5, ("getgrnam_recv called\n"));
1143 status = wb_cmd_getgrnam_recv(ctx, s3call, &gr);
1144 if(NT_STATUS_IS_OK(status))
1145 s3call->response.data.gr = *gr;
1147 wbsrv_samba3_async_epilogue(status, s3call);
1150 static void getgrgid_recv(struct composite_context *ctx);
1152 NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
1154 struct composite_context *ctx;
1155 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1157 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
1159 ctx = wb_cmd_getgrgid_send(s3call, service,
1160 s3call->request.data.gid);
1161 NT_STATUS_HAVE_NO_MEMORY(ctx);
1163 ctx->async.fn = getgrgid_recv;
1164 ctx->async.private_data = s3call;
1165 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1166 return NT_STATUS_OK;
1169 static void getgrgid_recv(struct composite_context *ctx)
1171 struct wbsrv_samba3_call *s3call =
1172 talloc_get_type(ctx->async.private_data,
1173 struct wbsrv_samba3_call);
1174 NTSTATUS status;
1175 struct winbindd_gr *gr;
1177 DEBUG(5, ("getgrgid_recv called\n"));
1179 status = wb_cmd_getgrgid_recv(ctx, s3call, &gr);
1180 if (NT_STATUS_IS_OK(status))
1181 s3call->response.data.gr = *gr;
1183 wbsrv_samba3_async_epilogue(status, s3call);
1186 NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
1188 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
1189 s3call->response.result = WINBINDD_ERROR;
1190 return NT_STATUS_OK;
1193 static void setgrent_recv(struct composite_context *ctx)
1195 struct wbsrv_samba3_call *s3call =
1196 talloc_get_type(ctx->async.private_data,
1197 struct wbsrv_samba3_call);
1198 NTSTATUS status;
1199 struct wbsrv_grent *grent;
1201 DEBUG(5, ("setpwent_recv called\n"));
1203 status = wb_cmd_setgrent_recv(ctx, s3call->wbconn, &grent);
1204 if (NT_STATUS_IS_OK(status)) {
1205 s3call->wbconn->protocol_private_data = grent;
1208 wbsrv_samba3_async_epilogue(status, s3call);
1211 NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
1213 struct composite_context *ctx;
1214 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1216 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
1218 ctx = wb_cmd_setgrent_send(s3call, service);
1219 NT_STATUS_HAVE_NO_MEMORY(ctx);
1221 ctx->async.fn = setgrent_recv;
1222 ctx->async.private_data = s3call;
1223 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1224 return NT_STATUS_OK;
1227 static void getgrent_recv(struct composite_context *ctx)
1229 struct wbsrv_samba3_call *s3call =
1230 talloc_get_type(ctx->async.private_data,
1231 struct wbsrv_samba3_call);
1232 NTSTATUS status;
1233 struct winbindd_gr *gr;
1234 uint32_t num_groups;
1236 DEBUG(5, ("getgrent_recv called\n"));
1238 status = wb_cmd_getgrent_recv(ctx, s3call, &gr, &num_groups);
1239 if (NT_STATUS_IS_OK(status)) {
1240 uint32_t extra_len = sizeof(struct winbindd_gr) * num_groups;
1242 s3call->response.data.num_entries = num_groups;
1243 s3call->response.extra_data.data = gr;
1244 s3call->response.length += extra_len;
1247 wbsrv_samba3_async_epilogue(status, s3call);
1250 NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
1252 struct composite_context *ctx;
1253 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1254 struct wbsrv_grent *grent;
1256 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
1258 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
1260 grent = talloc_get_type(s3call->wbconn->protocol_private_data,
1261 struct wbsrv_grent);
1262 NT_STATUS_HAVE_NO_MEMORY(grent);
1264 ctx = wb_cmd_getgrent_send(s3call, service, grent,
1265 s3call->request.data.num_entries);
1266 NT_STATUS_HAVE_NO_MEMORY(ctx);
1268 ctx->async.fn = getgrent_recv;
1269 ctx->async.private_data = s3call;
1270 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1271 return NT_STATUS_OK;
1274 NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
1276 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
1277 s3call->response.result = WINBINDD_OK;
1278 return NT_STATUS_OK;
1281 static void sid2uid_recv(struct composite_context *ctx);
1283 NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
1285 struct composite_context *ctx;
1286 struct wbsrv_service *service =
1287 s3call->wbconn->listen_socket->service;
1288 struct dom_sid *sid;
1290 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
1292 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1293 NT_STATUS_HAVE_NO_MEMORY(sid);
1295 ctx = wb_sid2uid_send(s3call, service, sid);
1296 NT_STATUS_HAVE_NO_MEMORY(ctx);
1298 ctx->async.fn = sid2uid_recv;
1299 ctx->async.private_data = s3call;
1300 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1301 return NT_STATUS_OK;
1305 static void sid2uid_recv(struct composite_context *ctx)
1307 struct wbsrv_samba3_call *s3call =
1308 talloc_get_type(ctx->async.private_data,
1309 struct wbsrv_samba3_call);
1310 NTSTATUS status;
1312 DEBUG(5, ("sid2uid_recv called\n"));
1314 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
1316 wbsrv_samba3_async_epilogue(status, s3call);
1319 static void sid2gid_recv(struct composite_context *ctx);
1321 NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
1323 struct composite_context *ctx;
1324 struct wbsrv_service *service =
1325 s3call->wbconn->listen_socket->service;
1326 struct dom_sid *sid;
1328 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
1330 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1331 NT_STATUS_HAVE_NO_MEMORY(sid);
1333 ctx = wb_sid2gid_send(s3call, service, sid);
1334 NT_STATUS_HAVE_NO_MEMORY(ctx);
1336 ctx->async.fn = sid2gid_recv;
1337 ctx->async.private_data = s3call;
1338 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1339 return NT_STATUS_OK;
1343 static void sid2gid_recv(struct composite_context *ctx)
1345 struct wbsrv_samba3_call *s3call =
1346 talloc_get_type(ctx->async.private_data,
1347 struct wbsrv_samba3_call);
1348 NTSTATUS status;
1350 DEBUG(5, ("sid2gid_recv called\n"));
1352 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
1354 wbsrv_samba3_async_epilogue(status, s3call);
1357 static void uid2sid_recv(struct composite_context *ctx);
1359 NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
1361 struct composite_context *ctx;
1362 struct wbsrv_service *service =
1363 s3call->wbconn->listen_socket->service;
1365 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1367 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
1368 NT_STATUS_HAVE_NO_MEMORY(ctx);
1370 ctx->async.fn = uid2sid_recv;
1371 ctx->async.private_data = s3call;
1372 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1373 return NT_STATUS_OK;
1377 static void uid2sid_recv(struct composite_context *ctx)
1379 struct wbsrv_samba3_call *s3call =
1380 talloc_get_type(ctx->async.private_data,
1381 struct wbsrv_samba3_call);
1382 NTSTATUS status;
1383 struct dom_sid *sid;
1384 char *sid_str;
1386 DEBUG(5, ("uid2sid_recv called\n"));
1388 status = wb_uid2sid_recv(ctx, s3call, &sid);
1389 if(NT_STATUS_IS_OK(status)) {
1390 sid_str = dom_sid_string(s3call, sid);
1392 /* If the conversion failed, bail out with a failure. */
1393 if (sid_str == NULL)
1394 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1396 /* But we assume this worked, so we'll set the string. Work
1397 * done. */
1398 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1399 s3call->response.data.sid.type = SID_NAME_USER;
1402 wbsrv_samba3_async_epilogue(status, s3call);
1405 static void gid2sid_recv(struct composite_context *ctx);
1407 NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1409 struct composite_context *ctx;
1410 struct wbsrv_service *service =
1411 s3call->wbconn->listen_socket->service;
1413 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1415 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1416 NT_STATUS_HAVE_NO_MEMORY(ctx);
1418 ctx->async.fn = gid2sid_recv;
1419 ctx->async.private_data = s3call;
1420 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1421 return NT_STATUS_OK;
1425 static void gid2sid_recv(struct composite_context *ctx)
1427 struct wbsrv_samba3_call *s3call =
1428 talloc_get_type(ctx->async.private_data,
1429 struct wbsrv_samba3_call);
1430 NTSTATUS status;
1431 struct dom_sid *sid;
1432 char *sid_str;
1434 DEBUG(5, ("gid2sid_recv called\n"));
1436 status = wb_gid2sid_recv(ctx, s3call, &sid);
1437 if(NT_STATUS_IS_OK(status)) {
1438 sid_str = dom_sid_string(s3call, sid);
1440 if (sid_str == NULL)
1441 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1443 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1444 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1447 wbsrv_samba3_async_epilogue(status, s3call);