s4 winbind: Implement a stubbed out version of WINBINDD_DOMAIN_INFO
[Samba/gebeck_regimport.git] / source4 / winbind / wb_samba3_cmd.c
blob7f5a69ca6bbc8ad7474f12bf5a2c0269cd37058f
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
8 Copyright (C) Kai Blin 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "winbind/wb_server.h"
26 #include "winbind/wb_async_helpers.h"
27 #include "param/param.h"
28 #include "winbind/wb_helper.h"
29 #include "libcli/composite/composite.h"
30 #include "version.h"
31 #include "librpc/gen_ndr/netlogon.h"
32 #include "libcli/security/security.h"
33 #include "auth/ntlm/pam_errors.h"
34 #include "auth/credentials/credentials.h"
35 #include "smbd/service_task.h"
37 /*
38 Send off the reply to an async Samba3 query, handling filling in the PAM, NTSTATUS and string errors.
41 static void wbsrv_samba3_async_auth_epilogue(NTSTATUS status,
42 struct wbsrv_samba3_call *s3call)
44 struct winbindd_response *resp = &s3call->response;
45 if (!NT_STATUS_IS_OK(status)) {
46 resp->result = WINBINDD_ERROR;
47 } else {
48 resp->result = WINBINDD_OK;
51 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
52 nt_errstr(status));
53 WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
54 get_friendly_nt_error_msg(status));
56 resp->data.auth.pam_error = nt_status_to_pam(status);
57 resp->data.auth.nt_status = NT_STATUS_V(status);
59 wbsrv_samba3_send_reply(s3call);
62 /*
63 Send of a generic reply to a Samba3 query
66 static void wbsrv_samba3_async_epilogue(NTSTATUS status,
67 struct wbsrv_samba3_call *s3call)
69 struct winbindd_response *resp = &s3call->response;
70 if (NT_STATUS_IS_OK(status)) {
71 resp->result = WINBINDD_OK;
72 } else {
73 resp->result = WINBINDD_ERROR;
76 wbsrv_samba3_send_reply(s3call);
79 /*
80 Boilerplate commands, simple queries without network traffic
83 NTSTATUS wbsrv_samba3_interface_version(struct wbsrv_samba3_call *s3call)
85 s3call->response.result = WINBINDD_OK;
86 s3call->response.data.interface_version = WINBIND_INTERFACE_VERSION;
87 return NT_STATUS_OK;
90 NTSTATUS wbsrv_samba3_info(struct wbsrv_samba3_call *s3call)
92 s3call->response.result = WINBINDD_OK;
93 s3call->response.data.info.winbind_separator = *lp_winbind_separator(s3call->wbconn->lp_ctx);
94 WBSRV_SAMBA3_SET_STRING(s3call->response.data.info.samba_version,
95 SAMBA_VERSION_STRING);
96 return NT_STATUS_OK;
99 NTSTATUS wbsrv_samba3_domain_name(struct wbsrv_samba3_call *s3call)
101 s3call->response.result = WINBINDD_OK;
102 WBSRV_SAMBA3_SET_STRING(s3call->response.data.domain_name,
103 lp_workgroup(s3call->wbconn->lp_ctx));
104 return NT_STATUS_OK;
107 NTSTATUS wbsrv_samba3_netbios_name(struct wbsrv_samba3_call *s3call)
109 s3call->response.result = WINBINDD_OK;
110 WBSRV_SAMBA3_SET_STRING(s3call->response.data.netbios_name,
111 lp_netbios_name(s3call->wbconn->lp_ctx));
112 return NT_STATUS_OK;
115 NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
117 const char *path = s3call->wbconn->listen_socket->service->priv_socket_path;
118 s3call->response.result = WINBINDD_OK;
119 s3call->response.extra_data.data = discard_const(path);
121 s3call->response.length += strlen(path) + 1;
122 return NT_STATUS_OK;
125 NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
127 s3call->response.result = WINBINDD_OK;
128 return NT_STATUS_OK;
131 NTSTATUS wbsrv_samba3_domain_info(struct wbsrv_samba3_call *s3call)
133 DEBUG(0, ("wbsrv_samba3_domain_info called, stub\n"));
134 s3call->response.result = WINBINDD_OK;
135 fstrcpy(s3call->response.data.domain_info.name,
136 s3call->request.domain_name);
137 fstrcpy(s3call->response.data.domain_info.alt_name,
138 s3call->request.domain_name);
139 fstrcpy(s3call->response.data.domain_info.sid, "S-1-2-3-4");
140 s3call->response.data.domain_info.native_mode = false;
141 s3call->response.data.domain_info.active_directory = false;
142 s3call->response.data.domain_info.primary = false;
144 return NT_STATUS_OK;
147 /* Plaintext authentication
149 This interface is used by ntlm_auth in it's 'basic' authentication
150 mode, as well as by pam_winbind to authenticate users where we are
151 given a plaintext password.
154 static void check_machacc_recv(struct composite_context *ctx);
156 NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
158 NTSTATUS status;
159 struct cli_credentials *creds;
160 struct composite_context *ctx;
161 struct wbsrv_service *service =
162 s3call->wbconn->listen_socket->service;
164 /* Create a credentials structure */
165 creds = cli_credentials_init(s3call);
166 if (creds == NULL) {
167 return NT_STATUS_NO_MEMORY;
170 cli_credentials_set_conf(creds, service->task->lp_ctx);
172 /* Connect the machine account to the credentials */
173 status = cli_credentials_set_machine_account(creds, service->task->lp_ctx);
174 if (!NT_STATUS_IS_OK(status)) {
175 talloc_free(creds);
176 return status;
179 ctx = wb_cmd_pam_auth_send(s3call, service, creds);
181 if (!ctx) {
182 talloc_free(creds);
183 return NT_STATUS_NO_MEMORY;
186 ctx->async.fn = check_machacc_recv;
187 ctx->async.private_data = s3call;
188 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
189 return NT_STATUS_OK;
192 static void check_machacc_recv(struct composite_context *ctx)
194 struct wbsrv_samba3_call *s3call =
195 talloc_get_type(ctx->async.private_data,
196 struct wbsrv_samba3_call);
197 NTSTATUS status;
199 status = wb_cmd_pam_auth_recv(ctx);
201 if (!NT_STATUS_IS_OK(status)) goto done;
203 done:
204 wbsrv_samba3_async_auth_epilogue(status, s3call);
208 Find the name of a suitable domain controller, by query on the
209 netlogon pipe to the DC.
212 static void getdcname_recv_dc(struct composite_context *ctx);
214 NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
216 struct composite_context *ctx;
217 struct wbsrv_service *service =
218 s3call->wbconn->listen_socket->service;
220 DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
222 ctx = wb_cmd_getdcname_send(s3call, service,
223 s3call->request.domain_name);
224 NT_STATUS_HAVE_NO_MEMORY(ctx);
226 ctx->async.fn = getdcname_recv_dc;
227 ctx->async.private_data = s3call;
228 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
229 return NT_STATUS_OK;
232 static void getdcname_recv_dc(struct composite_context *ctx)
234 struct wbsrv_samba3_call *s3call =
235 talloc_get_type(ctx->async.private_data,
236 struct wbsrv_samba3_call);
237 const char *dcname;
238 NTSTATUS status;
240 status = wb_cmd_getdcname_recv(ctx, s3call, &dcname);
241 if (!NT_STATUS_IS_OK(status)) goto done;
243 s3call->response.result = WINBINDD_OK;
244 WBSRV_SAMBA3_SET_STRING(s3call->response.data.dc_name, dcname);
246 done:
247 wbsrv_samba3_async_epilogue(status, s3call);
251 Lookup a user's domain groups
254 static void userdomgroups_recv_groups(struct composite_context *ctx);
256 NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
258 struct composite_context *ctx;
259 struct dom_sid *sid;
261 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
263 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
264 if (sid == NULL) {
265 DEBUG(5, ("Could not parse sid %s\n",
266 s3call->request.data.sid));
267 return NT_STATUS_NO_MEMORY;
270 ctx = wb_cmd_userdomgroups_send(
271 s3call, s3call->wbconn->listen_socket->service, sid);
272 NT_STATUS_HAVE_NO_MEMORY(ctx);
274 ctx->async.fn = userdomgroups_recv_groups;
275 ctx->async.private_data = s3call;
276 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
277 return NT_STATUS_OK;
280 static void userdomgroups_recv_groups(struct composite_context *ctx)
282 struct wbsrv_samba3_call *s3call =
283 talloc_get_type(ctx->async.private_data,
284 struct wbsrv_samba3_call);
285 int i, num_sids;
286 struct dom_sid **sids;
287 char *sids_string;
288 NTSTATUS status;
290 status = wb_cmd_userdomgroups_recv(ctx, s3call, &num_sids, &sids);
291 if (!NT_STATUS_IS_OK(status)) goto done;
293 sids_string = talloc_strdup(s3call, "");
294 if (sids_string == NULL) {
295 status = NT_STATUS_NO_MEMORY;
296 goto done;
299 for (i=0; i<num_sids; i++) {
300 sids_string = talloc_asprintf_append_buffer(
301 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
304 if (sids_string == NULL) {
305 status = NT_STATUS_NO_MEMORY;
306 goto done;
309 s3call->response.result = WINBINDD_OK;
310 s3call->response.extra_data.data = sids_string;
311 s3call->response.length += strlen(sids_string)+1;
312 s3call->response.data.num_entries = num_sids;
314 done:
315 wbsrv_samba3_async_epilogue(status, s3call);
319 Lookup the list of SIDs for a user
321 static void usersids_recv_sids(struct composite_context *ctx);
323 NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call)
325 struct composite_context *ctx;
326 struct dom_sid *sid;
328 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
330 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
331 if (sid == NULL) {
332 DEBUG(5, ("Could not parse sid %s\n",
333 s3call->request.data.sid));
334 return NT_STATUS_NO_MEMORY;
337 ctx = wb_cmd_usersids_send(
338 s3call, s3call->wbconn->listen_socket->service, sid);
339 NT_STATUS_HAVE_NO_MEMORY(ctx);
341 ctx->async.fn = usersids_recv_sids;
342 ctx->async.private_data = s3call;
343 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
344 return NT_STATUS_OK;
347 static void usersids_recv_sids(struct composite_context *ctx)
349 struct wbsrv_samba3_call *s3call =
350 talloc_get_type(ctx->async.private_data,
351 struct wbsrv_samba3_call);
352 int i, num_sids;
353 struct dom_sid **sids;
354 char *sids_string;
355 NTSTATUS status;
357 status = wb_cmd_usersids_recv(ctx, s3call, &num_sids, &sids);
358 if (!NT_STATUS_IS_OK(status)) goto done;
360 sids_string = talloc_strdup(s3call, "");
361 if (sids_string == NULL) {
362 status = NT_STATUS_NO_MEMORY;
363 goto done;
366 for (i=0; i<num_sids; i++) {
367 sids_string = talloc_asprintf_append_buffer(
368 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
369 if (sids_string == NULL) {
370 status = NT_STATUS_NO_MEMORY;
371 goto done;
375 s3call->response.result = WINBINDD_OK;
376 s3call->response.extra_data.data = sids_string;
377 s3call->response.length += strlen(sids_string);
378 s3call->response.data.num_entries = num_sids;
380 /* Hmmmm. Nasty protocol -- who invented the zeros between the
381 * SIDs? Hmmm. Could have been me -- vl */
383 while (*sids_string != '\0') {
384 if ((*sids_string) == '\n') {
385 *sids_string = '\0';
387 sids_string += 1;
390 done:
391 wbsrv_samba3_async_epilogue(status, s3call);
395 Lookup a DOMAIN\\user style name, and return a SID
398 static void lookupname_recv_sid(struct composite_context *ctx);
400 NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
402 struct composite_context *ctx;
403 struct wbsrv_service *service =
404 s3call->wbconn->listen_socket->service;
406 DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
408 ctx = wb_cmd_lookupname_send(s3call, service,
409 s3call->request.data.name.dom_name,
410 s3call->request.data.name.name);
411 NT_STATUS_HAVE_NO_MEMORY(ctx);
413 /* setup the callbacks */
414 ctx->async.fn = lookupname_recv_sid;
415 ctx->async.private_data = s3call;
416 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
417 return NT_STATUS_OK;
420 static void lookupname_recv_sid(struct composite_context *ctx)
422 struct wbsrv_samba3_call *s3call =
423 talloc_get_type(ctx->async.private_data,
424 struct wbsrv_samba3_call);
425 struct wb_sid_object *sid;
426 NTSTATUS status;
428 status = wb_cmd_lookupname_recv(ctx, s3call, &sid);
429 if (!NT_STATUS_IS_OK(status)) goto done;
431 s3call->response.result = WINBINDD_OK;
432 s3call->response.data.sid.type = sid->type;
433 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid,
434 dom_sid_string(s3call, sid->sid));
436 done:
437 wbsrv_samba3_async_epilogue(status, s3call);
441 Lookup a SID, and return a DOMAIN\\user style name
444 static void lookupsid_recv_name(struct composite_context *ctx);
446 NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
448 struct composite_context *ctx;
449 struct wbsrv_service *service =
450 s3call->wbconn->listen_socket->service;
451 struct dom_sid *sid;
453 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
455 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
456 if (sid == NULL) {
457 DEBUG(5, ("Could not parse sid %s\n",
458 s3call->request.data.sid));
459 return NT_STATUS_NO_MEMORY;
462 ctx = wb_cmd_lookupsid_send(s3call, service, sid);
463 NT_STATUS_HAVE_NO_MEMORY(ctx);
465 /* setup the callbacks */
466 ctx->async.fn = lookupsid_recv_name;
467 ctx->async.private_data = s3call;
468 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
469 return NT_STATUS_OK;
472 static void lookupsid_recv_name(struct composite_context *ctx)
474 struct wbsrv_samba3_call *s3call =
475 talloc_get_type(ctx->async.private_data,
476 struct wbsrv_samba3_call);
477 struct wb_sid_object *sid;
478 NTSTATUS status;
480 status = wb_cmd_lookupsid_recv(ctx, s3call, &sid);
481 if (!NT_STATUS_IS_OK(status)) goto done;
483 s3call->response.result = WINBINDD_OK;
484 s3call->response.data.name.type = sid->type;
485 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.dom_name,
486 sid->domain);
487 WBSRV_SAMBA3_SET_STRING(s3call->response.data.name.name, sid->name);
489 done:
490 wbsrv_samba3_async_epilogue(status, s3call);
494 Challenge-response authentication. This interface is used by
495 ntlm_auth and the smbd auth subsystem to pass NTLM authentication
496 requests along a common pipe to the domain controller.
498 The return value (in the async reply) may include the 'info3'
499 (effectivly most things you would want to know about the user), or
500 the NT and LM session keys seperated.
503 static void pam_auth_crap_recv(struct composite_context *ctx);
505 NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
507 struct composite_context *ctx;
508 struct wbsrv_service *service =
509 s3call->wbconn->listen_socket->service;
510 DATA_BLOB chal, nt_resp, lm_resp;
512 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
514 chal.data = s3call->request.data.auth_crap.chal;
515 chal.length = sizeof(s3call->request.data.auth_crap.chal);
516 nt_resp.data = (uint8_t *)s3call->request.data.auth_crap.nt_resp;
517 nt_resp.length = s3call->request.data.auth_crap.nt_resp_len;
518 lm_resp.data = (uint8_t *)s3call->request.data.auth_crap.lm_resp;
519 lm_resp.length = s3call->request.data.auth_crap.lm_resp_len;
521 ctx = wb_cmd_pam_auth_crap_send(
522 s3call, service,
523 s3call->request.data.auth_crap.logon_parameters,
524 s3call->request.data.auth_crap.domain,
525 s3call->request.data.auth_crap.user,
526 s3call->request.data.auth_crap.workstation,
527 chal, nt_resp, lm_resp);
528 NT_STATUS_HAVE_NO_MEMORY(ctx);
530 ctx->async.fn = pam_auth_crap_recv;
531 ctx->async.private_data = s3call;
532 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
533 return NT_STATUS_OK;
536 static void pam_auth_crap_recv(struct composite_context *ctx)
538 struct wbsrv_samba3_call *s3call =
539 talloc_get_type(ctx->async.private_data,
540 struct wbsrv_samba3_call);
541 NTSTATUS status;
542 DATA_BLOB info3;
543 struct netr_UserSessionKey user_session_key;
544 struct netr_LMSessionKey lm_key;
545 char *unix_username;
547 status = wb_cmd_pam_auth_crap_recv(ctx, s3call, &info3,
548 &user_session_key, &lm_key, &unix_username);
549 if (!NT_STATUS_IS_OK(status)) goto done;
551 if (s3call->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
552 memcpy(s3call->response.data.auth.user_session_key,
553 &user_session_key.key,
554 sizeof(s3call->response.data.auth.user_session_key));
557 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
558 s3call->response.extra_data.data = info3.data;
559 s3call->response.length += info3.length;
562 if (s3call->request.flags & WBFLAG_PAM_LMKEY) {
563 memcpy(s3call->response.data.auth.first_8_lm_hash,
564 lm_key.key,
565 sizeof(s3call->response.data.auth.first_8_lm_hash));
568 if (s3call->request.flags & WBFLAG_PAM_UNIX_NAME) {
569 s3call->response.extra_data.data = unix_username;
570 s3call->response.length += strlen(unix_username)+1;
573 done:
574 wbsrv_samba3_async_auth_epilogue(status, s3call);
577 /* Plaintext authentication
579 This interface is used by ntlm_auth in it's 'basic' authentication
580 mode, as well as by pam_winbind to authenticate users where we are
581 given a plaintext password.
584 static void pam_auth_recv(struct composite_context *ctx);
586 NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
588 struct composite_context *ctx;
589 struct wbsrv_service *service =
590 s3call->wbconn->listen_socket->service;
591 struct cli_credentials *credentials;
592 char *user, *domain;
594 if (!wb_samba3_split_username(s3call, s3call->wbconn->lp_ctx,
595 s3call->request.data.auth.user,
596 &domain, &user)) {
597 return NT_STATUS_NO_SUCH_USER;
600 credentials = cli_credentials_init(s3call);
601 if (!credentials) {
602 return NT_STATUS_NO_MEMORY;
604 cli_credentials_set_conf(credentials, service->task->lp_ctx);
605 cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
606 cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
608 cli_credentials_set_password(credentials, s3call->request.data.auth.pass, CRED_SPECIFIED);
610 ctx = wb_cmd_pam_auth_send(s3call, service, credentials);
611 NT_STATUS_HAVE_NO_MEMORY(ctx);
613 ctx->async.fn = pam_auth_recv;
614 ctx->async.private_data = s3call;
615 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
616 return NT_STATUS_OK;
619 static void pam_auth_recv(struct composite_context *ctx)
621 struct wbsrv_samba3_call *s3call =
622 talloc_get_type(ctx->async.private_data,
623 struct wbsrv_samba3_call);
624 NTSTATUS status;
626 status = wb_cmd_pam_auth_recv(ctx);
628 if (!NT_STATUS_IS_OK(status)) goto done;
630 done:
631 wbsrv_samba3_async_auth_epilogue(status, s3call);
635 List trusted domains
638 static void list_trustdom_recv_doms(struct composite_context *ctx);
640 NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
642 struct composite_context *ctx;
643 struct wbsrv_service *service =
644 s3call->wbconn->listen_socket->service;
646 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
648 ctx = wb_cmd_list_trustdoms_send(s3call, service);
649 NT_STATUS_HAVE_NO_MEMORY(ctx);
651 ctx->async.fn = list_trustdom_recv_doms;
652 ctx->async.private_data = s3call;
653 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
654 return NT_STATUS_OK;
657 static void list_trustdom_recv_doms(struct composite_context *ctx)
659 struct wbsrv_samba3_call *s3call =
660 talloc_get_type(ctx->async.private_data,
661 struct wbsrv_samba3_call);
662 int i, num_domains;
663 struct wb_dom_info **domains;
664 NTSTATUS status;
665 char *result;
667 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
668 &domains);
669 if (!NT_STATUS_IS_OK(status)) goto done;
671 result = talloc_strdup(s3call, "");
672 if (result == NULL) {
673 status = NT_STATUS_NO_MEMORY;
674 goto done;
677 for (i=0; i<num_domains; i++) {
678 result = talloc_asprintf_append_buffer(
679 result, "%s\\%s\\%s",
680 domains[i]->name, domains[i]->name,
681 dom_sid_string(s3call, domains[i]->sid));
684 if (result == NULL) {
685 status = NT_STATUS_NO_MEMORY;
686 goto done;
689 s3call->response.result = WINBINDD_OK;
690 if (num_domains > 0) {
691 s3call->response.extra_data.data = result;
692 s3call->response.length += strlen(result)+1;
695 done:
696 wbsrv_samba3_async_epilogue(status, s3call);
699 /* list groups */
700 static void list_groups_recv(struct composite_context *ctx);
702 NTSTATUS wbsrv_samba3_list_groups(struct wbsrv_samba3_call *s3call)
704 struct composite_context *ctx;
705 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
707 DEBUG(5, ("wbsrv_samba4_list_groups called\n"));
709 ctx = wb_cmd_list_groups_send(s3call, service,
710 s3call->request.domain_name);
711 NT_STATUS_HAVE_NO_MEMORY(ctx);
713 ctx->async.fn = list_groups_recv;
714 ctx->async.private_data = s3call;
715 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
716 return NT_STATUS_OK;
719 static void list_groups_recv(struct composite_context *ctx)
721 struct wbsrv_samba3_call *s3call = talloc_get_type_abort(
722 ctx->async.private_data,
723 struct wbsrv_samba3_call);
724 uint32_t extra_data_len;
725 char *extra_data;
726 NTSTATUS status;
728 DEBUG(5, ("list_groups_recv called\n"));
730 status = wb_cmd_list_groups_recv(ctx, s3call, &extra_data_len,
731 &extra_data);
733 if (NT_STATUS_IS_OK(status)) {
734 s3call->response.extra_data.data = extra_data;
735 s3call->response.length += extra_data_len;
736 if (extra_data) {
737 s3call->response.length += 1;
741 wbsrv_samba3_async_epilogue(status, s3call);
744 /* List users */
746 static void list_users_recv(struct composite_context *ctx);
748 NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
750 struct composite_context *ctx;
751 struct wbsrv_service *service =
752 s3call->wbconn->listen_socket->service;
754 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
756 ctx = wb_cmd_list_users_send(s3call, service,
757 s3call->request.domain_name);
758 NT_STATUS_HAVE_NO_MEMORY(ctx);
760 ctx->async.fn = list_users_recv;
761 ctx->async.private_data = s3call;
762 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
763 return NT_STATUS_OK;
766 static void list_users_recv(struct composite_context *ctx)
768 struct wbsrv_samba3_call *s3call =
769 talloc_get_type(ctx->async.private_data,
770 struct wbsrv_samba3_call);
771 uint32_t extra_data_len;
772 char *extra_data;
773 NTSTATUS status;
775 DEBUG(5, ("list_users_recv called\n"));
777 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
778 &extra_data);
780 if (NT_STATUS_IS_OK(status)) {
781 s3call->response.extra_data.data = extra_data;
782 s3call->response.length += extra_data_len;
783 if (extra_data) {
784 s3call->response.length += 1;
788 wbsrv_samba3_async_epilogue(status, s3call);
791 /* NSS calls */
793 static void getpwnam_recv(struct composite_context *ctx);
795 NTSTATUS wbsrv_samba3_getpwnam(struct wbsrv_samba3_call *s3call)
797 struct composite_context *ctx;
798 struct wbsrv_service *service =
799 s3call->wbconn->listen_socket->service;
801 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
803 ctx = wb_cmd_getpwnam_send(s3call, service,
804 s3call->request.data.username);
805 NT_STATUS_HAVE_NO_MEMORY(ctx);
807 ctx->async.fn = getpwnam_recv;
808 ctx->async.private_data = s3call;
809 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
810 return NT_STATUS_OK;
813 static void getpwnam_recv(struct composite_context *ctx)
815 struct wbsrv_samba3_call *s3call =
816 talloc_get_type(ctx->async.private_data,
817 struct wbsrv_samba3_call);
818 NTSTATUS status;
819 struct winbindd_pw *pw;
821 DEBUG(5, ("getpwnam_recv called\n"));
823 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
824 if(NT_STATUS_IS_OK(status))
825 s3call->response.data.pw = *pw;
827 wbsrv_samba3_async_epilogue(status, s3call);
830 static void getpwuid_recv(struct composite_context *ctx);
832 NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
834 struct composite_context *ctx;
835 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
837 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
839 ctx = wb_cmd_getpwuid_send(s3call, service,
840 s3call->request.data.uid);
841 NT_STATUS_HAVE_NO_MEMORY(ctx);
843 ctx->async.fn = getpwuid_recv;
844 ctx->async.private_data = s3call;
845 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
846 return NT_STATUS_OK;
849 static void getpwuid_recv(struct composite_context *ctx)
851 struct wbsrv_samba3_call *s3call =
852 talloc_get_type(ctx->async.private_data,
853 struct wbsrv_samba3_call);
854 NTSTATUS status;
855 struct winbindd_pw *pw;
857 DEBUG(5, ("getpwuid_recv called\n"));
859 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
860 if (NT_STATUS_IS_OK(status))
861 s3call->response.data.pw = *pw;
863 wbsrv_samba3_async_epilogue(status, s3call);
866 static void setpwent_recv(struct composite_context *ctx);
868 NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
870 struct composite_context *ctx;
871 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
873 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
875 ctx = wb_cmd_setpwent_send(s3call, service);
876 NT_STATUS_HAVE_NO_MEMORY(ctx);
878 ctx->async.fn = setpwent_recv;
879 ctx->async.private_data = s3call;
880 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
881 return NT_STATUS_OK;
884 static void setpwent_recv(struct composite_context *ctx)
886 struct wbsrv_samba3_call *s3call =
887 talloc_get_type(ctx->async.private_data,
888 struct wbsrv_samba3_call);
889 NTSTATUS status;
890 struct wbsrv_pwent *pwent;
892 DEBUG(5, ("setpwent_recv called\n"));
894 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
895 if (NT_STATUS_IS_OK(status)) {
896 s3call->wbconn->protocol_private_data = pwent;
899 wbsrv_samba3_async_epilogue(status, s3call);
902 static void getpwent_recv(struct composite_context *ctx);
904 NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
906 struct composite_context *ctx;
907 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
908 struct wbsrv_pwent *pwent;
910 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
912 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
914 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
915 struct wbsrv_pwent);
916 NT_STATUS_HAVE_NO_MEMORY(pwent);
918 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
919 s3call->request.data.num_entries);
920 NT_STATUS_HAVE_NO_MEMORY(ctx);
922 ctx->async.fn = getpwent_recv;
923 ctx->async.private_data = s3call;
924 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
925 return NT_STATUS_OK;
928 static void getpwent_recv(struct composite_context *ctx)
930 struct wbsrv_samba3_call *s3call =
931 talloc_get_type(ctx->async.private_data,
932 struct wbsrv_samba3_call);
933 NTSTATUS status;
934 struct winbindd_pw *pw;
935 uint32_t num_users;
937 DEBUG(5, ("getpwent_recv called\n"));
939 status = wb_cmd_getpwent_recv(ctx, s3call, &pw, &num_users);
940 if (NT_STATUS_IS_OK(status)) {
941 uint32_t extra_len = sizeof(struct winbindd_pw) * num_users;
943 s3call->response.data.num_entries = num_users;
944 s3call->response.extra_data.data = pw;
945 s3call->response.length += extra_len;
948 wbsrv_samba3_async_epilogue(status, s3call);
951 NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
953 struct wbsrv_pwent *pwent =
954 talloc_get_type(s3call->wbconn->protocol_private_data,
955 struct wbsrv_pwent);
956 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
958 talloc_free(pwent);
960 s3call->wbconn->protocol_private_data = NULL;
961 s3call->response.result = WINBINDD_OK;
962 return NT_STATUS_OK;
966 static void getgrnam_recv(struct composite_context *ctx);
968 NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
970 struct composite_context *ctx;
971 struct wbsrv_service *service =
972 s3call->wbconn->listen_socket->service;
974 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
976 ctx = wb_cmd_getgrnam_send(s3call, service,
977 s3call->request.data.groupname);
978 NT_STATUS_HAVE_NO_MEMORY(ctx);
980 ctx->async.fn = getgrnam_recv;
981 ctx->async.private_data = s3call;
982 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
983 return NT_STATUS_OK;
986 static void getgrnam_recv(struct composite_context *ctx)
988 struct wbsrv_samba3_call *s3call =
989 talloc_get_type(ctx->async.private_data,
990 struct wbsrv_samba3_call);
991 NTSTATUS status;
992 struct winbindd_gr *gr;
994 DEBUG(5, ("getgrnam_recv called\n"));
996 status = wb_cmd_getgrnam_recv(ctx, s3call, &gr);
997 if(NT_STATUS_IS_OK(status))
998 s3call->response.data.gr = *gr;
1000 wbsrv_samba3_async_epilogue(status, s3call);
1003 static void getgrgid_recv(struct composite_context *ctx);
1005 NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
1007 struct composite_context *ctx;
1008 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1010 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
1012 ctx = wb_cmd_getgrgid_send(s3call, service,
1013 s3call->request.data.gid);
1014 NT_STATUS_HAVE_NO_MEMORY(ctx);
1016 ctx->async.fn = getgrgid_recv;
1017 ctx->async.private_data = s3call;
1018 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1019 return NT_STATUS_OK;
1022 static void getgrgid_recv(struct composite_context *ctx)
1024 struct wbsrv_samba3_call *s3call =
1025 talloc_get_type(ctx->async.private_data,
1026 struct wbsrv_samba3_call);
1027 NTSTATUS status;
1028 struct winbindd_gr *gr;
1030 DEBUG(5, ("getgrgid_recv called\n"));
1032 status = wb_cmd_getgrgid_recv(ctx, s3call, &gr);
1033 if (NT_STATUS_IS_OK(status))
1034 s3call->response.data.gr = *gr;
1036 wbsrv_samba3_async_epilogue(status, s3call);
1039 NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
1041 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
1042 s3call->response.result = WINBINDD_ERROR;
1043 return NT_STATUS_OK;
1046 NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
1048 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
1049 s3call->response.result = WINBINDD_OK;
1050 return NT_STATUS_OK;
1053 NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
1055 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
1056 s3call->response.result = WINBINDD_ERROR;
1057 return NT_STATUS_OK;
1060 NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
1062 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
1063 s3call->response.result = WINBINDD_OK;
1064 return NT_STATUS_OK;
1067 static void sid2uid_recv(struct composite_context *ctx);
1069 NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
1071 struct composite_context *ctx;
1072 struct wbsrv_service *service =
1073 s3call->wbconn->listen_socket->service;
1074 struct dom_sid *sid;
1076 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
1078 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1079 NT_STATUS_HAVE_NO_MEMORY(sid);
1081 ctx = wb_sid2uid_send(s3call, service, sid);
1082 NT_STATUS_HAVE_NO_MEMORY(ctx);
1084 ctx->async.fn = sid2uid_recv;
1085 ctx->async.private_data = s3call;
1086 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1087 return NT_STATUS_OK;
1091 static void sid2uid_recv(struct composite_context *ctx)
1093 struct wbsrv_samba3_call *s3call =
1094 talloc_get_type(ctx->async.private_data,
1095 struct wbsrv_samba3_call);
1096 NTSTATUS status;
1098 DEBUG(5, ("sid2uid_recv called\n"));
1100 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
1102 wbsrv_samba3_async_epilogue(status, s3call);
1105 static void sid2gid_recv(struct composite_context *ctx);
1107 NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
1109 struct composite_context *ctx;
1110 struct wbsrv_service *service =
1111 s3call->wbconn->listen_socket->service;
1112 struct dom_sid *sid;
1114 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
1116 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1117 NT_STATUS_HAVE_NO_MEMORY(sid);
1119 ctx = wb_sid2gid_send(s3call, service, sid);
1120 NT_STATUS_HAVE_NO_MEMORY(ctx);
1122 ctx->async.fn = sid2gid_recv;
1123 ctx->async.private_data = s3call;
1124 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1125 return NT_STATUS_OK;
1129 static void sid2gid_recv(struct composite_context *ctx)
1131 struct wbsrv_samba3_call *s3call =
1132 talloc_get_type(ctx->async.private_data,
1133 struct wbsrv_samba3_call);
1134 NTSTATUS status;
1136 DEBUG(5, ("sid2gid_recv called\n"));
1138 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
1140 wbsrv_samba3_async_epilogue(status, s3call);
1143 static void uid2sid_recv(struct composite_context *ctx);
1145 NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
1147 struct composite_context *ctx;
1148 struct wbsrv_service *service =
1149 s3call->wbconn->listen_socket->service;
1151 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1153 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
1154 NT_STATUS_HAVE_NO_MEMORY(ctx);
1156 ctx->async.fn = uid2sid_recv;
1157 ctx->async.private_data = s3call;
1158 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1159 return NT_STATUS_OK;
1163 static void uid2sid_recv(struct composite_context *ctx)
1165 struct wbsrv_samba3_call *s3call =
1166 talloc_get_type(ctx->async.private_data,
1167 struct wbsrv_samba3_call);
1168 NTSTATUS status;
1169 struct dom_sid *sid;
1170 char *sid_str;
1172 DEBUG(5, ("uid2sid_recv called\n"));
1174 status = wb_uid2sid_recv(ctx, s3call, &sid);
1175 if(NT_STATUS_IS_OK(status)) {
1176 sid_str = dom_sid_string(s3call, sid);
1178 /* If the conversion failed, bail out with a failure. */
1179 if (sid_str == NULL)
1180 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1182 /* But we assume this worked, so we'll set the string. Work
1183 * done. */
1184 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1185 s3call->response.data.sid.type = SID_NAME_USER;
1188 wbsrv_samba3_async_epilogue(status, s3call);
1191 static void gid2sid_recv(struct composite_context *ctx);
1193 NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1195 struct composite_context *ctx;
1196 struct wbsrv_service *service =
1197 s3call->wbconn->listen_socket->service;
1199 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1201 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1202 NT_STATUS_HAVE_NO_MEMORY(ctx);
1204 ctx->async.fn = gid2sid_recv;
1205 ctx->async.private_data = s3call;
1206 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1207 return NT_STATUS_OK;
1211 static void gid2sid_recv(struct composite_context *ctx)
1213 struct wbsrv_samba3_call *s3call =
1214 talloc_get_type(ctx->async.private_data,
1215 struct wbsrv_samba3_call);
1216 NTSTATUS status;
1217 struct dom_sid *sid;
1218 char *sid_str;
1220 DEBUG(5, ("gid2sid_recv called\n"));
1222 status = wb_gid2sid_recv(ctx, s3call, &sid);
1223 if(NT_STATUS_IS_OK(status)) {
1224 sid_str = dom_sid_string(s3call, sid);
1226 if (sid_str == NULL)
1227 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1229 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1230 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1233 wbsrv_samba3_async_epilogue(status, s3call);