source: branches/samba-3.5.x/source4/winbind/wb_samba3_cmd.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 32.5 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Main winbindd samba3 server routines
4
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
9
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.
14
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.
19
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/>.
22*/
23
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"
36
37/*
38 Send off the reply to an async Samba3 query, handling filling in the PAM, NTSTATUS and string errors.
39*/
40
41static void wbsrv_samba3_async_auth_epilogue(NTSTATUS status,
42 struct wbsrv_samba3_call *s3call)
43{
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;
49 }
50
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));
55
56 resp->data.auth.pam_error = nt_status_to_pam(status);
57 resp->data.auth.nt_status = NT_STATUS_V(status);
58
59 wbsrv_samba3_send_reply(s3call);
60}
61
62/*
63 Send of a generic reply to a Samba3 query
64*/
65
66static void wbsrv_samba3_async_epilogue(NTSTATUS status,
67 struct wbsrv_samba3_call *s3call)
68{
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;
74 }
75
76 wbsrv_samba3_send_reply(s3call);
77}
78
79/*
80 Boilerplate commands, simple queries without network traffic
81*/
82
83NTSTATUS wbsrv_samba3_interface_version(struct wbsrv_samba3_call *s3call)
84{
85 s3call->response.result = WINBINDD_OK;
86 s3call->response.data.interface_version = WINBIND_INTERFACE_VERSION;
87 return NT_STATUS_OK;
88}
89
90NTSTATUS wbsrv_samba3_info(struct wbsrv_samba3_call *s3call)
91{
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;
97}
98
99NTSTATUS wbsrv_samba3_domain_name(struct wbsrv_samba3_call *s3call)
100{
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;
105}
106
107NTSTATUS wbsrv_samba3_netbios_name(struct wbsrv_samba3_call *s3call)
108{
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;
113}
114
115NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
116{
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);
120
121 s3call->response.length += strlen(path) + 1;
122 return NT_STATUS_OK;
123}
124
125NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
126{
127 s3call->response.result = WINBINDD_OK;
128 return NT_STATUS_OK;
129}
130
131NTSTATUS wbsrv_samba3_domain_info(struct wbsrv_samba3_call *s3call)
132{
133 DEBUG(5, ("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;
143
144 return NT_STATUS_OK;
145}
146
147/* Plaintext authentication
148
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.
152*/
153
154static void check_machacc_recv(struct composite_context *ctx);
155
156NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
157{
158 NTSTATUS status;
159 struct cli_credentials *creds;
160 struct composite_context *ctx;
161 struct wbsrv_service *service =
162 s3call->wbconn->listen_socket->service;
163
164 /* Create a credentials structure */
165 creds = cli_credentials_init(s3call);
166 if (creds == NULL) {
167 return NT_STATUS_NO_MEMORY;
168 }
169
170 cli_credentials_set_conf(creds, service->task->lp_ctx);
171
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;
177 }
178
179 ctx = wb_cmd_pam_auth_send(s3call, service, creds);
180
181 if (!ctx) {
182 talloc_free(creds);
183 return NT_STATUS_NO_MEMORY;
184 }
185
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;
190}
191
192static void check_machacc_recv(struct composite_context *ctx)
193{
194 struct wbsrv_samba3_call *s3call =
195 talloc_get_type(ctx->async.private_data,
196 struct wbsrv_samba3_call);
197 NTSTATUS status;
198
199 status = wb_cmd_pam_auth_recv(ctx);
200
201 if (!NT_STATUS_IS_OK(status)) goto done;
202
203 done:
204 wbsrv_samba3_async_auth_epilogue(status, s3call);
205}
206
207/*
208 Find the name of a suitable domain controller, by query on the
209 netlogon pipe to the DC.
210*/
211
212static void getdcname_recv_dc(struct composite_context *ctx);
213
214NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
215{
216 struct composite_context *ctx;
217 struct wbsrv_service *service =
218 s3call->wbconn->listen_socket->service;
219
220 DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
221
222 ctx = wb_cmd_getdcname_send(s3call, service,
223 s3call->request.domain_name);
224 NT_STATUS_HAVE_NO_MEMORY(ctx);
225
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;
230}
231
232static void getdcname_recv_dc(struct composite_context *ctx)
233{
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;
239
240 status = wb_cmd_getdcname_recv(ctx, s3call, &dcname);
241 if (!NT_STATUS_IS_OK(status)) goto done;
242
243 s3call->response.result = WINBINDD_OK;
244 WBSRV_SAMBA3_SET_STRING(s3call->response.data.dc_name, dcname);
245
246 done:
247 wbsrv_samba3_async_epilogue(status, s3call);
248}
249
250/*
251 Lookup a user's domain groups
252*/
253
254static void userdomgroups_recv_groups(struct composite_context *ctx);
255
256NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
257{
258 struct composite_context *ctx;
259 struct dom_sid *sid;
260
261 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
262
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;
268 }
269
270 ctx = wb_cmd_userdomgroups_send(
271 s3call, s3call->wbconn->listen_socket->service, sid);
272 NT_STATUS_HAVE_NO_MEMORY(ctx);
273
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;
278}
279
280static void userdomgroups_recv_groups(struct composite_context *ctx)
281{
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;
289
290 status = wb_cmd_userdomgroups_recv(ctx, s3call, &num_sids, &sids);
291 if (!NT_STATUS_IS_OK(status)) goto done;
292
293 sids_string = talloc_strdup(s3call, "");
294 if (sids_string == NULL) {
295 status = NT_STATUS_NO_MEMORY;
296 goto done;
297 }
298
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]));
302 }
303
304 if (sids_string == NULL) {
305 status = NT_STATUS_NO_MEMORY;
306 goto done;
307 }
308
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;
313
314 done:
315 wbsrv_samba3_async_epilogue(status, s3call);
316}
317
318/*
319 Lookup the list of SIDs for a user
320*/
321static void usersids_recv_sids(struct composite_context *ctx);
322
323NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call)
324{
325 struct composite_context *ctx;
326 struct dom_sid *sid;
327
328 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
329
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;
335 }
336
337 ctx = wb_cmd_usersids_send(
338 s3call, s3call->wbconn->listen_socket->service, sid);
339 NT_STATUS_HAVE_NO_MEMORY(ctx);
340
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;
345}
346
347static void usersids_recv_sids(struct composite_context *ctx)
348{
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;
356
357 status = wb_cmd_usersids_recv(ctx, s3call, &num_sids, &sids);
358 if (!NT_STATUS_IS_OK(status)) goto done;
359
360 sids_string = talloc_strdup(s3call, "");
361 if (sids_string == NULL) {
362 status = NT_STATUS_NO_MEMORY;
363 goto done;
364 }
365
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;
372 }
373 }
374
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;
379
380 /* Hmmmm. Nasty protocol -- who invented the zeros between the
381 * SIDs? Hmmm. Could have been me -- vl */
382
383 while (*sids_string != '\0') {
384 if ((*sids_string) == '\n') {
385 *sids_string = '\0';
386 }
387 sids_string += 1;
388 }
389
390 done:
391 wbsrv_samba3_async_epilogue(status, s3call);
392}
393
394/*
395 Lookup a DOMAIN\\user style name, and return a SID
396*/
397
398static void lookupname_recv_sid(struct composite_context *ctx);
399
400NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
401{
402 struct composite_context *ctx;
403 struct wbsrv_service *service =
404 s3call->wbconn->listen_socket->service;
405
406 DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
407
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);
412
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;
418}
419
420static void lookupname_recv_sid(struct composite_context *ctx)
421{
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;
427
428 status = wb_cmd_lookupname_recv(ctx, s3call, &sid);
429 if (!NT_STATUS_IS_OK(status)) goto done;
430
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));
435
436 done:
437 wbsrv_samba3_async_epilogue(status, s3call);
438}
439
440/*
441 Lookup a SID, and return a DOMAIN\\user style name
442*/
443
444static void lookupsid_recv_name(struct composite_context *ctx);
445
446NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
447{
448 struct composite_context *ctx;
449 struct wbsrv_service *service =
450 s3call->wbconn->listen_socket->service;
451 struct dom_sid *sid;
452
453 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
454
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;
460 }
461
462 ctx = wb_cmd_lookupsid_send(s3call, service, sid);
463 NT_STATUS_HAVE_NO_MEMORY(ctx);
464
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;
470}
471
472static void lookupsid_recv_name(struct composite_context *ctx)
473{
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;
479
480 status = wb_cmd_lookupsid_recv(ctx, s3call, &sid);
481 if (!NT_STATUS_IS_OK(status)) goto done;
482
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);
488
489 done:
490 wbsrv_samba3_async_epilogue(status, s3call);
491}
492
493/*
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.
497
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.
501*/
502
503static void pam_auth_crap_recv(struct composite_context *ctx);
504
505NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
506{
507 struct composite_context *ctx;
508 struct wbsrv_service *service =
509 s3call->wbconn->listen_socket->service;
510 DATA_BLOB chal, nt_resp, lm_resp;
511
512 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
513
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;
520
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);
529
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;
534}
535
536static void pam_auth_crap_recv(struct composite_context *ctx)
537{
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;
546
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;
550
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));
555 }
556
557 if (s3call->request.flags & WBFLAG_PAM_INFO3_NDR) {
558 s3call->response.extra_data.data = info3.data;
559 s3call->response.length += info3.length;
560 }
561
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));
566 }
567
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;
571 }
572
573 done:
574 wbsrv_samba3_async_auth_epilogue(status, s3call);
575}
576
577/* Plaintext authentication
578
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.
582*/
583
584static void pam_auth_recv(struct composite_context *ctx);
585
586NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
587{
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;
593
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;
598 }
599
600 credentials = cli_credentials_init(s3call);
601 if (!credentials) {
602 return NT_STATUS_NO_MEMORY;
603 }
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);
607
608 cli_credentials_set_password(credentials, s3call->request.data.auth.pass, CRED_SPECIFIED);
609
610 ctx = wb_cmd_pam_auth_send(s3call, service, credentials);
611 NT_STATUS_HAVE_NO_MEMORY(ctx);
612
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;
617}
618
619static void pam_auth_recv(struct composite_context *ctx)
620{
621 struct wbsrv_samba3_call *s3call =
622 talloc_get_type(ctx->async.private_data,
623 struct wbsrv_samba3_call);
624 NTSTATUS status;
625
626 status = wb_cmd_pam_auth_recv(ctx);
627
628 if (!NT_STATUS_IS_OK(status)) goto done;
629
630 done:
631 wbsrv_samba3_async_auth_epilogue(status, s3call);
632}
633
634/*
635 List trusted domains
636*/
637
638static void list_trustdom_recv_doms(struct composite_context *ctx);
639
640NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
641{
642 struct composite_context *ctx;
643 struct wbsrv_service *service =
644 s3call->wbconn->listen_socket->service;
645
646 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
647
648 ctx = wb_cmd_list_trustdoms_send(s3call, service);
649 NT_STATUS_HAVE_NO_MEMORY(ctx);
650
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;
655}
656
657static void list_trustdom_recv_doms(struct composite_context *ctx)
658{
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;
666
667 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
668 &domains);
669 if (!NT_STATUS_IS_OK(status)) goto done;
670
671 result = talloc_strdup(s3call, "");
672 if (result == NULL) {
673 status = NT_STATUS_NO_MEMORY;
674 goto done;
675 }
676
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));
682 }
683
684 if (result == NULL) {
685 status = NT_STATUS_NO_MEMORY;
686 goto done;
687 }
688
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;
693 }
694
695 done:
696 wbsrv_samba3_async_epilogue(status, s3call);
697}
698
699/* list groups */
700static void list_groups_recv(struct composite_context *ctx);
701
702NTSTATUS wbsrv_samba3_list_groups(struct wbsrv_samba3_call *s3call)
703{
704 struct composite_context *ctx;
705 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
706
707 DEBUG(5, ("wbsrv_samba4_list_groups called\n"));
708
709 ctx = wb_cmd_list_groups_send(s3call, service,
710 s3call->request.domain_name);
711 NT_STATUS_HAVE_NO_MEMORY(ctx);
712
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;
717}
718
719static void list_groups_recv(struct composite_context *ctx)
720{
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;
727
728 DEBUG(5, ("list_groups_recv called\n"));
729
730 status = wb_cmd_list_groups_recv(ctx, s3call, &extra_data_len,
731 &extra_data);
732
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;
738 }
739 }
740
741 wbsrv_samba3_async_epilogue(status, s3call);
742}
743
744/* List users */
745
746static void list_users_recv(struct composite_context *ctx);
747
748NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
749{
750 struct composite_context *ctx;
751 struct wbsrv_service *service =
752 s3call->wbconn->listen_socket->service;
753
754 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
755
756 ctx = wb_cmd_list_users_send(s3call, service,
757 s3call->request.domain_name);
758 NT_STATUS_HAVE_NO_MEMORY(ctx);
759
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;
764}
765
766static void list_users_recv(struct composite_context *ctx)
767{
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;
774
775 DEBUG(5, ("list_users_recv called\n"));
776
777 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
778 &extra_data);
779
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;
785 }
786 }
787
788 wbsrv_samba3_async_epilogue(status, s3call);
789}
790
791/* NSS calls */
792
793static void getpwnam_recv(struct composite_context *ctx);
794
795NTSTATUS wbsrv_samba3_getpwnam(struct wbsrv_samba3_call *s3call)
796{
797 struct composite_context *ctx;
798 struct wbsrv_service *service =
799 s3call->wbconn->listen_socket->service;
800
801 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
802
803 ctx = wb_cmd_getpwnam_send(s3call, service,
804 s3call->request.data.username);
805 NT_STATUS_HAVE_NO_MEMORY(ctx);
806
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;
811}
812
813static void getpwnam_recv(struct composite_context *ctx)
814{
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;
820
821 DEBUG(5, ("getpwnam_recv called\n"));
822
823 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
824 if(NT_STATUS_IS_OK(status))
825 s3call->response.data.pw = *pw;
826
827 wbsrv_samba3_async_epilogue(status, s3call);
828}
829
830static void getpwuid_recv(struct composite_context *ctx);
831
832NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
833{
834 struct composite_context *ctx;
835 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
836
837 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
838
839 ctx = wb_cmd_getpwuid_send(s3call, service,
840 s3call->request.data.uid);
841 NT_STATUS_HAVE_NO_MEMORY(ctx);
842
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;
847}
848
849static void getpwuid_recv(struct composite_context *ctx)
850{
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;
856
857 DEBUG(5, ("getpwuid_recv called\n"));
858
859 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
860 if (NT_STATUS_IS_OK(status))
861 s3call->response.data.pw = *pw;
862
863 wbsrv_samba3_async_epilogue(status, s3call);
864}
865
866static void setpwent_recv(struct composite_context *ctx);
867
868NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
869{
870 struct composite_context *ctx;
871 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
872
873 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
874
875 ctx = wb_cmd_setpwent_send(s3call, service);
876 NT_STATUS_HAVE_NO_MEMORY(ctx);
877
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;
882}
883
884static void setpwent_recv(struct composite_context *ctx)
885{
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;
891
892 DEBUG(5, ("setpwent_recv called\n"));
893
894 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
895 if (NT_STATUS_IS_OK(status)) {
896 s3call->wbconn->protocol_private_data = pwent;
897 }
898
899 wbsrv_samba3_async_epilogue(status, s3call);
900}
901
902static void getpwent_recv(struct composite_context *ctx);
903
904NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
905{
906 struct composite_context *ctx;
907 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
908 struct wbsrv_pwent *pwent;
909
910 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
911
912 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
913
914 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
915 struct wbsrv_pwent);
916 NT_STATUS_HAVE_NO_MEMORY(pwent);
917
918 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
919 s3call->request.data.num_entries);
920 NT_STATUS_HAVE_NO_MEMORY(ctx);
921
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;
926}
927
928static void getpwent_recv(struct composite_context *ctx)
929{
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;
936
937 DEBUG(5, ("getpwent_recv called\n"));
938
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;
942
943 s3call->response.data.num_entries = num_users;
944 s3call->response.extra_data.data = pw;
945 s3call->response.length += extra_len;
946 }
947
948 wbsrv_samba3_async_epilogue(status, s3call);
949}
950
951NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
952{
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"));
957
958 talloc_free(pwent);
959
960 s3call->wbconn->protocol_private_data = NULL;
961 s3call->response.result = WINBINDD_OK;
962 return NT_STATUS_OK;
963}
964
965
966static void getgrnam_recv(struct composite_context *ctx);
967
968NTSTATUS wbsrv_samba3_getgrnam(struct wbsrv_samba3_call *s3call)
969{
970 struct composite_context *ctx;
971 struct wbsrv_service *service =
972 s3call->wbconn->listen_socket->service;
973
974 DEBUG(5, ("wbsrv_samba3_getgrnam called\n"));
975
976 ctx = wb_cmd_getgrnam_send(s3call, service,
977 s3call->request.data.groupname);
978 NT_STATUS_HAVE_NO_MEMORY(ctx);
979
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;
984}
985
986static void getgrnam_recv(struct composite_context *ctx)
987{
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;
993
994 DEBUG(5, ("getgrnam_recv called\n"));
995
996 status = wb_cmd_getgrnam_recv(ctx, s3call, &gr);
997 if(NT_STATUS_IS_OK(status))
998 s3call->response.data.gr = *gr;
999
1000 wbsrv_samba3_async_epilogue(status, s3call);
1001}
1002
1003static void getgrgid_recv(struct composite_context *ctx);
1004
1005NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
1006{
1007 struct composite_context *ctx;
1008 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1009
1010 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
1011
1012 ctx = wb_cmd_getgrgid_send(s3call, service,
1013 s3call->request.data.gid);
1014 NT_STATUS_HAVE_NO_MEMORY(ctx);
1015
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;
1020}
1021
1022static void getgrgid_recv(struct composite_context *ctx)
1023{
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;
1029
1030 DEBUG(5, ("getgrgid_recv called\n"));
1031
1032 status = wb_cmd_getgrgid_recv(ctx, s3call, &gr);
1033 if (NT_STATUS_IS_OK(status))
1034 s3call->response.data.gr = *gr;
1035
1036 wbsrv_samba3_async_epilogue(status, s3call);
1037}
1038
1039NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
1040{
1041 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
1042 s3call->response.result = WINBINDD_ERROR;
1043 return NT_STATUS_OK;
1044}
1045
1046NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
1047{
1048 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
1049 s3call->response.result = WINBINDD_OK;
1050 return NT_STATUS_OK;
1051}
1052
1053NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
1054{
1055 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
1056 s3call->response.result = WINBINDD_ERROR;
1057 return NT_STATUS_OK;
1058}
1059
1060NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
1061{
1062 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
1063 s3call->response.result = WINBINDD_OK;
1064 return NT_STATUS_OK;
1065}
1066
1067static void sid2uid_recv(struct composite_context *ctx);
1068
1069NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
1070{
1071 struct composite_context *ctx;
1072 struct wbsrv_service *service =
1073 s3call->wbconn->listen_socket->service;
1074 struct dom_sid *sid;
1075
1076 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
1077
1078 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1079 NT_STATUS_HAVE_NO_MEMORY(sid);
1080
1081 ctx = wb_sid2uid_send(s3call, service, sid);
1082 NT_STATUS_HAVE_NO_MEMORY(ctx);
1083
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;
1088
1089}
1090
1091static void sid2uid_recv(struct composite_context *ctx)
1092{
1093 struct wbsrv_samba3_call *s3call =
1094 talloc_get_type(ctx->async.private_data,
1095 struct wbsrv_samba3_call);
1096 NTSTATUS status;
1097
1098 DEBUG(5, ("sid2uid_recv called\n"));
1099
1100 status = wb_sid2uid_recv(ctx, &s3call->response.data.uid);
1101
1102 wbsrv_samba3_async_epilogue(status, s3call);
1103}
1104
1105static void sid2gid_recv(struct composite_context *ctx);
1106
1107NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
1108{
1109 struct composite_context *ctx;
1110 struct wbsrv_service *service =
1111 s3call->wbconn->listen_socket->service;
1112 struct dom_sid *sid;
1113
1114 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
1115
1116 sid = dom_sid_parse_talloc(s3call, s3call->request.data.sid);
1117 NT_STATUS_HAVE_NO_MEMORY(sid);
1118
1119 ctx = wb_sid2gid_send(s3call, service, sid);
1120 NT_STATUS_HAVE_NO_MEMORY(ctx);
1121
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;
1126
1127}
1128
1129static void sid2gid_recv(struct composite_context *ctx)
1130{
1131 struct wbsrv_samba3_call *s3call =
1132 talloc_get_type(ctx->async.private_data,
1133 struct wbsrv_samba3_call);
1134 NTSTATUS status;
1135
1136 DEBUG(5, ("sid2gid_recv called\n"));
1137
1138 status = wb_sid2gid_recv(ctx, &s3call->response.data.gid);
1139
1140 wbsrv_samba3_async_epilogue(status, s3call);
1141}
1142
1143static void uid2sid_recv(struct composite_context *ctx);
1144
1145NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
1146{
1147 struct composite_context *ctx;
1148 struct wbsrv_service *service =
1149 s3call->wbconn->listen_socket->service;
1150
1151 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1152
1153 ctx = wb_uid2sid_send(s3call, service, s3call->request.data.uid);
1154 NT_STATUS_HAVE_NO_MEMORY(ctx);
1155
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;
1160
1161}
1162
1163static void uid2sid_recv(struct composite_context *ctx)
1164{
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;
1171
1172 DEBUG(5, ("uid2sid_recv called\n"));
1173
1174 status = wb_uid2sid_recv(ctx, s3call, &sid);
1175 if(NT_STATUS_IS_OK(status)) {
1176 sid_str = dom_sid_string(s3call, sid);
1177
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);
1181
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;
1186 }
1187
1188 wbsrv_samba3_async_epilogue(status, s3call);
1189}
1190
1191static void gid2sid_recv(struct composite_context *ctx);
1192
1193NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1194{
1195 struct composite_context *ctx;
1196 struct wbsrv_service *service =
1197 s3call->wbconn->listen_socket->service;
1198
1199 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1200
1201 ctx = wb_gid2sid_send(s3call, service, s3call->request.data.gid);
1202 NT_STATUS_HAVE_NO_MEMORY(ctx);
1203
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;
1208
1209}
1210
1211static void gid2sid_recv(struct composite_context *ctx)
1212{
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;
1219
1220 DEBUG(5, ("gid2sid_recv called\n"));
1221
1222 status = wb_gid2sid_recv(ctx, s3call, &sid);
1223 if(NT_STATUS_IS_OK(status)) {
1224 sid_str = dom_sid_string(s3call, sid);
1225
1226 if (sid_str == NULL)
1227 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1228
1229 WBSRV_SAMBA3_SET_STRING(s3call->response.data.sid.sid, sid_str);
1230 s3call->response.data.sid.type = SID_NAME_DOMAIN;
1231 }
1232
1233 wbsrv_samba3_async_epilogue(status, s3call);
1234}
1235
Note: See TracBrowser for help on using the repository browser.