Fix unqualified "net join"
[Samba.git] / source4 / winbind / wb_samba3_cmd.c
blob2c273e517595f4bd82cbd2ebf1a296806ee21e21
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 "winbind/wb_async_helpers.h"
27 #include "param/param.h"
28 #include "winbind/wb_helper.h"
29 #include "libcli/composite/composite.h"
30 #include "version.h"
31 #include "librpc/gen_ndr/netlogon.h"
32 #include "libcli/security/security.h"
33 #include "auth/ntlm/pam_errors.h"
34 #include "auth/credentials/credentials.h"
35 #include "smbd/service_task.h"
37 /*
38 Send off the reply to an async Samba3 query, handling filling in the PAM, NTSTATUS and string errors.
41 static void wbsrv_samba3_async_auth_epilogue(NTSTATUS status,
42 struct wbsrv_samba3_call *s3call)
44 struct winbindd_response *resp = &s3call->response;
45 if (!NT_STATUS_IS_OK(status)) {
46 resp->result = WINBINDD_ERROR;
47 } else {
48 resp->result = WINBINDD_OK;
51 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
52 nt_errstr(status));
53 WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
54 get_friendly_nt_error_msg(status));
56 resp->data.auth.pam_error = nt_status_to_pam(status);
57 resp->data.auth.nt_status = NT_STATUS_V(status);
59 wbsrv_samba3_send_reply(s3call);
62 /*
63 Send of a generic reply to a Samba3 query
66 static void wbsrv_samba3_async_epilogue(NTSTATUS status,
67 struct wbsrv_samba3_call *s3call)
69 struct winbindd_response *resp = &s3call->response;
70 if (NT_STATUS_IS_OK(status)) {
71 resp->result = WINBINDD_OK;
72 } else {
73 resp->result = WINBINDD_ERROR;
76 wbsrv_samba3_send_reply(s3call);
79 /*
80 Boilerplate commands, simple queries without network traffic
83 NTSTATUS wbsrv_samba3_interface_version(struct wbsrv_samba3_call *s3call)
85 s3call->response.result = WINBINDD_OK;
86 s3call->response.data.interface_version = WINBIND_INTERFACE_VERSION;
87 return NT_STATUS_OK;
90 NTSTATUS wbsrv_samba3_info(struct wbsrv_samba3_call *s3call)
92 s3call->response.result = WINBINDD_OK;
93 s3call->response.data.info.winbind_separator = *lp_winbind_separator(s3call->wbconn->lp_ctx);
94 WBSRV_SAMBA3_SET_STRING(s3call->response.data.info.samba_version,
95 SAMBA_VERSION_STRING);
96 return NT_STATUS_OK;
99 NTSTATUS wbsrv_samba3_domain_name(struct wbsrv_samba3_call *s3call)
101 s3call->response.result = WINBINDD_OK;
102 WBSRV_SAMBA3_SET_STRING(s3call->response.data.domain_name,
103 lp_workgroup(s3call->wbconn->lp_ctx));
104 return NT_STATUS_OK;
107 NTSTATUS wbsrv_samba3_netbios_name(struct wbsrv_samba3_call *s3call)
109 s3call->response.result = WINBINDD_OK;
110 WBSRV_SAMBA3_SET_STRING(s3call->response.data.netbios_name,
111 lp_netbios_name(s3call->wbconn->lp_ctx));
112 return NT_STATUS_OK;
115 NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
117 const char *path = s3call->wbconn->listen_socket->service->priv_socket_path;
118 s3call->response.result = WINBINDD_OK;
119 s3call->response.extra_data.data = discard_const(path);
121 s3call->response.length += strlen(path) + 1;
122 return NT_STATUS_OK;
125 NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
127 s3call->response.result = WINBINDD_OK;
128 return NT_STATUS_OK;
131 /* Plaintext authentication
133 This interface is used by ntlm_auth in it's 'basic' authentication
134 mode, as well as by pam_winbind to authenticate users where we are
135 given a plaintext password.
138 static void check_machacc_recv(struct composite_context *ctx);
140 NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
142 NTSTATUS status;
143 struct cli_credentials *creds;
144 struct composite_context *ctx;
145 struct wbsrv_service *service =
146 s3call->wbconn->listen_socket->service;
148 /* Create a credentials structure */
149 creds = cli_credentials_init(s3call);
150 if (creds == NULL) {
151 return NT_STATUS_NO_MEMORY;
154 cli_credentials_set_conf(creds, service->task->lp_ctx);
156 /* Connect the machine account to the credentials */
157 status = cli_credentials_set_machine_account(creds, service->task->lp_ctx);
158 if (!NT_STATUS_IS_OK(status)) {
159 talloc_free(creds);
160 return status;
163 ctx = wb_cmd_pam_auth_send(s3call, service, creds);
165 if (!ctx) {
166 talloc_free(creds);
167 return NT_STATUS_NO_MEMORY;
170 ctx->async.fn = check_machacc_recv;
171 ctx->async.private_data = s3call;
172 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
173 return NT_STATUS_OK;
176 static void check_machacc_recv(struct composite_context *ctx)
178 struct wbsrv_samba3_call *s3call =
179 talloc_get_type(ctx->async.private_data,
180 struct wbsrv_samba3_call);
181 NTSTATUS status;
183 status = wb_cmd_pam_auth_recv(ctx);
185 if (!NT_STATUS_IS_OK(status)) goto done;
187 done:
188 wbsrv_samba3_async_auth_epilogue(status, s3call);
192 Find the name of a suitable domain controller, by query on the
193 netlogon pipe to the DC.
196 static void getdcname_recv_dc(struct composite_context *ctx);
198 NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
200 struct composite_context *ctx;
201 struct wbsrv_service *service =
202 s3call->wbconn->listen_socket->service;
204 DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
206 ctx = wb_cmd_getdcname_send(s3call, service,
207 s3call->request.domain_name);
208 NT_STATUS_HAVE_NO_MEMORY(ctx);
210 ctx->async.fn = getdcname_recv_dc;
211 ctx->async.private_data = s3call;
212 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
213 return NT_STATUS_OK;
216 static void getdcname_recv_dc(struct composite_context *ctx)
218 struct wbsrv_samba3_call *s3call =
219 talloc_get_type(ctx->async.private_data,
220 struct wbsrv_samba3_call);
221 const char *dcname;
222 NTSTATUS status;
224 status = wb_cmd_getdcname_recv(ctx, s3call, &dcname);
225 if (!NT_STATUS_IS_OK(status)) goto done;
227 s3call->response.result = WINBINDD_OK;
228 WBSRV_SAMBA3_SET_STRING(s3call->response.data.dc_name, dcname);
230 done:
231 wbsrv_samba3_async_epilogue(status, s3call);
235 Lookup a user's domain groups
238 static void userdomgroups_recv_groups(struct composite_context *ctx);
240 NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
242 struct composite_context *ctx;
243 struct dom_sid *sid;
245 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
247 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
248 if (sid == NULL) {
249 DEBUG(5, ("Could not parse sid %s\n",
250 s3call->request.data.sid));
251 return NT_STATUS_NO_MEMORY;
254 ctx = wb_cmd_userdomgroups_send(
255 s3call, s3call->wbconn->listen_socket->service, sid);
256 NT_STATUS_HAVE_NO_MEMORY(ctx);
258 ctx->async.fn = userdomgroups_recv_groups;
259 ctx->async.private_data = s3call;
260 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
261 return NT_STATUS_OK;
264 static void userdomgroups_recv_groups(struct composite_context *ctx)
266 struct wbsrv_samba3_call *s3call =
267 talloc_get_type(ctx->async.private_data,
268 struct wbsrv_samba3_call);
269 int i, num_sids;
270 struct dom_sid **sids;
271 char *sids_string;
272 NTSTATUS status;
274 status = wb_cmd_userdomgroups_recv(ctx, s3call, &num_sids, &sids);
275 if (!NT_STATUS_IS_OK(status)) goto done;
277 sids_string = talloc_strdup(s3call, "");
278 if (sids_string == NULL) {
279 status = NT_STATUS_NO_MEMORY;
280 goto done;
283 for (i=0; i<num_sids; i++) {
284 sids_string = talloc_asprintf_append_buffer(
285 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
288 if (sids_string == NULL) {
289 status = NT_STATUS_NO_MEMORY;
290 goto done;
293 s3call->response.result = WINBINDD_OK;
294 s3call->response.extra_data.data = sids_string;
295 s3call->response.length += strlen(sids_string)+1;
296 s3call->response.data.num_entries = num_sids;
298 done:
299 wbsrv_samba3_async_epilogue(status, s3call);
303 Lookup the list of SIDs for a user
305 static void usersids_recv_sids(struct composite_context *ctx);
307 NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call)
309 struct composite_context *ctx;
310 struct dom_sid *sid;
312 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
314 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
315 if (sid == NULL) {
316 DEBUG(5, ("Could not parse sid %s\n",
317 s3call->request.data.sid));
318 return NT_STATUS_NO_MEMORY;
321 ctx = wb_cmd_usersids_send(
322 s3call, s3call->wbconn->listen_socket->service, sid);
323 NT_STATUS_HAVE_NO_MEMORY(ctx);
325 ctx->async.fn = usersids_recv_sids;
326 ctx->async.private_data = s3call;
327 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
328 return NT_STATUS_OK;
331 static void usersids_recv_sids(struct composite_context *ctx)
333 struct wbsrv_samba3_call *s3call =
334 talloc_get_type(ctx->async.private_data,
335 struct wbsrv_samba3_call);
336 int i, num_sids;
337 struct dom_sid **sids;
338 char *sids_string;
339 NTSTATUS status;
341 status = wb_cmd_usersids_recv(ctx, s3call, &num_sids, &sids);
342 if (!NT_STATUS_IS_OK(status)) goto done;
344 sids_string = talloc_strdup(s3call, "");
345 if (sids_string == NULL) {
346 status = NT_STATUS_NO_MEMORY;
347 goto done;
350 for (i=0; i<num_sids; i++) {
351 sids_string = talloc_asprintf_append_buffer(
352 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
353 if (sids_string == NULL) {
354 status = NT_STATUS_NO_MEMORY;
355 goto done;
359 s3call->response.result = WINBINDD_OK;
360 s3call->response.extra_data.data = sids_string;
361 s3call->response.length += strlen(sids_string);
362 s3call->response.data.num_entries = num_sids;
364 /* Hmmmm. Nasty protocol -- who invented the zeros between the
365 * SIDs? Hmmm. Could have been me -- vl */
367 while (*sids_string != '\0') {
368 if ((*sids_string) == '\n') {
369 *sids_string = '\0';
371 sids_string += 1;
374 done:
375 wbsrv_samba3_async_epilogue(status, s3call);
379 Lookup a DOMAIN\\user style name, and return a SID
382 static void lookupname_recv_sid(struct composite_context *ctx);
384 NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
386 struct composite_context *ctx;
387 struct wbsrv_service *service =
388 s3call->wbconn->listen_socket->service;
390 DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
392 ctx = wb_cmd_lookupname_send(s3call, service,
393 s3call->request.data.name.dom_name,
394 s3call->request.data.name.name);
395 NT_STATUS_HAVE_NO_MEMORY(ctx);
397 /* setup the callbacks */
398 ctx->async.fn = lookupname_recv_sid;
399 ctx->async.private_data = s3call;
400 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
401 return NT_STATUS_OK;
404 static void lookupname_recv_sid(struct composite_context *ctx)
406 struct wbsrv_samba3_call *s3call =
407 talloc_get_type(ctx->async.private_data,
408 struct wbsrv_samba3_call);
409 struct wb_sid_object *sid;
410 NTSTATUS status;
412 status = wb_cmd_lookupname_recv(ctx, s3call, &sid);
413 if (!NT_STATUS_IS_OK(status)) goto done;
415 s3call->response.result = WINBINDD_OK;
416 s3call->response.data.sid.type = sid->type;
417 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid,
418 dom_sid_string(s3call, sid->sid));
420 done:
421 wbsrv_samba3_async_epilogue(status, s3call);
425 Lookup a SID, and return a DOMAIN\\user style name
428 static void lookupsid_recv_name(struct composite_context *ctx);
430 NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
432 struct composite_context *ctx;
433 struct wbsrv_service *service =
434 s3call->wbconn->listen_socket->service;
435 struct dom_sid *sid;
437 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
439 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
440 if (sid == NULL) {
441 DEBUG(5, ("Could not parse sid %s\n",
442 s3call->request.data.sid));
443 return NT_STATUS_NO_MEMORY;
446 ctx = wb_cmd_lookupsid_send(s3call, service, sid);
447 NT_STATUS_HAVE_NO_MEMORY(ctx);
449 /* setup the callbacks */
450 ctx->async.fn = lookupsid_recv_name;
451 ctx->async.private_data = s3call;
452 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
453 return NT_STATUS_OK;
456 static void lookupsid_recv_name(struct composite_context *ctx)
458 struct wbsrv_samba3_call *s3call =
459 talloc_get_type(ctx->async.private_data,
460 struct wbsrv_samba3_call);
461 struct wb_sid_object *sid;
462 NTSTATUS status;
464 status = wb_cmd_lookupsid_recv(ctx, s3call, &sid);
465 if (!NT_STATUS_IS_OK(status)) goto done;
467 s3call->response.result = WINBINDD_OK;
468 s3call->response.data.name.type = sid->type;
469 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.dom_name,
470 sid->domain);
471 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.name, sid->name);
473 done:
474 wbsrv_samba3_async_epilogue(status, s3call);
478 Challenge-response authentication. This interface is used by
479 ntlm_auth and the smbd auth subsystem to pass NTLM authentication
480 requests along a common pipe to the domain controller.
482 The return value (in the async reply) may include the 'info3'
483 (effectivly most things you would want to know about the user), or
484 the NT and LM session keys seperated.
487 static void pam_auth_crap_recv(struct composite_context *ctx);
489 NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
491 struct composite_context *ctx;
492 struct wbsrv_service *service =
493 s3call->wbconn->listen_socket->service;
494 DATA_BLOB chal, nt_resp, lm_resp;
496 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
498 chal.data = s3call->request.data.auth_crap.chal;
499 chal.length = sizeof(s3call->request.data.auth_crap.chal);
500 nt_resp.data = (uint8_t *)s3call->request.data.auth_crap.nt_resp;
501 nt_resp.length = s3call->request.data.auth_crap.nt_resp_len;
502 lm_resp.data = (uint8_t *)s3call->request.data.auth_crap.lm_resp;
503 lm_resp.length = s3call->request.data.auth_crap.lm_resp_len;
505 ctx = wb_cmd_pam_auth_crap_send(
506 s3call, service,
507 s3call->request.data.auth_crap.logon_parameters,
508 s3call->request.data.auth_crap.domain,
509 s3call->request.data.auth_crap.user,
510 s3call->request.data.auth_crap.workstation,
511 chal, nt_resp, lm_resp);
512 NT_STATUS_HAVE_NO_MEMORY(ctx);
514 ctx->async.fn = pam_auth_crap_recv;
515 ctx->async.private_data = s3call;
516 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
517 return NT_STATUS_OK;
520 static void pam_auth_crap_recv(struct composite_context *ctx)
522 struct wbsrv_samba3_call *s3call =
523 talloc_get_type(ctx->async.private_data,
524 struct wbsrv_samba3_call);
525 NTSTATUS status;
526 DATA_BLOB info3;
527 struct netr_UserSessionKey user_session_key;
528 struct netr_LMSessionKey lm_key;
529 char *unix_username;
531 status = wb_cmd_pam_auth_crap_recv(ctx, s3call, &info3,
532 &user_session_key, &lm_key, &unix_username);
533 if (!NT_STATUS_IS_OK(status)) goto done;
535 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
536 memcpy(s3call->response.data.auth.user_session_key,
537 &user_session_key.key,
538 sizeof(s3call->response.data.auth.user_session_key));
541 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
542 s3call->response.extra_data.data = info3.data;
543 s3call->response.length += info3.length;
546 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
547 memcpy(s3call->response.data.auth.first_8_lm_hash,
548 lm_key.key,
549 sizeof(s3call->response.data.auth.first_8_lm_hash));
552 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
553 s3call->response.extra_data.data = unix_username;
554 s3call->response.length += strlen(unix_username)+1;
557 done:
558 wbsrv_samba3_async_auth_epilogue(status, s3call);
561 /* Plaintext authentication
563 This interface is used by ntlm_auth in it's 'basic' authentication
564 mode, as well as by pam_winbind to authenticate users where we are
565 given a plaintext password.
568 static void pam_auth_recv(struct composite_context *ctx);
570 NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
572 struct composite_context *ctx;
573 struct wbsrv_service *service =
574 s3call->wbconn->listen_socket->service;
575 struct cli_credentials *credentials;
576 char *user, *domain;
578 if (!wb_samba3_split_username(s3call, s3call->wbconn->lp_ctx,
579 s3call->request.data.auth.user,
580 &domain, &user)) {
581 return NT_STATUS_NO_SUCH_USER;
584 credentials = cli_credentials_init(s3call);
585 if (!credentials) {
586 return NT_STATUS_NO_MEMORY;
588 cli_credentials_set_conf(credentials, service->task->lp_ctx);
589 cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
590 cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
592 cli_credentials_set_password(credentials, s3call->request.data.auth.pass, CRED_SPECIFIED);
594 ctx = wb_cmd_pam_auth_send(s3call, service, credentials);
595 NT_STATUS_HAVE_NO_MEMORY(ctx);
597 ctx->async.fn = pam_auth_recv;
598 ctx->async.private_data = s3call;
599 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
600 return NT_STATUS_OK;
603 static void pam_auth_recv(struct composite_context *ctx)
605 struct wbsrv_samba3_call *s3call =
606 talloc_get_type(ctx->async.private_data,
607 struct wbsrv_samba3_call);
608 NTSTATUS status;
610 status = wb_cmd_pam_auth_recv(ctx);
612 if (!NT_STATUS_IS_OK(status)) goto done;
614 done:
615 wbsrv_samba3_async_auth_epilogue(status, s3call);
619 List trusted domains
622 static void list_trustdom_recv_doms(struct composite_context *ctx);
624 NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
626 struct composite_context *ctx;
627 struct wbsrv_service *service =
628 s3call->wbconn->listen_socket->service;
630 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
632 ctx = wb_cmd_list_trustdoms_send(s3call, service);
633 NT_STATUS_HAVE_NO_MEMORY(ctx);
635 ctx->async.fn = list_trustdom_recv_doms;
636 ctx->async.private_data = s3call;
637 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
638 return NT_STATUS_OK;
641 static void list_trustdom_recv_doms(struct composite_context *ctx)
643 struct wbsrv_samba3_call *s3call =
644 talloc_get_type(ctx->async.private_data,
645 struct wbsrv_samba3_call);
646 int i, num_domains;
647 struct wb_dom_info **domains;
648 NTSTATUS status;
649 char *result;
651 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
652 &domains);
653 if (!NT_STATUS_IS_OK(status)) goto done;
655 result = talloc_strdup(s3call, "");
656 if (result == NULL) {
657 status = NT_STATUS_NO_MEMORY;
658 goto done;
661 for (i=0; i<num_domains; i++) {
662 result = talloc_asprintf_append_buffer(
663 result, "%s\\%s\\%s",
664 domains[i]->name, domains[i]->name,
665 dom_sid_string(s3call, domains[i]->sid));
668 if (result == NULL) {
669 status = NT_STATUS_NO_MEMORY;
670 goto done;
673 s3call->response.result = WINBINDD_OK;
674 if (num_domains > 0) {
675 s3call->response.extra_data.data = result;
676 s3call->response.length += strlen(result)+1;
679 done:
680 wbsrv_samba3_async_epilogue(status, s3call);
683 /* list groups */
684 static void list_groups_recv(struct composite_context *ctx);
686 NTSTATUS wbsrv_samba3_list_groups(struct wbsrv_samba3_call *s3call)
688 struct composite_context *ctx;
689 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
691 DEBUG(5, ("wbsrv_samba4_list_groups called\n"));
693 ctx = wb_cmd_list_groups_send(s3call, service,
694 s3call->request.domain_name);
695 NT_STATUS_HAVE_NO_MEMORY(ctx);
697 ctx->async.fn = list_groups_recv;
698 ctx->async.private_data = s3call;
699 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
700 return NT_STATUS_OK;
703 static void list_groups_recv(struct composite_context *ctx)
705 struct wbsrv_samba3_call *s3call = talloc_get_type_abort(
706 ctx->async.private_data,
707 struct wbsrv_samba3_call);
708 uint32_t extra_data_len;
709 char *extra_data;
710 NTSTATUS status;
712 DEBUG(5, ("list_groups_recv called\n"));
714 status = wb_cmd_list_groups_recv(ctx, s3call, &extra_data_len,
715 &extra_data);
717 if (NT_STATUS_IS_OK(status)) {
718 s3call->response.extra_data.data = extra_data;
719 s3call->response.length += extra_data_len;
720 if (extra_data) {
721 s3call->response.length += 1;
725 wbsrv_samba3_async_epilogue(status, s3call);
728 /* List users */
730 static void list_users_recv(struct composite_context *ctx);
732 NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
734 struct composite_context *ctx;
735 struct wbsrv_service *service =
736 s3call->wbconn->listen_socket->service;
738 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
740 ctx = wb_cmd_list_users_send(s3call, service,
741 s3call->request.domain_name);
742 NT_STATUS_HAVE_NO_MEMORY(ctx);
744 ctx->async.fn = list_users_recv;
745 ctx->async.private_data = s3call;
746 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
747 return NT_STATUS_OK;
750 static void list_users_recv(struct composite_context *ctx)
752 struct wbsrv_samba3_call *s3call =
753 talloc_get_type(ctx->async.private_data,
754 struct wbsrv_samba3_call);
755 uint32_t extra_data_len;
756 char *extra_data;
757 NTSTATUS status;
759 DEBUG(5, ("list_users_recv called\n"));
761 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
762 &extra_data);
764 if (NT_STATUS_IS_OK(status)) {
765 s3call->response.extra_data.data = extra_data;
766 s3call->response.length += extra_data_len;
767 if (extra_data) {
768 s3call->response.length += 1;
772 wbsrv_samba3_async_epilogue(status, s3call);
775 /* NSS calls */
777 static void getpwnam_recv(struct composite_context *ctx);
779 NTSTATUS wbsrv_samba3_getpwnam(struct wbsrv_samba3_call *s3call)
781 struct composite_context *ctx;
782 struct wbsrv_service *service =
783 s3call->wbconn->listen_socket->service;
785 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
787 ctx = wb_cmd_getpwnam_send(s3call, service,
788 s3call->request.data.username);
789 NT_STATUS_HAVE_NO_MEMORY(ctx);
791 ctx->async.fn = getpwnam_recv;
792 ctx->async.private_data = s3call;
793 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
794 return NT_STATUS_OK;
797 static void getpwnam_recv(struct composite_context *ctx)
799 struct wbsrv_samba3_call *s3call =
800 talloc_get_type(ctx->async.private_data,
801 struct wbsrv_samba3_call);
802 NTSTATUS status;
803 struct winbindd_pw *pw;
805 DEBUG(5, ("getpwnam_recv called\n"));
807 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
808 if(NT_STATUS_IS_OK(status))
809 s3call->response.data.pw = *pw;
811 wbsrv_samba3_async_epilogue(status, s3call);
814 static void getpwuid_recv(struct composite_context *ctx);
816 NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
818 struct composite_context *ctx;
819 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
821 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
823 ctx = wb_cmd_getpwuid_send(s3call, service,
824 s3call->request.data.uid);
825 NT_STATUS_HAVE_NO_MEMORY(ctx);
827 ctx->async.fn = getpwuid_recv;
828 ctx->async.private_data = s3call;
829 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
830 return NT_STATUS_OK;
833 static void getpwuid_recv(struct composite_context *ctx)
835 struct wbsrv_samba3_call *s3call =
836 talloc_get_type(ctx->async.private_data,
837 struct wbsrv_samba3_call);
838 NTSTATUS status;
839 struct winbindd_pw *pw;
841 DEBUG(5, ("getpwuid_recv called\n"));
843 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
844 if (NT_STATUS_IS_OK(status))
845 s3call->response.data.pw = *pw;
847 wbsrv_samba3_async_epilogue(status, s3call);
850 static void setpwent_recv(struct composite_context *ctx);
852 NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
854 struct composite_context *ctx;
855 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
857 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
859 ctx = wb_cmd_setpwent_send(s3call, service);
860 NT_STATUS_HAVE_NO_MEMORY(ctx);
862 ctx->async.fn = setpwent_recv;
863 ctx->async.private_data = s3call;
864 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
865 return NT_STATUS_OK;
868 static void setpwent_recv(struct composite_context *ctx)
870 struct wbsrv_samba3_call *s3call =
871 talloc_get_type(ctx->async.private_data,
872 struct wbsrv_samba3_call);
873 NTSTATUS status;
874 struct wbsrv_pwent *pwent;
876 DEBUG(5, ("setpwent_recv called\n"));
878 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
879 if (NT_STATUS_IS_OK(status)) {
880 s3call->wbconn->protocol_private_data = pwent;
883 wbsrv_samba3_async_epilogue(status, s3call);
886 static void getpwent_recv(struct composite_context *ctx);
888 NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
890 struct composite_context *ctx;
891 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
892 struct wbsrv_pwent *pwent;
894 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
896 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
898 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
899 struct wbsrv_pwent);
900 NT_STATUS_HAVE_NO_MEMORY(pwent);
902 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
903 s3call->request.data.num_entries);
904 NT_STATUS_HAVE_NO_MEMORY(ctx);
906 ctx->async.fn = getpwent_recv;
907 ctx->async.private_data = s3call;
908 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
909 return NT_STATUS_OK;
912 static void getpwent_recv(struct composite_context *ctx)
914 struct wbsrv_samba3_call *s3call =
915 talloc_get_type(ctx->async.private_data,
916 struct wbsrv_samba3_call);
917 NTSTATUS status;
918 struct winbindd_pw *pw;
919 uint32_t num_users;
921 DEBUG(5, ("getpwent_recv called\n"));
923 status = wb_cmd_getpwent_recv(ctx, s3call, &pw, &num_users);
924 if (NT_STATUS_IS_OK(status)) {
925 uint32_t extra_len = sizeof(struct winbindd_pw) * num_users;
927 s3call->response.data.num_entries = num_users;
928 s3call->response.extra_data.data = pw;
929 s3call->response.length += extra_len;
932 wbsrv_samba3_async_epilogue(status, s3call);
935 NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
937 struct wbsrv_pwent *pwent =
938 talloc_get_type(s3call->wbconn->protocol_private_data,
939 struct wbsrv_pwent);
940 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
942 talloc_free(pwent);
944 s3call->wbconn->protocol_private_data = NULL;
945 s3call->response.result = WINBINDD_OK;
946 return NT_STATUS_OK;
950 static void getgrnam_recv(struct composite_context *ctx);
952 NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
954 struct composite_context *ctx;
955 struct wbsrv_service *service =
956 s3call->wbconn->listen_socket->service;
958 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
960 ctx = wb_cmd_getgrnam_send(s3call, service,
961 s3call->request.data.groupname);
962 NT_STATUS_HAVE_NO_MEMORY(ctx);
964 ctx->async.fn = getgrnam_recv;
965 ctx->async.private_data = s3call;
966 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
967 return NT_STATUS_OK;
970 static void getgrnam_recv(struct composite_context *ctx)
972 struct wbsrv_samba3_call *s3call =
973 talloc_get_type(ctx->async.private_data,
974 struct wbsrv_samba3_call);
975 NTSTATUS status;
976 struct winbindd_gr *gr;
978 DEBUG(5, ("getgrnam_recv called\n"));
980 status = wb_cmd_getgrnam_recv(ctx, s3call, &gr);
981 if(NT_STATUS_IS_OK(status))
982 s3call->response.data.gr = *gr;
984 wbsrv_samba3_async_epilogue(status, s3call);
987 static void getgrgid_recv(struct composite_context *ctx);
989 NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
991 struct composite_context *ctx;
992 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
994 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
996 ctx = wb_cmd_getgrgid_send(s3call, service,
997 s3call->request.data.gid);
998 NT_STATUS_HAVE_NO_MEMORY(ctx);
1000 ctx->async.fn = getgrgid_recv;
1001 ctx->async.private_data = s3call;
1002 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1003 return NT_STATUS_OK;
1006 static void getgrgid_recv(struct composite_context *ctx)
1008 struct wbsrv_samba3_call *s3call =
1009 talloc_get_type(ctx->async.private_data,
1010 struct wbsrv_samba3_call);
1011 NTSTATUS status;
1012 struct winbindd_gr *gr;
1014 DEBUG(5, ("getgrgid_recv called\n"));
1016 status = wb_cmd_getgrgid_recv(ctx, s3call, &gr);
1017 if (NT_STATUS_IS_OK(status))
1018 s3call->response.data.gr = *gr;
1020 wbsrv_samba3_async_epilogue(status, s3call);
1023 NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
1025 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
1026 s3call->response.result = WINBINDD_ERROR;
1027 return NT_STATUS_OK;
1030 NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
1032 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
1033 s3call->response.result = WINBINDD_OK;
1034 return NT_STATUS_OK;
1037 NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
1039 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
1040 s3call->response.result = WINBINDD_ERROR;
1041 return NT_STATUS_OK;
1044 NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
1046 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
1047 s3call->response.result = WINBINDD_OK;
1048 return NT_STATUS_OK;
1051 static void sid2uid_recv(struct composite_context *ctx);
1053 NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
1055 struct composite_context *ctx;
1056 struct wbsrv_service *service =
1057 s3call->wbconn->listen_socket->service;
1058 struct dom_sid *sid;
1060 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
1062 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1063 NT_STATUS_HAVE_NO_MEMORY(sid);
1065 ctx = wb_sid2uid_send(s3call, service, sid);
1066 NT_STATUS_HAVE_NO_MEMORY(ctx);
1068 ctx->async.fn = sid2uid_recv;
1069 ctx->async.private_data = s3call;
1070 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1071 return NT_STATUS_OK;
1075 static void sid2uid_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;
1082 DEBUG(5, ("sid2uid_recv called\n"));
1084 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
1086 wbsrv_samba3_async_epilogue(status, s3call);
1089 static void sid2gid_recv(struct composite_context *ctx);
1091 NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
1093 struct composite_context *ctx;
1094 struct wbsrv_service *service =
1095 s3call->wbconn->listen_socket->service;
1096 struct dom_sid *sid;
1098 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
1100 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1101 NT_STATUS_HAVE_NO_MEMORY(sid);
1103 ctx = wb_sid2gid_send(s3call, service, sid);
1104 NT_STATUS_HAVE_NO_MEMORY(ctx);
1106 ctx->async.fn = sid2gid_recv;
1107 ctx->async.private_data = s3call;
1108 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1109 return NT_STATUS_OK;
1113 static void sid2gid_recv(struct composite_context *ctx)
1115 struct wbsrv_samba3_call *s3call =
1116 talloc_get_type(ctx->async.private_data,
1117 struct wbsrv_samba3_call);
1118 NTSTATUS status;
1120 DEBUG(5, ("sid2gid_recv called\n"));
1122 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
1124 wbsrv_samba3_async_epilogue(status, s3call);
1127 static void uid2sid_recv(struct composite_context *ctx);
1129 NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
1131 struct composite_context *ctx;
1132 struct wbsrv_service *service =
1133 s3call->wbconn->listen_socket->service;
1135 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1137 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
1138 NT_STATUS_HAVE_NO_MEMORY(ctx);
1140 ctx->async.fn = uid2sid_recv;
1141 ctx->async.private_data = s3call;
1142 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1143 return NT_STATUS_OK;
1147 static void uid2sid_recv(struct composite_context *ctx)
1149 struct wbsrv_samba3_call *s3call =
1150 talloc_get_type(ctx->async.private_data,
1151 struct wbsrv_samba3_call);
1152 NTSTATUS status;
1153 struct dom_sid *sid;
1154 char *sid_str;
1156 DEBUG(5, ("uid2sid_recv called\n"));
1158 status = wb_uid2sid_recv(ctx, s3call, &sid);
1159 if(NT_STATUS_IS_OK(status)) {
1160 sid_str = dom_sid_string(s3call, sid);
1162 /* If the conversion failed, bail out with a failure. */
1163 if (sid_str == NULL)
1164 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1166 /* But we assume this worked, so we'll set the string. Work
1167 * done. */
1168 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1169 s3call->response.data.sid.type = SID_NAME_USER;
1172 wbsrv_samba3_async_epilogue(status, s3call);
1175 static void gid2sid_recv(struct composite_context *ctx);
1177 NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1179 struct composite_context *ctx;
1180 struct wbsrv_service *service =
1181 s3call->wbconn->listen_socket->service;
1183 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1185 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1186 NT_STATUS_HAVE_NO_MEMORY(ctx);
1188 ctx->async.fn = gid2sid_recv;
1189 ctx->async.private_data = s3call;
1190 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1191 return NT_STATUS_OK;
1195 static void gid2sid_recv(struct composite_context *ctx)
1197 struct wbsrv_samba3_call *s3call =
1198 talloc_get_type(ctx->async.private_data,
1199 struct wbsrv_samba3_call);
1200 NTSTATUS status;
1201 struct dom_sid *sid;
1202 char *sid_str;
1204 DEBUG(5, ("gid2sid_recv called\n"));
1206 status = wb_gid2sid_recv(ctx, s3call, &sid);
1207 if(NT_STATUS_IS_OK(status)) {
1208 sid_str = dom_sid_string(s3call, sid);
1210 if (sid_str == NULL)
1211 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1213 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1214 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1217 wbsrv_samba3_async_epilogue(status, s3call);