Fetch the SID of the user we are running as and send with the common
[Samba/nascimento.git] / source4 / winbind / wb_samba3_cmd.c
blobd245d7ae37df020f8c229a5d229c2b5c397dee1a
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 uint32_t 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 uint32_t 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 This is a stub function in order to limit error message in the pam_winbind module
597 NTSTATUS wbsrv_samba3_pam_logoff(struct wbsrv_samba3_call *s3call)
599 NTSTATUS status;
600 struct winbindd_response *resp = &s3call->response;
602 status = NT_STATUS_OK;
604 DEBUG(5, ("wbsrv_samba3_pam_logoff called\n"));
605 DEBUG(10, ("Winbind logoff not implemented\n"));
606 resp->result = WINBINDD_OK;
608 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
609 nt_errstr(status));
610 WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
611 get_friendly_nt_error_msg(status));
613 resp->data.auth.pam_error = nt_status_to_pam(status);
614 resp->data.auth.nt_status = NT_STATUS_V(status);
615 DEBUG(5, ("wbsrv_samba3_pam_logoff called\n"));
617 return NT_STATUS_OK;
621 Challenge-response authentication. This interface is used by
622 ntlm_auth and the smbd auth subsystem to pass NTLM authentication
623 requests along a common pipe to the domain controller.
625 The return value (in the async reply) may include the 'info3'
626 (effectivly most things you would want to know about the user), or
627 the NT and LM session keys seperated.
630 static void pam_auth_crap_recv(struct composite_context *ctx);
632 NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
634 struct composite_context *ctx;
635 struct wbsrv_service *service =
636 s3call->wbconn->listen_socket->service;
637 DATA_BLOB chal, nt_resp, lm_resp;
639 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
641 chal.data = s3call->request.data.auth_crap.chal;
642 chal.length = sizeof(s3call->request.data.auth_crap.chal);
643 nt_resp.data = (uint8_t *)s3call->request.data.auth_crap.nt_resp;
644 nt_resp.length = s3call->request.data.auth_crap.nt_resp_len;
645 lm_resp.data = (uint8_t *)s3call->request.data.auth_crap.lm_resp;
646 lm_resp.length = s3call->request.data.auth_crap.lm_resp_len;
648 ctx = wb_cmd_pam_auth_crap_send(
649 s3call, service,
650 s3call->request.data.auth_crap.logon_parameters,
651 s3call->request.data.auth_crap.domain,
652 s3call->request.data.auth_crap.user,
653 s3call->request.data.auth_crap.workstation,
654 chal, nt_resp, lm_resp);
655 NT_STATUS_HAVE_NO_MEMORY(ctx);
657 ctx->async.fn = pam_auth_crap_recv;
658 ctx->async.private_data = s3call;
659 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
660 return NT_STATUS_OK;
663 static void pam_auth_crap_recv(struct composite_context *ctx)
665 struct wbsrv_samba3_call *s3call =
666 talloc_get_type(ctx->async.private_data,
667 struct wbsrv_samba3_call);
668 NTSTATUS status;
669 DATA_BLOB info3;
670 struct netr_UserSessionKey user_session_key;
671 struct netr_LMSessionKey lm_key;
672 char *unix_username;
674 status = wb_cmd_pam_auth_crap_recv(ctx, s3call, &info3,
675 &user_session_key, &lm_key, &unix_username);
676 if (!NT_STATUS_IS_OK(status)) goto done;
678 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
679 memcpy(s3call->response.data.auth.user_session_key,
680 &user_session_key.key,
681 sizeof(s3call->response.data.auth.user_session_key));
684 if (s3call->request.flags & WBFLAG_PAM_INFO3_TEXT) {
685 status = wb_samba3_append_info3_as_txt(ctx, s3call, info3);
686 if (!NT_STATUS_IS_OK(status)) {
687 DEBUG(10,("Failed to append INFO3 (TXT): %s\n",
688 nt_errstr(status)));
689 goto done;
693 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
694 s3call->response.extra_data.data = info3.data;
695 s3call->response.length += info3.length;
698 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
699 memcpy(s3call->response.data.auth.first_8_lm_hash,
700 lm_key.key,
701 sizeof(s3call->response.data.auth.first_8_lm_hash));
704 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
705 WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.unix_username,unix_username);
708 done:
709 wbsrv_samba3_async_auth_epilogue(status, s3call);
712 /* Plaintext authentication
714 This interface is used by ntlm_auth in it's 'basic' authentication
715 mode, as well as by pam_winbind to authenticate users where we are
716 given a plaintext password.
719 static void pam_auth_recv(struct composite_context *ctx);
721 NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
723 struct composite_context *ctx;
724 struct wbsrv_service *service =
725 s3call->wbconn->listen_socket->service;
726 struct cli_credentials *credentials;
727 char *user, *domain;
729 if (!wb_samba3_split_username(s3call, s3call->wbconn->lp_ctx,
730 s3call->request.data.auth.user,
731 &domain, &user)) {
732 return NT_STATUS_NO_SUCH_USER;
735 credentials = cli_credentials_init(s3call);
736 if (!credentials) {
737 return NT_STATUS_NO_MEMORY;
739 cli_credentials_set_conf(credentials, service->task->lp_ctx);
740 cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
741 cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
743 cli_credentials_set_password(credentials, s3call->request.data.auth.pass, CRED_SPECIFIED);
745 ctx = wb_cmd_pam_auth_send(s3call, service, credentials);
746 NT_STATUS_HAVE_NO_MEMORY(ctx);
748 ctx->async.fn = pam_auth_recv;
749 ctx->async.private_data = s3call;
750 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
751 return NT_STATUS_OK;
754 static void pam_auth_recv(struct composite_context *ctx)
756 struct wbsrv_samba3_call *s3call =
757 talloc_get_type(ctx->async.private_data,
758 struct wbsrv_samba3_call);
759 NTSTATUS status;
760 DATA_BLOB info3;
761 struct netr_UserSessionKey user_session_key;
762 struct netr_LMSessionKey lm_key;
763 char *unix_username;
765 status = wb_cmd_pam_auth_recv(ctx, s3call, &info3,
766 &user_session_key, &lm_key, &unix_username);
768 if (!NT_STATUS_IS_OK(status)) goto done;
770 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
771 memcpy(s3call->response.data.auth.user_session_key,
772 &user_session_key.key,
773 sizeof(s3call->response.data.auth.user_session_key));
776 if (s3call->request.flags & WBFLAG_PAM_INFO3_TEXT) {
777 status = wb_samba3_append_info3_as_txt(ctx, s3call, info3);
778 if (!NT_STATUS_IS_OK(status)) {
779 DEBUG(10,("Failed to append INFO3 (TXT): %s\n",
780 nt_errstr(status)));
781 goto done;
785 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
786 s3call->response.extra_data.data = info3.data;
787 s3call->response.length += info3.length;
790 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
791 memcpy(s3call->response.data.auth.first_8_lm_hash,
792 lm_key.key,
793 sizeof(s3call->response.data.auth.first_8_lm_hash));
796 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
797 WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.unix_username,unix_username);
801 done:
802 wbsrv_samba3_async_auth_epilogue(status, s3call);
806 List trusted domains
809 static void list_trustdom_recv_doms(struct composite_context *ctx);
811 NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
813 struct composite_context *ctx;
814 struct wbsrv_service *service =
815 s3call->wbconn->listen_socket->service;
817 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
819 ctx = wb_cmd_list_trustdoms_send(s3call, service);
820 NT_STATUS_HAVE_NO_MEMORY(ctx);
822 ctx->async.fn = list_trustdom_recv_doms;
823 ctx->async.private_data = s3call;
824 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
825 return NT_STATUS_OK;
828 static void list_trustdom_recv_doms(struct composite_context *ctx)
830 struct wbsrv_samba3_call *s3call =
831 talloc_get_type(ctx->async.private_data,
832 struct wbsrv_samba3_call);
833 uint32_t i, num_domains;
834 struct wb_dom_info **domains;
835 NTSTATUS status;
836 char *result;
838 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
839 &domains);
840 if (!NT_STATUS_IS_OK(status)) goto done;
842 result = talloc_strdup(s3call, "");
843 if (result == NULL) {
844 status = NT_STATUS_NO_MEMORY;
845 goto done;
848 for (i=0; i<num_domains; i++) {
849 result = talloc_asprintf_append_buffer(
850 result, "%s\\%s\\%s",
851 domains[i]->name, domains[i]->name,
852 dom_sid_string(s3call, domains[i]->sid));
855 if (result == NULL) {
856 status = NT_STATUS_NO_MEMORY;
857 goto done;
860 s3call->response.result = WINBINDD_OK;
861 if (num_domains > 0) {
862 s3call->response.extra_data.data = result;
863 s3call->response.length += strlen(result)+1;
866 done:
867 wbsrv_samba3_async_epilogue(status, s3call);
870 /* list groups */
871 static void list_groups_recv(struct composite_context *ctx);
873 NTSTATUS wbsrv_samba3_list_groups(struct wbsrv_samba3_call *s3call)
875 struct composite_context *ctx;
876 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
878 DEBUG(5, ("wbsrv_samba4_list_groups called\n"));
880 ctx = wb_cmd_list_groups_send(s3call, service,
881 s3call->request.domain_name);
882 NT_STATUS_HAVE_NO_MEMORY(ctx);
884 ctx->async.fn = list_groups_recv;
885 ctx->async.private_data = s3call;
886 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
887 return NT_STATUS_OK;
890 static void list_groups_recv(struct composite_context *ctx)
892 struct wbsrv_samba3_call *s3call = talloc_get_type_abort(
893 ctx->async.private_data,
894 struct wbsrv_samba3_call);
895 uint32_t extra_data_len;
896 char *extra_data;
897 NTSTATUS status;
899 DEBUG(5, ("list_groups_recv called\n"));
901 status = wb_cmd_list_groups_recv(ctx, s3call, &extra_data_len,
902 &extra_data);
904 if (NT_STATUS_IS_OK(status)) {
905 s3call->response.extra_data.data = extra_data;
906 s3call->response.length += extra_data_len;
907 if (extra_data) {
908 s3call->response.length += 1;
912 wbsrv_samba3_async_epilogue(status, s3call);
915 /* List users */
917 static void list_users_recv(struct composite_context *ctx);
919 NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
921 struct composite_context *ctx;
922 struct wbsrv_service *service =
923 s3call->wbconn->listen_socket->service;
925 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
927 ctx = wb_cmd_list_users_send(s3call, service,
928 s3call->request.domain_name);
929 NT_STATUS_HAVE_NO_MEMORY(ctx);
931 ctx->async.fn = list_users_recv;
932 ctx->async.private_data = s3call;
933 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
934 return NT_STATUS_OK;
937 static void list_users_recv(struct composite_context *ctx)
939 struct wbsrv_samba3_call *s3call =
940 talloc_get_type(ctx->async.private_data,
941 struct wbsrv_samba3_call);
942 uint32_t extra_data_len;
943 char *extra_data;
944 NTSTATUS status;
946 DEBUG(5, ("list_users_recv called\n"));
948 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
949 &extra_data);
951 if (NT_STATUS_IS_OK(status)) {
952 s3call->response.extra_data.data = extra_data;
953 s3call->response.length += extra_data_len;
954 if (extra_data) {
955 s3call->response.length += 1;
959 wbsrv_samba3_async_epilogue(status, s3call);
962 /* NSS calls */
964 static void getpwnam_recv(struct composite_context *ctx);
966 NTSTATUS wbsrv_samba3_getpwnam(struct wbsrv_samba3_call *s3call)
968 struct composite_context *ctx;
969 struct wbsrv_service *service =
970 s3call->wbconn->listen_socket->service;
972 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
974 ctx = wb_cmd_getpwnam_send(s3call, service,
975 s3call->request.data.username);
976 NT_STATUS_HAVE_NO_MEMORY(ctx);
978 ctx->async.fn = getpwnam_recv;
979 ctx->async.private_data = s3call;
980 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
981 return NT_STATUS_OK;
984 static void getpwnam_recv(struct composite_context *ctx)
986 struct wbsrv_samba3_call *s3call =
987 talloc_get_type(ctx->async.private_data,
988 struct wbsrv_samba3_call);
989 NTSTATUS status;
990 struct winbindd_pw *pw;
992 DEBUG(5, ("getpwnam_recv called\n"));
994 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
995 if(NT_STATUS_IS_OK(status))
996 s3call->response.data.pw = *pw;
998 wbsrv_samba3_async_epilogue(status, s3call);
1001 static void getpwuid_recv(struct composite_context *ctx);
1003 NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
1005 struct composite_context *ctx;
1006 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1008 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
1010 ctx = wb_cmd_getpwuid_send(s3call, service,
1011 s3call->request.data.uid);
1012 NT_STATUS_HAVE_NO_MEMORY(ctx);
1014 ctx->async.fn = getpwuid_recv;
1015 ctx->async.private_data = s3call;
1016 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1017 return NT_STATUS_OK;
1020 static void getpwuid_recv(struct composite_context *ctx)
1022 struct wbsrv_samba3_call *s3call =
1023 talloc_get_type(ctx->async.private_data,
1024 struct wbsrv_samba3_call);
1025 NTSTATUS status;
1026 struct winbindd_pw *pw;
1028 DEBUG(5, ("getpwuid_recv called\n"));
1030 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
1031 if (NT_STATUS_IS_OK(status))
1032 s3call->response.data.pw = *pw;
1034 wbsrv_samba3_async_epilogue(status, s3call);
1037 static void setpwent_recv(struct composite_context *ctx);
1039 NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
1041 struct composite_context *ctx;
1042 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1044 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
1046 ctx = wb_cmd_setpwent_send(s3call, service);
1047 NT_STATUS_HAVE_NO_MEMORY(ctx);
1049 ctx->async.fn = setpwent_recv;
1050 ctx->async.private_data = s3call;
1051 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1052 return NT_STATUS_OK;
1055 static void setpwent_recv(struct composite_context *ctx)
1057 struct wbsrv_samba3_call *s3call =
1058 talloc_get_type(ctx->async.private_data,
1059 struct wbsrv_samba3_call);
1060 NTSTATUS status;
1061 struct wbsrv_pwent *pwent;
1063 DEBUG(5, ("setpwent_recv called\n"));
1065 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
1066 if (NT_STATUS_IS_OK(status)) {
1067 s3call->wbconn->protocol_private_data = pwent;
1070 wbsrv_samba3_async_epilogue(status, s3call);
1073 static void getpwent_recv(struct composite_context *ctx);
1075 NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
1077 struct composite_context *ctx;
1078 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1079 struct wbsrv_pwent *pwent;
1081 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
1083 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
1085 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
1086 struct wbsrv_pwent);
1087 NT_STATUS_HAVE_NO_MEMORY(pwent);
1089 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
1090 s3call->request.data.num_entries);
1091 NT_STATUS_HAVE_NO_MEMORY(ctx);
1093 ctx->async.fn = getpwent_recv;
1094 ctx->async.private_data = s3call;
1095 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1096 return NT_STATUS_OK;
1099 static void getpwent_recv(struct composite_context *ctx)
1101 struct wbsrv_samba3_call *s3call =
1102 talloc_get_type(ctx->async.private_data,
1103 struct wbsrv_samba3_call);
1104 NTSTATUS status;
1105 struct winbindd_pw *pw;
1106 uint32_t num_users;
1108 DEBUG(5, ("getpwent_recv called\n"));
1110 status = wb_cmd_getpwent_recv(ctx, s3call, &pw, &num_users);
1111 if (NT_STATUS_IS_OK(status)) {
1112 uint32_t extra_len = sizeof(struct winbindd_pw) * num_users;
1114 s3call->response.data.num_entries = num_users;
1115 s3call->response.extra_data.data = pw;
1116 s3call->response.length += extra_len;
1119 wbsrv_samba3_async_epilogue(status, s3call);
1122 NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
1124 struct wbsrv_pwent *pwent =
1125 talloc_get_type(s3call->wbconn->protocol_private_data,
1126 struct wbsrv_pwent);
1127 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
1129 talloc_free(pwent);
1131 s3call->wbconn->protocol_private_data = NULL;
1132 s3call->response.result = WINBINDD_OK;
1133 return NT_STATUS_OK;
1137 static void getgrnam_recv(struct composite_context *ctx);
1139 NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
1141 struct composite_context *ctx;
1142 struct wbsrv_service *service =
1143 s3call->wbconn->listen_socket->service;
1145 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
1147 ctx = wb_cmd_getgrnam_send(s3call, service,
1148 s3call->request.data.groupname);
1149 NT_STATUS_HAVE_NO_MEMORY(ctx);
1151 ctx->async.fn = getgrnam_recv;
1152 ctx->async.private_data = s3call;
1153 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1154 return NT_STATUS_OK;
1157 static void getgrnam_recv(struct composite_context *ctx)
1159 struct wbsrv_samba3_call *s3call =
1160 talloc_get_type(ctx->async.private_data,
1161 struct wbsrv_samba3_call);
1162 NTSTATUS status;
1163 struct winbindd_gr *gr;
1165 DEBUG(5, ("getgrnam_recv called\n"));
1167 status = wb_cmd_getgrnam_recv(ctx, s3call, &gr);
1168 if(NT_STATUS_IS_OK(status))
1169 s3call->response.data.gr = *gr;
1171 wbsrv_samba3_async_epilogue(status, s3call);
1174 static void getgrgid_recv(struct composite_context *ctx);
1176 NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
1178 struct composite_context *ctx;
1179 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1181 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
1183 ctx = wb_cmd_getgrgid_send(s3call, service,
1184 s3call->request.data.gid);
1185 NT_STATUS_HAVE_NO_MEMORY(ctx);
1187 ctx->async.fn = getgrgid_recv;
1188 ctx->async.private_data = s3call;
1189 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1190 return NT_STATUS_OK;
1193 static void getgrgid_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 winbindd_gr *gr;
1201 DEBUG(5, ("getgrgid_recv called\n"));
1203 status = wb_cmd_getgrgid_recv(ctx, s3call, &gr);
1204 if (NT_STATUS_IS_OK(status))
1205 s3call->response.data.gr = *gr;
1207 wbsrv_samba3_async_epilogue(status, s3call);
1210 static void getgroups_recv(struct composite_context *ctx);
1212 NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
1214 struct composite_context *ctx;
1215 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1217 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
1218 /* S3 code do the same so why not ... */
1219 s3call->request.data.username[sizeof(s3call->request.data.username)-1]='\0';
1220 ctx = wb_cmd_getgroups_send(s3call, service, s3call->request.data.username);
1221 NT_STATUS_HAVE_NO_MEMORY(ctx);
1223 ctx->async.fn = getgroups_recv;
1224 ctx->async.private_data = s3call;
1225 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1226 return NT_STATUS_OK;
1229 static void getgroups_recv(struct composite_context *ctx)
1231 struct wbsrv_samba3_call *s3call =
1232 talloc_get_type(ctx->async.private_data,
1233 struct wbsrv_samba3_call);
1234 gid_t *gids;
1235 uint32_t num_groups;
1236 NTSTATUS status;
1237 DEBUG(5, ("getgroups_recv called\n"));
1239 status = wb_cmd_getgroups_recv(ctx, s3call, &gids, &num_groups);
1240 if (NT_STATUS_IS_OK(status)) {
1241 uint32_t extra_len = sizeof(gid_t) * num_groups;
1243 s3call->response.data.num_entries = num_groups;
1244 s3call->response.extra_data.data = gids;
1245 s3call->response.length += extra_len;
1246 } else {
1247 s3call->response.result = WINBINDD_ERROR;
1250 wbsrv_samba3_async_epilogue(status, s3call);
1253 static void setgrent_recv(struct composite_context *ctx);
1255 NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
1257 struct composite_context *ctx;
1258 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1260 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
1262 ctx = wb_cmd_setgrent_send(s3call, service);
1263 NT_STATUS_HAVE_NO_MEMORY(ctx);
1265 ctx->async.fn = setgrent_recv;
1266 ctx->async.private_data = s3call;
1267 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1268 return NT_STATUS_OK;
1271 static void setgrent_recv(struct composite_context *ctx)
1273 struct wbsrv_samba3_call *s3call =
1274 talloc_get_type(ctx->async.private_data,
1275 struct wbsrv_samba3_call);
1276 NTSTATUS status;
1277 struct wbsrv_grent *grent;
1279 DEBUG(5, ("setpwent_recv called\n"));
1281 status = wb_cmd_setgrent_recv(ctx, s3call->wbconn, &grent);
1282 if (NT_STATUS_IS_OK(status)) {
1283 s3call->wbconn->protocol_private_data = grent;
1286 wbsrv_samba3_async_epilogue(status, s3call);
1289 static void getgrent_recv(struct composite_context *ctx);
1291 NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
1293 struct composite_context *ctx;
1294 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1295 struct wbsrv_grent *grent;
1297 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
1299 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
1301 grent = talloc_get_type(s3call->wbconn->protocol_private_data,
1302 struct wbsrv_grent);
1303 NT_STATUS_HAVE_NO_MEMORY(grent);
1305 ctx = wb_cmd_getgrent_send(s3call, service, grent,
1306 s3call->request.data.num_entries);
1307 NT_STATUS_HAVE_NO_MEMORY(ctx);
1309 ctx->async.fn = getgrent_recv;
1310 ctx->async.private_data = s3call;
1311 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1312 return NT_STATUS_OK;
1315 static void getgrent_recv(struct composite_context *ctx)
1317 struct wbsrv_samba3_call *s3call =
1318 talloc_get_type(ctx->async.private_data,
1319 struct wbsrv_samba3_call);
1320 NTSTATUS status;
1321 struct winbindd_gr *gr;
1322 uint32_t num_groups;
1324 DEBUG(5, ("getgrent_recv called\n"));
1326 status = wb_cmd_getgrent_recv(ctx, s3call, &gr, &num_groups);
1327 if (NT_STATUS_IS_OK(status)) {
1328 uint32_t extra_len = sizeof(struct winbindd_gr) * num_groups;
1330 s3call->response.data.num_entries = num_groups;
1331 s3call->response.extra_data.data = gr;
1332 s3call->response.length += extra_len;
1335 wbsrv_samba3_async_epilogue(status, s3call);
1338 NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
1340 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
1341 s3call->response.result = WINBINDD_OK;
1342 return NT_STATUS_OK;
1345 static void sid2uid_recv(struct composite_context *ctx);
1347 NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
1349 struct composite_context *ctx;
1350 struct wbsrv_service *service =
1351 s3call->wbconn->listen_socket->service;
1352 struct dom_sid *sid;
1354 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
1356 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1357 NT_STATUS_HAVE_NO_MEMORY(sid);
1359 ctx = wb_sid2uid_send(s3call, service, sid);
1360 NT_STATUS_HAVE_NO_MEMORY(ctx);
1362 ctx->async.fn = sid2uid_recv;
1363 ctx->async.private_data = s3call;
1364 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1365 return NT_STATUS_OK;
1369 static void sid2uid_recv(struct composite_context *ctx)
1371 struct wbsrv_samba3_call *s3call =
1372 talloc_get_type(ctx->async.private_data,
1373 struct wbsrv_samba3_call);
1374 NTSTATUS status;
1376 DEBUG(5, ("sid2uid_recv called\n"));
1378 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
1380 wbsrv_samba3_async_epilogue(status, s3call);
1383 static void sid2gid_recv(struct composite_context *ctx);
1385 NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
1387 struct composite_context *ctx;
1388 struct wbsrv_service *service =
1389 s3call->wbconn->listen_socket->service;
1390 struct dom_sid *sid;
1392 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
1394 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1395 NT_STATUS_HAVE_NO_MEMORY(sid);
1397 ctx = wb_sid2gid_send(s3call, service, sid);
1398 NT_STATUS_HAVE_NO_MEMORY(ctx);
1400 ctx->async.fn = sid2gid_recv;
1401 ctx->async.private_data = s3call;
1402 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1403 return NT_STATUS_OK;
1407 static void sid2gid_recv(struct composite_context *ctx)
1409 struct wbsrv_samba3_call *s3call =
1410 talloc_get_type(ctx->async.private_data,
1411 struct wbsrv_samba3_call);
1412 NTSTATUS status;
1414 DEBUG(5, ("sid2gid_recv called\n"));
1416 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
1418 wbsrv_samba3_async_epilogue(status, s3call);
1421 static void uid2sid_recv(struct composite_context *ctx);
1423 NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
1425 struct composite_context *ctx;
1426 struct wbsrv_service *service =
1427 s3call->wbconn->listen_socket->service;
1429 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1431 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
1432 NT_STATUS_HAVE_NO_MEMORY(ctx);
1434 ctx->async.fn = uid2sid_recv;
1435 ctx->async.private_data = s3call;
1436 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1437 return NT_STATUS_OK;
1441 static void uid2sid_recv(struct composite_context *ctx)
1443 struct wbsrv_samba3_call *s3call =
1444 talloc_get_type(ctx->async.private_data,
1445 struct wbsrv_samba3_call);
1446 NTSTATUS status;
1447 struct dom_sid *sid;
1448 char *sid_str;
1450 DEBUG(5, ("uid2sid_recv called\n"));
1452 status = wb_uid2sid_recv(ctx, s3call, &sid);
1453 if(NT_STATUS_IS_OK(status)) {
1454 sid_str = dom_sid_string(s3call, sid);
1456 /* If the conversion failed, bail out with a failure. */
1457 if (sid_str == NULL)
1458 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1460 /* But we assume this worked, so we'll set the string. Work
1461 * done. */
1462 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1463 s3call->response.data.sid.type = SID_NAME_USER;
1466 wbsrv_samba3_async_epilogue(status, s3call);
1469 static void gid2sid_recv(struct composite_context *ctx);
1471 NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1473 struct composite_context *ctx;
1474 struct wbsrv_service *service =
1475 s3call->wbconn->listen_socket->service;
1477 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1479 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1480 NT_STATUS_HAVE_NO_MEMORY(ctx);
1482 ctx->async.fn = gid2sid_recv;
1483 ctx->async.private_data = s3call;
1484 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1485 return NT_STATUS_OK;
1489 static void gid2sid_recv(struct composite_context *ctx)
1491 struct wbsrv_samba3_call *s3call =
1492 talloc_get_type(ctx->async.private_data,
1493 struct wbsrv_samba3_call);
1494 NTSTATUS status;
1495 struct dom_sid *sid;
1496 char *sid_str;
1498 DEBUG(5, ("gid2sid_recv called\n"));
1500 status = wb_gid2sid_recv(ctx, s3call, &sid);
1501 if(NT_STATUS_IS_OK(status)) {
1502 sid_str = dom_sid_string(s3call, sid);
1504 if (sid_str == NULL)
1505 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1507 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1508 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1511 wbsrv_samba3_async_epilogue(status, s3call);