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
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "winbind/wb_server.h"
25 #include "winbind/wb_async_helpers.h"
26 #include "param/param.h"
27 #include "winbind/wb_helper.h"
28 #include "libcli/composite/composite.h"
30 #include "librpc/gen_ndr/netlogon.h"
31 #include "libcli/security/security.h"
32 #include "auth/pam_errors.h"
33 #include "auth/credentials/credentials.h"
34 #include "smbd/service_task.h"
37 Send off the reply to an async Samba3 query, handling filling in the PAM, NTSTATUS and string errors.
40 static void wbsrv_samba3_async_auth_epilogue(NTSTATUS status,
41 struct wbsrv_samba3_call *s3call)
43 struct winbindd_response *resp = &s3call->response;
44 if (!NT_STATUS_IS_OK(status)) {
45 resp->result = WINBINDD_ERROR;
47 resp->result = WINBINDD_OK;
50 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
52 WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
53 get_friendly_nt_error_msg(status));
55 resp->data.auth.pam_error = nt_status_to_pam(status);
56 resp->data.auth.nt_status = NT_STATUS_V(status);
58 wbsrv_samba3_send_reply(s3call);
62 Send of a generic reply to a Samba3 query
65 static void wbsrv_samba3_async_epilogue(NTSTATUS status,
66 struct wbsrv_samba3_call *s3call)
68 struct winbindd_response *resp = &s3call->response;
69 if (NT_STATUS_IS_OK(status)) {
70 resp->result = WINBINDD_OK;
72 resp->result = WINBINDD_ERROR;
75 wbsrv_samba3_send_reply(s3call);
79 Boilerplate commands, simple queries without network traffic
82 NTSTATUS wbsrv_samba3_interface_version(struct wbsrv_samba3_call *s3call)
84 s3call->response.result = WINBINDD_OK;
85 s3call->response.data.interface_version = WINBIND_INTERFACE_VERSION;
89 NTSTATUS wbsrv_samba3_info(struct wbsrv_samba3_call *s3call)
91 s3call->response.result = WINBINDD_OK;
92 s3call->response.data.info.winbind_separator = *lp_winbind_separator(s3call->wbconn->lp_ctx);
93 WBSRV_SAMBA3_SET_STRING(s3call->response.data.info.samba_version,
94 SAMBA_VERSION_STRING);
98 NTSTATUS wbsrv_samba3_domain_name(struct wbsrv_samba3_call *s3call)
100 s3call->response.result = WINBINDD_OK;
101 WBSRV_SAMBA3_SET_STRING(s3call->response.data.domain_name,
102 lp_workgroup(s3call->wbconn->lp_ctx));
106 NTSTATUS wbsrv_samba3_netbios_name(struct wbsrv_samba3_call *s3call)
108 s3call->response.result = WINBINDD_OK;
109 WBSRV_SAMBA3_SET_STRING(s3call->response.data.netbios_name,
110 lp_netbios_name(s3call->wbconn->lp_ctx));
114 NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
116 char *path = smbd_tmp_path(s3call, s3call->wbconn->lp_ctx, WINBINDD_SAMBA3_PRIVILEGED_SOCKET);
117 NT_STATUS_HAVE_NO_MEMORY(path);
118 s3call->response.result = WINBINDD_OK;
119 s3call->response.extra_data.data = path;
121 s3call->response.length += strlen(path) + 1;
125 NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
127 s3call->response.result = WINBINDD_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)
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);
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)) {
163 ctx = wb_cmd_pam_auth_send(s3call, service, 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;
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);
183 status = wb_cmd_pam_auth_recv(ctx);
185 if (!NT_STATUS_IS_OK(status)) goto 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;
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);
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);
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;
245 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
247 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
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;
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);
270 struct dom_sid **sids;
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;
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;
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;
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;
312 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
314 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
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;
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);
337 struct dom_sid **sids;
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;
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;
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') {
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;
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;
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));
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;
437 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
439 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
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;
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;
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,
471 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.name, sid->name);
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(
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;
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);
527 struct netr_UserSessionKey user_session_key;
528 struct netr_LMSessionKey lm_key;
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,
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;
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;
578 if (!wb_samba3_split_username(s3call, s3call->wbconn->lp_ctx,
579 s3call->request.data.auth.user,
581 return NT_STATUS_NO_SUCH_USER;
584 credentials = cli_credentials_init(s3call);
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;
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);
610 status = wb_cmd_pam_auth_recv(ctx);
612 if (!NT_STATUS_IS_OK(status)) goto done;
615 wbsrv_samba3_async_auth_epilogue(status, s3call);
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;
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);
647 struct wb_dom_info **domains;
651 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_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;
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;
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;
680 wbsrv_samba3_async_epilogue(status, s3call);
686 static void list_users_recv(struct composite_context *ctx);
688 NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
690 struct composite_context *ctx;
691 struct wbsrv_service *service =
692 s3call->wbconn->listen_socket->service;
694 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
696 ctx = wb_cmd_list_users_send(s3call, service,
697 s3call->request.domain_name);
698 NT_STATUS_HAVE_NO_MEMORY(ctx);
700 ctx->async.fn = list_users_recv;
701 ctx->async.private_data = s3call;
702 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
706 static void list_users_recv(struct composite_context *ctx)
708 struct wbsrv_samba3_call *s3call =
709 talloc_get_type(ctx->async.private_data,
710 struct wbsrv_samba3_call);
711 uint32_t extra_data_len;
715 DEBUG(5, ("list_users_recv called\n"));
717 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
720 if (NT_STATUS_IS_OK(status)) {
721 s3call->response.extra_data.data = extra_data;
722 s3call->response.length += extra_data_len;
725 wbsrv_samba3_async_epilogue(status, s3call);
730 static void getpwnam_recv(struct composite_context *ctx);
732 NTSTATUS wbsrv_samba3_getpwnam(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_getpwnam called\n"));
740 ctx = wb_cmd_getpwnam_send(s3call, service,
741 s3call->request.data.username);
742 NT_STATUS_HAVE_NO_MEMORY(ctx);
744 ctx->async.fn = getpwnam_recv;
745 ctx->async.private_data = s3call;
746 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
750 static void getpwnam_recv(struct composite_context *ctx)
752 struct wbsrv_samba3_call *s3call =
753 talloc_get_type(ctx->async.private_data,
754 struct wbsrv_samba3_call);
756 struct winbindd_pw *pw;
758 DEBUG(5, ("getpwnam_recv called\n"));
760 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
761 if(NT_STATUS_IS_OK(status))
762 s3call->response.data.pw = *pw;
764 wbsrv_samba3_async_epilogue(status, s3call);
767 static void getpwuid_recv(struct composite_context *ctx);
769 NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
771 struct composite_context *ctx;
772 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
774 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
776 ctx = wb_cmd_getpwuid_send(s3call, service,
777 s3call->request.data.uid);
778 NT_STATUS_HAVE_NO_MEMORY(ctx);
780 ctx->async.fn = getpwuid_recv;
781 ctx->async.private_data = s3call;
782 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
786 static void getpwuid_recv(struct composite_context *ctx)
788 struct wbsrv_samba3_call *s3call =
789 talloc_get_type(ctx->async.private_data,
790 struct wbsrv_samba3_call);
792 struct winbindd_pw *pw;
794 DEBUG(5, ("getpwuid_recv called\n"));
796 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
797 if (NT_STATUS_IS_OK(status))
798 s3call->response.data.pw = *pw;
800 wbsrv_samba3_async_epilogue(status, s3call);
803 static void setpwent_recv(struct composite_context *ctx);
805 NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
807 struct composite_context *ctx;
808 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
810 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
812 ctx = wb_cmd_setpwent_send(s3call, service);
813 NT_STATUS_HAVE_NO_MEMORY(ctx);
815 ctx->async.fn = setpwent_recv;
816 ctx->async.private_data = s3call;
817 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
821 static void setpwent_recv(struct composite_context *ctx)
823 struct wbsrv_samba3_call *s3call =
824 talloc_get_type(ctx->async.private_data,
825 struct wbsrv_samba3_call);
827 struct wbsrv_pwent *pwent;
829 DEBUG(5, ("setpwent_recv called\n"));
831 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
832 if (NT_STATUS_IS_OK(status)) {
833 s3call->wbconn->protocol_private_data = pwent;
836 wbsrv_samba3_async_epilogue(status, s3call);
839 static void getpwent_recv(struct composite_context *ctx);
841 NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
843 struct composite_context *ctx;
844 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
845 struct wbsrv_pwent *pwent;
847 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
849 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
851 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
853 NT_STATUS_HAVE_NO_MEMORY(pwent);
855 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
856 s3call->request.data.num_entries);
857 NT_STATUS_HAVE_NO_MEMORY(ctx);
859 ctx->async.fn = getpwent_recv;
860 ctx->async.private_data = s3call;
861 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
865 static void getpwent_recv(struct composite_context *ctx)
867 struct wbsrv_samba3_call *s3call =
868 talloc_get_type(ctx->async.private_data,
869 struct wbsrv_samba3_call);
871 struct winbindd_pw *pw;
874 DEBUG(5, ("getpwent_recv called\n"));
876 status = wb_cmd_getpwent_recv(ctx, s3call, &pw, &num_users);
877 if (NT_STATUS_IS_OK(status)) {
878 uint32_t extra_len = sizeof(struct winbindd_pw) * num_users;
880 s3call->response.data.num_entries = num_users;
881 s3call->response.extra_data.data = pw;
882 s3call->response.length += extra_len;
885 wbsrv_samba3_async_epilogue(status, s3call);
888 NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
890 struct wbsrv_pwent *pwent =
891 talloc_get_type(s3call->wbconn->protocol_private_data,
893 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
897 s3call->wbconn->protocol_private_data = NULL;
898 s3call->response.result = WINBINDD_OK;
902 NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
904 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
905 s3call->response.result = WINBINDD_ERROR;
909 NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
911 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
912 s3call->response.result = WINBINDD_ERROR;
916 NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
918 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
919 s3call->response.result = WINBINDD_ERROR;
923 NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
925 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
926 s3call->response.result = WINBINDD_OK;
930 NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
932 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
933 s3call->response.result = WINBINDD_ERROR;
937 NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
939 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
940 s3call->response.result = WINBINDD_OK;
944 static void sid2uid_recv(struct composite_context *ctx);
946 NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
948 struct composite_context *ctx;
949 struct wbsrv_service *service =
950 s3call->wbconn->listen_socket->service;
953 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
955 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
956 NT_STATUS_HAVE_NO_MEMORY(sid);
958 ctx = wb_sid2uid_send(s3call, service, sid);
959 NT_STATUS_HAVE_NO_MEMORY(ctx);
961 ctx->async.fn = sid2uid_recv;
962 ctx->async.private_data = s3call;
963 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
968 static void sid2uid_recv(struct composite_context *ctx)
970 struct wbsrv_samba3_call *s3call =
971 talloc_get_type(ctx->async.private_data,
972 struct wbsrv_samba3_call);
975 DEBUG(5, ("sid2uid_recv called\n"));
977 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
979 wbsrv_samba3_async_epilogue(status, s3call);
982 static void sid2gid_recv(struct composite_context *ctx);
984 NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
986 struct composite_context *ctx;
987 struct wbsrv_service *service =
988 s3call->wbconn->listen_socket->service;
991 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
993 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
994 NT_STATUS_HAVE_NO_MEMORY(sid);
996 ctx = wb_sid2gid_send(s3call, service, sid);
997 NT_STATUS_HAVE_NO_MEMORY(ctx);
999 ctx->async.fn = sid2gid_recv;
1000 ctx->async.private_data = s3call;
1001 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1002 return NT_STATUS_OK;
1006 static void sid2gid_recv(struct composite_context *ctx)
1008 struct wbsrv_samba3_call *s3call =
1009 talloc_get_type(ctx->async.private_data,
1010 struct wbsrv_samba3_call);
1013 DEBUG(5, ("sid2gid_recv called\n"));
1015 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
1017 wbsrv_samba3_async_epilogue(status, s3call);
1020 static void uid2sid_recv(struct composite_context *ctx);
1022 NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
1024 struct composite_context *ctx;
1025 struct wbsrv_service *service =
1026 s3call->wbconn->listen_socket->service;
1028 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1030 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
1031 NT_STATUS_HAVE_NO_MEMORY(ctx);
1033 ctx->async.fn = uid2sid_recv;
1034 ctx->async.private_data = s3call;
1035 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1036 return NT_STATUS_OK;
1040 static void uid2sid_recv(struct composite_context *ctx)
1042 struct wbsrv_samba3_call *s3call =
1043 talloc_get_type(ctx->async.private_data,
1044 struct wbsrv_samba3_call);
1046 struct dom_sid *sid;
1049 DEBUG(5, ("uid2sid_recv called\n"));
1051 status = wb_uid2sid_recv(ctx, s3call, &sid);
1052 if(NT_STATUS_IS_OK(status)) {
1053 sid_str = dom_sid_string(s3call, sid);
1055 /* If the conversion failed, bail out with a failure. */
1056 if (sid_str == NULL)
1057 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1059 /* But we assume this worked, so we'll set the string. Work
1061 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1062 s3call->response.data.sid.type = SID_NAME_USER;
1065 wbsrv_samba3_async_epilogue(status, s3call);
1068 static void gid2sid_recv(struct composite_context *ctx);
1070 NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1072 struct composite_context *ctx;
1073 struct wbsrv_service *service =
1074 s3call->wbconn->listen_socket->service;
1076 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1078 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1079 NT_STATUS_HAVE_NO_MEMORY(ctx);
1081 ctx->async.fn = gid2sid_recv;
1082 ctx->async.private_data = s3call;
1083 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1084 return NT_STATUS_OK;
1088 static void gid2sid_recv(struct composite_context *ctx)
1090 struct wbsrv_samba3_call *s3call =
1091 talloc_get_type(ctx->async.private_data,
1092 struct wbsrv_samba3_call);
1094 struct dom_sid *sid;
1097 DEBUG(5, ("gid2sid_recv called\n"));
1099 status = wb_gid2sid_recv(ctx, s3call, &sid);
1100 if(NT_STATUS_IS_OK(status)) {
1101 sid_str = dom_sid_string(s3call, sid);
1103 if (sid_str == NULL)
1104 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1106 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1107 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1110 wbsrv_samba3_async_epilogue(status, s3call);