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/>.
25 #include "winbind/wb_server.h"
26 #include "param/param.h"
27 #include "winbind/wb_helper.h"
28 #include "libcli/composite/composite.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,
43 struct netr_SamInfo3 *info3;
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 */
55 ndr_err = ndr_pull_struct_blob(&info3b,
57 lp_iconv_convenience(s3call->wbconn->lp_ctx),
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++) {
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",
126 info3->sids[i].attributes);
127 NT_STATUS_HAVE_NO_MEMORY(ex);
132 s3call->response.extra_data.data = ex;
133 s3call->response.length += talloc_get_size(ex);
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;
149 resp->result = WINBINDD_OK;
152 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
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;
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;
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);
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));
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));
216 NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
218 struct loadparm_context *lp_ctx = s3call->wbconn->listen_socket->service->task->lp_ctx;
219 const char *priv_socket_dir = lp_winbindd_privileged_socket_directory(lp_ctx);
221 s3call->response.result = WINBINDD_OK;
222 s3call->response.extra_data.data = discard_const(priv_socket_dir);
224 s3call->response.length += strlen(priv_socket_dir) + 1;
228 NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
230 s3call->response.result = WINBINDD_OK;
234 NTSTATUS wbsrv_samba3_domain_info(struct wbsrv_samba3_call *s3call)
236 DEBUG(5, ("wbsrv_samba3_domain_info called, stub\n"));
237 s3call->response.result = WINBINDD_OK;
238 fstrcpy(s3call->response.data.domain_info.name,
239 s3call->request.domain_name);
240 fstrcpy(s3call->response.data.domain_info.alt_name,
241 s3call->request.domain_name);
242 fstrcpy(s3call->response.data.domain_info.sid, "S-1-2-3-4");
243 s3call->response.data.domain_info.native_mode = false;
244 s3call->response.data.domain_info.active_directory = false;
245 s3call->response.data.domain_info.primary = false;
250 /* Plaintext authentication
252 This interface is used by ntlm_auth in it's 'basic' authentication
253 mode, as well as by pam_winbind to authenticate users where we are
254 given a plaintext password.
257 static void check_machacc_recv(struct composite_context *ctx);
259 NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
262 struct cli_credentials *creds;
263 struct composite_context *ctx;
264 struct wbsrv_service *service =
265 s3call->wbconn->listen_socket->service;
267 /* Create a credentials structure */
268 creds = cli_credentials_init(s3call);
270 return NT_STATUS_NO_MEMORY;
273 cli_credentials_set_conf(creds, service->task->lp_ctx);
275 /* Connect the machine account to the credentials */
276 status = cli_credentials_set_machine_account(creds, service->task->lp_ctx);
277 if (!NT_STATUS_IS_OK(status)) {
282 ctx = wb_cmd_pam_auth_send(s3call, service, creds);
286 return NT_STATUS_NO_MEMORY;
289 ctx->async.fn = check_machacc_recv;
290 ctx->async.private_data = s3call;
291 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
295 static void check_machacc_recv(struct composite_context *ctx)
297 struct wbsrv_samba3_call *s3call =
298 talloc_get_type(ctx->async.private_data,
299 struct wbsrv_samba3_call);
302 status = wb_cmd_pam_auth_recv(ctx, s3call, NULL, NULL, NULL, NULL);
304 if (!NT_STATUS_IS_OK(status)) goto done;
307 wbsrv_samba3_async_auth_epilogue(status, s3call);
311 Find the name of a suitable domain controller, by query on the
312 netlogon pipe to the DC.
315 static void getdcname_recv_dc(struct composite_context *ctx);
317 NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
319 struct composite_context *ctx;
320 struct wbsrv_service *service =
321 s3call->wbconn->listen_socket->service;
323 DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
325 ctx = wb_cmd_getdcname_send(s3call, service,
326 s3call->request.domain_name);
327 NT_STATUS_HAVE_NO_MEMORY(ctx);
329 ctx->async.fn = getdcname_recv_dc;
330 ctx->async.private_data = s3call;
331 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
335 static void getdcname_recv_dc(struct composite_context *ctx)
337 struct wbsrv_samba3_call *s3call =
338 talloc_get_type(ctx->async.private_data,
339 struct wbsrv_samba3_call);
343 status = wb_cmd_getdcname_recv(ctx, s3call, &dcname);
344 if (!NT_STATUS_IS_OK(status)) goto done;
346 s3call->response.result = WINBINDD_OK;
347 WBSRV_SAMBA3_SET_STRING(s3call->response.data.dc_name, dcname);
350 wbsrv_samba3_async_epilogue(status, s3call);
354 Lookup a user's domain groups
357 static void userdomgroups_recv_groups(struct composite_context *ctx);
359 NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
361 struct composite_context *ctx;
364 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
366 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
368 DEBUG(5, ("Could not parse sid %s\n",
369 s3call->request.data.sid));
370 return NT_STATUS_NO_MEMORY;
373 ctx = wb_cmd_userdomgroups_send(
374 s3call, s3call->wbconn->listen_socket->service, sid);
375 NT_STATUS_HAVE_NO_MEMORY(ctx);
377 ctx->async.fn = userdomgroups_recv_groups;
378 ctx->async.private_data = s3call;
379 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
383 static void userdomgroups_recv_groups(struct composite_context *ctx)
385 struct wbsrv_samba3_call *s3call =
386 talloc_get_type(ctx->async.private_data,
387 struct wbsrv_samba3_call);
388 uint32_t i, num_sids;
389 struct dom_sid **sids;
393 status = wb_cmd_userdomgroups_recv(ctx, s3call, &num_sids, &sids);
394 if (!NT_STATUS_IS_OK(status)) goto done;
396 sids_string = talloc_strdup(s3call, "");
397 if (sids_string == NULL) {
398 status = NT_STATUS_NO_MEMORY;
402 for (i=0; i<num_sids; i++) {
403 sids_string = talloc_asprintf_append_buffer(
404 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
407 if (sids_string == NULL) {
408 status = NT_STATUS_NO_MEMORY;
412 s3call->response.result = WINBINDD_OK;
413 s3call->response.extra_data.data = sids_string;
414 s3call->response.length += strlen(sids_string)+1;
415 s3call->response.data.num_entries = num_sids;
418 wbsrv_samba3_async_epilogue(status, s3call);
422 Lookup the list of SIDs for a user
424 static void usersids_recv_sids(struct composite_context *ctx);
426 NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call)
428 struct composite_context *ctx;
431 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
433 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
435 DEBUG(5, ("Could not parse sid %s\n",
436 s3call->request.data.sid));
437 return NT_STATUS_NO_MEMORY;
440 ctx = wb_cmd_usersids_send(
441 s3call, s3call->wbconn->listen_socket->service, sid);
442 NT_STATUS_HAVE_NO_MEMORY(ctx);
444 ctx->async.fn = usersids_recv_sids;
445 ctx->async.private_data = s3call;
446 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
450 static void usersids_recv_sids(struct composite_context *ctx)
452 struct wbsrv_samba3_call *s3call =
453 talloc_get_type(ctx->async.private_data,
454 struct wbsrv_samba3_call);
455 uint32_t i, num_sids;
456 struct dom_sid **sids;
460 status = wb_cmd_usersids_recv(ctx, s3call, &num_sids, &sids);
461 if (!NT_STATUS_IS_OK(status)) goto done;
463 sids_string = talloc_strdup(s3call, "");
464 if (sids_string == NULL) {
465 status = NT_STATUS_NO_MEMORY;
469 for (i=0; i<num_sids; i++) {
470 sids_string = talloc_asprintf_append_buffer(
471 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
472 if (sids_string == NULL) {
473 status = NT_STATUS_NO_MEMORY;
478 s3call->response.result = WINBINDD_OK;
479 s3call->response.extra_data.data = sids_string;
480 s3call->response.length += strlen(sids_string);
481 s3call->response.data.num_entries = num_sids;
483 /* Hmmmm. Nasty protocol -- who invented the zeros between the
484 * SIDs? Hmmm. Could have been me -- vl */
486 while (*sids_string != '\0') {
487 if ((*sids_string) == '\n') {
494 wbsrv_samba3_async_epilogue(status, s3call);
498 Lookup a DOMAIN\\user style name, and return a SID
501 static void lookupname_recv_sid(struct composite_context *ctx);
503 NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
505 struct composite_context *ctx;
506 struct wbsrv_service *service =
507 s3call->wbconn->listen_socket->service;
509 DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
511 ctx = wb_cmd_lookupname_send(s3call, service,
512 s3call->request.data.name.dom_name,
513 s3call->request.data.name.name);
514 NT_STATUS_HAVE_NO_MEMORY(ctx);
516 /* setup the callbacks */
517 ctx->async.fn = lookupname_recv_sid;
518 ctx->async.private_data = s3call;
519 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
523 static void lookupname_recv_sid(struct composite_context *ctx)
525 struct wbsrv_samba3_call *s3call =
526 talloc_get_type(ctx->async.private_data,
527 struct wbsrv_samba3_call);
528 struct wb_sid_object *sid;
531 status = wb_cmd_lookupname_recv(ctx, s3call, &sid);
532 if (!NT_STATUS_IS_OK(status)) goto done;
534 s3call->response.result = WINBINDD_OK;
535 s3call->response.data.sid.type = sid->type;
536 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid,
537 dom_sid_string(s3call, sid->sid));
540 wbsrv_samba3_async_epilogue(status, s3call);
544 Lookup a SID, and return a DOMAIN\\user style name
547 static void lookupsid_recv_name(struct composite_context *ctx);
549 NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
551 struct composite_context *ctx;
552 struct wbsrv_service *service =
553 s3call->wbconn->listen_socket->service;
556 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
558 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
560 DEBUG(5, ("Could not parse sid %s\n",
561 s3call->request.data.sid));
562 return NT_STATUS_NO_MEMORY;
565 ctx = wb_cmd_lookupsid_send(s3call, service, sid);
566 NT_STATUS_HAVE_NO_MEMORY(ctx);
568 /* setup the callbacks */
569 ctx->async.fn = lookupsid_recv_name;
570 ctx->async.private_data = s3call;
571 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
575 static void lookupsid_recv_name(struct composite_context *ctx)
577 struct wbsrv_samba3_call *s3call =
578 talloc_get_type(ctx->async.private_data,
579 struct wbsrv_samba3_call);
580 struct wb_sid_object *sid;
583 status = wb_cmd_lookupsid_recv(ctx, s3call, &sid);
584 if (!NT_STATUS_IS_OK(status)) goto done;
586 s3call->response.result = WINBINDD_OK;
587 s3call->response.data.name.type = sid->type;
588 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.dom_name,
590 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.name, sid->name);
593 wbsrv_samba3_async_epilogue(status, s3call);
597 This is a stub function in order to limit error message in the pam_winbind module
599 NTSTATUS wbsrv_samba3_pam_logoff(struct wbsrv_samba3_call *s3call)
602 struct winbindd_response *resp = &s3call->response;
604 status = NT_STATUS_OK;
606 DEBUG(5, ("wbsrv_samba3_pam_logoff called\n"));
607 DEBUG(10, ("Winbind logoff not implemented\n"));
608 resp->result = WINBINDD_OK;
610 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
612 WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
613 get_friendly_nt_error_msg(status));
615 resp->data.auth.pam_error = nt_status_to_pam(status);
616 resp->data.auth.nt_status = NT_STATUS_V(status);
617 DEBUG(5, ("wbsrv_samba3_pam_logoff called\n"));
623 Challenge-response authentication. This interface is used by
624 ntlm_auth and the smbd auth subsystem to pass NTLM authentication
625 requests along a common pipe to the domain controller.
627 The return value (in the async reply) may include the 'info3'
628 (effectivly most things you would want to know about the user), or
629 the NT and LM session keys seperated.
632 static void pam_auth_crap_recv(struct composite_context *ctx);
634 NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
636 struct composite_context *ctx;
637 struct wbsrv_service *service =
638 s3call->wbconn->listen_socket->service;
639 DATA_BLOB chal, nt_resp, lm_resp;
641 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
643 chal.data = s3call->request.data.auth_crap.chal;
644 chal.length = sizeof(s3call->request.data.auth_crap.chal);
645 nt_resp.data = (uint8_t *)s3call->request.data.auth_crap.nt_resp;
646 nt_resp.length = s3call->request.data.auth_crap.nt_resp_len;
647 lm_resp.data = (uint8_t *)s3call->request.data.auth_crap.lm_resp;
648 lm_resp.length = s3call->request.data.auth_crap.lm_resp_len;
650 ctx = wb_cmd_pam_auth_crap_send(
652 s3call->request.data.auth_crap.logon_parameters,
653 s3call->request.data.auth_crap.domain,
654 s3call->request.data.auth_crap.user,
655 s3call->request.data.auth_crap.workstation,
656 chal, nt_resp, lm_resp);
657 NT_STATUS_HAVE_NO_MEMORY(ctx);
659 ctx->async.fn = pam_auth_crap_recv;
660 ctx->async.private_data = s3call;
661 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
665 static void pam_auth_crap_recv(struct composite_context *ctx)
667 struct wbsrv_samba3_call *s3call =
668 talloc_get_type(ctx->async.private_data,
669 struct wbsrv_samba3_call);
672 struct netr_UserSessionKey user_session_key;
673 struct netr_LMSessionKey lm_key;
676 status = wb_cmd_pam_auth_crap_recv(ctx, s3call, &info3,
677 &user_session_key, &lm_key, &unix_username);
678 if (!NT_STATUS_IS_OK(status)) goto done;
680 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
681 memcpy(s3call->response.data.auth.user_session_key,
682 &user_session_key.key,
683 sizeof(s3call->response.data.auth.user_session_key));
686 if (s3call->request.flags & WBFLAG_PAM_INFO3_TEXT) {
687 status = wb_samba3_append_info3_as_txt(ctx, s3call, info3);
688 if (!NT_STATUS_IS_OK(status)) {
689 DEBUG(10,("Failed to append INFO3 (TXT): %s\n",
695 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
696 s3call->response.extra_data.data = info3.data;
697 s3call->response.length += info3.length;
700 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
701 memcpy(s3call->response.data.auth.first_8_lm_hash,
703 sizeof(s3call->response.data.auth.first_8_lm_hash));
706 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
707 WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.unix_username,unix_username);
711 wbsrv_samba3_async_auth_epilogue(status, s3call);
714 /* Plaintext authentication
716 This interface is used by ntlm_auth in it's 'basic' authentication
717 mode, as well as by pam_winbind to authenticate users where we are
718 given a plaintext password.
721 static void pam_auth_recv(struct composite_context *ctx);
723 NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
725 struct composite_context *ctx;
726 struct wbsrv_service *service =
727 s3call->wbconn->listen_socket->service;
728 struct cli_credentials *credentials;
731 if (!wb_samba3_split_username(s3call, s3call->wbconn->lp_ctx,
732 s3call->request.data.auth.user,
734 return NT_STATUS_NO_SUCH_USER;
737 credentials = cli_credentials_init(s3call);
739 return NT_STATUS_NO_MEMORY;
741 cli_credentials_set_conf(credentials, service->task->lp_ctx);
742 cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
743 cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
745 cli_credentials_set_password(credentials, s3call->request.data.auth.pass, CRED_SPECIFIED);
747 ctx = wb_cmd_pam_auth_send(s3call, service, credentials);
748 NT_STATUS_HAVE_NO_MEMORY(ctx);
750 ctx->async.fn = pam_auth_recv;
751 ctx->async.private_data = s3call;
752 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
756 static void pam_auth_recv(struct composite_context *ctx)
758 struct wbsrv_samba3_call *s3call =
759 talloc_get_type(ctx->async.private_data,
760 struct wbsrv_samba3_call);
763 struct netr_UserSessionKey user_session_key;
764 struct netr_LMSessionKey lm_key;
767 status = wb_cmd_pam_auth_recv(ctx, s3call, &info3,
768 &user_session_key, &lm_key, &unix_username);
770 if (!NT_STATUS_IS_OK(status)) goto done;
772 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
773 memcpy(s3call->response.data.auth.user_session_key,
774 &user_session_key.key,
775 sizeof(s3call->response.data.auth.user_session_key));
778 if (s3call->request.flags & WBFLAG_PAM_INFO3_TEXT) {
779 status = wb_samba3_append_info3_as_txt(ctx, s3call, info3);
780 if (!NT_STATUS_IS_OK(status)) {
781 DEBUG(10,("Failed to append INFO3 (TXT): %s\n",
787 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
788 s3call->response.extra_data.data = info3.data;
789 s3call->response.length += info3.length;
792 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
793 memcpy(s3call->response.data.auth.first_8_lm_hash,
795 sizeof(s3call->response.data.auth.first_8_lm_hash));
798 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
799 WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.unix_username,unix_username);
804 wbsrv_samba3_async_auth_epilogue(status, s3call);
811 static void list_trustdom_recv_doms(struct composite_context *ctx);
813 NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
815 struct composite_context *ctx;
816 struct wbsrv_service *service =
817 s3call->wbconn->listen_socket->service;
819 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
821 ctx = wb_cmd_list_trustdoms_send(s3call, service);
822 NT_STATUS_HAVE_NO_MEMORY(ctx);
824 ctx->async.fn = list_trustdom_recv_doms;
825 ctx->async.private_data = s3call;
826 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
830 static void list_trustdom_recv_doms(struct composite_context *ctx)
832 struct wbsrv_samba3_call *s3call =
833 talloc_get_type(ctx->async.private_data,
834 struct wbsrv_samba3_call);
835 uint32_t i, num_domains;
836 struct wb_dom_info **domains;
840 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
842 if (!NT_STATUS_IS_OK(status)) goto done;
844 result = talloc_strdup(s3call, "");
845 if (result == NULL) {
846 status = NT_STATUS_NO_MEMORY;
850 for (i=0; i<num_domains; i++) {
851 result = talloc_asprintf_append_buffer(
852 result, "%s\\%s\\%s",
853 domains[i]->name, domains[i]->name,
854 dom_sid_string(s3call, domains[i]->sid));
857 if (result == NULL) {
858 status = NT_STATUS_NO_MEMORY;
862 s3call->response.result = WINBINDD_OK;
863 if (num_domains > 0) {
864 s3call->response.extra_data.data = result;
865 s3call->response.length += strlen(result)+1;
866 s3call->response.data.num_entries = num_domains;
870 wbsrv_samba3_async_epilogue(status, s3call);
874 static void list_groups_recv(struct composite_context *ctx);
876 NTSTATUS wbsrv_samba3_list_groups(struct wbsrv_samba3_call *s3call)
878 struct composite_context *ctx;
879 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
881 DEBUG(5, ("wbsrv_samba4_list_groups called\n"));
883 ctx = wb_cmd_list_groups_send(s3call, service,
884 s3call->request.domain_name);
885 NT_STATUS_HAVE_NO_MEMORY(ctx);
887 ctx->async.fn = list_groups_recv;
888 ctx->async.private_data = s3call;
889 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
893 static void list_groups_recv(struct composite_context *ctx)
895 struct wbsrv_samba3_call *s3call = talloc_get_type_abort(
896 ctx->async.private_data,
897 struct wbsrv_samba3_call);
898 uint32_t extra_data_len;
903 DEBUG(5, ("list_groups_recv called\n"));
905 status = wb_cmd_list_groups_recv(ctx, s3call, &extra_data_len,
906 &extra_data, &num_groups);
908 if (NT_STATUS_IS_OK(status)) {
909 s3call->response.extra_data.data = extra_data;
910 s3call->response.length += extra_data_len;
912 s3call->response.length += 1;
913 s3call->response.data.num_entries = num_groups;
917 wbsrv_samba3_async_epilogue(status, s3call);
922 static void list_users_recv(struct composite_context *ctx);
924 NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
926 struct composite_context *ctx;
927 struct wbsrv_service *service =
928 s3call->wbconn->listen_socket->service;
930 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
932 ctx = wb_cmd_list_users_send(s3call, service,
933 s3call->request.domain_name);
934 NT_STATUS_HAVE_NO_MEMORY(ctx);
936 ctx->async.fn = list_users_recv;
937 ctx->async.private_data = s3call;
938 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
942 static void list_users_recv(struct composite_context *ctx)
944 struct wbsrv_samba3_call *s3call =
945 talloc_get_type(ctx->async.private_data,
946 struct wbsrv_samba3_call);
947 uint32_t extra_data_len;
951 DEBUG(5, ("list_users_recv called\n"));
953 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
956 if (NT_STATUS_IS_OK(status)) {
957 s3call->response.extra_data.data = extra_data;
958 s3call->response.length += extra_data_len;
960 s3call->response.length += 1;
964 wbsrv_samba3_async_epilogue(status, s3call);
969 static void getpwnam_recv(struct composite_context *ctx);
971 NTSTATUS wbsrv_samba3_getpwnam(struct wbsrv_samba3_call *s3call)
973 struct composite_context *ctx;
974 struct wbsrv_service *service =
975 s3call->wbconn->listen_socket->service;
977 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
979 ctx = wb_cmd_getpwnam_send(s3call, service,
980 s3call->request.data.username);
981 NT_STATUS_HAVE_NO_MEMORY(ctx);
983 ctx->async.fn = getpwnam_recv;
984 ctx->async.private_data = s3call;
985 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
989 static void getpwnam_recv(struct composite_context *ctx)
991 struct wbsrv_samba3_call *s3call =
992 talloc_get_type(ctx->async.private_data,
993 struct wbsrv_samba3_call);
995 struct winbindd_pw *pw;
997 DEBUG(5, ("getpwnam_recv called\n"));
999 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
1000 if(NT_STATUS_IS_OK(status))
1001 s3call->response.data.pw = *pw;
1003 wbsrv_samba3_async_epilogue(status, s3call);
1006 static void getpwuid_recv(struct composite_context *ctx);
1008 NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
1010 struct composite_context *ctx;
1011 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1013 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
1015 ctx = wb_cmd_getpwuid_send(s3call, service,
1016 s3call->request.data.uid);
1017 NT_STATUS_HAVE_NO_MEMORY(ctx);
1019 ctx->async.fn = getpwuid_recv;
1020 ctx->async.private_data = s3call;
1021 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1022 return NT_STATUS_OK;
1025 static void getpwuid_recv(struct composite_context *ctx)
1027 struct wbsrv_samba3_call *s3call =
1028 talloc_get_type(ctx->async.private_data,
1029 struct wbsrv_samba3_call);
1031 struct winbindd_pw *pw;
1033 DEBUG(5, ("getpwuid_recv called\n"));
1035 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
1036 if (NT_STATUS_IS_OK(status))
1037 s3call->response.data.pw = *pw;
1039 wbsrv_samba3_async_epilogue(status, s3call);
1042 static void setpwent_recv(struct composite_context *ctx);
1044 NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
1046 struct composite_context *ctx;
1047 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1049 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
1051 ctx = wb_cmd_setpwent_send(s3call, service);
1052 NT_STATUS_HAVE_NO_MEMORY(ctx);
1054 ctx->async.fn = setpwent_recv;
1055 ctx->async.private_data = s3call;
1056 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1057 return NT_STATUS_OK;
1060 static void setpwent_recv(struct composite_context *ctx)
1062 struct wbsrv_samba3_call *s3call =
1063 talloc_get_type(ctx->async.private_data,
1064 struct wbsrv_samba3_call);
1066 struct wbsrv_pwent *pwent;
1068 DEBUG(5, ("setpwent_recv called\n"));
1070 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
1071 if (NT_STATUS_IS_OK(status)) {
1072 s3call->wbconn->protocol_private_data = pwent;
1075 wbsrv_samba3_async_epilogue(status, s3call);
1078 static void getpwent_recv(struct composite_context *ctx);
1080 NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
1082 struct composite_context *ctx;
1083 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1084 struct wbsrv_pwent *pwent;
1086 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
1088 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
1090 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
1091 struct wbsrv_pwent);
1092 NT_STATUS_HAVE_NO_MEMORY(pwent);
1094 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
1095 s3call->request.data.num_entries);
1096 NT_STATUS_HAVE_NO_MEMORY(ctx);
1098 ctx->async.fn = getpwent_recv;
1099 ctx->async.private_data = s3call;
1100 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1101 return NT_STATUS_OK;
1104 static void getpwent_recv(struct composite_context *ctx)
1106 struct wbsrv_samba3_call *s3call =
1107 talloc_get_type(ctx->async.private_data,
1108 struct wbsrv_samba3_call);
1110 struct winbindd_pw *pw;
1113 DEBUG(5, ("getpwent_recv called\n"));
1115 status = wb_cmd_getpwent_recv(ctx, s3call, &pw, &num_users);
1116 if (NT_STATUS_IS_OK(status)) {
1117 uint32_t extra_len = sizeof(struct winbindd_pw) * num_users;
1119 s3call->response.data.num_entries = num_users;
1120 s3call->response.extra_data.data = pw;
1121 s3call->response.length += extra_len;
1124 wbsrv_samba3_async_epilogue(status, s3call);
1127 NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
1129 struct wbsrv_pwent *pwent =
1130 talloc_get_type(s3call->wbconn->protocol_private_data,
1131 struct wbsrv_pwent);
1132 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
1136 s3call->wbconn->protocol_private_data = NULL;
1137 s3call->response.result = WINBINDD_OK;
1138 return NT_STATUS_OK;
1142 static void getgrnam_recv(struct composite_context *ctx);
1144 NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
1146 struct composite_context *ctx;
1147 struct wbsrv_service *service =
1148 s3call->wbconn->listen_socket->service;
1150 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
1152 ctx = wb_cmd_getgrnam_send(s3call, service,
1153 s3call->request.data.groupname);
1154 NT_STATUS_HAVE_NO_MEMORY(ctx);
1156 ctx->async.fn = getgrnam_recv;
1157 ctx->async.private_data = s3call;
1158 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1159 return NT_STATUS_OK;
1162 static void getgrnam_recv(struct composite_context *ctx)
1164 struct wbsrv_samba3_call *s3call =
1165 talloc_get_type(ctx->async.private_data,
1166 struct wbsrv_samba3_call);
1168 struct winbindd_gr *gr;
1170 DEBUG(5, ("getgrnam_recv called\n"));
1172 status = wb_cmd_getgrnam_recv(ctx, s3call, &gr);
1173 if(NT_STATUS_IS_OK(status))
1174 s3call->response.data.gr = *gr;
1176 wbsrv_samba3_async_epilogue(status, s3call);
1179 static void getgrgid_recv(struct composite_context *ctx);
1181 NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
1183 struct composite_context *ctx;
1184 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1186 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
1188 ctx = wb_cmd_getgrgid_send(s3call, service,
1189 s3call->request.data.gid);
1190 NT_STATUS_HAVE_NO_MEMORY(ctx);
1192 ctx->async.fn = getgrgid_recv;
1193 ctx->async.private_data = s3call;
1194 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1195 return NT_STATUS_OK;
1198 static void getgrgid_recv(struct composite_context *ctx)
1200 struct wbsrv_samba3_call *s3call =
1201 talloc_get_type(ctx->async.private_data,
1202 struct wbsrv_samba3_call);
1204 struct winbindd_gr *gr;
1206 DEBUG(5, ("getgrgid_recv called\n"));
1208 status = wb_cmd_getgrgid_recv(ctx, s3call, &gr);
1209 if (NT_STATUS_IS_OK(status))
1210 s3call->response.data.gr = *gr;
1212 wbsrv_samba3_async_epilogue(status, s3call);
1215 static void getgroups_recv(struct composite_context *ctx);
1217 NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
1219 struct composite_context *ctx;
1220 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1222 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
1223 /* S3 code do the same so why not ... */
1224 s3call->request.data.username[sizeof(s3call->request.data.username)-1]='\0';
1225 ctx = wb_cmd_getgroups_send(s3call, service, s3call->request.data.username);
1226 NT_STATUS_HAVE_NO_MEMORY(ctx);
1228 ctx->async.fn = getgroups_recv;
1229 ctx->async.private_data = s3call;
1230 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1231 return NT_STATUS_OK;
1234 static void getgroups_recv(struct composite_context *ctx)
1236 struct wbsrv_samba3_call *s3call =
1237 talloc_get_type(ctx->async.private_data,
1238 struct wbsrv_samba3_call);
1240 uint32_t num_groups;
1242 DEBUG(5, ("getgroups_recv called\n"));
1244 status = wb_cmd_getgroups_recv(ctx, s3call, &gids, &num_groups);
1245 if (NT_STATUS_IS_OK(status)) {
1246 uint32_t extra_len = sizeof(gid_t) * num_groups;
1248 s3call->response.data.num_entries = num_groups;
1249 s3call->response.extra_data.data = gids;
1250 s3call->response.length += extra_len;
1252 s3call->response.result = WINBINDD_ERROR;
1255 wbsrv_samba3_async_epilogue(status, s3call);
1258 static void setgrent_recv(struct composite_context *ctx);
1260 NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
1262 struct composite_context *ctx;
1263 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1265 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
1267 ctx = wb_cmd_setgrent_send(s3call, service);
1268 NT_STATUS_HAVE_NO_MEMORY(ctx);
1270 ctx->async.fn = setgrent_recv;
1271 ctx->async.private_data = s3call;
1272 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1273 return NT_STATUS_OK;
1276 static void setgrent_recv(struct composite_context *ctx)
1278 struct wbsrv_samba3_call *s3call =
1279 talloc_get_type(ctx->async.private_data,
1280 struct wbsrv_samba3_call);
1282 struct wbsrv_grent *grent;
1284 DEBUG(5, ("setpwent_recv called\n"));
1286 status = wb_cmd_setgrent_recv(ctx, s3call->wbconn, &grent);
1287 if (NT_STATUS_IS_OK(status)) {
1288 s3call->wbconn->protocol_private_data = grent;
1291 wbsrv_samba3_async_epilogue(status, s3call);
1294 static void getgrent_recv(struct composite_context *ctx);
1296 NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
1298 struct composite_context *ctx;
1299 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1300 struct wbsrv_grent *grent;
1302 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
1304 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
1306 grent = talloc_get_type(s3call->wbconn->protocol_private_data,
1307 struct wbsrv_grent);
1308 NT_STATUS_HAVE_NO_MEMORY(grent);
1310 ctx = wb_cmd_getgrent_send(s3call, service, grent,
1311 s3call->request.data.num_entries);
1312 NT_STATUS_HAVE_NO_MEMORY(ctx);
1314 ctx->async.fn = getgrent_recv;
1315 ctx->async.private_data = s3call;
1316 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1317 return NT_STATUS_OK;
1320 static void getgrent_recv(struct composite_context *ctx)
1322 struct wbsrv_samba3_call *s3call =
1323 talloc_get_type(ctx->async.private_data,
1324 struct wbsrv_samba3_call);
1326 struct winbindd_gr *gr;
1327 uint32_t num_groups;
1329 DEBUG(5, ("getgrent_recv called\n"));
1331 status = wb_cmd_getgrent_recv(ctx, s3call, &gr, &num_groups);
1332 if (NT_STATUS_IS_OK(status)) {
1333 uint32_t extra_len = sizeof(struct winbindd_gr) * num_groups;
1335 s3call->response.data.num_entries = num_groups;
1336 s3call->response.extra_data.data = gr;
1337 s3call->response.length += extra_len;
1340 wbsrv_samba3_async_epilogue(status, s3call);
1343 NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
1345 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
1346 s3call->response.result = WINBINDD_OK;
1347 return NT_STATUS_OK;
1350 static void sid2uid_recv(struct composite_context *ctx);
1352 NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
1354 struct composite_context *ctx;
1355 struct wbsrv_service *service =
1356 s3call->wbconn->listen_socket->service;
1357 struct dom_sid *sid;
1359 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
1361 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1362 NT_STATUS_HAVE_NO_MEMORY(sid);
1364 ctx = wb_sid2uid_send(s3call, service, sid);
1365 NT_STATUS_HAVE_NO_MEMORY(ctx);
1367 ctx->async.fn = sid2uid_recv;
1368 ctx->async.private_data = s3call;
1369 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1370 return NT_STATUS_OK;
1374 static void sid2uid_recv(struct composite_context *ctx)
1376 struct wbsrv_samba3_call *s3call =
1377 talloc_get_type(ctx->async.private_data,
1378 struct wbsrv_samba3_call);
1381 DEBUG(5, ("sid2uid_recv called\n"));
1383 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
1385 wbsrv_samba3_async_epilogue(status, s3call);
1388 static void sid2gid_recv(struct composite_context *ctx);
1390 NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
1392 struct composite_context *ctx;
1393 struct wbsrv_service *service =
1394 s3call->wbconn->listen_socket->service;
1395 struct dom_sid *sid;
1397 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
1399 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1400 NT_STATUS_HAVE_NO_MEMORY(sid);
1402 ctx = wb_sid2gid_send(s3call, service, sid);
1403 NT_STATUS_HAVE_NO_MEMORY(ctx);
1405 ctx->async.fn = sid2gid_recv;
1406 ctx->async.private_data = s3call;
1407 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1408 return NT_STATUS_OK;
1412 static void sid2gid_recv(struct composite_context *ctx)
1414 struct wbsrv_samba3_call *s3call =
1415 talloc_get_type(ctx->async.private_data,
1416 struct wbsrv_samba3_call);
1419 DEBUG(5, ("sid2gid_recv called\n"));
1421 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
1423 wbsrv_samba3_async_epilogue(status, s3call);
1426 static void uid2sid_recv(struct composite_context *ctx);
1428 NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
1430 struct composite_context *ctx;
1431 struct wbsrv_service *service =
1432 s3call->wbconn->listen_socket->service;
1434 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1436 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
1437 NT_STATUS_HAVE_NO_MEMORY(ctx);
1439 ctx->async.fn = uid2sid_recv;
1440 ctx->async.private_data = s3call;
1441 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1442 return NT_STATUS_OK;
1446 static void uid2sid_recv(struct composite_context *ctx)
1448 struct wbsrv_samba3_call *s3call =
1449 talloc_get_type(ctx->async.private_data,
1450 struct wbsrv_samba3_call);
1452 struct dom_sid *sid;
1455 DEBUG(5, ("uid2sid_recv called\n"));
1457 status = wb_uid2sid_recv(ctx, s3call, &sid);
1458 if(NT_STATUS_IS_OK(status)) {
1459 sid_str = dom_sid_string(s3call, sid);
1461 /* If the conversion failed, bail out with a failure. */
1462 if (sid_str == NULL)
1463 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1465 /* But we assume this worked, so we'll set the string. Work
1467 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1468 s3call->response.data.sid.type = SID_NAME_USER;
1471 wbsrv_samba3_async_epilogue(status, s3call);
1474 static void gid2sid_recv(struct composite_context *ctx);
1476 NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1478 struct composite_context *ctx;
1479 struct wbsrv_service *service =
1480 s3call->wbconn->listen_socket->service;
1482 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1484 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1485 NT_STATUS_HAVE_NO_MEMORY(ctx);
1487 ctx->async.fn = gid2sid_recv;
1488 ctx->async.private_data = s3call;
1489 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1490 return NT_STATUS_OK;
1494 static void gid2sid_recv(struct composite_context *ctx)
1496 struct wbsrv_samba3_call *s3call =
1497 talloc_get_type(ctx->async.private_data,
1498 struct wbsrv_samba3_call);
1500 struct dom_sid *sid;
1503 DEBUG(5, ("gid2sid_recv called\n"));
1505 status = wb_gid2sid_recv(ctx, s3call, &sid);
1506 if(NT_STATUS_IS_OK(status)) {
1507 sid_str = dom_sid_string(s3call, sid);
1509 if (sid_str == NULL)
1510 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1512 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1513 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1516 wbsrv_samba3_async_epilogue(status, s3call);