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/ntlm/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 const char *path = s3call->wbconn->listen_socket->service->priv_socket_path;
117 s3call->response.result = WINBINDD_OK;
118 s3call->response.extra_data.data = discard_const(path);
120 s3call->response.length += strlen(path) + 1;
124 NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
126 s3call->response.result = WINBINDD_OK;
130 /* Plaintext authentication
132 This interface is used by ntlm_auth in it's 'basic' authentication
133 mode, as well as by pam_winbind to authenticate users where we are
134 given a plaintext password.
137 static void check_machacc_recv(struct composite_context *ctx);
139 NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
142 struct cli_credentials *creds;
143 struct composite_context *ctx;
144 struct wbsrv_service *service =
145 s3call->wbconn->listen_socket->service;
147 /* Create a credentials structure */
148 creds = cli_credentials_init(s3call);
150 return NT_STATUS_NO_MEMORY;
153 cli_credentials_set_conf(creds, service->task->lp_ctx);
155 /* Connect the machine account to the credentials */
156 status = cli_credentials_set_machine_account(creds, service->task->lp_ctx);
157 if (!NT_STATUS_IS_OK(status)) {
162 ctx = wb_cmd_pam_auth_send(s3call, service, creds);
166 return NT_STATUS_NO_MEMORY;
169 ctx->async.fn = check_machacc_recv;
170 ctx->async.private_data = s3call;
171 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
175 static void check_machacc_recv(struct composite_context *ctx)
177 struct wbsrv_samba3_call *s3call =
178 talloc_get_type(ctx->async.private_data,
179 struct wbsrv_samba3_call);
182 status = wb_cmd_pam_auth_recv(ctx);
184 if (!NT_STATUS_IS_OK(status)) goto done;
187 wbsrv_samba3_async_auth_epilogue(status, s3call);
191 Find the name of a suitable domain controller, by query on the
192 netlogon pipe to the DC.
195 static void getdcname_recv_dc(struct composite_context *ctx);
197 NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
199 struct composite_context *ctx;
200 struct wbsrv_service *service =
201 s3call->wbconn->listen_socket->service;
203 DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
205 ctx = wb_cmd_getdcname_send(s3call, service,
206 s3call->request.domain_name);
207 NT_STATUS_HAVE_NO_MEMORY(ctx);
209 ctx->async.fn = getdcname_recv_dc;
210 ctx->async.private_data = s3call;
211 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
215 static void getdcname_recv_dc(struct composite_context *ctx)
217 struct wbsrv_samba3_call *s3call =
218 talloc_get_type(ctx->async.private_data,
219 struct wbsrv_samba3_call);
223 status = wb_cmd_getdcname_recv(ctx, s3call, &dcname);
224 if (!NT_STATUS_IS_OK(status)) goto done;
226 s3call->response.result = WINBINDD_OK;
227 WBSRV_SAMBA3_SET_STRING(s3call->response.data.dc_name, dcname);
230 wbsrv_samba3_async_epilogue(status, s3call);
234 Lookup a user's domain groups
237 static void userdomgroups_recv_groups(struct composite_context *ctx);
239 NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
241 struct composite_context *ctx;
244 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
246 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
248 DEBUG(5, ("Could not parse sid %s\n",
249 s3call->request.data.sid));
250 return NT_STATUS_NO_MEMORY;
253 ctx = wb_cmd_userdomgroups_send(
254 s3call, s3call->wbconn->listen_socket->service, sid);
255 NT_STATUS_HAVE_NO_MEMORY(ctx);
257 ctx->async.fn = userdomgroups_recv_groups;
258 ctx->async.private_data = s3call;
259 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
263 static void userdomgroups_recv_groups(struct composite_context *ctx)
265 struct wbsrv_samba3_call *s3call =
266 talloc_get_type(ctx->async.private_data,
267 struct wbsrv_samba3_call);
269 struct dom_sid **sids;
273 status = wb_cmd_userdomgroups_recv(ctx, s3call, &num_sids, &sids);
274 if (!NT_STATUS_IS_OK(status)) goto done;
276 sids_string = talloc_strdup(s3call, "");
277 if (sids_string == NULL) {
278 status = NT_STATUS_NO_MEMORY;
282 for (i=0; i<num_sids; i++) {
283 sids_string = talloc_asprintf_append_buffer(
284 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
287 if (sids_string == NULL) {
288 status = NT_STATUS_NO_MEMORY;
292 s3call->response.result = WINBINDD_OK;
293 s3call->response.extra_data.data = sids_string;
294 s3call->response.length += strlen(sids_string)+1;
295 s3call->response.data.num_entries = num_sids;
298 wbsrv_samba3_async_epilogue(status, s3call);
302 Lookup the list of SIDs for a user
304 static void usersids_recv_sids(struct composite_context *ctx);
306 NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call)
308 struct composite_context *ctx;
311 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
313 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
315 DEBUG(5, ("Could not parse sid %s\n",
316 s3call->request.data.sid));
317 return NT_STATUS_NO_MEMORY;
320 ctx = wb_cmd_usersids_send(
321 s3call, s3call->wbconn->listen_socket->service, sid);
322 NT_STATUS_HAVE_NO_MEMORY(ctx);
324 ctx->async.fn = usersids_recv_sids;
325 ctx->async.private_data = s3call;
326 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
330 static void usersids_recv_sids(struct composite_context *ctx)
332 struct wbsrv_samba3_call *s3call =
333 talloc_get_type(ctx->async.private_data,
334 struct wbsrv_samba3_call);
336 struct dom_sid **sids;
340 status = wb_cmd_usersids_recv(ctx, s3call, &num_sids, &sids);
341 if (!NT_STATUS_IS_OK(status)) goto done;
343 sids_string = talloc_strdup(s3call, "");
344 if (sids_string == NULL) {
345 status = NT_STATUS_NO_MEMORY;
349 for (i=0; i<num_sids; i++) {
350 sids_string = talloc_asprintf_append_buffer(
351 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
352 if (sids_string == NULL) {
353 status = NT_STATUS_NO_MEMORY;
358 s3call->response.result = WINBINDD_OK;
359 s3call->response.extra_data.data = sids_string;
360 s3call->response.length += strlen(sids_string);
361 s3call->response.data.num_entries = num_sids;
363 /* Hmmmm. Nasty protocol -- who invented the zeros between the
364 * SIDs? Hmmm. Could have been me -- vl */
366 while (*sids_string != '\0') {
367 if ((*sids_string) == '\n') {
374 wbsrv_samba3_async_epilogue(status, s3call);
378 Lookup a DOMAIN\\user style name, and return a SID
381 static void lookupname_recv_sid(struct composite_context *ctx);
383 NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
385 struct composite_context *ctx;
386 struct wbsrv_service *service =
387 s3call->wbconn->listen_socket->service;
389 DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
391 ctx = wb_cmd_lookupname_send(s3call, service,
392 s3call->request.data.name.dom_name,
393 s3call->request.data.name.name);
394 NT_STATUS_HAVE_NO_MEMORY(ctx);
396 /* setup the callbacks */
397 ctx->async.fn = lookupname_recv_sid;
398 ctx->async.private_data = s3call;
399 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
403 static void lookupname_recv_sid(struct composite_context *ctx)
405 struct wbsrv_samba3_call *s3call =
406 talloc_get_type(ctx->async.private_data,
407 struct wbsrv_samba3_call);
408 struct wb_sid_object *sid;
411 status = wb_cmd_lookupname_recv(ctx, s3call, &sid);
412 if (!NT_STATUS_IS_OK(status)) goto done;
414 s3call->response.result = WINBINDD_OK;
415 s3call->response.data.sid.type = sid->type;
416 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid,
417 dom_sid_string(s3call, sid->sid));
420 wbsrv_samba3_async_epilogue(status, s3call);
424 Lookup a SID, and return a DOMAIN\\user style name
427 static void lookupsid_recv_name(struct composite_context *ctx);
429 NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
431 struct composite_context *ctx;
432 struct wbsrv_service *service =
433 s3call->wbconn->listen_socket->service;
436 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
438 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
440 DEBUG(5, ("Could not parse sid %s\n",
441 s3call->request.data.sid));
442 return NT_STATUS_NO_MEMORY;
445 ctx = wb_cmd_lookupsid_send(s3call, service, sid);
446 NT_STATUS_HAVE_NO_MEMORY(ctx);
448 /* setup the callbacks */
449 ctx->async.fn = lookupsid_recv_name;
450 ctx->async.private_data = s3call;
451 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
455 static void lookupsid_recv_name(struct composite_context *ctx)
457 struct wbsrv_samba3_call *s3call =
458 talloc_get_type(ctx->async.private_data,
459 struct wbsrv_samba3_call);
460 struct wb_sid_object *sid;
463 status = wb_cmd_lookupsid_recv(ctx, s3call, &sid);
464 if (!NT_STATUS_IS_OK(status)) goto done;
466 s3call->response.result = WINBINDD_OK;
467 s3call->response.data.name.type = sid->type;
468 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.dom_name,
470 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.name, sid->name);
473 wbsrv_samba3_async_epilogue(status, s3call);
477 Challenge-response authentication. This interface is used by
478 ntlm_auth and the smbd auth subsystem to pass NTLM authentication
479 requests along a common pipe to the domain controller.
481 The return value (in the async reply) may include the 'info3'
482 (effectivly most things you would want to know about the user), or
483 the NT and LM session keys seperated.
486 static void pam_auth_crap_recv(struct composite_context *ctx);
488 NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
490 struct composite_context *ctx;
491 struct wbsrv_service *service =
492 s3call->wbconn->listen_socket->service;
493 DATA_BLOB chal, nt_resp, lm_resp;
495 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
497 chal.data = s3call->request.data.auth_crap.chal;
498 chal.length = sizeof(s3call->request.data.auth_crap.chal);
499 nt_resp.data = (uint8_t *)s3call->request.data.auth_crap.nt_resp;
500 nt_resp.length = s3call->request.data.auth_crap.nt_resp_len;
501 lm_resp.data = (uint8_t *)s3call->request.data.auth_crap.lm_resp;
502 lm_resp.length = s3call->request.data.auth_crap.lm_resp_len;
504 ctx = wb_cmd_pam_auth_crap_send(
506 s3call->request.data.auth_crap.logon_parameters,
507 s3call->request.data.auth_crap.domain,
508 s3call->request.data.auth_crap.user,
509 s3call->request.data.auth_crap.workstation,
510 chal, nt_resp, lm_resp);
511 NT_STATUS_HAVE_NO_MEMORY(ctx);
513 ctx->async.fn = pam_auth_crap_recv;
514 ctx->async.private_data = s3call;
515 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
519 static void pam_auth_crap_recv(struct composite_context *ctx)
521 struct wbsrv_samba3_call *s3call =
522 talloc_get_type(ctx->async.private_data,
523 struct wbsrv_samba3_call);
526 struct netr_UserSessionKey user_session_key;
527 struct netr_LMSessionKey lm_key;
530 status = wb_cmd_pam_auth_crap_recv(ctx, s3call, &info3,
531 &user_session_key, &lm_key, &unix_username);
532 if (!NT_STATUS_IS_OK(status)) goto done;
534 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
535 memcpy(s3call->response.data.auth.user_session_key,
536 &user_session_key.key,
537 sizeof(s3call->response.data.auth.user_session_key));
540 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
541 s3call->response.extra_data.data = info3.data;
542 s3call->response.length += info3.length;
545 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
546 memcpy(s3call->response.data.auth.first_8_lm_hash,
548 sizeof(s3call->response.data.auth.first_8_lm_hash));
551 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
552 s3call->response.extra_data.data = unix_username;
553 s3call->response.length += strlen(unix_username)+1;
557 wbsrv_samba3_async_auth_epilogue(status, s3call);
560 /* Plaintext authentication
562 This interface is used by ntlm_auth in it's 'basic' authentication
563 mode, as well as by pam_winbind to authenticate users where we are
564 given a plaintext password.
567 static void pam_auth_recv(struct composite_context *ctx);
569 NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
571 struct composite_context *ctx;
572 struct wbsrv_service *service =
573 s3call->wbconn->listen_socket->service;
574 struct cli_credentials *credentials;
577 if (!wb_samba3_split_username(s3call, s3call->wbconn->lp_ctx,
578 s3call->request.data.auth.user,
580 return NT_STATUS_NO_SUCH_USER;
583 credentials = cli_credentials_init(s3call);
585 return NT_STATUS_NO_MEMORY;
587 cli_credentials_set_conf(credentials, service->task->lp_ctx);
588 cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
589 cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
591 cli_credentials_set_password(credentials, s3call->request.data.auth.pass, CRED_SPECIFIED);
593 ctx = wb_cmd_pam_auth_send(s3call, service, credentials);
594 NT_STATUS_HAVE_NO_MEMORY(ctx);
596 ctx->async.fn = pam_auth_recv;
597 ctx->async.private_data = s3call;
598 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
602 static void pam_auth_recv(struct composite_context *ctx)
604 struct wbsrv_samba3_call *s3call =
605 talloc_get_type(ctx->async.private_data,
606 struct wbsrv_samba3_call);
609 status = wb_cmd_pam_auth_recv(ctx);
611 if (!NT_STATUS_IS_OK(status)) goto done;
614 wbsrv_samba3_async_auth_epilogue(status, s3call);
621 static void list_trustdom_recv_doms(struct composite_context *ctx);
623 NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
625 struct composite_context *ctx;
626 struct wbsrv_service *service =
627 s3call->wbconn->listen_socket->service;
629 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
631 ctx = wb_cmd_list_trustdoms_send(s3call, service);
632 NT_STATUS_HAVE_NO_MEMORY(ctx);
634 ctx->async.fn = list_trustdom_recv_doms;
635 ctx->async.private_data = s3call;
636 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
640 static void list_trustdom_recv_doms(struct composite_context *ctx)
642 struct wbsrv_samba3_call *s3call =
643 talloc_get_type(ctx->async.private_data,
644 struct wbsrv_samba3_call);
646 struct wb_dom_info **domains;
650 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
652 if (!NT_STATUS_IS_OK(status)) goto done;
654 result = talloc_strdup(s3call, "");
655 if (result == NULL) {
656 status = NT_STATUS_NO_MEMORY;
660 for (i=0; i<num_domains; i++) {
661 result = talloc_asprintf_append_buffer(
662 result, "%s\\%s\\%s",
663 domains[i]->name, domains[i]->name,
664 dom_sid_string(s3call, domains[i]->sid));
667 if (result == NULL) {
668 status = NT_STATUS_NO_MEMORY;
672 s3call->response.result = WINBINDD_OK;
673 if (num_domains > 0) {
674 s3call->response.extra_data.data = result;
675 s3call->response.length += strlen(result)+1;
679 wbsrv_samba3_async_epilogue(status, s3call);
685 static void list_users_recv(struct composite_context *ctx);
687 NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
689 struct composite_context *ctx;
690 struct wbsrv_service *service =
691 s3call->wbconn->listen_socket->service;
693 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
695 ctx = wb_cmd_list_users_send(s3call, service,
696 s3call->request.domain_name);
697 NT_STATUS_HAVE_NO_MEMORY(ctx);
699 ctx->async.fn = list_users_recv;
700 ctx->async.private_data = s3call;
701 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
705 static void list_users_recv(struct composite_context *ctx)
707 struct wbsrv_samba3_call *s3call =
708 talloc_get_type(ctx->async.private_data,
709 struct wbsrv_samba3_call);
710 uint32_t extra_data_len;
714 DEBUG(5, ("list_users_recv called\n"));
716 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
719 if (NT_STATUS_IS_OK(status)) {
720 s3call->response.extra_data.data = extra_data;
721 s3call->response.length += extra_data_len;
723 s3call->response.length += 1;
727 wbsrv_samba3_async_epilogue(status, s3call);
732 static void getpwnam_recv(struct composite_context *ctx);
734 NTSTATUS wbsrv_samba3_getpwnam(struct wbsrv_samba3_call *s3call)
736 struct composite_context *ctx;
737 struct wbsrv_service *service =
738 s3call->wbconn->listen_socket->service;
740 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
742 ctx = wb_cmd_getpwnam_send(s3call, service,
743 s3call->request.data.username);
744 NT_STATUS_HAVE_NO_MEMORY(ctx);
746 ctx->async.fn = getpwnam_recv;
747 ctx->async.private_data = s3call;
748 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
752 static void getpwnam_recv(struct composite_context *ctx)
754 struct wbsrv_samba3_call *s3call =
755 talloc_get_type(ctx->async.private_data,
756 struct wbsrv_samba3_call);
758 struct winbindd_pw *pw;
760 DEBUG(5, ("getpwnam_recv called\n"));
762 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
763 if(NT_STATUS_IS_OK(status))
764 s3call->response.data.pw = *pw;
766 wbsrv_samba3_async_epilogue(status, s3call);
769 static void getpwuid_recv(struct composite_context *ctx);
771 NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
773 struct composite_context *ctx;
774 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
776 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
778 ctx = wb_cmd_getpwuid_send(s3call, service,
779 s3call->request.data.uid);
780 NT_STATUS_HAVE_NO_MEMORY(ctx);
782 ctx->async.fn = getpwuid_recv;
783 ctx->async.private_data = s3call;
784 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
788 static void getpwuid_recv(struct composite_context *ctx)
790 struct wbsrv_samba3_call *s3call =
791 talloc_get_type(ctx->async.private_data,
792 struct wbsrv_samba3_call);
794 struct winbindd_pw *pw;
796 DEBUG(5, ("getpwuid_recv called\n"));
798 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
799 if (NT_STATUS_IS_OK(status))
800 s3call->response.data.pw = *pw;
802 wbsrv_samba3_async_epilogue(status, s3call);
805 static void setpwent_recv(struct composite_context *ctx);
807 NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
809 struct composite_context *ctx;
810 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
812 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
814 ctx = wb_cmd_setpwent_send(s3call, service);
815 NT_STATUS_HAVE_NO_MEMORY(ctx);
817 ctx->async.fn = setpwent_recv;
818 ctx->async.private_data = s3call;
819 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
823 static void setpwent_recv(struct composite_context *ctx)
825 struct wbsrv_samba3_call *s3call =
826 talloc_get_type(ctx->async.private_data,
827 struct wbsrv_samba3_call);
829 struct wbsrv_pwent *pwent;
831 DEBUG(5, ("setpwent_recv called\n"));
833 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
834 if (NT_STATUS_IS_OK(status)) {
835 s3call->wbconn->protocol_private_data = pwent;
838 wbsrv_samba3_async_epilogue(status, s3call);
841 static void getpwent_recv(struct composite_context *ctx);
843 NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
845 struct composite_context *ctx;
846 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
847 struct wbsrv_pwent *pwent;
849 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
851 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
853 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
855 NT_STATUS_HAVE_NO_MEMORY(pwent);
857 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
858 s3call->request.data.num_entries);
859 NT_STATUS_HAVE_NO_MEMORY(ctx);
861 ctx->async.fn = getpwent_recv;
862 ctx->async.private_data = s3call;
863 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
867 static void getpwent_recv(struct composite_context *ctx)
869 struct wbsrv_samba3_call *s3call =
870 talloc_get_type(ctx->async.private_data,
871 struct wbsrv_samba3_call);
873 struct winbindd_pw *pw;
876 DEBUG(5, ("getpwent_recv called\n"));
878 status = wb_cmd_getpwent_recv(ctx, s3call, &pw, &num_users);
879 if (NT_STATUS_IS_OK(status)) {
880 uint32_t extra_len = sizeof(struct winbindd_pw) * num_users;
882 s3call->response.data.num_entries = num_users;
883 s3call->response.extra_data.data = pw;
884 s3call->response.length += extra_len;
887 wbsrv_samba3_async_epilogue(status, s3call);
890 NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
892 struct wbsrv_pwent *pwent =
893 talloc_get_type(s3call->wbconn->protocol_private_data,
895 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
899 s3call->wbconn->protocol_private_data = NULL;
900 s3call->response.result = WINBINDD_OK;
905 static void getgrnam_recv(struct composite_context *ctx);
907 NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
909 struct composite_context *ctx;
910 struct wbsrv_service *service =
911 s3call->wbconn->listen_socket->service;
913 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
915 ctx = wb_cmd_getgrnam_send(s3call, service,
916 s3call->request.data.groupname);
917 NT_STATUS_HAVE_NO_MEMORY(ctx);
919 ctx->async.fn = getgrnam_recv;
920 ctx->async.private_data = s3call;
921 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
925 static void getgrnam_recv(struct composite_context *ctx)
927 struct wbsrv_samba3_call *s3call =
928 talloc_get_type(ctx->async.private_data,
929 struct wbsrv_samba3_call);
931 struct winbindd_gr *gr;
933 DEBUG(5, ("getgrnam_recv called\n"));
935 status = wb_cmd_getgrnam_recv(ctx, s3call, &gr);
936 if(NT_STATUS_IS_OK(status))
937 s3call->response.data.gr = *gr;
939 wbsrv_samba3_async_epilogue(status, s3call);
942 static void getgrgid_recv(struct composite_context *ctx);
944 NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
946 struct composite_context *ctx;
947 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
949 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
951 ctx = wb_cmd_getgrgid_send(s3call, service,
952 s3call->request.data.gid);
953 NT_STATUS_HAVE_NO_MEMORY(ctx);
955 ctx->async.fn = getgrgid_recv;
956 ctx->async.private_data = s3call;
957 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
961 static void getgrgid_recv(struct composite_context *ctx)
963 struct wbsrv_samba3_call *s3call =
964 talloc_get_type(ctx->async.private_data,
965 struct wbsrv_samba3_call);
967 struct winbindd_gr *gr;
969 DEBUG(5, ("getgrgid_recv called\n"));
971 status = wb_cmd_getgrgid_recv(ctx, s3call, &gr);
972 if (NT_STATUS_IS_OK(status))
973 s3call->response.data.gr = *gr;
975 wbsrv_samba3_async_epilogue(status, s3call);
978 NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
980 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
981 s3call->response.result = WINBINDD_ERROR;
985 NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
987 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
988 s3call->response.result = WINBINDD_OK;
992 NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
994 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
995 s3call->response.result = WINBINDD_ERROR;
999 NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
1001 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
1002 s3call->response.result = WINBINDD_OK;
1003 return NT_STATUS_OK;
1006 static void sid2uid_recv(struct composite_context *ctx);
1008 NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
1010 struct composite_context *ctx;
1011 struct wbsrv_service *service =
1012 s3call->wbconn->listen_socket->service;
1013 struct dom_sid *sid;
1015 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
1017 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1018 NT_STATUS_HAVE_NO_MEMORY(sid);
1020 ctx = wb_sid2uid_send(s3call, service, sid);
1021 NT_STATUS_HAVE_NO_MEMORY(ctx);
1023 ctx->async.fn = sid2uid_recv;
1024 ctx->async.private_data = s3call;
1025 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1026 return NT_STATUS_OK;
1030 static void sid2uid_recv(struct composite_context *ctx)
1032 struct wbsrv_samba3_call *s3call =
1033 talloc_get_type(ctx->async.private_data,
1034 struct wbsrv_samba3_call);
1037 DEBUG(5, ("sid2uid_recv called\n"));
1039 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
1041 wbsrv_samba3_async_epilogue(status, s3call);
1044 static void sid2gid_recv(struct composite_context *ctx);
1046 NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
1048 struct composite_context *ctx;
1049 struct wbsrv_service *service =
1050 s3call->wbconn->listen_socket->service;
1051 struct dom_sid *sid;
1053 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
1055 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1056 NT_STATUS_HAVE_NO_MEMORY(sid);
1058 ctx = wb_sid2gid_send(s3call, service, sid);
1059 NT_STATUS_HAVE_NO_MEMORY(ctx);
1061 ctx->async.fn = sid2gid_recv;
1062 ctx->async.private_data = s3call;
1063 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1064 return NT_STATUS_OK;
1068 static void sid2gid_recv(struct composite_context *ctx)
1070 struct wbsrv_samba3_call *s3call =
1071 talloc_get_type(ctx->async.private_data,
1072 struct wbsrv_samba3_call);
1075 DEBUG(5, ("sid2gid_recv called\n"));
1077 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
1079 wbsrv_samba3_async_epilogue(status, s3call);
1082 static void uid2sid_recv(struct composite_context *ctx);
1084 NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
1086 struct composite_context *ctx;
1087 struct wbsrv_service *service =
1088 s3call->wbconn->listen_socket->service;
1090 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1092 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
1093 NT_STATUS_HAVE_NO_MEMORY(ctx);
1095 ctx->async.fn = uid2sid_recv;
1096 ctx->async.private_data = s3call;
1097 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1098 return NT_STATUS_OK;
1102 static void uid2sid_recv(struct composite_context *ctx)
1104 struct wbsrv_samba3_call *s3call =
1105 talloc_get_type(ctx->async.private_data,
1106 struct wbsrv_samba3_call);
1108 struct dom_sid *sid;
1111 DEBUG(5, ("uid2sid_recv called\n"));
1113 status = wb_uid2sid_recv(ctx, s3call, &sid);
1114 if(NT_STATUS_IS_OK(status)) {
1115 sid_str = dom_sid_string(s3call, sid);
1117 /* If the conversion failed, bail out with a failure. */
1118 if (sid_str == NULL)
1119 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1121 /* But we assume this worked, so we'll set the string. Work
1123 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1124 s3call->response.data.sid.type = SID_NAME_USER;
1127 wbsrv_samba3_async_epilogue(status, s3call);
1130 static void gid2sid_recv(struct composite_context *ctx);
1132 NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1134 struct composite_context *ctx;
1135 struct wbsrv_service *service =
1136 s3call->wbconn->listen_socket->service;
1138 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1140 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1141 NT_STATUS_HAVE_NO_MEMORY(ctx);
1143 ctx->async.fn = gid2sid_recv;
1144 ctx->async.private_data = s3call;
1145 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1146 return NT_STATUS_OK;
1150 static void gid2sid_recv(struct composite_context *ctx)
1152 struct wbsrv_samba3_call *s3call =
1153 talloc_get_type(ctx->async.private_data,
1154 struct wbsrv_samba3_call);
1156 struct dom_sid *sid;
1159 DEBUG(5, ("gid2sid_recv called\n"));
1161 status = wb_gid2sid_recv(ctx, s3call, &sid);
1162 if(NT_STATUS_IS_OK(status)) {
1163 sid_str = dom_sid_string(s3call, sid);
1165 if (sid_str == NULL)
1166 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1168 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1169 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1172 wbsrv_samba3_async_epilogue(status, s3call);