source: trunk/server/source4/winbind/wb_samba3_cmd.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 42.8 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 "param/param.h"
27#include "winbind/wb_helper.h"
28#include "libcli/composite/composite.h"
29#include "version.h"
30#include "librpc/gen_ndr/ndr_netlogon.h"
31#include "libcli/security/security.h"
32#include "../libcli/auth/pam_errors.h"
33#include "auth/credentials/credentials.h"
34#include "smbd/service_task.h"
35
36/*
37 support the old Samba3 TXT form of the info3
38 */
39static NTSTATUS wb_samba3_append_info3_as_txt(TALLOC_CTX *mem_ctx,
40 struct wbsrv_samba3_call *s3call,
41 DATA_BLOB info3b)
42{
43 struct netr_SamInfo3 *info3;
44 char *ex;
45 uint32_t i;
46 enum ndr_err_code ndr_err;
47
48 info3 = talloc(mem_ctx, struct netr_SamInfo3);
49 NT_STATUS_HAVE_NO_MEMORY(info3);
50
51 /* The Samba3 protocol has a redundent 4 bytes at the start */
52 info3b.data += 4;
53 info3b.length -= 4;
54
55 ndr_err = ndr_pull_struct_blob(&info3b,
56 mem_ctx,
57 info3,
58 (ndr_pull_flags_fn_t)ndr_pull_netr_SamInfo3);
59 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
60 return ndr_map_error2ntstatus(ndr_err);
61 }
62
63 s3call->response->data.auth.info3.logon_time =
64 nt_time_to_unix(info3->base.last_logon);
65 s3call->response->data.auth.info3.logoff_time =
66 nt_time_to_unix(info3->base.last_logoff);
67 s3call->response->data.auth.info3.kickoff_time =
68 nt_time_to_unix(info3->base.acct_expiry);
69 s3call->response->data.auth.info3.pass_last_set_time =
70 nt_time_to_unix(info3->base.last_password_change);
71 s3call->response->data.auth.info3.pass_can_change_time =
72 nt_time_to_unix(info3->base.allow_password_change);
73 s3call->response->data.auth.info3.pass_must_change_time =
74 nt_time_to_unix(info3->base.force_password_change);
75
76 s3call->response->data.auth.info3.logon_count = info3->base.logon_count;
77 s3call->response->data.auth.info3.bad_pw_count = info3->base.bad_password_count;
78
79 s3call->response->data.auth.info3.user_rid = info3->base.rid;
80 s3call->response->data.auth.info3.group_rid = info3->base.primary_gid;
81 fstrcpy(s3call->response->data.auth.info3.dom_sid, dom_sid_string(mem_ctx, info3->base.domain_sid));
82
83 s3call->response->data.auth.info3.num_groups = info3->base.groups.count;
84 s3call->response->data.auth.info3.user_flgs = info3->base.user_flags;
85
86 s3call->response->data.auth.info3.acct_flags = info3->base.acct_flags;
87 s3call->response->data.auth.info3.num_other_sids = info3->sidcount;
88
89 fstrcpy(s3call->response->data.auth.info3.user_name,
90 info3->base.account_name.string);
91 fstrcpy(s3call->response->data.auth.info3.full_name,
92 info3->base.full_name.string);
93 fstrcpy(s3call->response->data.auth.info3.logon_script,
94 info3->base.logon_script.string);
95 fstrcpy(s3call->response->data.auth.info3.profile_path,
96 info3->base.profile_path.string);
97 fstrcpy(s3call->response->data.auth.info3.home_dir,
98 info3->base.home_directory.string);
99 fstrcpy(s3call->response->data.auth.info3.dir_drive,
100 info3->base.home_drive.string);
101
102 fstrcpy(s3call->response->data.auth.info3.logon_srv,
103 info3->base.logon_server.string);
104 fstrcpy(s3call->response->data.auth.info3.logon_dom,
105 info3->base.domain.string);
106
107 ex = talloc_strdup(mem_ctx, "");
108 NT_STATUS_HAVE_NO_MEMORY(ex);
109
110 for (i=0; i < info3->base.groups.count; i++) {
111 ex = talloc_asprintf_append_buffer(ex, "0x%08X:0x%08X\n",
112 info3->base.groups.rids[i].rid,
113 info3->base.groups.rids[i].attributes);
114 NT_STATUS_HAVE_NO_MEMORY(ex);
115 }
116
117 for (i=0; i < info3->sidcount; i++) {
118 char *sid;
119
120 sid = dom_sid_string(mem_ctx, info3->sids[i].sid);
121 NT_STATUS_HAVE_NO_MEMORY(sid);
122
123 ex = talloc_asprintf_append_buffer(ex, "%s:0x%08X\n",
124 sid,
125 info3->sids[i].attributes);
126 NT_STATUS_HAVE_NO_MEMORY(ex);
127
128 talloc_free(sid);
129 }
130
131 s3call->response->extra_data.data = ex;
132 s3call->response->length += talloc_get_size(ex);
133
134 return NT_STATUS_OK;
135}
136
137/*
138 Send off the reply to an async Samba3 query, handling filling in the PAM, NTSTATUS and string errors.
139*/
140
141static void wbsrv_samba3_async_auth_epilogue(NTSTATUS status,
142 struct wbsrv_samba3_call *s3call)
143{
144 struct winbindd_response *resp = s3call->response;
145 if (!NT_STATUS_IS_OK(status)) {
146 resp->result = WINBINDD_ERROR;
147 } else {
148 resp->result = WINBINDD_OK;
149 }
150
151 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
152 nt_errstr(status));
153 WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
154 get_friendly_nt_error_msg(status));
155
156 resp->data.auth.pam_error = nt_status_to_pam(status);
157 resp->data.auth.nt_status = NT_STATUS_V(status);
158
159 wbsrv_samba3_send_reply(s3call);
160}
161
162/*
163 Send of a generic reply to a Samba3 query
164*/
165
166static void wbsrv_samba3_async_epilogue(NTSTATUS status,
167 struct wbsrv_samba3_call *s3call)
168{
169 struct winbindd_response *resp = s3call->response;
170 if (NT_STATUS_IS_OK(status)) {
171 resp->result = WINBINDD_OK;
172 } else {
173 resp->result = WINBINDD_ERROR;
174 }
175
176 wbsrv_samba3_send_reply(s3call);
177}
178
179/*
180 Boilerplate commands, simple queries without network traffic
181*/
182
183NTSTATUS wbsrv_samba3_interface_version(struct wbsrv_samba3_call *s3call)
184{
185 s3call->response->result = WINBINDD_OK;
186 s3call->response->data.interface_version = WINBIND_INTERFACE_VERSION;
187 return NT_STATUS_OK;
188}
189
190NTSTATUS wbsrv_samba3_info(struct wbsrv_samba3_call *s3call)
191{
192 s3call->response->result = WINBINDD_OK;
193 s3call->response->data.info.winbind_separator = *lpcfg_winbind_separator(s3call->wbconn->lp_ctx);
194 WBSRV_SAMBA3_SET_STRING(s3call->response->data.info.samba_version,
195 SAMBA_VERSION_STRING);
196 return NT_STATUS_OK;
197}
198
199NTSTATUS wbsrv_samba3_domain_name(struct wbsrv_samba3_call *s3call)
200{
201 s3call->response->result = WINBINDD_OK;
202 WBSRV_SAMBA3_SET_STRING(s3call->response->data.domain_name,
203 lpcfg_workgroup(s3call->wbconn->lp_ctx));
204 return NT_STATUS_OK;
205}
206
207NTSTATUS wbsrv_samba3_netbios_name(struct wbsrv_samba3_call *s3call)
208{
209 s3call->response->result = WINBINDD_OK;
210 WBSRV_SAMBA3_SET_STRING(s3call->response->data.netbios_name,
211 lpcfg_netbios_name(s3call->wbconn->lp_ctx));
212 return NT_STATUS_OK;
213}
214
215NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
216{
217 struct loadparm_context *lp_ctx = s3call->wbconn->listen_socket->service->task->lp_ctx;
218 const char *priv_socket_dir = lpcfg_winbindd_privileged_socket_directory(lp_ctx);
219
220 s3call->response->result = WINBINDD_OK;
221 s3call->response->extra_data.data = discard_const(priv_socket_dir);
222
223 s3call->response->length += strlen(priv_socket_dir) + 1;
224 return NT_STATUS_OK;
225}
226
227NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
228{
229 s3call->response->result = WINBINDD_OK;
230 return NT_STATUS_OK;
231}
232
233NTSTATUS wbsrv_samba3_domain_info(struct wbsrv_samba3_call *s3call)
234{
235 DEBUG(5, ("wbsrv_samba3_domain_info called, stub\n"));
236 s3call->response->result = WINBINDD_OK;
237 fstrcpy(s3call->response->data.domain_info.name,
238 s3call->request->domain_name);
239 fstrcpy(s3call->response->data.domain_info.alt_name,
240 s3call->request->domain_name);
241 fstrcpy(s3call->response->data.domain_info.sid, "S-1-2-3-4");
242 s3call->response->data.domain_info.native_mode = false;
243 s3call->response->data.domain_info.active_directory = false;
244 s3call->response->data.domain_info.primary = false;
245
246 return NT_STATUS_OK;
247}
248
249/* Plaintext authentication
250
251 This interface is used by ntlm_auth in it's 'basic' authentication
252 mode, as well as by pam_winbind to authenticate users where we are
253 given a plaintext password.
254*/
255
256static void check_machacc_recv(struct composite_context *ctx);
257
258NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
259{
260 NTSTATUS status;
261 struct cli_credentials *creds;
262 struct composite_context *ctx;
263 struct wbsrv_service *service =
264 s3call->wbconn->listen_socket->service;
265
266 /* Create a credentials structure */
267 creds = cli_credentials_init(s3call);
268 if (creds == NULL) {
269 return NT_STATUS_NO_MEMORY;
270 }
271
272 cli_credentials_set_conf(creds, service->task->lp_ctx);
273
274 /* Connect the machine account to the credentials */
275 status = cli_credentials_set_machine_account(creds, service->task->lp_ctx);
276 if (!NT_STATUS_IS_OK(status)) {
277 talloc_free(creds);
278 return status;
279 }
280
281 ctx = wb_cmd_pam_auth_send(s3call, service, creds);
282
283 if (!ctx) {
284 talloc_free(creds);
285 return NT_STATUS_NO_MEMORY;
286 }
287
288 ctx->async.fn = check_machacc_recv;
289 ctx->async.private_data = s3call;
290 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
291 return NT_STATUS_OK;
292}
293
294static void check_machacc_recv(struct composite_context *ctx)
295{
296 struct wbsrv_samba3_call *s3call =
297 talloc_get_type(ctx->async.private_data,
298 struct wbsrv_samba3_call);
299 NTSTATUS status;
300
301 status = wb_cmd_pam_auth_recv(ctx, s3call, NULL, NULL, NULL, NULL);
302
303 if (!NT_STATUS_IS_OK(status)) goto done;
304
305 done:
306 wbsrv_samba3_async_auth_epilogue(status, s3call);
307}
308
309/*
310 Find the name of a suitable domain controller, by query on the
311 netlogon pipe to the DC.
312*/
313
314static void getdcname_recv_dc(struct composite_context *ctx);
315
316NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
317{
318 struct composite_context *ctx;
319 struct wbsrv_service *service =
320 s3call->wbconn->listen_socket->service;
321
322 DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
323
324 ctx = wb_cmd_getdcname_send(s3call, service,
325 s3call->request->domain_name);
326 NT_STATUS_HAVE_NO_MEMORY(ctx);
327
328 ctx->async.fn = getdcname_recv_dc;
329 ctx->async.private_data = s3call;
330 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
331 return NT_STATUS_OK;
332}
333
334static void getdcname_recv_dc(struct composite_context *ctx)
335{
336 struct wbsrv_samba3_call *s3call =
337 talloc_get_type(ctx->async.private_data,
338 struct wbsrv_samba3_call);
339 const char *dcname;
340 NTSTATUS status;
341
342 status = wb_cmd_getdcname_recv(ctx, s3call, &dcname);
343 if (!NT_STATUS_IS_OK(status)) goto done;
344
345 s3call->response->result = WINBINDD_OK;
346 WBSRV_SAMBA3_SET_STRING(s3call->response->data.dc_name, dcname);
347
348 done:
349 wbsrv_samba3_async_epilogue(status, s3call);
350}
351
352/*
353 Lookup a user's domain groups
354*/
355
356static void userdomgroups_recv_groups(struct composite_context *ctx);
357
358NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
359{
360 struct composite_context *ctx;
361 struct dom_sid *sid;
362
363 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
364
365 sid = dom_sid_parse_talloc(s3call, s3call->request->data.sid);
366 if (sid == NULL) {
367 DEBUG(5, ("Could not parse sid %s\n",
368 s3call->request->data.sid));
369 return NT_STATUS_NO_MEMORY;
370 }
371
372 ctx = wb_cmd_userdomgroups_send(
373 s3call, s3call->wbconn->listen_socket->service, sid);
374 NT_STATUS_HAVE_NO_MEMORY(ctx);
375
376 ctx->async.fn = userdomgroups_recv_groups;
377 ctx->async.private_data = s3call;
378 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
379 return NT_STATUS_OK;
380}
381
382static void userdomgroups_recv_groups(struct composite_context *ctx)
383{
384 struct wbsrv_samba3_call *s3call =
385 talloc_get_type(ctx->async.private_data,
386 struct wbsrv_samba3_call);
387 uint32_t i, num_sids;
388 struct dom_sid **sids;
389 char *sids_string;
390 NTSTATUS status;
391
392 status = wb_cmd_userdomgroups_recv(ctx, s3call, &num_sids, &sids);
393 if (!NT_STATUS_IS_OK(status)) goto done;
394
395 sids_string = talloc_strdup(s3call, "");
396 if (sids_string == NULL) {
397 status = NT_STATUS_NO_MEMORY;
398 goto done;
399 }
400
401 for (i=0; i<num_sids; i++) {
402 sids_string = talloc_asprintf_append_buffer(
403 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
404 }
405
406 if (sids_string == NULL) {
407 status = NT_STATUS_NO_MEMORY;
408 goto done;
409 }
410
411 s3call->response->result = WINBINDD_OK;
412 s3call->response->extra_data.data = sids_string;
413 s3call->response->length += strlen(sids_string)+1;
414 s3call->response->data.num_entries = num_sids;
415
416 done:
417 wbsrv_samba3_async_epilogue(status, s3call);
418}
419
420/*
421 Lookup the list of SIDs for a user
422*/
423static void usersids_recv_sids(struct composite_context *ctx);
424
425NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call)
426{
427 struct composite_context *ctx;
428 struct dom_sid *sid;
429
430 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
431
432 sid = dom_sid_parse_talloc(s3call, s3call->request->data.sid);
433 if (sid == NULL) {
434 DEBUG(5, ("Could not parse sid %s\n",
435 s3call->request->data.sid));
436 return NT_STATUS_NO_MEMORY;
437 }
438
439 ctx = wb_cmd_usersids_send(
440 s3call, s3call->wbconn->listen_socket->service, sid);
441 NT_STATUS_HAVE_NO_MEMORY(ctx);
442
443 ctx->async.fn = usersids_recv_sids;
444 ctx->async.private_data = s3call;
445 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
446 return NT_STATUS_OK;
447}
448
449static void usersids_recv_sids(struct composite_context *ctx)
450{
451 struct wbsrv_samba3_call *s3call =
452 talloc_get_type(ctx->async.private_data,
453 struct wbsrv_samba3_call);
454 uint32_t i, num_sids;
455 struct dom_sid **sids;
456 char *sids_string;
457 NTSTATUS status;
458
459 status = wb_cmd_usersids_recv(ctx, s3call, &num_sids, &sids);
460 if (!NT_STATUS_IS_OK(status)) goto done;
461
462 sids_string = talloc_strdup(s3call, "");
463 if (sids_string == NULL) {
464 status = NT_STATUS_NO_MEMORY;
465 goto done;
466 }
467
468 for (i=0; i<num_sids; i++) {
469 sids_string = talloc_asprintf_append_buffer(
470 sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
471 if (sids_string == NULL) {
472 status = NT_STATUS_NO_MEMORY;
473 goto done;
474 }
475 }
476
477 s3call->response->result = WINBINDD_OK;
478 s3call->response->extra_data.data = sids_string;
479 s3call->response->length += strlen(sids_string);
480 s3call->response->data.num_entries = num_sids;
481
482 /* Hmmmm. Nasty protocol -- who invented the zeros between the
483 * SIDs? Hmmm. Could have been me -- vl */
484
485 while (*sids_string != '\0') {
486 if ((*sids_string) == '\n') {
487 *sids_string = '\0';
488 }
489 sids_string += 1;
490 }
491
492 done:
493 wbsrv_samba3_async_epilogue(status, s3call);
494}
495
496/*
497 Lookup a DOMAIN\\user style name, and return a SID
498*/
499
500static void lookupname_recv_sid(struct composite_context *ctx);
501
502NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
503{
504 struct composite_context *ctx;
505 struct wbsrv_service *service =
506 s3call->wbconn->listen_socket->service;
507
508 DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
509
510 ctx = wb_cmd_lookupname_send(s3call, service,
511 s3call->request->data.name.dom_name,
512 s3call->request->data.name.name);
513 NT_STATUS_HAVE_NO_MEMORY(ctx);
514
515 /* setup the callbacks */
516 ctx->async.fn = lookupname_recv_sid;
517 ctx->async.private_data = s3call;
518 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
519 return NT_STATUS_OK;
520}
521
522static void lookupname_recv_sid(struct composite_context *ctx)
523{
524 struct wbsrv_samba3_call *s3call =
525 talloc_get_type(ctx->async.private_data,
526 struct wbsrv_samba3_call);
527 struct wb_sid_object *sid;
528 NTSTATUS status;
529
530 status = wb_cmd_lookupname_recv(ctx, s3call, &sid);
531 if (!NT_STATUS_IS_OK(status)) goto done;
532
533 s3call->response->result = WINBINDD_OK;
534 s3call->response->data.sid.type = sid->type;
535 WBSRV_SAMBA3_SET_STRING(s3call->response->data.sid.sid,
536 dom_sid_string(s3call, sid->sid));
537
538 done:
539 wbsrv_samba3_async_epilogue(status, s3call);
540}
541
542/*
543 Lookup a SID, and return a DOMAIN\\user style name
544*/
545
546static void lookupsid_recv_name(struct composite_context *ctx);
547
548NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
549{
550 struct composite_context *ctx;
551 struct wbsrv_service *service =
552 s3call->wbconn->listen_socket->service;
553 struct dom_sid *sid;
554
555 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
556
557 sid = dom_sid_parse_talloc(s3call, s3call->request->data.sid);
558 if (sid == NULL) {
559 DEBUG(5, ("Could not parse sid %s\n",
560 s3call->request->data.sid));
561 return NT_STATUS_NO_MEMORY;
562 }
563
564 ctx = wb_cmd_lookupsid_send(s3call, service, sid);
565 NT_STATUS_HAVE_NO_MEMORY(ctx);
566
567 /* setup the callbacks */
568 ctx->async.fn = lookupsid_recv_name;
569 ctx->async.private_data = s3call;
570 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
571 return NT_STATUS_OK;
572}
573
574static void lookupsid_recv_name(struct composite_context *ctx)
575{
576 struct wbsrv_samba3_call *s3call =
577 talloc_get_type(ctx->async.private_data,
578 struct wbsrv_samba3_call);
579 struct wb_sid_object *sid;
580 NTSTATUS status;
581
582 status = wb_cmd_lookupsid_recv(ctx, s3call, &sid);
583 if (!NT_STATUS_IS_OK(status)) goto done;
584
585 s3call->response->result = WINBINDD_OK;
586 s3call->response->data.name.type = sid->type;
587 WBSRV_SAMBA3_SET_STRING(s3call->response->data.name.dom_name,
588 sid->domain);
589 WBSRV_SAMBA3_SET_STRING(s3call->response->data.name.name, sid->name);
590
591 done:
592 wbsrv_samba3_async_epilogue(status, s3call);
593}
594
595/*
596 This is a stub function in order to limit error message in the pam_winbind module
597*/
598NTSTATUS wbsrv_samba3_pam_logoff(struct wbsrv_samba3_call *s3call)
599{
600 NTSTATUS status;
601 struct winbindd_response *resp = s3call->response;
602
603 status = NT_STATUS_OK;
604
605 DEBUG(5, ("wbsrv_samba3_pam_logoff called\n"));
606 DEBUG(10, ("Winbind logoff not implemented\n"));
607 resp->result = WINBINDD_OK;
608
609 WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
610 nt_errstr(status));
611 WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
612 get_friendly_nt_error_msg(status));
613
614 resp->data.auth.pam_error = nt_status_to_pam(status);
615 resp->data.auth.nt_status = NT_STATUS_V(status);
616 DEBUG(5, ("wbsrv_samba3_pam_logoff called\n"));
617
618 return NT_STATUS_OK;
619}
620
621/*
622 Challenge-response authentication. This interface is used by
623 ntlm_auth and the smbd auth subsystem to pass NTLM authentication
624 requests along a common pipe to the domain controller.
625
626 The return value (in the async reply) may include the 'info3'
627 (effectivly most things you would want to know about the user), or
628 the NT and LM session keys seperated.
629*/
630
631static void pam_auth_crap_recv(struct composite_context *ctx);
632
633NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
634{
635 struct composite_context *ctx;
636 struct wbsrv_service *service =
637 s3call->wbconn->listen_socket->service;
638 DATA_BLOB chal, nt_resp, lm_resp;
639
640 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
641
642 chal.data = s3call->request->data.auth_crap.chal;
643 chal.length = sizeof(s3call->request->data.auth_crap.chal);
644 nt_resp.data = (uint8_t *)s3call->request->data.auth_crap.nt_resp;
645 nt_resp.length = s3call->request->data.auth_crap.nt_resp_len;
646 lm_resp.data = (uint8_t *)s3call->request->data.auth_crap.lm_resp;
647 lm_resp.length = s3call->request->data.auth_crap.lm_resp_len;
648
649 ctx = wb_cmd_pam_auth_crap_send(
650 s3call, service,
651 s3call->request->data.auth_crap.logon_parameters,
652 s3call->request->data.auth_crap.domain,
653 s3call->request->data.auth_crap.user,
654 s3call->request->data.auth_crap.workstation,
655 chal, nt_resp, lm_resp);
656 NT_STATUS_HAVE_NO_MEMORY(ctx);
657
658 ctx->async.fn = pam_auth_crap_recv;
659 ctx->async.private_data = s3call;
660 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
661 return NT_STATUS_OK;
662}
663
664static void pam_auth_crap_recv(struct composite_context *ctx)
665{
666 struct wbsrv_samba3_call *s3call =
667 talloc_get_type(ctx->async.private_data,
668 struct wbsrv_samba3_call);
669 NTSTATUS status;
670 DATA_BLOB info3;
671 struct netr_UserSessionKey user_session_key;
672 struct netr_LMSessionKey lm_key;
673 char *unix_username;
674
675 status = wb_cmd_pam_auth_crap_recv(ctx, s3call, &info3,
676 &user_session_key, &lm_key, &unix_username);
677 if (!NT_STATUS_IS_OK(status)) goto done;
678
679 if (s3call->request->flags & WBFLAG_PAM_USER_SESSION_KEY) {
680 memcpy(s3call->response->data.auth.user_session_key,
681 &user_session_key.key,
682 sizeof(s3call->response->data.auth.user_session_key));
683 }
684
685 if (s3call->request->flags & WBFLAG_PAM_INFO3_TEXT) {
686 status = wb_samba3_append_info3_as_txt(ctx, s3call, info3);
687 if (!NT_STATUS_IS_OK(status)) {
688 DEBUG(10,("Failed to append INFO3 (TXT): %s\n",
689 nt_errstr(status)));
690 goto done;
691 }
692 }
693
694 if (s3call->request->flags & WBFLAG_PAM_INFO3_NDR) {
695 s3call->response->extra_data.data = info3.data;
696 s3call->response->length += info3.length;
697 }
698
699 if (s3call->request->flags & WBFLAG_PAM_LMKEY) {
700 memcpy(s3call->response->data.auth.first_8_lm_hash,
701 lm_key.key,
702 sizeof(s3call->response->data.auth.first_8_lm_hash));
703 }
704
705 if (s3call->request->flags & WBFLAG_PAM_UNIX_NAME) {
706 WBSRV_SAMBA3_SET_STRING(s3call->response->data.auth.unix_username,unix_username);
707 }
708
709 done:
710 wbsrv_samba3_async_auth_epilogue(status, s3call);
711}
712
713/* Plaintext authentication
714
715 This interface is used by ntlm_auth in it's 'basic' authentication
716 mode, as well as by pam_winbind to authenticate users where we are
717 given a plaintext password.
718*/
719
720static void pam_auth_recv(struct composite_context *ctx);
721
722NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
723{
724 struct composite_context *ctx;
725 struct wbsrv_service *service =
726 s3call->wbconn->listen_socket->service;
727 struct cli_credentials *credentials;
728 char *user, *domain;
729
730 if (!wb_samba3_split_username(s3call, s3call->wbconn->lp_ctx,
731 s3call->request->data.auth.user,
732 &domain, &user)) {
733 return NT_STATUS_NO_SUCH_USER;
734 }
735
736 credentials = cli_credentials_init(s3call);
737 if (!credentials) {
738 return NT_STATUS_NO_MEMORY;
739 }
740 cli_credentials_set_conf(credentials, service->task->lp_ctx);
741 cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
742 cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
743
744 cli_credentials_set_password(credentials, s3call->request->data.auth.pass, CRED_SPECIFIED);
745
746 ctx = wb_cmd_pam_auth_send(s3call, service, credentials);
747 NT_STATUS_HAVE_NO_MEMORY(ctx);
748
749 ctx->async.fn = pam_auth_recv;
750 ctx->async.private_data = s3call;
751 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
752 return NT_STATUS_OK;
753}
754
755static void pam_auth_recv(struct composite_context *ctx)
756{
757 struct wbsrv_samba3_call *s3call =
758 talloc_get_type(ctx->async.private_data,
759 struct wbsrv_samba3_call);
760 NTSTATUS status;
761 DATA_BLOB info3;
762 struct netr_UserSessionKey user_session_key;
763 struct netr_LMSessionKey lm_key;
764 char *unix_username;
765
766 status = wb_cmd_pam_auth_recv(ctx, s3call, &info3,
767 &user_session_key, &lm_key, &unix_username);
768
769 if (!NT_STATUS_IS_OK(status)) goto done;
770
771 if (s3call->request->flags & WBFLAG_PAM_USER_SESSION_KEY) {
772 memcpy(s3call->response->data.auth.user_session_key,
773 &user_session_key.key,
774 sizeof(s3call->response->data.auth.user_session_key));
775 }
776
777 if (s3call->request->flags & WBFLAG_PAM_INFO3_TEXT) {
778 status = wb_samba3_append_info3_as_txt(ctx, s3call, info3);
779 if (!NT_STATUS_IS_OK(status)) {
780 DEBUG(10,("Failed to append INFO3 (TXT): %s\n",
781 nt_errstr(status)));
782 goto done;
783 }
784 }
785
786 if (s3call->request->flags & WBFLAG_PAM_INFO3_NDR) {
787 s3call->response->extra_data.data = info3.data;
788 s3call->response->length += info3.length;
789 }
790
791 if (s3call->request->flags & WBFLAG_PAM_LMKEY) {
792 memcpy(s3call->response->data.auth.first_8_lm_hash,
793 lm_key.key,
794 sizeof(s3call->response->data.auth.first_8_lm_hash));
795 }
796
797 if (s3call->request->flags & WBFLAG_PAM_UNIX_NAME) {
798 WBSRV_SAMBA3_SET_STRING(s3call->response->data.auth.unix_username,unix_username);
799 }
800
801
802 done:
803 wbsrv_samba3_async_auth_epilogue(status, s3call);
804}
805
806/*
807 List trusted domains
808*/
809
810static void list_trustdom_recv_doms(struct composite_context *ctx);
811
812NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
813{
814 struct composite_context *ctx;
815 struct wbsrv_service *service =
816 s3call->wbconn->listen_socket->service;
817
818 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
819
820 ctx = wb_cmd_list_trustdoms_send(s3call, service);
821 NT_STATUS_HAVE_NO_MEMORY(ctx);
822
823 ctx->async.fn = list_trustdom_recv_doms;
824 ctx->async.private_data = s3call;
825 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
826 return NT_STATUS_OK;
827}
828
829static void list_trustdom_recv_doms(struct composite_context *ctx)
830{
831 struct wbsrv_samba3_call *s3call =
832 talloc_get_type(ctx->async.private_data,
833 struct wbsrv_samba3_call);
834 uint32_t i, num_domains;
835 struct wb_dom_info **domains;
836 NTSTATUS status;
837 char *result;
838
839 status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
840 &domains);
841 if (!NT_STATUS_IS_OK(status)) goto done;
842
843 result = talloc_strdup(s3call, "");
844 if (result == NULL) {
845 status = NT_STATUS_NO_MEMORY;
846 goto done;
847 }
848
849 for (i=0; i<num_domains; i++) {
850 result = talloc_asprintf_append_buffer(
851 result, "%s\\%s\\%s",
852 domains[i]->name, domains[i]->name,
853 dom_sid_string(s3call, domains[i]->sid));
854 }
855
856 if (result == NULL) {
857 status = NT_STATUS_NO_MEMORY;
858 goto done;
859 }
860
861 s3call->response->result = WINBINDD_OK;
862 if (num_domains > 0) {
863 s3call->response->extra_data.data = result;
864 s3call->response->length += strlen(result)+1;
865 s3call->response->data.num_entries = num_domains;
866 }
867
868 done:
869 wbsrv_samba3_async_epilogue(status, s3call);
870}
871
872/* list groups */
873static void list_groups_recv(struct composite_context *ctx);
874
875NTSTATUS wbsrv_samba3_list_groups(struct wbsrv_samba3_call *s3call)
876{
877 struct composite_context *ctx;
878 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
879
880 DEBUG(5, ("wbsrv_samba4_list_groups called\n"));
881
882 ctx = wb_cmd_list_groups_send(s3call, service,
883 s3call->request->domain_name);
884 NT_STATUS_HAVE_NO_MEMORY(ctx);
885
886 ctx->async.fn = list_groups_recv;
887 ctx->async.private_data = s3call;
888 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
889 return NT_STATUS_OK;
890}
891
892static void list_groups_recv(struct composite_context *ctx)
893{
894 struct wbsrv_samba3_call *s3call = talloc_get_type_abort(
895 ctx->async.private_data,
896 struct wbsrv_samba3_call);
897 uint32_t extra_data_len;
898 char *extra_data;
899 uint32_t num_groups;
900 NTSTATUS status;
901
902 DEBUG(5, ("list_groups_recv called\n"));
903
904 status = wb_cmd_list_groups_recv(ctx, s3call, &extra_data_len,
905 &extra_data, &num_groups);
906
907 if (NT_STATUS_IS_OK(status)) {
908 s3call->response->extra_data.data = extra_data;
909 s3call->response->length += extra_data_len;
910 if (extra_data) {
911 s3call->response->length += 1;
912 s3call->response->data.num_entries = num_groups;
913 }
914 }
915
916 wbsrv_samba3_async_epilogue(status, s3call);
917}
918
919/* List users */
920
921static void list_users_recv(struct composite_context *ctx);
922
923NTSTATUS wbsrv_samba3_list_users(struct wbsrv_samba3_call *s3call)
924{
925 struct composite_context *ctx;
926 struct wbsrv_service *service =
927 s3call->wbconn->listen_socket->service;
928
929 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
930
931 ctx = wb_cmd_list_users_send(s3call, service,
932 s3call->request->domain_name);
933 NT_STATUS_HAVE_NO_MEMORY(ctx);
934
935 ctx->async.fn = list_users_recv;
936 ctx->async.private_data = s3call;
937 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
938 return NT_STATUS_OK;
939}
940
941static void list_users_recv(struct composite_context *ctx)
942{
943 struct wbsrv_samba3_call *s3call =
944 talloc_get_type(ctx->async.private_data,
945 struct wbsrv_samba3_call);
946 uint32_t extra_data_len;
947 char *extra_data;
948 uint32_t num_users;
949 NTSTATUS status;
950
951 DEBUG(5, ("list_users_recv called\n"));
952
953 status = wb_cmd_list_users_recv(ctx, s3call, &extra_data_len,
954 &extra_data, &num_users);
955
956 if (NT_STATUS_IS_OK(status)) {
957 s3call->response->extra_data.data = extra_data;
958 s3call->response->length += extra_data_len;
959 if (extra_data) {
960 s3call->response->length += 1;
961 s3call->response->data.num_entries = num_users;
962 }
963 }
964
965 wbsrv_samba3_async_epilogue(status, s3call);
966}
967
968/* NSS calls */
969
970static void getpwnam_recv(struct composite_context *ctx);
971
972NTSTATUS wbsrv_samba3_getpwnam(struct wbsrv_samba3_call *s3call)
973{
974 struct composite_context *ctx;
975 struct wbsrv_service *service =
976 s3call->wbconn->listen_socket->service;
977
978 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
979
980 ctx = wb_cmd_getpwnam_send(s3call, service,
981 s3call->request->data.username);
982 NT_STATUS_HAVE_NO_MEMORY(ctx);
983
984 ctx->async.fn = getpwnam_recv;
985 ctx->async.private_data = s3call;
986 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
987 return NT_STATUS_OK;
988}
989
990static void getpwnam_recv(struct composite_context *ctx)
991{
992 struct wbsrv_samba3_call *s3call =
993 talloc_get_type(ctx->async.private_data,
994 struct wbsrv_samba3_call);
995 NTSTATUS status;
996 struct winbindd_pw *pw;
997
998 DEBUG(5, ("getpwnam_recv called\n"));
999
1000 status = wb_cmd_getpwnam_recv(ctx, s3call, &pw);
1001 if(NT_STATUS_IS_OK(status))
1002 s3call->response->data.pw = *pw;
1003
1004 wbsrv_samba3_async_epilogue(status, s3call);
1005}
1006
1007static void getpwuid_recv(struct composite_context *ctx);
1008
1009NTSTATUS wbsrv_samba3_getpwuid(struct wbsrv_samba3_call *s3call)
1010{
1011 struct composite_context *ctx;
1012 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1013
1014 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
1015
1016 ctx = wb_cmd_getpwuid_send(s3call, service,
1017 s3call->request->data.uid);
1018 NT_STATUS_HAVE_NO_MEMORY(ctx);
1019
1020 ctx->async.fn = getpwuid_recv;
1021 ctx->async.private_data = s3call;
1022 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1023 return NT_STATUS_OK;
1024}
1025
1026static void getpwuid_recv(struct composite_context *ctx)
1027{
1028 struct wbsrv_samba3_call *s3call =
1029 talloc_get_type(ctx->async.private_data,
1030 struct wbsrv_samba3_call);
1031 NTSTATUS status;
1032 struct winbindd_pw *pw;
1033
1034 DEBUG(5, ("getpwuid_recv called\n"));
1035
1036 status = wb_cmd_getpwuid_recv(ctx, s3call, &pw);
1037 if (NT_STATUS_IS_OK(status))
1038 s3call->response->data.pw = *pw;
1039
1040 wbsrv_samba3_async_epilogue(status, s3call);
1041}
1042
1043static void setpwent_recv(struct composite_context *ctx);
1044
1045NTSTATUS wbsrv_samba3_setpwent(struct wbsrv_samba3_call *s3call)
1046{
1047 struct composite_context *ctx;
1048 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1049
1050 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
1051
1052 ctx = wb_cmd_setpwent_send(s3call, service);
1053 NT_STATUS_HAVE_NO_MEMORY(ctx);
1054
1055 ctx->async.fn = setpwent_recv;
1056 ctx->async.private_data = s3call;
1057 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1058 return NT_STATUS_OK;
1059}
1060
1061static void setpwent_recv(struct composite_context *ctx)
1062{
1063 struct wbsrv_samba3_call *s3call =
1064 talloc_get_type(ctx->async.private_data,
1065 struct wbsrv_samba3_call);
1066 NTSTATUS status;
1067 struct wbsrv_pwent *pwent;
1068
1069 DEBUG(5, ("setpwent_recv called\n"));
1070
1071 status = wb_cmd_setpwent_recv(ctx, s3call->wbconn, &pwent);
1072 if (NT_STATUS_IS_OK(status)) {
1073 s3call->wbconn->protocol_private_data = pwent;
1074 }
1075
1076 wbsrv_samba3_async_epilogue(status, s3call);
1077}
1078
1079static void getpwent_recv(struct composite_context *ctx);
1080
1081NTSTATUS wbsrv_samba3_getpwent(struct wbsrv_samba3_call *s3call)
1082{
1083 struct composite_context *ctx;
1084 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1085 struct wbsrv_pwent *pwent;
1086
1087 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
1088
1089 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
1090
1091 pwent = talloc_get_type(s3call->wbconn->protocol_private_data,
1092 struct wbsrv_pwent);
1093 NT_STATUS_HAVE_NO_MEMORY(pwent);
1094
1095 ctx = wb_cmd_getpwent_send(s3call, service, pwent,
1096 s3call->request->data.num_entries);
1097 NT_STATUS_HAVE_NO_MEMORY(ctx);
1098
1099 ctx->async.fn = getpwent_recv;
1100 ctx->async.private_data = s3call;
1101 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1102 return NT_STATUS_OK;
1103}
1104
1105static void getpwent_recv(struct composite_context *ctx)
1106{
1107 struct wbsrv_samba3_call *s3call =
1108 talloc_get_type(ctx->async.private_data,
1109 struct wbsrv_samba3_call);
1110 NTSTATUS status;
1111 struct winbindd_pw *pw;
1112 uint32_t num_users;
1113
1114 DEBUG(5, ("getpwent_recv called\n"));
1115
1116 status = wb_cmd_getpwent_recv(ctx, s3call, &pw, &num_users);
1117 if (NT_STATUS_IS_OK(status)) {
1118 uint32_t extra_len = sizeof(struct winbindd_pw) * num_users;
1119
1120 s3call->response->data.num_entries = num_users;
1121 s3call->response->extra_data.data = pw;
1122 s3call->response->length += extra_len;
1123 }
1124
1125 wbsrv_samba3_async_epilogue(status, s3call);
1126}
1127
1128NTSTATUS wbsrv_samba3_endpwent(struct wbsrv_samba3_call *s3call)
1129{
1130 struct wbsrv_pwent *pwent =
1131 talloc_get_type(s3call->wbconn->protocol_private_data,
1132 struct wbsrv_pwent);
1133 DEBUG(5, ("wbsrv_samba3_endpwent called\n"));
1134
1135 talloc_free(pwent);
1136
1137 s3call->wbconn->protocol_private_data = NULL;
1138 s3call->response->result = WINBINDD_OK;
1139 return NT_STATUS_OK;
1140}
1141
1142
1143static void getgrnam_recv(struct composite_context *ctx);
1144
1145NTSTATUS wbsrv_samba3_getgrnam(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_getgrnam called\n"));
1152
1153 ctx = wb_cmd_getgrnam_send(s3call, service,
1154 s3call->request->data.groupname);
1155 NT_STATUS_HAVE_NO_MEMORY(ctx);
1156
1157 ctx->async.fn = getgrnam_recv;
1158 ctx->async.private_data = s3call;
1159 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1160 return NT_STATUS_OK;
1161}
1162
1163static void getgrnam_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 winbindd_gr *gr;
1170
1171 DEBUG(5, ("getgrnam_recv called\n"));
1172
1173 status = wb_cmd_getgrnam_recv(ctx, s3call, &gr);
1174 if(NT_STATUS_IS_OK(status))
1175 s3call->response->data.gr = *gr;
1176
1177 wbsrv_samba3_async_epilogue(status, s3call);
1178}
1179
1180static void getgrgid_recv(struct composite_context *ctx);
1181
1182NTSTATUS wbsrv_samba3_getgrgid(struct wbsrv_samba3_call *s3call)
1183{
1184 struct composite_context *ctx;
1185 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1186
1187 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
1188
1189 ctx = wb_cmd_getgrgid_send(s3call, service,
1190 s3call->request->data.gid);
1191 NT_STATUS_HAVE_NO_MEMORY(ctx);
1192
1193 ctx->async.fn = getgrgid_recv;
1194 ctx->async.private_data = s3call;
1195 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1196 return NT_STATUS_OK;
1197}
1198
1199static void getgrgid_recv(struct composite_context *ctx)
1200{
1201 struct wbsrv_samba3_call *s3call =
1202 talloc_get_type(ctx->async.private_data,
1203 struct wbsrv_samba3_call);
1204 NTSTATUS status;
1205 struct winbindd_gr *gr;
1206
1207 DEBUG(5, ("getgrgid_recv called\n"));
1208
1209 status = wb_cmd_getgrgid_recv(ctx, s3call, &gr);
1210 if (NT_STATUS_IS_OK(status))
1211 s3call->response->data.gr = *gr;
1212
1213 wbsrv_samba3_async_epilogue(status, s3call);
1214}
1215
1216static void getgroups_recv(struct composite_context *ctx);
1217
1218NTSTATUS wbsrv_samba3_getgroups(struct wbsrv_samba3_call *s3call)
1219{
1220 struct composite_context *ctx;
1221 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1222
1223 DEBUG(5, ("wbsrv_samba3_getgroups called\n"));
1224 /* S3 code do the same so why not ... */
1225 s3call->request->data.username[sizeof(s3call->request->data.username)-1]='\0';
1226 ctx = wb_cmd_getgroups_send(s3call, service, s3call->request->data.username);
1227 NT_STATUS_HAVE_NO_MEMORY(ctx);
1228
1229 ctx->async.fn = getgroups_recv;
1230 ctx->async.private_data = s3call;
1231 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1232 return NT_STATUS_OK;
1233}
1234
1235static void getgroups_recv(struct composite_context *ctx)
1236{
1237 struct wbsrv_samba3_call *s3call =
1238 talloc_get_type(ctx->async.private_data,
1239 struct wbsrv_samba3_call);
1240 gid_t *gids;
1241 uint32_t num_groups;
1242 NTSTATUS status;
1243 DEBUG(5, ("getgroups_recv called\n"));
1244
1245 status = wb_cmd_getgroups_recv(ctx, s3call, &gids, &num_groups);
1246 if (NT_STATUS_IS_OK(status)) {
1247 uint32_t extra_len = sizeof(gid_t) * num_groups;
1248
1249 s3call->response->data.num_entries = num_groups;
1250 s3call->response->extra_data.data = gids;
1251 s3call->response->length += extra_len;
1252 } else {
1253 s3call->response->result = WINBINDD_ERROR;
1254 }
1255
1256 wbsrv_samba3_async_epilogue(status, s3call);
1257}
1258
1259static void setgrent_recv(struct composite_context *ctx);
1260
1261NTSTATUS wbsrv_samba3_setgrent(struct wbsrv_samba3_call *s3call)
1262{
1263 struct composite_context *ctx;
1264 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1265
1266 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
1267
1268 ctx = wb_cmd_setgrent_send(s3call, service);
1269 NT_STATUS_HAVE_NO_MEMORY(ctx);
1270
1271 ctx->async.fn = setgrent_recv;
1272 ctx->async.private_data = s3call;
1273 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1274 return NT_STATUS_OK;
1275}
1276
1277static void setgrent_recv(struct composite_context *ctx)
1278{
1279 struct wbsrv_samba3_call *s3call =
1280 talloc_get_type(ctx->async.private_data,
1281 struct wbsrv_samba3_call);
1282 NTSTATUS status;
1283 struct wbsrv_grent *grent;
1284
1285 DEBUG(5, ("setpwent_recv called\n"));
1286
1287 status = wb_cmd_setgrent_recv(ctx, s3call->wbconn, &grent);
1288 if (NT_STATUS_IS_OK(status)) {
1289 s3call->wbconn->protocol_private_data = grent;
1290 }
1291
1292 wbsrv_samba3_async_epilogue(status, s3call);
1293}
1294
1295static void getgrent_recv(struct composite_context *ctx);
1296
1297NTSTATUS wbsrv_samba3_getgrent(struct wbsrv_samba3_call *s3call)
1298{
1299 struct composite_context *ctx;
1300 struct wbsrv_service *service = s3call->wbconn->listen_socket->service;
1301 struct wbsrv_grent *grent;
1302
1303 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
1304
1305 NT_STATUS_HAVE_NO_MEMORY(s3call->wbconn->protocol_private_data);
1306
1307 grent = talloc_get_type(s3call->wbconn->protocol_private_data,
1308 struct wbsrv_grent);
1309 NT_STATUS_HAVE_NO_MEMORY(grent);
1310
1311 ctx = wb_cmd_getgrent_send(s3call, service, grent,
1312 s3call->request->data.num_entries);
1313 NT_STATUS_HAVE_NO_MEMORY(ctx);
1314
1315 ctx->async.fn = getgrent_recv;
1316 ctx->async.private_data = s3call;
1317 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1318 return NT_STATUS_OK;
1319}
1320
1321static void getgrent_recv(struct composite_context *ctx)
1322{
1323 struct wbsrv_samba3_call *s3call =
1324 talloc_get_type(ctx->async.private_data,
1325 struct wbsrv_samba3_call);
1326 NTSTATUS status;
1327 struct winbindd_gr *gr;
1328 uint32_t num_groups;
1329
1330 DEBUG(5, ("getgrent_recv called\n"));
1331
1332 status = wb_cmd_getgrent_recv(ctx, s3call, &gr, &num_groups);
1333 if (NT_STATUS_IS_OK(status)) {
1334 uint32_t extra_len = sizeof(struct winbindd_gr) * num_groups;
1335
1336 s3call->response->data.num_entries = num_groups;
1337 s3call->response->extra_data.data = gr;
1338 s3call->response->length += extra_len;
1339 }
1340
1341 wbsrv_samba3_async_epilogue(status, s3call);
1342}
1343
1344NTSTATUS wbsrv_samba3_endgrent(struct wbsrv_samba3_call *s3call)
1345{
1346 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
1347 s3call->response->result = WINBINDD_OK;
1348 return NT_STATUS_OK;
1349}
1350
1351static void sid2uid_recv(struct composite_context *ctx);
1352
1353NTSTATUS wbsrv_samba3_sid2uid(struct wbsrv_samba3_call *s3call)
1354{
1355 struct composite_context *ctx;
1356 struct wbsrv_service *service =
1357 s3call->wbconn->listen_socket->service;
1358 struct dom_sid *sid;
1359
1360 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
1361
1362 sid = dom_sid_parse_talloc(s3call, s3call->request->data.sid);
1363 NT_STATUS_HAVE_NO_MEMORY(sid);
1364
1365 ctx = wb_sid2uid_send(s3call, service, sid);
1366 NT_STATUS_HAVE_NO_MEMORY(ctx);
1367
1368 ctx->async.fn = sid2uid_recv;
1369 ctx->async.private_data = s3call;
1370 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1371 return NT_STATUS_OK;
1372
1373}
1374
1375static void sid2uid_recv(struct composite_context *ctx)
1376{
1377 struct wbsrv_samba3_call *s3call =
1378 talloc_get_type(ctx->async.private_data,
1379 struct wbsrv_samba3_call);
1380 NTSTATUS status;
1381
1382 DEBUG(5, ("sid2uid_recv called\n"));
1383
1384 status = wb_sid2uid_recv(ctx, &s3call->response->data.uid);
1385
1386 wbsrv_samba3_async_epilogue(status, s3call);
1387}
1388
1389static void sid2gid_recv(struct composite_context *ctx);
1390
1391NTSTATUS wbsrv_samba3_sid2gid(struct wbsrv_samba3_call *s3call)
1392{
1393 struct composite_context *ctx;
1394 struct wbsrv_service *service =
1395 s3call->wbconn->listen_socket->service;
1396 struct dom_sid *sid;
1397
1398 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
1399
1400 sid = dom_sid_parse_talloc(s3call, s3call->request->data.sid);
1401 NT_STATUS_HAVE_NO_MEMORY(sid);
1402
1403 ctx = wb_sid2gid_send(s3call, service, sid);
1404 NT_STATUS_HAVE_NO_MEMORY(ctx);
1405
1406 ctx->async.fn = sid2gid_recv;
1407 ctx->async.private_data = s3call;
1408 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1409 return NT_STATUS_OK;
1410
1411}
1412
1413static void sid2gid_recv(struct composite_context *ctx)
1414{
1415 struct wbsrv_samba3_call *s3call =
1416 talloc_get_type(ctx->async.private_data,
1417 struct wbsrv_samba3_call);
1418 NTSTATUS status;
1419
1420 DEBUG(5, ("sid2gid_recv called\n"));
1421
1422 status = wb_sid2gid_recv(ctx, &s3call->response->data.gid);
1423
1424 wbsrv_samba3_async_epilogue(status, s3call);
1425}
1426
1427static void uid2sid_recv(struct composite_context *ctx);
1428
1429NTSTATUS wbsrv_samba3_uid2sid(struct wbsrv_samba3_call *s3call)
1430{
1431 struct composite_context *ctx;
1432 struct wbsrv_service *service =
1433 s3call->wbconn->listen_socket->service;
1434
1435 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1436
1437 ctx = wb_uid2sid_send(s3call, service, s3call->request->data.uid);
1438 NT_STATUS_HAVE_NO_MEMORY(ctx);
1439
1440 ctx->async.fn = uid2sid_recv;
1441 ctx->async.private_data = s3call;
1442 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1443 return NT_STATUS_OK;
1444
1445}
1446
1447static void uid2sid_recv(struct composite_context *ctx)
1448{
1449 struct wbsrv_samba3_call *s3call =
1450 talloc_get_type(ctx->async.private_data,
1451 struct wbsrv_samba3_call);
1452 NTSTATUS status;
1453 struct dom_sid *sid;
1454 char *sid_str;
1455
1456 DEBUG(5, ("uid2sid_recv called\n"));
1457
1458 status = wb_uid2sid_recv(ctx, s3call, &sid);
1459 if(NT_STATUS_IS_OK(status)) {
1460 sid_str = dom_sid_string(s3call, sid);
1461
1462 /* If the conversion failed, bail out with a failure. */
1463 if (sid_str == NULL)
1464 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1465
1466 /* But we assume this worked, so we'll set the string. Work
1467 * done. */
1468 WBSRV_SAMBA3_SET_STRING(s3call->response->data.sid.sid, sid_str);
1469 s3call->response->data.sid.type = SID_NAME_USER;
1470 }
1471
1472 wbsrv_samba3_async_epilogue(status, s3call);
1473}
1474
1475static void gid2sid_recv(struct composite_context *ctx);
1476
1477NTSTATUS wbsrv_samba3_gid2sid(struct wbsrv_samba3_call *s3call)
1478{
1479 struct composite_context *ctx;
1480 struct wbsrv_service *service =
1481 s3call->wbconn->listen_socket->service;
1482
1483 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1484
1485 ctx = wb_gid2sid_send(s3call, service, s3call->request->data.gid);
1486 NT_STATUS_HAVE_NO_MEMORY(ctx);
1487
1488 ctx->async.fn = gid2sid_recv;
1489 ctx->async.private_data = s3call;
1490 s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
1491 return NT_STATUS_OK;
1492
1493}
1494
1495static void gid2sid_recv(struct composite_context *ctx)
1496{
1497 struct wbsrv_samba3_call *s3call =
1498 talloc_get_type(ctx->async.private_data,
1499 struct wbsrv_samba3_call);
1500 NTSTATUS status;
1501 struct dom_sid *sid;
1502 char *sid_str;
1503
1504 DEBUG(5, ("gid2sid_recv called\n"));
1505
1506 status = wb_gid2sid_recv(ctx, s3call, &sid);
1507 if(NT_STATUS_IS_OK(status)) {
1508 sid_str = dom_sid_string(s3call, sid);
1509
1510 if (sid_str == NULL)
1511 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY,s3call);
1512
1513 WBSRV_SAMBA3_SET_STRING(s3call->response->data.sid.sid, sid_str);
1514 s3call->response->data.sid.type = SID_NAME_DOMAIN;
1515 }
1516
1517 wbsrv_samba3_async_epilogue(status, s3call);
1518}
1519
Note: See TracBrowser for help on using the repository browser.