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 "nsswitch/winbind_nss_config.h"
25 #include "nsswitch/winbindd_nss.h"
26 #include "winbind/wb_server.h"
27 #include "winbind/wb_async_helpers.h"
28 #include "winbind/wb_helper.h"
29 #include "libcli/composite/composite.h"
31 #include "librpc/gen_ndr/netlogon.h"
32 #include "libcli/security/security.h"
33 #include "auth/pam_errors.h"
34 #include "param/param.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;
46 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
48 WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
49 get_friendly_nt_error_msg(status));
51 resp->result = WINBINDD_OK;
54 resp->data.auth.pam_error = nt_status_to_pam(status);
55 resp->data.auth.nt_status = NT_STATUS_V(status);
57 wbsrv_samba3_send_reply(s3call);
61 Send of a generic reply to a Samba3 query
64 static void wbsrv_samba3_async_epilogue(NTSTATUS status,
65 struct wbsrv_samba3_call *s3call)
67 struct winbindd_response *resp = &s3call->response;
68 if (NT_STATUS_IS_OK(status)) {
69 resp->result = WINBINDD_OK;
71 resp->result = WINBINDD_ERROR;
74 wbsrv_samba3_send_reply(s3call);
78 Boilerplate commands, simple queries without network traffic
81 NTSTATUS wbsrv_samba3_interface_version(struct wbsrv_samba3_call *s3call)
83 s3call->response.result = WINBINDD_OK;
84 s3call->response.data.interface_version = WINBIND_INTERFACE_VERSION;
88 NTSTATUS wbsrv_samba3_info(struct wbsrv_samba3_call *s3call)
90 s3call->response.result = WINBINDD_OK;
91 s3call->response.data.info.winbind_separator = *lp_winbind_separator();
92 WBSRV_SAMBA3_SET_STRING(s3call->response.data.info.samba_version,
93 SAMBA_VERSION_STRING);
97 NTSTATUS wbsrv_samba3_domain_name(struct wbsrv_samba3_call *s3call)
99 s3call->response.result = WINBINDD_OK;
100 WBSRV_SAMBA3_SET_STRING(s3call->response.data.domain_name,
105 NTSTATUS wbsrv_samba3_netbios_name(struct wbsrv_samba3_call *s3call)
107 s3call->response.result = WINBINDD_OK;
108 WBSRV_SAMBA3_SET_STRING(s3call->response.data.netbios_name,
113 NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
115 s3call->response.result = WINBINDD_OK;
116 s3call->response.extra_data.data =
117 smbd_tmp_path(s3call, WINBINDD_SAMBA3_PRIVILEGED_SOCKET);
118 NT_STATUS_HAVE_NO_MEMORY(s3call->response.extra_data.data);
122 NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
124 s3call->response.result = WINBINDD_OK;
130 Validate that we have a working pipe to the domain controller.
131 Return any NT error found in the process
134 static void checkmachacc_recv_creds(struct composite_context *ctx);
136 NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
138 struct composite_context *ctx;
140 DEBUG(5, ("wbsrv_samba3_check_machacc called\n"));
142 ctx = wb_cmd_checkmachacc_send(s3call->call);
143 NT_STATUS_HAVE_NO_MEMORY(ctx);
145 ctx->async.fn = checkmachacc_recv_creds;
146 ctx->async.private_data = s3call;
147 s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
151 static void checkmachacc_recv_creds(struct composite_context *ctx)
153 struct wbsrv_samba3_call *s3call =
154 talloc_get_type(ctx->async.private_data,
155 struct wbsrv_samba3_call);
158 status = wb_cmd_checkmachacc_recv(ctx);
160 wbsrv_samba3_async_auth_epilogue(status, s3call);
165 Find the name of a suitable domain controller, by query on the
166 netlogon pipe to the DC.
169 static void getdcname_recv_dc(struct composite_context *ctx);
171 NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
173 struct composite_context *ctx;
174 struct wbsrv_service *service =
175 s3call->wbconn->listen_socket->service;
177 DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
179 ctx = wb_cmd_getdcname_send(s3call, service,
180 s3call->request.domain_name);
181 NT_STATUS_HAVE_NO_MEMORY(ctx);
183 ctx->async.fn = getdcname_recv_dc;
184 ctx->async.private_data = s3call;
185 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
189 static void getdcname_recv_dc(struct composite_context *ctx)
191 struct wbsrv_samba3_call *s3call =
192 talloc_get_type(ctx->async.private_data,
193 struct wbsrv_samba3_call);
197 status = wb_cmd_getdcname_recv(ctx, s3call, &dcname);
198 if (!NT_STATUS_IS_OK(status)) goto done;
200 s3call->response.result = WINBINDD_OK;
201 WBSRV_SAMBA3_SET_STRING(s3call->response.data.dc_name, dcname);
204 wbsrv_samba3_async_epilogue(status, s3call);
208 Lookup a user's domain groups
211 static void userdomgroups_recv_groups(struct composite_context *ctx);
213 NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
215 struct composite_context *ctx;
218 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
220 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
222 DEBUG(5, ("Could not parse sid %s\n",
223 s3call->request.data.sid));
224 return NT_STATUS_NO_MEMORY;
227 ctx = wb_cmd_userdomgroups_send(
228 s3call, s3call->wbconn->listen_socket->service, sid);
229 NT_STATUS_HAVE_NO_MEMORY(ctx);
231 ctx->async.fn = userdomgroups_recv_groups;
232 ctx->async.private_data = s3call;
233 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
237 static void userdomgroups_recv_groups(struct composite_context *ctx)
239 struct wbsrv_samba3_call *s3call =
240 talloc_get_type(ctx->async.private_data,
241 struct wbsrv_samba3_call);
243 struct dom_sid **sids;
247 status = wb_cmd_userdomgroups_recv(ctx, s3call, &num_sids, &sids);
248 if (!NT_STATUS_IS_OK(status)) goto done;
250 sids_string = talloc_strdup(s3call, "");
251 if (sids_string == NULL) {
252 status = NT_STATUS_NO_MEMORY;
256 for (i=0; i<num_sids; i++) {
257 sids_string = talloc_asprintf_append(
258 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
261 if (sids_string == NULL) {
262 status = NT_STATUS_NO_MEMORY;
266 s3call->response.result = WINBINDD_OK;
267 s3call->response.extra_data.data = sids_string;
268 s3call->response.length += strlen(sids_string)+1;
269 s3call->response.data.num_entries = num_sids;
272 wbsrv_samba3_async_epilogue(status, s3call);
276 Lookup the list of SIDs for a user
278 static void usersids_recv_sids(struct composite_context *ctx);
280 NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call)
282 struct composite_context *ctx;
285 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
287 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
289 DEBUG(5, ("Could not parse sid %s\n",
290 s3call->request.data.sid));
291 return NT_STATUS_NO_MEMORY;
294 ctx = wb_cmd_usersids_send(
295 s3call, s3call->wbconn->listen_socket->service, sid);
296 NT_STATUS_HAVE_NO_MEMORY(ctx);
298 ctx->async.fn = usersids_recv_sids;
299 ctx->async.private_data = s3call;
300 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
304 static void usersids_recv_sids(struct composite_context *ctx)
306 struct wbsrv_samba3_call *s3call =
307 talloc_get_type(ctx->async.private_data,
308 struct wbsrv_samba3_call);
310 struct dom_sid **sids;
314 status = wb_cmd_usersids_recv(ctx, s3call, &num_sids, &sids);
315 if (!NT_STATUS_IS_OK(status)) goto done;
317 sids_string = talloc_strdup(s3call, "");
318 if (sids_string == NULL) {
319 status = NT_STATUS_NO_MEMORY;
323 for (i=0; i<num_sids; i++) {
324 sids_string = talloc_asprintf_append(
325 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
326 if (sids_string == NULL) {
327 status = NT_STATUS_NO_MEMORY;
332 s3call->response.result = WINBINDD_OK;
333 s3call->response.extra_data.data = sids_string;
334 s3call->response.length += strlen(sids_string);
335 s3call->response.data.num_entries = num_sids;
337 /* Hmmmm. Nasty protocol -- who invented the zeros between the
338 * SIDs? Hmmm. Could have been me -- vl */
340 while (*sids_string != '\0') {
341 if ((*sids_string) == '\n') {
348 wbsrv_samba3_async_epilogue(status, s3call);
352 Lookup a DOMAIN\\user style name, and return a SID
355 static void lookupname_recv_sid(struct composite_context *ctx);
357 NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
359 struct composite_context *ctx;
360 struct wbsrv_service *service =
361 s3call->wbconn->listen_socket->service;
363 DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
365 ctx = wb_cmd_lookupname_send(s3call, service,
366 s3call->request.data.name.dom_name,
367 s3call->request.data.name.name);
368 NT_STATUS_HAVE_NO_MEMORY(ctx);
370 /* setup the callbacks */
371 ctx->async.fn = lookupname_recv_sid;
372 ctx->async.private_data = s3call;
373 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
377 static void lookupname_recv_sid(struct composite_context *ctx)
379 struct wbsrv_samba3_call *s3call =
380 talloc_get_type(ctx->async.private_data,
381 struct wbsrv_samba3_call);
382 struct wb_sid_object *sid;
385 status = wb_cmd_lookupname_recv(ctx, s3call, &sid);
386 if (!NT_STATUS_IS_OK(status)) goto done;
388 s3call->response.result = WINBINDD_OK;
389 s3call->response.data.sid.type = sid->type;
390 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid,
391 dom_sid_string(s3call, sid->sid));
394 wbsrv_samba3_async_epilogue(status, s3call);
398 Lookup a SID, and return a DOMAIN\\user style name
401 static void lookupsid_recv_name(struct composite_context *ctx);
403 NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
405 struct composite_context *ctx;
406 struct wbsrv_service *service =
407 s3call->wbconn->listen_socket->service;
410 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
412 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
414 DEBUG(5, ("Could not parse sid %s\n",
415 s3call->request.data.sid));
416 return NT_STATUS_NO_MEMORY;
419 ctx = wb_cmd_lookupsid_send(s3call, service, sid);
420 NT_STATUS_HAVE_NO_MEMORY(ctx);
422 /* setup the callbacks */
423 ctx->async.fn = lookupsid_recv_name;
424 ctx->async.private_data = s3call;
425 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
429 static void lookupsid_recv_name(struct composite_context *ctx)
431 struct wbsrv_samba3_call *s3call =
432 talloc_get_type(ctx->async.private_data,
433 struct wbsrv_samba3_call);
434 struct wb_sid_object *sid;
437 status = wb_cmd_lookupsid_recv(ctx, s3call, &sid);
438 if (!NT_STATUS_IS_OK(status)) goto done;
440 s3call->response.result = WINBINDD_OK;
441 s3call->response.data.name.type = sid->type;
442 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.dom_name,
444 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.name, sid->name);
447 wbsrv_samba3_async_epilogue(status, s3call);
451 Challenge-response authentication. This interface is used by
452 ntlm_auth and the smbd auth subsystem to pass NTLM authentication
453 requests along a common pipe to the domain controller.
455 The return value (in the async reply) may include the 'info3'
456 (effectivly most things you would want to know about the user), or
457 the NT and LM session keys seperated.
460 static void pam_auth_crap_recv(struct composite_context *ctx);
462 NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
464 struct composite_context *ctx;
465 struct wbsrv_service *service =
466 s3call->wbconn->listen_socket->service;
467 DATA_BLOB chal, nt_resp, lm_resp;
469 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
471 chal.data = s3call->request.data.auth_crap.chal;
472 chal.length = sizeof(s3call->request.data.auth_crap.chal);
473 nt_resp.data = (uint8_t *)s3call->request.data.auth_crap.nt_resp;
474 nt_resp.length = s3call->request.data.auth_crap.nt_resp_len;
475 lm_resp.data = (uint8_t *)s3call->request.data.auth_crap.lm_resp;
476 lm_resp.length = s3call->request.data.auth_crap.lm_resp_len;
478 ctx = wb_cmd_pam_auth_crap_send(
480 s3call->request.data.auth_crap.logon_parameters,
481 s3call->request.data.auth_crap.domain,
482 s3call->request.data.auth_crap.user,
483 s3call->request.data.auth_crap.workstation,
484 chal, nt_resp, lm_resp);
485 NT_STATUS_HAVE_NO_MEMORY(ctx);
487 ctx->async.fn = pam_auth_crap_recv;
488 ctx->async.private_data = s3call;
489 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
493 static void pam_auth_crap_recv(struct composite_context *ctx)
495 struct wbsrv_samba3_call *s3call =
496 talloc_get_type(ctx->async.private_data,
497 struct wbsrv_samba3_call);
500 struct netr_UserSessionKey user_session_key;
501 struct netr_LMSessionKey lm_key;
504 status = wb_cmd_pam_auth_crap_recv(ctx, s3call, &info3,
505 &user_session_key, &lm_key, &unix_username);
506 if (!NT_STATUS_IS_OK(status)) goto done;
508 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
509 memcpy(s3call->response.data.auth.user_session_key,
510 &user_session_key.key,
511 sizeof(s3call->response.data.auth.user_session_key));
514 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
515 s3call->response.extra_data.data = info3.data;
516 s3call->response.length += info3.length;
519 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
520 memcpy(s3call->response.data.auth.first_8_lm_hash,
522 sizeof(s3call->response.data.auth.first_8_lm_hash));
525 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
526 s3call->response.extra_data.data = unix_username;
527 s3call->response.length += strlen(unix_username)+1;
531 wbsrv_samba3_async_auth_epilogue(status, s3call);
534 /* Plaintext authentication
536 This interface is used by ntlm_auth in it's 'basic' authentication
537 mode, as well as by pam_winbind to authenticate users where we are
538 given a plaintext password.
541 static void pam_auth_recv(struct composite_context *ctx);
543 NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
545 struct composite_context *ctx;
546 struct wbsrv_service *service =
547 s3call->wbconn->listen_socket->service;
550 if (!wb_samba3_split_username(s3call,
551 s3call->request.data.auth.user,
553 return NT_STATUS_NO_SUCH_USER;
556 ctx = wb_cmd_pam_auth_send(s3call, service, domain, user,
557 s3call->request.data.auth.pass);
558 NT_STATUS_HAVE_NO_MEMORY(ctx);
560 ctx->async.fn = pam_auth_recv;
561 ctx->async.private_data = s3call;
562 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
566 static void pam_auth_recv(struct composite_context *ctx)
568 struct wbsrv_samba3_call *s3call =
569 talloc_get_type(ctx->async.private_data,
570 struct wbsrv_samba3_call);
573 status = wb_cmd_pam_auth_recv(ctx);
575 if (!NT_STATUS_IS_OK(status)) goto done;
578 wbsrv_samba3_async_auth_epilogue(status, s3call);
585 static void list_trustdom_recv_doms(struct composite_context *ctx);
587 NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
589 struct composite_context *ctx;
590 struct wbsrv_service *service =
591 s3call->wbconn->listen_socket->service;
593 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
595 ctx = wb_cmd_list_trustdoms_send(s3call, service);
596 NT_STATUS_HAVE_NO_MEMORY(ctx);
598 ctx->async.fn = list_trustdom_recv_doms;
599 ctx->async.private_data = s3call;
600 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
604 static void list_trustdom_recv_doms(struct composite_context *ctx)
606 struct wbsrv_samba3_call *s3call =
607 talloc_get_type(ctx->async.private_data,
608 struct wbsrv_samba3_call);
610 struct wb_dom_info **domains;
614 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
616 if (!NT_STATUS_IS_OK(status)) goto done;
618 result = talloc_strdup(s3call, "");
619 if (result == NULL) {
620 status = NT_STATUS_NO_MEMORY;
624 for (i=0; i<num_domains; i++) {
625 result = talloc_asprintf_append(
626 result, "%s\\%s\\%s",
627 domains[i]->name, domains[i]->name,
628 dom_sid_string(s3call, domains[i]->sid));
631 if (result == NULL) {
632 status = NT_STATUS_NO_MEMORY;
636 s3call->response.result = WINBINDD_OK;
637 if (num_domains > 0) {
638 s3call->response.extra_data.data = result;
639 s3call->response.length += strlen(result)+1;
643 wbsrv_samba3_async_epilogue(status, s3call);
649 static void list_users_recv(struct composite_context *ctx);
651 NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
653 struct composite_context *ctx;
654 struct wbsrv_service *service =
655 s3call->wbconn->listen_socket->service;
657 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
659 ctx = wb_cmd_list_users_send(s3call, service,
660 s3call->request.domain_name);
661 NT_STATUS_HAVE_NO_MEMORY(ctx);
663 ctx->async.fn = list_users_recv;
664 ctx->async.private_data = s3call;
665 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
669 static void list_users_recv(struct composite_context *ctx)
671 struct wbsrv_samba3_call *s3call =
672 talloc_get_type(ctx->async.private_data,
673 struct wbsrv_samba3_call);
674 uint32_t extra_data_len;
678 DEBUG(5, ("list_users_recv called\n"));
680 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
683 if (NT_STATUS_IS_OK(status)) {
684 s3call->response.extra_data.data = extra_data;
685 s3call->response.length += extra_data_len;
688 wbsrv_samba3_async_epilogue(status, s3call);
693 static void getpwnam_recv(struct composite_context *ctx);
695 NTSTATUS wbsrv_samba3_getpwnam(struct wbsrv_samba3_call *s3call)
697 struct composite_context *ctx;
698 struct wbsrv_service *service =
699 s3call->wbconn->listen_socket->service;
701 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
703 ctx = wb_cmd_getpwnam_send(s3call, service,
704 s3call->request.data.username);
705 NT_STATUS_HAVE_NO_MEMORY(ctx);
707 ctx->async.fn = getpwnam_recv;
708 ctx->async.private_data = s3call;
709 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
713 static void getpwnam_recv(struct composite_context *ctx)
715 struct wbsrv_samba3_call *s3call =
716 talloc_get_type(ctx->async.private_data,
717 struct wbsrv_samba3_call);
719 struct winbindd_pw *pw;
721 DEBUG(5, ("getpwnam_recv called\n"));
723 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
724 if(NT_STATUS_IS_OK(status))
725 s3call->response.data.pw = *pw;
727 wbsrv_samba3_async_epilogue(status, s3call);
730 static void getpwuid_recv(struct composite_context *ctx);
732 NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
734 struct composite_context *ctx;
735 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
737 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
739 ctx = wb_cmd_getpwuid_send(s3call, service,
740 s3call->request.data.uid);
741 NT_STATUS_HAVE_NO_MEMORY(ctx);
743 ctx->async.fn = getpwuid_recv;
744 ctx->async.private_data = s3call;
745 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
749 static void getpwuid_recv(struct composite_context *ctx)
751 struct wbsrv_samba3_call *s3call =
752 talloc_get_type(ctx->async.private_data,
753 struct wbsrv_samba3_call);
755 struct winbindd_pw *pw;
757 DEBUG(5, ("getpwuid_recv called\n"));
759 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
760 if (NT_STATUS_IS_OK(status))
761 s3call->response.data.pw = *pw;
763 wbsrv_samba3_async_epilogue(status, s3call);
766 static void setpwent_recv(struct composite_context *ctx);
768 NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
770 struct composite_context *ctx;
771 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
773 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
775 ctx = wb_cmd_setpwent_send(s3call, service);
776 NT_STATUS_HAVE_NO_MEMORY(ctx);
778 ctx->async.fn = setpwent_recv;
779 ctx->async.private_data = s3call;
780 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
784 static void setpwent_recv(struct composite_context *ctx)
786 struct wbsrv_samba3_call *s3call =
787 talloc_get_type(ctx->async.private_data,
788 struct wbsrv_samba3_call);
790 struct wbsrv_pwent *pwent;
792 DEBUG(5, ("setpwent_recv called\n"));
794 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
795 if (NT_STATUS_IS_OK(status)) {
796 s3call->wbconn->protocol_private_data = pwent;
799 wbsrv_samba3_async_epilogue(status, s3call);
802 static void getpwent_recv(struct composite_context *ctx);
804 NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
806 struct composite_context *ctx;
807 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
808 struct wbsrv_pwent *pwent;
810 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
812 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
814 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
816 NT_STATUS_HAVE_NO_MEMORY(pwent);
818 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
819 s3call->request.data.num_entries);
820 NT_STATUS_HAVE_NO_MEMORY(ctx);
822 ctx->async.fn = getpwent_recv;
823 ctx->async.private_data = s3call;
824 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
828 static void getpwent_recv(struct composite_context *ctx)
830 struct wbsrv_samba3_call *s3call =
831 talloc_get_type(ctx->async.private_data,
832 struct wbsrv_samba3_call);
834 struct winbindd_pw *pw;
837 DEBUG(5, ("getpwent_recv called\n"));
839 status = wb_cmd_getpwent_recv(ctx, s3call, &pw, &num_users);
840 if (NT_STATUS_IS_OK(status)) {
841 uint32_t extra_len = sizeof(struct winbindd_pw) * num_users;
843 s3call->response.data.num_entries = num_users;
844 s3call->response.extra_data.data = pw;
845 s3call->response.length += extra_len;
848 wbsrv_samba3_async_epilogue(status, s3call);
851 NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
853 struct wbsrv_pwent *pwent =
854 talloc_get_type(s3call->wbconn->protocol_private_data,
856 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
860 s3call->wbconn->protocol_private_data = NULL;
861 s3call->response.result = WINBINDD_OK;
865 NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
867 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
868 s3call->response.result = WINBINDD_ERROR;
872 NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
874 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
875 s3call->response.result = WINBINDD_ERROR;
879 NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
881 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
882 s3call->response.result = WINBINDD_ERROR;
886 NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
888 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
889 s3call->response.result = WINBINDD_OK;
893 NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
895 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
896 s3call->response.result = WINBINDD_ERROR;
900 NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
902 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
903 s3call->response.result = WINBINDD_OK;
907 static void sid2uid_recv(struct composite_context *ctx);
909 NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
911 struct composite_context *ctx;
912 struct wbsrv_service *service =
913 s3call->wbconn->listen_socket->service;
916 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
918 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
919 NT_STATUS_HAVE_NO_MEMORY(sid);
921 ctx = wb_sid2uid_send(s3call, service, sid);
922 NT_STATUS_HAVE_NO_MEMORY(ctx);
924 ctx->async.fn = sid2uid_recv;
925 ctx->async.private_data = s3call;
926 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
931 static void sid2uid_recv(struct composite_context *ctx)
933 struct wbsrv_samba3_call *s3call =
934 talloc_get_type(ctx->async.private_data,
935 struct wbsrv_samba3_call);
938 DEBUG(5, ("sid2uid_recv called\n"));
940 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
942 wbsrv_samba3_async_epilogue(status, s3call);
945 static void sid2gid_recv(struct composite_context *ctx);
947 NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
949 struct composite_context *ctx;
950 struct wbsrv_service *service =
951 s3call->wbconn->listen_socket->service;
954 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
956 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
957 NT_STATUS_HAVE_NO_MEMORY(sid);
959 ctx = wb_sid2gid_send(s3call, service, sid);
960 NT_STATUS_HAVE_NO_MEMORY(ctx);
962 ctx->async.fn = sid2gid_recv;
963 ctx->async.private_data = s3call;
964 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
969 static void sid2gid_recv(struct composite_context *ctx)
971 struct wbsrv_samba3_call *s3call =
972 talloc_get_type(ctx->async.private_data,
973 struct wbsrv_samba3_call);
976 DEBUG(5, ("sid2gid_recv called\n"));
978 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
980 wbsrv_samba3_async_epilogue(status, s3call);
983 static void uid2sid_recv(struct composite_context *ctx);
985 NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
987 struct composite_context *ctx;
988 struct wbsrv_service *service =
989 s3call->wbconn->listen_socket->service;
991 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
993 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
994 NT_STATUS_HAVE_NO_MEMORY(ctx);
996 ctx->async.fn = uid2sid_recv;
997 ctx->async.private_data = s3call;
998 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1003 static void uid2sid_recv(struct composite_context *ctx)
1005 struct wbsrv_samba3_call *s3call =
1006 talloc_get_type(ctx->async.private_data,
1007 struct wbsrv_samba3_call);
1009 struct dom_sid *sid;
1012 DEBUG(5, ("uid2sid_recv called\n"));
1014 status = wb_uid2sid_recv(ctx, s3call, &sid);
1015 if(NT_STATUS_IS_OK(status)) {
1016 sid_str = dom_sid_string(s3call, sid);
1018 /* If the conversion failed, bail out with a failure. */
1019 if (sid_str == NULL)
1020 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1022 /* But we assume this worked, so we'll set the string. Work
1024 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1025 s3call->response.data.sid.type = SID_NAME_USER;
1028 wbsrv_samba3_async_epilogue(status, s3call);
1031 static void gid2sid_recv(struct composite_context *ctx);
1033 NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1035 struct composite_context *ctx;
1036 struct wbsrv_service *service =
1037 s3call->wbconn->listen_socket->service;
1039 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1041 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1042 NT_STATUS_HAVE_NO_MEMORY(ctx);
1044 ctx->async.fn = gid2sid_recv;
1045 ctx->async.private_data = s3call;
1046 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1047 return NT_STATUS_OK;
1051 static void gid2sid_recv(struct composite_context *ctx)
1053 struct wbsrv_samba3_call *s3call =
1054 talloc_get_type(ctx->async.private_data,
1055 struct wbsrv_samba3_call);
1057 struct dom_sid *sid;
1060 DEBUG(5, ("gid2sid_recv called\n"));
1062 status = wb_gid2sid_recv(ctx, s3call, &sid);
1063 if(NT_STATUS_IS_OK(status)) {
1064 sid_str = dom_sid_string(s3call, sid);
1066 if (sid_str == NULL)
1067 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1069 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1070 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1073 wbsrv_samba3_async_epilogue(status, s3call);