Fix very old bug in ASQ
[Samba/ekacnet.git] / source4 / winbind / wb_samba3_cmd.c
blob03b59f56e9b40f0e9cd456cb4542da517c9e5ba8
1 /*
2 Unix SMB/CIFS implementation.
3 Main winbindd samba3 server routines
5 Copyright (C) Stefan Metzmacher 2005
6 Copyright (C) Volker Lendecke 2005
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
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/>.
23 #include "includes.h"
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"
29 #include "version.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"
36 /*
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 } else {
47 resp->result = WINBINDD_OK;
50 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
51 nt_errstr(status));
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);
61 /*
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;
71 } else {
72 resp->result = WINBINDD_ERROR;
75 wbsrv_samba3_send_reply(s3call);
78 /*
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;
86 return NT_STATUS_OK;
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);
95 return NT_STATUS_OK;
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));
103 return NT_STATUS_OK;
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));
111 return NT_STATUS_OK;
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 = path;
120 s3call->response.length += strlen(path) + 1;
121 return NT_STATUS_OK;
124 NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
126 s3call->response.result = WINBINDD_OK;
127 return NT_STATUS_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)
141 NTSTATUS status;
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);
149 if (creds == NULL) {
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)) {
158 talloc_free(creds);
159 return status;
162 ctx = wb_cmd_pam_auth_send(s3call, service, creds);
164 if (!ctx) {
165 talloc_free(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;
172 return NT_STATUS_OK;
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);
180 NTSTATUS status;
182 status = wb_cmd_pam_auth_recv(ctx);
184 if (!NT_STATUS_IS_OK(status)) goto done;
186 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;
212 return NT_STATUS_OK;
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);
220 const char *dcname;
221 NTSTATUS status;
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);
229 done:
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;
242 struct dom_sid *sid;
244 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
246 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
247 if (sid == NULL) {
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;
260 return NT_STATUS_OK;
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);
268 int i, num_sids;
269 struct dom_sid **sids;
270 char *sids_string;
271 NTSTATUS status;
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;
279 goto done;
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;
289 goto done;
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;
297 done:
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;
309 struct dom_sid *sid;
311 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
313 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
314 if (sid == NULL) {
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;
327 return NT_STATUS_OK;
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);
335 int i, num_sids;
336 struct dom_sid **sids;
337 char *sids_string;
338 NTSTATUS status;
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;
346 goto done;
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;
354 goto done;
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') {
368 *sids_string = '\0';
370 sids_string += 1;
373 done:
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;
400 return NT_STATUS_OK;
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;
409 NTSTATUS status;
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));
419 done:
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;
434 struct dom_sid *sid;
436 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
438 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
439 if (sid == NULL) {
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;
452 return NT_STATUS_OK;
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;
461 NTSTATUS status;
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,
469 sid->domain);
470 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.name, sid->name);
472 done:
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(
505 s3call, service,
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;
516 return NT_STATUS_OK;
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);
524 NTSTATUS status;
525 DATA_BLOB info3;
526 struct netr_UserSessionKey user_session_key;
527 struct netr_LMSessionKey lm_key;
528 char *unix_username;
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,
547 lm_key.key,
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;
556 done:
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;
575 char *user, *domain;
577 if (!wb_samba3_split_username(s3call, s3call->wbconn->lp_ctx,
578 s3call->request.data.auth.user,
579 &domain, &user)) {
580 return NT_STATUS_NO_SUCH_USER;
583 credentials = cli_credentials_init(s3call);
584 if (!credentials) {
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;
599 return NT_STATUS_OK;
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);
607 NTSTATUS status;
609 status = wb_cmd_pam_auth_recv(ctx);
611 if (!NT_STATUS_IS_OK(status)) goto done;
613 done:
614 wbsrv_samba3_async_auth_epilogue(status, s3call);
618 List trusted domains
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;
637 return NT_STATUS_OK;
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);
645 int i, num_domains;
646 struct wb_dom_info **domains;
647 NTSTATUS status;
648 char *result;
650 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
651 &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;
657 goto done;
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;
669 goto done;
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;
678 done:
679 wbsrv_samba3_async_epilogue(status, s3call);
683 /* List users */
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;
702 return NT_STATUS_OK;
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;
711 char *extra_data;
712 NTSTATUS status;
714 DEBUG(5, ("list_users_recv called\n"));
716 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
717 &extra_data);
719 if (NT_STATUS_IS_OK(status)) {
720 s3call->response.extra_data.data = extra_data;
721 s3call->response.length += extra_data_len;
722 if (extra_data) {
723 s3call->response.length += 1;
727 wbsrv_samba3_async_epilogue(status, s3call);
730 /* NSS calls */
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;
749 return NT_STATUS_OK;
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);
757 NTSTATUS status;
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;
785 return NT_STATUS_OK;
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);
793 NTSTATUS status;
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;
820 return NT_STATUS_OK;
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);
828 NTSTATUS status;
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,
854 struct wbsrv_pwent);
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;
864 return NT_STATUS_OK;
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);
872 NTSTATUS status;
873 struct winbindd_pw *pw;
874 uint32_t num_users;
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,
894 struct wbsrv_pwent);
895 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
897 talloc_free(pwent);
899 s3call->wbconn->protocol_private_data = NULL;
900 s3call->response.result = WINBINDD_OK;
901 return NT_STATUS_OK;
904 NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
906 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
907 s3call->response.result = WINBINDD_ERROR;
908 return NT_STATUS_OK;
911 NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
913 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
914 s3call->response.result = WINBINDD_ERROR;
915 return NT_STATUS_OK;
918 NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
920 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
921 s3call->response.result = WINBINDD_ERROR;
922 return NT_STATUS_OK;
925 NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
927 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
928 s3call->response.result = WINBINDD_OK;
929 return NT_STATUS_OK;
932 NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
934 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
935 s3call->response.result = WINBINDD_ERROR;
936 return NT_STATUS_OK;
939 NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
941 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
942 s3call->response.result = WINBINDD_OK;
943 return NT_STATUS_OK;
946 static void sid2uid_recv(struct composite_context *ctx);
948 NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
950 struct composite_context *ctx;
951 struct wbsrv_service *service =
952 s3call->wbconn->listen_socket->service;
953 struct dom_sid *sid;
955 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
957 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
958 NT_STATUS_HAVE_NO_MEMORY(sid);
960 ctx = wb_sid2uid_send(s3call, service, sid);
961 NT_STATUS_HAVE_NO_MEMORY(ctx);
963 ctx->async.fn = sid2uid_recv;
964 ctx->async.private_data = s3call;
965 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
966 return NT_STATUS_OK;
970 static void sid2uid_recv(struct composite_context *ctx)
972 struct wbsrv_samba3_call *s3call =
973 talloc_get_type(ctx->async.private_data,
974 struct wbsrv_samba3_call);
975 NTSTATUS status;
977 DEBUG(5, ("sid2uid_recv called\n"));
979 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
981 wbsrv_samba3_async_epilogue(status, s3call);
984 static void sid2gid_recv(struct composite_context *ctx);
986 NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
988 struct composite_context *ctx;
989 struct wbsrv_service *service =
990 s3call->wbconn->listen_socket->service;
991 struct dom_sid *sid;
993 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
995 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
996 NT_STATUS_HAVE_NO_MEMORY(sid);
998 ctx = wb_sid2gid_send(s3call, service, sid);
999 NT_STATUS_HAVE_NO_MEMORY(ctx);
1001 ctx->async.fn = sid2gid_recv;
1002 ctx->async.private_data = s3call;
1003 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1004 return NT_STATUS_OK;
1008 static void sid2gid_recv(struct composite_context *ctx)
1010 struct wbsrv_samba3_call *s3call =
1011 talloc_get_type(ctx->async.private_data,
1012 struct wbsrv_samba3_call);
1013 NTSTATUS status;
1015 DEBUG(5, ("sid2gid_recv called\n"));
1017 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
1019 wbsrv_samba3_async_epilogue(status, s3call);
1022 static void uid2sid_recv(struct composite_context *ctx);
1024 NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
1026 struct composite_context *ctx;
1027 struct wbsrv_service *service =
1028 s3call->wbconn->listen_socket->service;
1030 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1032 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
1033 NT_STATUS_HAVE_NO_MEMORY(ctx);
1035 ctx->async.fn = uid2sid_recv;
1036 ctx->async.private_data = s3call;
1037 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1038 return NT_STATUS_OK;
1042 static void uid2sid_recv(struct composite_context *ctx)
1044 struct wbsrv_samba3_call *s3call =
1045 talloc_get_type(ctx->async.private_data,
1046 struct wbsrv_samba3_call);
1047 NTSTATUS status;
1048 struct dom_sid *sid;
1049 char *sid_str;
1051 DEBUG(5, ("uid2sid_recv called\n"));
1053 status = wb_uid2sid_recv(ctx, s3call, &sid);
1054 if(NT_STATUS_IS_OK(status)) {
1055 sid_str = dom_sid_string(s3call, sid);
1057 /* If the conversion failed, bail out with a failure. */
1058 if (sid_str == NULL)
1059 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1061 /* But we assume this worked, so we'll set the string. Work
1062 * done. */
1063 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1064 s3call->response.data.sid.type = SID_NAME_USER;
1067 wbsrv_samba3_async_epilogue(status, s3call);
1070 static void gid2sid_recv(struct composite_context *ctx);
1072 NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1074 struct composite_context *ctx;
1075 struct wbsrv_service *service =
1076 s3call->wbconn->listen_socket->service;
1078 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1080 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1081 NT_STATUS_HAVE_NO_MEMORY(ctx);
1083 ctx->async.fn = gid2sid_recv;
1084 ctx->async.private_data = s3call;
1085 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1086 return NT_STATUS_OK;
1090 static void gid2sid_recv(struct composite_context *ctx)
1092 struct wbsrv_samba3_call *s3call =
1093 talloc_get_type(ctx->async.private_data,
1094 struct wbsrv_samba3_call);
1095 NTSTATUS status;
1096 struct dom_sid *sid;
1097 char *sid_str;
1099 DEBUG(5, ("gid2sid_recv called\n"));
1101 status = wb_gid2sid_recv(ctx, s3call, &sid);
1102 if(NT_STATUS_IS_OK(status)) {
1103 sid_str = dom_sid_string(s3call, sid);
1105 if (sid_str == NULL)
1106 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1108 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1109 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1112 wbsrv_samba3_async_epilogue(status, s3call);