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 "winbind/wb_helper.h"
27 #include "libcli/composite/composite.h"
29 #include "librpc/gen_ndr/netlogon.h"
30 #include "libcli/security/security.h"
31 #include "auth/pam_errors.h"
32 #include "param/param.h"
35 Send off the reply to an async Samba3 query, handling filling in the PAM, NTSTATUS and string errors.
38 static void wbsrv_samba3_async_auth_epilogue(NTSTATUS status,
39 struct wbsrv_samba3_call *s3call)
41 struct winbindd_response *resp = &s3call->response;
42 if (!NT_STATUS_IS_OK(status)) {
43 resp->result = WINBINDD_ERROR;
44 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
46 WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
47 get_friendly_nt_error_msg(status));
49 resp->result = WINBINDD_OK;
52 resp->data.auth.pam_error = nt_status_to_pam(status);
53 resp->data.auth.nt_status = NT_STATUS_V(status);
55 wbsrv_samba3_send_reply(s3call);
59 Send of a generic reply to a Samba3 query
62 static void wbsrv_samba3_async_epilogue(NTSTATUS status,
63 struct wbsrv_samba3_call *s3call)
65 struct winbindd_response *resp = &s3call->response;
66 if (NT_STATUS_IS_OK(status)) {
67 resp->result = WINBINDD_OK;
69 resp->result = WINBINDD_ERROR;
72 wbsrv_samba3_send_reply(s3call);
76 Boilerplate commands, simple queries without network traffic
79 NTSTATUS wbsrv_samba3_interface_version(struct wbsrv_samba3_call *s3call)
81 s3call->response.result = WINBINDD_OK;
82 s3call->response.data.interface_version = WINBIND_INTERFACE_VERSION;
86 NTSTATUS wbsrv_samba3_info(struct wbsrv_samba3_call *s3call)
88 s3call->response.result = WINBINDD_OK;
89 s3call->response.data.info.winbind_separator = *lp_winbind_separator(global_loadparm);
90 WBSRV_SAMBA3_SET_STRING(s3call->response.data.info.samba_version,
91 SAMBA_VERSION_STRING);
95 NTSTATUS wbsrv_samba3_domain_name(struct wbsrv_samba3_call *s3call)
97 s3call->response.result = WINBINDD_OK;
98 WBSRV_SAMBA3_SET_STRING(s3call->response.data.domain_name,
99 lp_workgroup(global_loadparm));
103 NTSTATUS wbsrv_samba3_netbios_name(struct wbsrv_samba3_call *s3call)
105 s3call->response.result = WINBINDD_OK;
106 WBSRV_SAMBA3_SET_STRING(s3call->response.data.netbios_name,
107 lp_netbios_name(global_loadparm));
111 NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
113 s3call->response.result = WINBINDD_OK;
114 s3call->response.extra_data.data =
115 smbd_tmp_path(s3call, global_loadparm, WINBINDD_SAMBA3_PRIVILEGED_SOCKET);
116 NT_STATUS_HAVE_NO_MEMORY(s3call->response.extra_data.data);
120 NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
122 s3call->response.result = WINBINDD_OK;
128 Validate that we have a working pipe to the domain controller.
129 Return any NT error found in the process
132 static void checkmachacc_recv_creds(struct composite_context *ctx);
134 NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
136 struct composite_context *ctx;
138 DEBUG(5, ("wbsrv_samba3_check_machacc called\n"));
140 ctx = wb_cmd_checkmachacc_send(s3call->call);
141 NT_STATUS_HAVE_NO_MEMORY(ctx);
143 ctx->async.fn = checkmachacc_recv_creds;
144 ctx->async.private_data = s3call;
145 s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
149 static void checkmachacc_recv_creds(struct composite_context *ctx)
151 struct wbsrv_samba3_call *s3call =
152 talloc_get_type(ctx->async.private_data,
153 struct wbsrv_samba3_call);
156 status = wb_cmd_checkmachacc_recv(ctx);
158 wbsrv_samba3_async_auth_epilogue(status, s3call);
163 Find the name of a suitable domain controller, by query on the
164 netlogon pipe to the DC.
167 static void getdcname_recv_dc(struct composite_context *ctx);
169 NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
171 struct composite_context *ctx;
172 struct wbsrv_service *service =
173 s3call->wbconn->listen_socket->service;
175 DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
177 ctx = wb_cmd_getdcname_send(s3call, service,
178 s3call->request.domain_name);
179 NT_STATUS_HAVE_NO_MEMORY(ctx);
181 ctx->async.fn = getdcname_recv_dc;
182 ctx->async.private_data = s3call;
183 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
187 static void getdcname_recv_dc(struct composite_context *ctx)
189 struct wbsrv_samba3_call *s3call =
190 talloc_get_type(ctx->async.private_data,
191 struct wbsrv_samba3_call);
195 status = wb_cmd_getdcname_recv(ctx, s3call, &dcname);
196 if (!NT_STATUS_IS_OK(status)) goto done;
198 s3call->response.result = WINBINDD_OK;
199 WBSRV_SAMBA3_SET_STRING(s3call->response.data.dc_name, dcname);
202 wbsrv_samba3_async_epilogue(status, s3call);
206 Lookup a user's domain groups
209 static void userdomgroups_recv_groups(struct composite_context *ctx);
211 NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
213 struct composite_context *ctx;
216 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
218 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
220 DEBUG(5, ("Could not parse sid %s\n",
221 s3call->request.data.sid));
222 return NT_STATUS_NO_MEMORY;
225 ctx = wb_cmd_userdomgroups_send(
226 s3call, s3call->wbconn->listen_socket->service, sid);
227 NT_STATUS_HAVE_NO_MEMORY(ctx);
229 ctx->async.fn = userdomgroups_recv_groups;
230 ctx->async.private_data = s3call;
231 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
235 static void userdomgroups_recv_groups(struct composite_context *ctx)
237 struct wbsrv_samba3_call *s3call =
238 talloc_get_type(ctx->async.private_data,
239 struct wbsrv_samba3_call);
241 struct dom_sid **sids;
245 status = wb_cmd_userdomgroups_recv(ctx, s3call, &num_sids, &sids);
246 if (!NT_STATUS_IS_OK(status)) goto done;
248 sids_string = talloc_strdup(s3call, "");
249 if (sids_string == NULL) {
250 status = NT_STATUS_NO_MEMORY;
254 for (i=0; i<num_sids; i++) {
255 sids_string = talloc_asprintf_append_buffer(
256 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
259 if (sids_string == NULL) {
260 status = NT_STATUS_NO_MEMORY;
264 s3call->response.result = WINBINDD_OK;
265 s3call->response.extra_data.data = sids_string;
266 s3call->response.length += strlen(sids_string)+1;
267 s3call->response.data.num_entries = num_sids;
270 wbsrv_samba3_async_epilogue(status, s3call);
274 Lookup the list of SIDs for a user
276 static void usersids_recv_sids(struct composite_context *ctx);
278 NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call)
280 struct composite_context *ctx;
283 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
285 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
287 DEBUG(5, ("Could not parse sid %s\n",
288 s3call->request.data.sid));
289 return NT_STATUS_NO_MEMORY;
292 ctx = wb_cmd_usersids_send(
293 s3call, s3call->wbconn->listen_socket->service, sid);
294 NT_STATUS_HAVE_NO_MEMORY(ctx);
296 ctx->async.fn = usersids_recv_sids;
297 ctx->async.private_data = s3call;
298 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
302 static void usersids_recv_sids(struct composite_context *ctx)
304 struct wbsrv_samba3_call *s3call =
305 talloc_get_type(ctx->async.private_data,
306 struct wbsrv_samba3_call);
308 struct dom_sid **sids;
312 status = wb_cmd_usersids_recv(ctx, s3call, &num_sids, &sids);
313 if (!NT_STATUS_IS_OK(status)) goto done;
315 sids_string = talloc_strdup(s3call, "");
316 if (sids_string == NULL) {
317 status = NT_STATUS_NO_MEMORY;
321 for (i=0; i<num_sids; i++) {
322 sids_string = talloc_asprintf_append_buffer(
323 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
324 if (sids_string == NULL) {
325 status = NT_STATUS_NO_MEMORY;
330 s3call->response.result = WINBINDD_OK;
331 s3call->response.extra_data.data = sids_string;
332 s3call->response.length += strlen(sids_string);
333 s3call->response.data.num_entries = num_sids;
335 /* Hmmmm. Nasty protocol -- who invented the zeros between the
336 * SIDs? Hmmm. Could have been me -- vl */
338 while (*sids_string != '\0') {
339 if ((*sids_string) == '\n') {
346 wbsrv_samba3_async_epilogue(status, s3call);
350 Lookup a DOMAIN\\user style name, and return a SID
353 static void lookupname_recv_sid(struct composite_context *ctx);
355 NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
357 struct composite_context *ctx;
358 struct wbsrv_service *service =
359 s3call->wbconn->listen_socket->service;
361 DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
363 ctx = wb_cmd_lookupname_send(s3call, service,
364 s3call->request.data.name.dom_name,
365 s3call->request.data.name.name);
366 NT_STATUS_HAVE_NO_MEMORY(ctx);
368 /* setup the callbacks */
369 ctx->async.fn = lookupname_recv_sid;
370 ctx->async.private_data = s3call;
371 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
375 static void lookupname_recv_sid(struct composite_context *ctx)
377 struct wbsrv_samba3_call *s3call =
378 talloc_get_type(ctx->async.private_data,
379 struct wbsrv_samba3_call);
380 struct wb_sid_object *sid;
383 status = wb_cmd_lookupname_recv(ctx, s3call, &sid);
384 if (!NT_STATUS_IS_OK(status)) goto done;
386 s3call->response.result = WINBINDD_OK;
387 s3call->response.data.sid.type = sid->type;
388 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid,
389 dom_sid_string(s3call, sid->sid));
392 wbsrv_samba3_async_epilogue(status, s3call);
396 Lookup a SID, and return a DOMAIN\\user style name
399 static void lookupsid_recv_name(struct composite_context *ctx);
401 NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
403 struct composite_context *ctx;
404 struct wbsrv_service *service =
405 s3call->wbconn->listen_socket->service;
408 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
410 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
412 DEBUG(5, ("Could not parse sid %s\n",
413 s3call->request.data.sid));
414 return NT_STATUS_NO_MEMORY;
417 ctx = wb_cmd_lookupsid_send(s3call, service, sid);
418 NT_STATUS_HAVE_NO_MEMORY(ctx);
420 /* setup the callbacks */
421 ctx->async.fn = lookupsid_recv_name;
422 ctx->async.private_data = s3call;
423 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
427 static void lookupsid_recv_name(struct composite_context *ctx)
429 struct wbsrv_samba3_call *s3call =
430 talloc_get_type(ctx->async.private_data,
431 struct wbsrv_samba3_call);
432 struct wb_sid_object *sid;
435 status = wb_cmd_lookupsid_recv(ctx, s3call, &sid);
436 if (!NT_STATUS_IS_OK(status)) goto done;
438 s3call->response.result = WINBINDD_OK;
439 s3call->response.data.name.type = sid->type;
440 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.dom_name,
442 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.name, sid->name);
445 wbsrv_samba3_async_epilogue(status, s3call);
449 Challenge-response authentication. This interface is used by
450 ntlm_auth and the smbd auth subsystem to pass NTLM authentication
451 requests along a common pipe to the domain controller.
453 The return value (in the async reply) may include the 'info3'
454 (effectivly most things you would want to know about the user), or
455 the NT and LM session keys seperated.
458 static void pam_auth_crap_recv(struct composite_context *ctx);
460 NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
462 struct composite_context *ctx;
463 struct wbsrv_service *service =
464 s3call->wbconn->listen_socket->service;
465 DATA_BLOB chal, nt_resp, lm_resp;
467 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
469 chal.data = s3call->request.data.auth_crap.chal;
470 chal.length = sizeof(s3call->request.data.auth_crap.chal);
471 nt_resp.data = (uint8_t *)s3call->request.data.auth_crap.nt_resp;
472 nt_resp.length = s3call->request.data.auth_crap.nt_resp_len;
473 lm_resp.data = (uint8_t *)s3call->request.data.auth_crap.lm_resp;
474 lm_resp.length = s3call->request.data.auth_crap.lm_resp_len;
476 ctx = wb_cmd_pam_auth_crap_send(
478 s3call->request.data.auth_crap.logon_parameters,
479 s3call->request.data.auth_crap.domain,
480 s3call->request.data.auth_crap.user,
481 s3call->request.data.auth_crap.workstation,
482 chal, nt_resp, lm_resp);
483 NT_STATUS_HAVE_NO_MEMORY(ctx);
485 ctx->async.fn = pam_auth_crap_recv;
486 ctx->async.private_data = s3call;
487 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
491 static void pam_auth_crap_recv(struct composite_context *ctx)
493 struct wbsrv_samba3_call *s3call =
494 talloc_get_type(ctx->async.private_data,
495 struct wbsrv_samba3_call);
498 struct netr_UserSessionKey user_session_key;
499 struct netr_LMSessionKey lm_key;
502 status = wb_cmd_pam_auth_crap_recv(ctx, s3call, &info3,
503 &user_session_key, &lm_key, &unix_username);
504 if (!NT_STATUS_IS_OK(status)) goto done;
506 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
507 memcpy(s3call->response.data.auth.user_session_key,
508 &user_session_key.key,
509 sizeof(s3call->response.data.auth.user_session_key));
512 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
513 s3call->response.extra_data.data = info3.data;
514 s3call->response.length += info3.length;
517 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
518 memcpy(s3call->response.data.auth.first_8_lm_hash,
520 sizeof(s3call->response.data.auth.first_8_lm_hash));
523 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
524 s3call->response.extra_data.data = unix_username;
525 s3call->response.length += strlen(unix_username)+1;
529 wbsrv_samba3_async_auth_epilogue(status, s3call);
532 /* Plaintext authentication
534 This interface is used by ntlm_auth in it's 'basic' authentication
535 mode, as well as by pam_winbind to authenticate users where we are
536 given a plaintext password.
539 static void pam_auth_recv(struct composite_context *ctx);
541 NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
543 struct composite_context *ctx;
544 struct wbsrv_service *service =
545 s3call->wbconn->listen_socket->service;
548 if (!wb_samba3_split_username(s3call,
549 s3call->request.data.auth.user,
551 return NT_STATUS_NO_SUCH_USER;
554 ctx = wb_cmd_pam_auth_send(s3call, service, domain, user,
555 s3call->request.data.auth.pass);
556 NT_STATUS_HAVE_NO_MEMORY(ctx);
558 ctx->async.fn = pam_auth_recv;
559 ctx->async.private_data = s3call;
560 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
564 static void pam_auth_recv(struct composite_context *ctx)
566 struct wbsrv_samba3_call *s3call =
567 talloc_get_type(ctx->async.private_data,
568 struct wbsrv_samba3_call);
571 status = wb_cmd_pam_auth_recv(ctx);
573 if (!NT_STATUS_IS_OK(status)) goto done;
576 wbsrv_samba3_async_auth_epilogue(status, s3call);
583 static void list_trustdom_recv_doms(struct composite_context *ctx);
585 NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
587 struct composite_context *ctx;
588 struct wbsrv_service *service =
589 s3call->wbconn->listen_socket->service;
591 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
593 ctx = wb_cmd_list_trustdoms_send(s3call, service);
594 NT_STATUS_HAVE_NO_MEMORY(ctx);
596 ctx->async.fn = list_trustdom_recv_doms;
597 ctx->async.private_data = s3call;
598 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
602 static void list_trustdom_recv_doms(struct composite_context *ctx)
604 struct wbsrv_samba3_call *s3call =
605 talloc_get_type(ctx->async.private_data,
606 struct wbsrv_samba3_call);
608 struct wb_dom_info **domains;
612 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
614 if (!NT_STATUS_IS_OK(status)) goto done;
616 result = talloc_strdup(s3call, "");
617 if (result == NULL) {
618 status = NT_STATUS_NO_MEMORY;
622 for (i=0; i<num_domains; i++) {
623 result = talloc_asprintf_append_buffer(
624 result, "%s\\%s\\%s",
625 domains[i]->name, domains[i]->name,
626 dom_sid_string(s3call, domains[i]->sid));
629 if (result == NULL) {
630 status = NT_STATUS_NO_MEMORY;
634 s3call->response.result = WINBINDD_OK;
635 if (num_domains > 0) {
636 s3call->response.extra_data.data = result;
637 s3call->response.length += strlen(result)+1;
641 wbsrv_samba3_async_epilogue(status, s3call);
647 static void list_users_recv(struct composite_context *ctx);
649 NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
651 struct composite_context *ctx;
652 struct wbsrv_service *service =
653 s3call->wbconn->listen_socket->service;
655 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
657 ctx = wb_cmd_list_users_send(s3call, service,
658 s3call->request.domain_name);
659 NT_STATUS_HAVE_NO_MEMORY(ctx);
661 ctx->async.fn = list_users_recv;
662 ctx->async.private_data = s3call;
663 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
667 static void list_users_recv(struct composite_context *ctx)
669 struct wbsrv_samba3_call *s3call =
670 talloc_get_type(ctx->async.private_data,
671 struct wbsrv_samba3_call);
672 uint32_t extra_data_len;
676 DEBUG(5, ("list_users_recv called\n"));
678 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
681 if (NT_STATUS_IS_OK(status)) {
682 s3call->response.extra_data.data = extra_data;
683 s3call->response.length += extra_data_len;
686 wbsrv_samba3_async_epilogue(status, s3call);
691 static void getpwnam_recv(struct composite_context *ctx);
693 NTSTATUS wbsrv_samba3_getpwnam(struct wbsrv_samba3_call *s3call)
695 struct composite_context *ctx;
696 struct wbsrv_service *service =
697 s3call->wbconn->listen_socket->service;
699 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
701 ctx = wb_cmd_getpwnam_send(s3call, service,
702 s3call->request.data.username);
703 NT_STATUS_HAVE_NO_MEMORY(ctx);
705 ctx->async.fn = getpwnam_recv;
706 ctx->async.private_data = s3call;
707 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
711 static void getpwnam_recv(struct composite_context *ctx)
713 struct wbsrv_samba3_call *s3call =
714 talloc_get_type(ctx->async.private_data,
715 struct wbsrv_samba3_call);
717 struct winbindd_pw *pw;
719 DEBUG(5, ("getpwnam_recv called\n"));
721 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
722 if(NT_STATUS_IS_OK(status))
723 s3call->response.data.pw = *pw;
725 wbsrv_samba3_async_epilogue(status, s3call);
728 static void getpwuid_recv(struct composite_context *ctx);
730 NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
732 struct composite_context *ctx;
733 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
735 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
737 ctx = wb_cmd_getpwuid_send(s3call, service,
738 s3call->request.data.uid);
739 NT_STATUS_HAVE_NO_MEMORY(ctx);
741 ctx->async.fn = getpwuid_recv;
742 ctx->async.private_data = s3call;
743 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
747 static void getpwuid_recv(struct composite_context *ctx)
749 struct wbsrv_samba3_call *s3call =
750 talloc_get_type(ctx->async.private_data,
751 struct wbsrv_samba3_call);
753 struct winbindd_pw *pw;
755 DEBUG(5, ("getpwuid_recv called\n"));
757 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
758 if (NT_STATUS_IS_OK(status))
759 s3call->response.data.pw = *pw;
761 wbsrv_samba3_async_epilogue(status, s3call);
764 static void setpwent_recv(struct composite_context *ctx);
766 NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
768 struct composite_context *ctx;
769 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
771 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
773 ctx = wb_cmd_setpwent_send(s3call, service);
774 NT_STATUS_HAVE_NO_MEMORY(ctx);
776 ctx->async.fn = setpwent_recv;
777 ctx->async.private_data = s3call;
778 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
782 static void setpwent_recv(struct composite_context *ctx)
784 struct wbsrv_samba3_call *s3call =
785 talloc_get_type(ctx->async.private_data,
786 struct wbsrv_samba3_call);
788 struct wbsrv_pwent *pwent;
790 DEBUG(5, ("setpwent_recv called\n"));
792 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
793 if (NT_STATUS_IS_OK(status)) {
794 s3call->wbconn->protocol_private_data = pwent;
797 wbsrv_samba3_async_epilogue(status, s3call);
800 static void getpwent_recv(struct composite_context *ctx);
802 NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
804 struct composite_context *ctx;
805 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
806 struct wbsrv_pwent *pwent;
808 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
810 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
812 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
814 NT_STATUS_HAVE_NO_MEMORY(pwent);
816 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
817 s3call->request.data.num_entries);
818 NT_STATUS_HAVE_NO_MEMORY(ctx);
820 ctx->async.fn = getpwent_recv;
821 ctx->async.private_data = s3call;
822 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
826 static void getpwent_recv(struct composite_context *ctx)
828 struct wbsrv_samba3_call *s3call =
829 talloc_get_type(ctx->async.private_data,
830 struct wbsrv_samba3_call);
832 struct winbindd_pw *pw;
835 DEBUG(5, ("getpwent_recv called\n"));
837 status = wb_cmd_getpwent_recv(ctx, s3call, &pw, &num_users);
838 if (NT_STATUS_IS_OK(status)) {
839 uint32_t extra_len = sizeof(struct winbindd_pw) * num_users;
841 s3call->response.data.num_entries = num_users;
842 s3call->response.extra_data.data = pw;
843 s3call->response.length += extra_len;
846 wbsrv_samba3_async_epilogue(status, s3call);
849 NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
851 struct wbsrv_pwent *pwent =
852 talloc_get_type(s3call->wbconn->protocol_private_data,
854 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
858 s3call->wbconn->protocol_private_data = NULL;
859 s3call->response.result = WINBINDD_OK;
863 NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
865 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
866 s3call->response.result = WINBINDD_ERROR;
870 NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
872 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
873 s3call->response.result = WINBINDD_ERROR;
877 NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
879 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
880 s3call->response.result = WINBINDD_ERROR;
884 NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
886 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
887 s3call->response.result = WINBINDD_OK;
891 NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
893 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
894 s3call->response.result = WINBINDD_ERROR;
898 NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
900 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
901 s3call->response.result = WINBINDD_OK;
905 static void sid2uid_recv(struct composite_context *ctx);
907 NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
909 struct composite_context *ctx;
910 struct wbsrv_service *service =
911 s3call->wbconn->listen_socket->service;
914 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
916 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
917 NT_STATUS_HAVE_NO_MEMORY(sid);
919 ctx = wb_sid2uid_send(s3call, service, sid);
920 NT_STATUS_HAVE_NO_MEMORY(ctx);
922 ctx->async.fn = sid2uid_recv;
923 ctx->async.private_data = s3call;
924 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
929 static void sid2uid_recv(struct composite_context *ctx)
931 struct wbsrv_samba3_call *s3call =
932 talloc_get_type(ctx->async.private_data,
933 struct wbsrv_samba3_call);
936 DEBUG(5, ("sid2uid_recv called\n"));
938 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
940 wbsrv_samba3_async_epilogue(status, s3call);
943 static void sid2gid_recv(struct composite_context *ctx);
945 NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
947 struct composite_context *ctx;
948 struct wbsrv_service *service =
949 s3call->wbconn->listen_socket->service;
952 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
954 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
955 NT_STATUS_HAVE_NO_MEMORY(sid);
957 ctx = wb_sid2gid_send(s3call, service, sid);
958 NT_STATUS_HAVE_NO_MEMORY(ctx);
960 ctx->async.fn = sid2gid_recv;
961 ctx->async.private_data = s3call;
962 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
967 static void sid2gid_recv(struct composite_context *ctx)
969 struct wbsrv_samba3_call *s3call =
970 talloc_get_type(ctx->async.private_data,
971 struct wbsrv_samba3_call);
974 DEBUG(5, ("sid2gid_recv called\n"));
976 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
978 wbsrv_samba3_async_epilogue(status, s3call);
981 static void uid2sid_recv(struct composite_context *ctx);
983 NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
985 struct composite_context *ctx;
986 struct wbsrv_service *service =
987 s3call->wbconn->listen_socket->service;
989 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
991 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
992 NT_STATUS_HAVE_NO_MEMORY(ctx);
994 ctx->async.fn = uid2sid_recv;
995 ctx->async.private_data = s3call;
996 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1001 static void uid2sid_recv(struct composite_context *ctx)
1003 struct wbsrv_samba3_call *s3call =
1004 talloc_get_type(ctx->async.private_data,
1005 struct wbsrv_samba3_call);
1007 struct dom_sid *sid;
1010 DEBUG(5, ("uid2sid_recv called\n"));
1012 status = wb_uid2sid_recv(ctx, s3call, &sid);
1013 if(NT_STATUS_IS_OK(status)) {
1014 sid_str = dom_sid_string(s3call, sid);
1016 /* If the conversion failed, bail out with a failure. */
1017 if (sid_str == NULL)
1018 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1020 /* But we assume this worked, so we'll set the string. Work
1022 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1023 s3call->response.data.sid.type = SID_NAME_USER;
1026 wbsrv_samba3_async_epilogue(status, s3call);
1029 static void gid2sid_recv(struct composite_context *ctx);
1031 NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1033 struct composite_context *ctx;
1034 struct wbsrv_service *service =
1035 s3call->wbconn->listen_socket->service;
1037 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1039 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1040 NT_STATUS_HAVE_NO_MEMORY(ctx);
1042 ctx->async.fn = gid2sid_recv;
1043 ctx->async.private_data = s3call;
1044 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1045 return NT_STATUS_OK;
1049 static void gid2sid_recv(struct composite_context *ctx)
1051 struct wbsrv_samba3_call *s3call =
1052 talloc_get_type(ctx->async.private_data,
1053 struct wbsrv_samba3_call);
1055 struct dom_sid *sid;
1058 DEBUG(5, ("gid2sid_recv called\n"));
1060 status = wb_gid2sid_recv(ctx, s3call, &sid);
1061 if(NT_STATUS_IS_OK(status)) {
1062 sid_str = dom_sid_string(s3call, sid);
1064 if (sid_str == NULL)
1065 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1067 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1068 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1071 wbsrv_samba3_async_epilogue(status, s3call);