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/>.
25 #include "winbind/wb_server.h"
26 #include "param/param.h"
27 #include "winbind/wb_helper.h"
28 #include "libcli/composite/composite.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"
37 support the old Samba3 TXT form of the info3
39 static NTSTATUS
wb_samba3_append_info3_as_txt(TALLOC_CTX
*mem_ctx
,
40 struct wbsrv_samba3_call
*s3call
,
43 struct netr_SamInfo3
*info3
;
46 enum ndr_err_code ndr_err
;
48 info3
= talloc(mem_ctx
, struct netr_SamInfo3
);
49 NT_STATUS_HAVE_NO_MEMORY(info3
);
51 /* The Samba3 protocol has a redundant 4 bytes at the start */
55 ndr_err
= ndr_pull_struct_blob(&info3b
,
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
);
63 s3call
->response
->data
.auth
.info3
.logon_time
=
64 nt_time_to_unix(info3
->base
.logon_time
);
65 s3call
->response
->data
.auth
.info3
.logoff_time
=
66 nt_time_to_unix(info3
->base
.logoff_time
);
67 s3call
->response
->data
.auth
.info3
.kickoff_time
=
68 nt_time_to_unix(info3
->base
.kickoff_time
);
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
);
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
;
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
));
83 s3call
->response
->data
.auth
.info3
.num_groups
= info3
->base
.groups
.count
;
84 s3call
->response
->data
.auth
.info3
.user_flgs
= info3
->base
.user_flags
;
86 s3call
->response
->data
.auth
.info3
.acct_flags
= info3
->base
.acct_flags
;
87 s3call
->response
->data
.auth
.info3
.num_other_sids
= info3
->sidcount
;
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
);
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
.logon_domain
.string
);
107 ex
= talloc_strdup(mem_ctx
, "");
108 NT_STATUS_HAVE_NO_MEMORY(ex
);
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
);
117 for (i
=0; i
< info3
->sidcount
; i
++) {
120 sid
= dom_sid_string(mem_ctx
, info3
->sids
[i
].sid
);
121 NT_STATUS_HAVE_NO_MEMORY(sid
);
123 ex
= talloc_asprintf_append_buffer(ex
, "%s:0x%08X\n",
125 info3
->sids
[i
].attributes
);
126 NT_STATUS_HAVE_NO_MEMORY(ex
);
131 s3call
->response
->extra_data
.data
= ex
;
132 s3call
->response
->length
+= talloc_get_size(ex
);
138 Send off the reply to an async Samba3 query, handling filling in the PAM, NTSTATUS and string errors.
141 static void wbsrv_samba3_async_auth_epilogue(NTSTATUS status
,
142 struct wbsrv_samba3_call
*s3call
)
144 struct winbindd_response
*resp
= s3call
->response
;
145 if (!NT_STATUS_IS_OK(status
)) {
146 resp
->result
= WINBINDD_ERROR
;
148 resp
->result
= WINBINDD_OK
;
151 WBSRV_SAMBA3_SET_STRING(resp
->data
.auth
.nt_status_string
,
153 WBSRV_SAMBA3_SET_STRING(resp
->data
.auth
.error_string
,
154 get_friendly_nt_error_msg(status
));
156 resp
->data
.auth
.pam_error
= nt_status_to_pam(status
);
157 resp
->data
.auth
.nt_status
= NT_STATUS_V(status
);
159 wbsrv_samba3_send_reply(s3call
);
163 Send of a generic reply to a Samba3 query
166 static void wbsrv_samba3_async_epilogue(NTSTATUS status
,
167 struct wbsrv_samba3_call
*s3call
)
169 struct winbindd_response
*resp
= s3call
->response
;
170 if (NT_STATUS_IS_OK(status
)) {
171 resp
->result
= WINBINDD_OK
;
173 resp
->result
= WINBINDD_ERROR
;
176 wbsrv_samba3_send_reply(s3call
);
180 Boilerplate commands, simple queries without network traffic
183 NTSTATUS
wbsrv_samba3_interface_version(struct wbsrv_samba3_call
*s3call
)
185 s3call
->response
->result
= WINBINDD_OK
;
186 s3call
->response
->data
.interface_version
= WINBIND_INTERFACE_VERSION
;
190 NTSTATUS
wbsrv_samba3_info(struct wbsrv_samba3_call
*s3call
)
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
);
199 NTSTATUS
wbsrv_samba3_domain_name(struct wbsrv_samba3_call
*s3call
)
201 s3call
->response
->result
= WINBINDD_OK
;
202 WBSRV_SAMBA3_SET_STRING(s3call
->response
->data
.domain_name
,
203 lpcfg_workgroup(s3call
->wbconn
->lp_ctx
));
207 NTSTATUS
wbsrv_samba3_netbios_name(struct wbsrv_samba3_call
*s3call
)
209 s3call
->response
->result
= WINBINDD_OK
;
210 WBSRV_SAMBA3_SET_STRING(s3call
->response
->data
.netbios_name
,
211 lpcfg_netbios_name(s3call
->wbconn
->lp_ctx
));
215 NTSTATUS
wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call
*s3call
)
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
);
220 s3call
->response
->result
= WINBINDD_OK
;
221 s3call
->response
->extra_data
.data
= discard_const(priv_socket_dir
);
223 s3call
->response
->length
+= strlen(priv_socket_dir
) + 1;
227 NTSTATUS
wbsrv_samba3_ping(struct wbsrv_samba3_call
*s3call
)
229 s3call
->response
->result
= WINBINDD_OK
;
233 NTSTATUS
wbsrv_samba3_domain_info(struct wbsrv_samba3_call
*s3call
)
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;
249 /* Plaintext authentication
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.
256 static void check_machacc_recv(struct composite_context
*ctx
);
258 NTSTATUS
wbsrv_samba3_check_machacc(struct wbsrv_samba3_call
*s3call
)
261 struct cli_credentials
*creds
;
262 struct composite_context
*ctx
;
263 struct wbsrv_service
*service
=
264 s3call
->wbconn
->listen_socket
->service
;
266 /* Create a credentials structure */
267 creds
= cli_credentials_init(s3call
);
269 return NT_STATUS_NO_MEMORY
;
272 cli_credentials_set_conf(creds
, service
->task
->lp_ctx
);
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
)) {
281 ctx
= wb_cmd_pam_auth_send(s3call
, service
, creds
);
285 return NT_STATUS_NO_MEMORY
;
288 ctx
->async
.fn
= check_machacc_recv
;
289 ctx
->async
.private_data
= s3call
;
290 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
294 static void check_machacc_recv(struct composite_context
*ctx
)
296 struct wbsrv_samba3_call
*s3call
=
297 talloc_get_type(ctx
->async
.private_data
,
298 struct wbsrv_samba3_call
);
301 status
= wb_cmd_pam_auth_recv(ctx
, s3call
, NULL
, NULL
, NULL
, NULL
);
303 if (!NT_STATUS_IS_OK(status
)) goto done
;
306 wbsrv_samba3_async_auth_epilogue(status
, s3call
);
310 Find the name of a suitable domain controller, by query on the
311 netlogon pipe to the DC.
314 static void getdcname_recv_dc(struct composite_context
*ctx
);
316 NTSTATUS
wbsrv_samba3_getdcname(struct wbsrv_samba3_call
*s3call
)
318 struct composite_context
*ctx
;
319 struct wbsrv_service
*service
=
320 s3call
->wbconn
->listen_socket
->service
;
322 DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
324 ctx
= wb_cmd_getdcname_send(s3call
, service
,
325 s3call
->request
->domain_name
);
326 NT_STATUS_HAVE_NO_MEMORY(ctx
);
328 ctx
->async
.fn
= getdcname_recv_dc
;
329 ctx
->async
.private_data
= s3call
;
330 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
334 static void getdcname_recv_dc(struct composite_context
*ctx
)
336 struct wbsrv_samba3_call
*s3call
=
337 talloc_get_type(ctx
->async
.private_data
,
338 struct wbsrv_samba3_call
);
342 status
= wb_cmd_getdcname_recv(ctx
, s3call
, &dcname
);
343 if (!NT_STATUS_IS_OK(status
)) goto done
;
345 s3call
->response
->result
= WINBINDD_OK
;
346 WBSRV_SAMBA3_SET_STRING(s3call
->response
->data
.dc_name
, dcname
);
349 wbsrv_samba3_async_epilogue(status
, s3call
);
353 Lookup a user's domain groups
356 static void userdomgroups_recv_groups(struct composite_context
*ctx
);
358 NTSTATUS
wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call
*s3call
)
360 struct composite_context
*ctx
;
363 DEBUG(5, ("wbsrv_samba3_userdomgroups called\n"));
365 sid
= dom_sid_parse_talloc(s3call
, s3call
->request
->data
.sid
);
367 DEBUG(5, ("Could not parse sid %s\n",
368 s3call
->request
->data
.sid
));
369 return NT_STATUS_NO_MEMORY
;
372 ctx
= wb_cmd_userdomgroups_send(
373 s3call
, s3call
->wbconn
->listen_socket
->service
, sid
);
374 NT_STATUS_HAVE_NO_MEMORY(ctx
);
376 ctx
->async
.fn
= userdomgroups_recv_groups
;
377 ctx
->async
.private_data
= s3call
;
378 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
382 static void userdomgroups_recv_groups(struct composite_context
*ctx
)
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
;
392 status
= wb_cmd_userdomgroups_recv(ctx
, s3call
, &num_sids
, &sids
);
393 if (!NT_STATUS_IS_OK(status
)) goto done
;
395 sids_string
= talloc_strdup(s3call
, "");
396 if (sids_string
== NULL
) {
397 status
= NT_STATUS_NO_MEMORY
;
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
]));
406 if (sids_string
== NULL
) {
407 status
= NT_STATUS_NO_MEMORY
;
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
;
417 wbsrv_samba3_async_epilogue(status
, s3call
);
421 Lookup the list of SIDs for a user
423 static void usersids_recv_sids(struct composite_context
*ctx
);
425 NTSTATUS
wbsrv_samba3_usersids(struct wbsrv_samba3_call
*s3call
)
427 struct composite_context
*ctx
;
430 DEBUG(5, ("wbsrv_samba3_usersids called\n"));
432 sid
= dom_sid_parse_talloc(s3call
, s3call
->request
->data
.sid
);
434 DEBUG(5, ("Could not parse sid %s\n",
435 s3call
->request
->data
.sid
));
436 return NT_STATUS_NO_MEMORY
;
439 ctx
= wb_cmd_usersids_send(
440 s3call
, s3call
->wbconn
->listen_socket
->service
, sid
);
441 NT_STATUS_HAVE_NO_MEMORY(ctx
);
443 ctx
->async
.fn
= usersids_recv_sids
;
444 ctx
->async
.private_data
= s3call
;
445 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
449 static void usersids_recv_sids(struct composite_context
*ctx
)
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
;
459 status
= wb_cmd_usersids_recv(ctx
, s3call
, &num_sids
, &sids
);
460 if (!NT_STATUS_IS_OK(status
)) goto done
;
462 sids_string
= talloc_strdup(s3call
, "");
463 if (sids_string
== NULL
) {
464 status
= NT_STATUS_NO_MEMORY
;
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
;
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
;
482 /* Hmmmm. Nasty protocol -- who invented the zeros between the
483 * SIDs? Hmmm. Could have been me -- vl */
485 while (*sids_string
!= '\0') {
486 if ((*sids_string
) == '\n') {
493 wbsrv_samba3_async_epilogue(status
, s3call
);
497 Lookup a DOMAIN\\user style name, and return a SID
500 static void lookupname_recv_sid(struct composite_context
*ctx
);
502 NTSTATUS
wbsrv_samba3_lookupname(struct wbsrv_samba3_call
*s3call
)
504 struct composite_context
*ctx
;
505 struct wbsrv_service
*service
=
506 s3call
->wbconn
->listen_socket
->service
;
508 DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
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
);
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
;
522 static void lookupname_recv_sid(struct composite_context
*ctx
)
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
;
530 status
= wb_cmd_lookupname_recv(ctx
, s3call
, &sid
);
531 if (!NT_STATUS_IS_OK(status
)) goto done
;
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
));
539 wbsrv_samba3_async_epilogue(status
, s3call
);
543 Lookup a SID, and return a DOMAIN\\user style name
546 static void lookupsid_recv_name(struct composite_context
*ctx
);
548 NTSTATUS
wbsrv_samba3_lookupsid(struct wbsrv_samba3_call
*s3call
)
550 struct composite_context
*ctx
;
551 struct wbsrv_service
*service
=
552 s3call
->wbconn
->listen_socket
->service
;
555 DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
557 sid
= dom_sid_parse_talloc(s3call
, s3call
->request
->data
.sid
);
559 DEBUG(5, ("Could not parse sid %s\n",
560 s3call
->request
->data
.sid
));
561 return NT_STATUS_NO_MEMORY
;
564 ctx
= wb_cmd_lookupsid_send(s3call
, service
, sid
);
565 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
574 static void lookupsid_recv_name(struct composite_context
*ctx
)
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
;
582 status
= wb_cmd_lookupsid_recv(ctx
, s3call
, &sid
);
583 if (!NT_STATUS_IS_OK(status
)) goto done
;
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
,
589 WBSRV_SAMBA3_SET_STRING(s3call
->response
->data
.name
.name
, sid
->name
);
592 wbsrv_samba3_async_epilogue(status
, s3call
);
596 This is a stub function in order to limit error message in the pam_winbind module
598 NTSTATUS
wbsrv_samba3_pam_logoff(struct wbsrv_samba3_call
*s3call
)
601 struct winbindd_response
*resp
= s3call
->response
;
603 status
= NT_STATUS_OK
;
605 DEBUG(5, ("wbsrv_samba3_pam_logoff called\n"));
606 DEBUG(10, ("Winbind logoff not implemented\n"));
607 resp
->result
= WINBINDD_OK
;
609 WBSRV_SAMBA3_SET_STRING(resp
->data
.auth
.nt_status_string
,
611 WBSRV_SAMBA3_SET_STRING(resp
->data
.auth
.error_string
,
612 get_friendly_nt_error_msg(status
));
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"));
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.
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 separated.
631 static void pam_auth_crap_recv(struct composite_context
*ctx
);
633 NTSTATUS
wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call
*s3call
)
635 struct composite_context
*ctx
;
636 struct wbsrv_service
*service
=
637 s3call
->wbconn
->listen_socket
->service
;
638 DATA_BLOB chal
, nt_resp
, lm_resp
;
640 DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
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
;
649 ctx
= wb_cmd_pam_auth_crap_send(
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
);
658 ctx
->async
.fn
= pam_auth_crap_recv
;
659 ctx
->async
.private_data
= s3call
;
660 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
664 static void pam_auth_crap_recv(struct composite_context
*ctx
)
666 struct wbsrv_samba3_call
*s3call
=
667 talloc_get_type(ctx
->async
.private_data
,
668 struct wbsrv_samba3_call
);
671 struct netr_UserSessionKey user_session_key
;
672 struct netr_LMSessionKey lm_key
;
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
;
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
));
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",
694 if (s3call
->request
->flags
& WBFLAG_PAM_INFO3_NDR
) {
695 s3call
->response
->extra_data
.data
= info3
.data
;
696 s3call
->response
->length
+= info3
.length
;
699 if (s3call
->request
->flags
& WBFLAG_PAM_LMKEY
) {
700 memcpy(s3call
->response
->data
.auth
.first_8_lm_hash
,
702 sizeof(s3call
->response
->data
.auth
.first_8_lm_hash
));
705 if (s3call
->request
->flags
& WBFLAG_PAM_UNIX_NAME
) {
706 WBSRV_SAMBA3_SET_STRING(s3call
->response
->data
.auth
.unix_username
,unix_username
);
710 wbsrv_samba3_async_auth_epilogue(status
, s3call
);
713 /* Plaintext authentication
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.
720 static void pam_auth_recv(struct composite_context
*ctx
);
722 NTSTATUS
wbsrv_samba3_pam_auth(struct wbsrv_samba3_call
*s3call
)
724 struct composite_context
*ctx
;
725 struct wbsrv_service
*service
=
726 s3call
->wbconn
->listen_socket
->service
;
727 struct cli_credentials
*credentials
;
730 if (!wb_samba3_split_username(s3call
, s3call
->wbconn
->lp_ctx
,
731 s3call
->request
->data
.auth
.user
,
733 return NT_STATUS_NO_SUCH_USER
;
736 credentials
= cli_credentials_init(s3call
);
738 return NT_STATUS_NO_MEMORY
;
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
);
744 cli_credentials_set_password(credentials
, s3call
->request
->data
.auth
.pass
, CRED_SPECIFIED
);
746 ctx
= wb_cmd_pam_auth_send(s3call
, service
, credentials
);
747 NT_STATUS_HAVE_NO_MEMORY(ctx
);
749 ctx
->async
.fn
= pam_auth_recv
;
750 ctx
->async
.private_data
= s3call
;
751 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
755 static void pam_auth_recv(struct composite_context
*ctx
)
757 struct wbsrv_samba3_call
*s3call
=
758 talloc_get_type(ctx
->async
.private_data
,
759 struct wbsrv_samba3_call
);
762 struct netr_UserSessionKey user_session_key
;
763 struct netr_LMSessionKey lm_key
;
766 status
= wb_cmd_pam_auth_recv(ctx
, s3call
, &info3
,
767 &user_session_key
, &lm_key
, &unix_username
);
769 if (!NT_STATUS_IS_OK(status
)) goto done
;
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
));
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",
786 if (s3call
->request
->flags
& WBFLAG_PAM_INFO3_NDR
) {
787 s3call
->response
->extra_data
.data
= info3
.data
;
788 s3call
->response
->length
+= info3
.length
;
791 if (s3call
->request
->flags
& WBFLAG_PAM_LMKEY
) {
792 memcpy(s3call
->response
->data
.auth
.first_8_lm_hash
,
794 sizeof(s3call
->response
->data
.auth
.first_8_lm_hash
));
797 if (s3call
->request
->flags
& WBFLAG_PAM_UNIX_NAME
) {
798 WBSRV_SAMBA3_SET_STRING(s3call
->response
->data
.auth
.unix_username
,unix_username
);
803 wbsrv_samba3_async_auth_epilogue(status
, s3call
);
810 static void list_trustdom_recv_doms(struct composite_context
*ctx
);
812 NTSTATUS
wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call
*s3call
)
814 struct composite_context
*ctx
;
815 struct wbsrv_service
*service
=
816 s3call
->wbconn
->listen_socket
->service
;
818 DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
820 ctx
= wb_cmd_list_trustdoms_send(s3call
, service
);
821 NT_STATUS_HAVE_NO_MEMORY(ctx
);
823 ctx
->async
.fn
= list_trustdom_recv_doms
;
824 ctx
->async
.private_data
= s3call
;
825 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
829 static void list_trustdom_recv_doms(struct composite_context
*ctx
)
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
;
839 status
= wb_cmd_list_trustdoms_recv(ctx
, s3call
, &num_domains
,
841 if (!NT_STATUS_IS_OK(status
)) goto done
;
843 result
= talloc_strdup(s3call
, "");
844 if (result
== NULL
) {
845 status
= NT_STATUS_NO_MEMORY
;
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
));
856 if (result
== NULL
) {
857 status
= NT_STATUS_NO_MEMORY
;
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
;
869 wbsrv_samba3_async_epilogue(status
, s3call
);
873 static void list_groups_recv(struct composite_context
*ctx
);
875 NTSTATUS
wbsrv_samba3_list_groups(struct wbsrv_samba3_call
*s3call
)
877 struct composite_context
*ctx
;
878 struct wbsrv_service
*service
= s3call
->wbconn
->listen_socket
->service
;
880 DEBUG(5, ("wbsrv_samba4_list_groups called\n"));
882 ctx
= wb_cmd_list_groups_send(s3call
, service
,
883 s3call
->request
->domain_name
);
884 NT_STATUS_HAVE_NO_MEMORY(ctx
);
886 ctx
->async
.fn
= list_groups_recv
;
887 ctx
->async
.private_data
= s3call
;
888 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
892 static void list_groups_recv(struct composite_context
*ctx
)
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
;
902 DEBUG(5, ("list_groups_recv called\n"));
904 status
= wb_cmd_list_groups_recv(ctx
, s3call
, &extra_data_len
,
905 &extra_data
, &num_groups
);
907 if (NT_STATUS_IS_OK(status
)) {
908 s3call
->response
->extra_data
.data
= extra_data
;
909 s3call
->response
->length
+= extra_data_len
;
911 s3call
->response
->length
+= 1;
912 s3call
->response
->data
.num_entries
= num_groups
;
916 wbsrv_samba3_async_epilogue(status
, s3call
);
921 static void list_users_recv(struct composite_context
*ctx
);
923 NTSTATUS
wbsrv_samba3_list_users(struct wbsrv_samba3_call
*s3call
)
925 struct composite_context
*ctx
;
926 struct wbsrv_service
*service
=
927 s3call
->wbconn
->listen_socket
->service
;
929 DEBUG(5, ("wbsrv_samba3_list_users called\n"));
931 ctx
= wb_cmd_list_users_send(s3call
, service
,
932 s3call
->request
->domain_name
);
933 NT_STATUS_HAVE_NO_MEMORY(ctx
);
935 ctx
->async
.fn
= list_users_recv
;
936 ctx
->async
.private_data
= s3call
;
937 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
941 static void list_users_recv(struct composite_context
*ctx
)
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
;
951 DEBUG(5, ("list_users_recv called\n"));
953 status
= wb_cmd_list_users_recv(ctx
, s3call
, &extra_data_len
,
954 &extra_data
, &num_users
);
956 if (NT_STATUS_IS_OK(status
)) {
957 s3call
->response
->extra_data
.data
= extra_data
;
958 s3call
->response
->length
+= extra_data_len
;
960 s3call
->response
->length
+= 1;
961 s3call
->response
->data
.num_entries
= num_users
;
965 wbsrv_samba3_async_epilogue(status
, s3call
);
970 static void getpwnam_recv(struct composite_context
*ctx
);
972 NTSTATUS
wbsrv_samba3_getpwnam(struct wbsrv_samba3_call
*s3call
)
974 struct composite_context
*ctx
;
975 struct wbsrv_service
*service
=
976 s3call
->wbconn
->listen_socket
->service
;
978 DEBUG(5, ("wbsrv_samba3_getpwnam called\n"));
980 ctx
= wb_cmd_getpwnam_send(s3call
, service
,
981 s3call
->request
->data
.username
);
982 NT_STATUS_HAVE_NO_MEMORY(ctx
);
984 ctx
->async
.fn
= getpwnam_recv
;
985 ctx
->async
.private_data
= s3call
;
986 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
990 static void getpwnam_recv(struct composite_context
*ctx
)
992 struct wbsrv_samba3_call
*s3call
=
993 talloc_get_type(ctx
->async
.private_data
,
994 struct wbsrv_samba3_call
);
996 struct winbindd_pw
*pw
;
998 DEBUG(5, ("getpwnam_recv called\n"));
1000 status
= wb_cmd_getpwnam_recv(ctx
, s3call
, &pw
);
1001 if(NT_STATUS_IS_OK(status
))
1002 s3call
->response
->data
.pw
= *pw
;
1004 wbsrv_samba3_async_epilogue(status
, s3call
);
1007 static void getpwuid_recv(struct composite_context
*ctx
);
1009 NTSTATUS
wbsrv_samba3_getpwuid(struct wbsrv_samba3_call
*s3call
)
1011 struct composite_context
*ctx
;
1012 struct wbsrv_service
*service
= s3call
->wbconn
->listen_socket
->service
;
1014 DEBUG(5, ("wbsrv_samba3_getpwuid called\n"));
1016 ctx
= wb_cmd_getpwuid_send(s3call
, service
,
1017 s3call
->request
->data
.uid
);
1018 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1026 static void getpwuid_recv(struct composite_context
*ctx
)
1028 struct wbsrv_samba3_call
*s3call
=
1029 talloc_get_type(ctx
->async
.private_data
,
1030 struct wbsrv_samba3_call
);
1032 struct winbindd_pw
*pw
;
1034 DEBUG(5, ("getpwuid_recv called\n"));
1036 status
= wb_cmd_getpwuid_recv(ctx
, s3call
, &pw
);
1037 if (NT_STATUS_IS_OK(status
))
1038 s3call
->response
->data
.pw
= *pw
;
1040 wbsrv_samba3_async_epilogue(status
, s3call
);
1043 static void setpwent_recv(struct composite_context
*ctx
);
1045 NTSTATUS
wbsrv_samba3_setpwent(struct wbsrv_samba3_call
*s3call
)
1047 struct composite_context
*ctx
;
1048 struct wbsrv_service
*service
= s3call
->wbconn
->listen_socket
->service
;
1050 DEBUG(5, ("wbsrv_samba3_setpwent called\n"));
1052 ctx
= wb_cmd_setpwent_send(s3call
, service
);
1053 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1061 static void setpwent_recv(struct composite_context
*ctx
)
1063 struct wbsrv_samba3_call
*s3call
=
1064 talloc_get_type(ctx
->async
.private_data
,
1065 struct wbsrv_samba3_call
);
1067 struct wbsrv_pwent
*pwent
;
1069 DEBUG(5, ("setpwent_recv called\n"));
1071 status
= wb_cmd_setpwent_recv(ctx
, s3call
->wbconn
, &pwent
);
1072 if (NT_STATUS_IS_OK(status
)) {
1073 s3call
->wbconn
->protocol_private_data
= pwent
;
1076 wbsrv_samba3_async_epilogue(status
, s3call
);
1079 static void getpwent_recv(struct composite_context
*ctx
);
1081 NTSTATUS
wbsrv_samba3_getpwent(struct wbsrv_samba3_call
*s3call
)
1083 struct composite_context
*ctx
;
1084 struct wbsrv_service
*service
= s3call
->wbconn
->listen_socket
->service
;
1085 struct wbsrv_pwent
*pwent
;
1087 DEBUG(5, ("wbsrv_samba3_getpwent called\n"));
1089 NT_STATUS_HAVE_NO_MEMORY(s3call
->wbconn
->protocol_private_data
);
1091 pwent
= talloc_get_type(s3call
->wbconn
->protocol_private_data
,
1092 struct wbsrv_pwent
);
1093 NT_STATUS_HAVE_NO_MEMORY(pwent
);
1095 ctx
= wb_cmd_getpwent_send(s3call
, service
, pwent
,
1096 s3call
->request
->data
.num_entries
);
1097 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1105 static void getpwent_recv(struct composite_context
*ctx
)
1107 struct wbsrv_samba3_call
*s3call
=
1108 talloc_get_type(ctx
->async
.private_data
,
1109 struct wbsrv_samba3_call
);
1111 struct winbindd_pw
*pw
;
1114 DEBUG(5, ("getpwent_recv called\n"));
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
;
1120 s3call
->response
->data
.num_entries
= num_users
;
1121 s3call
->response
->extra_data
.data
= pw
;
1122 s3call
->response
->length
+= extra_len
;
1125 wbsrv_samba3_async_epilogue(status
, s3call
);
1128 NTSTATUS
wbsrv_samba3_endpwent(struct wbsrv_samba3_call
*s3call
)
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"));
1137 s3call
->wbconn
->protocol_private_data
= NULL
;
1138 s3call
->response
->result
= WINBINDD_OK
;
1139 return NT_STATUS_OK
;
1143 static void getgrnam_recv(struct composite_context
*ctx
);
1145 NTSTATUS
wbsrv_samba3_getgrnam(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_getgrnam called\n"));
1153 ctx
= wb_cmd_getgrnam_send(s3call
, service
,
1154 s3call
->request
->data
.groupname
);
1155 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1163 static void getgrnam_recv(struct composite_context
*ctx
)
1165 struct wbsrv_samba3_call
*s3call
=
1166 talloc_get_type(ctx
->async
.private_data
,
1167 struct wbsrv_samba3_call
);
1169 struct winbindd_gr
*gr
;
1171 DEBUG(5, ("getgrnam_recv called\n"));
1173 status
= wb_cmd_getgrnam_recv(ctx
, s3call
, &gr
);
1174 if(NT_STATUS_IS_OK(status
))
1175 s3call
->response
->data
.gr
= *gr
;
1177 wbsrv_samba3_async_epilogue(status
, s3call
);
1180 static void getgrgid_recv(struct composite_context
*ctx
);
1182 NTSTATUS
wbsrv_samba3_getgrgid(struct wbsrv_samba3_call
*s3call
)
1184 struct composite_context
*ctx
;
1185 struct wbsrv_service
*service
= s3call
->wbconn
->listen_socket
->service
;
1187 DEBUG(5, ("wbsrv_samba3_getgrgid called\n"));
1189 ctx
= wb_cmd_getgrgid_send(s3call
, service
,
1190 s3call
->request
->data
.gid
);
1191 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1199 static void getgrgid_recv(struct composite_context
*ctx
)
1201 struct wbsrv_samba3_call
*s3call
=
1202 talloc_get_type(ctx
->async
.private_data
,
1203 struct wbsrv_samba3_call
);
1205 struct winbindd_gr
*gr
;
1207 DEBUG(5, ("getgrgid_recv called\n"));
1209 status
= wb_cmd_getgrgid_recv(ctx
, s3call
, &gr
);
1210 if (NT_STATUS_IS_OK(status
))
1211 s3call
->response
->data
.gr
= *gr
;
1213 wbsrv_samba3_async_epilogue(status
, s3call
);
1216 static void getgroups_recv(struct composite_context
*ctx
);
1218 NTSTATUS
wbsrv_samba3_getgroups(struct wbsrv_samba3_call
*s3call
)
1220 struct composite_context
*ctx
;
1221 struct wbsrv_service
*service
= s3call
->wbconn
->listen_socket
->service
;
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
);
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
;
1235 static void getgroups_recv(struct composite_context
*ctx
)
1237 struct wbsrv_samba3_call
*s3call
=
1238 talloc_get_type(ctx
->async
.private_data
,
1239 struct wbsrv_samba3_call
);
1241 uint32_t num_groups
;
1243 DEBUG(5, ("getgroups_recv called\n"));
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
;
1249 s3call
->response
->data
.num_entries
= num_groups
;
1250 s3call
->response
->extra_data
.data
= gids
;
1251 s3call
->response
->length
+= extra_len
;
1253 s3call
->response
->result
= WINBINDD_ERROR
;
1256 wbsrv_samba3_async_epilogue(status
, s3call
);
1259 static void setgrent_recv(struct composite_context
*ctx
);
1261 NTSTATUS
wbsrv_samba3_setgrent(struct wbsrv_samba3_call
*s3call
)
1263 struct composite_context
*ctx
;
1264 struct wbsrv_service
*service
= s3call
->wbconn
->listen_socket
->service
;
1266 DEBUG(5, ("wbsrv_samba3_setgrent called\n"));
1268 ctx
= wb_cmd_setgrent_send(s3call
, service
);
1269 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1277 static void setgrent_recv(struct composite_context
*ctx
)
1279 struct wbsrv_samba3_call
*s3call
=
1280 talloc_get_type(ctx
->async
.private_data
,
1281 struct wbsrv_samba3_call
);
1283 struct wbsrv_grent
*grent
;
1285 DEBUG(5, ("setpwent_recv called\n"));
1287 status
= wb_cmd_setgrent_recv(ctx
, s3call
->wbconn
, &grent
);
1288 if (NT_STATUS_IS_OK(status
)) {
1289 s3call
->wbconn
->protocol_private_data
= grent
;
1292 wbsrv_samba3_async_epilogue(status
, s3call
);
1295 static void getgrent_recv(struct composite_context
*ctx
);
1297 NTSTATUS
wbsrv_samba3_getgrent(struct wbsrv_samba3_call
*s3call
)
1299 struct composite_context
*ctx
;
1300 struct wbsrv_service
*service
= s3call
->wbconn
->listen_socket
->service
;
1301 struct wbsrv_grent
*grent
;
1303 DEBUG(5, ("wbsrv_samba3_getgrent called\n"));
1305 NT_STATUS_HAVE_NO_MEMORY(s3call
->wbconn
->protocol_private_data
);
1307 grent
= talloc_get_type(s3call
->wbconn
->protocol_private_data
,
1308 struct wbsrv_grent
);
1309 NT_STATUS_HAVE_NO_MEMORY(grent
);
1311 ctx
= wb_cmd_getgrent_send(s3call
, service
, grent
,
1312 s3call
->request
->data
.num_entries
);
1313 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1321 static void getgrent_recv(struct composite_context
*ctx
)
1323 struct wbsrv_samba3_call
*s3call
=
1324 talloc_get_type(ctx
->async
.private_data
,
1325 struct wbsrv_samba3_call
);
1327 struct winbindd_gr
*gr
;
1328 uint32_t num_groups
;
1330 DEBUG(5, ("getgrent_recv called\n"));
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
;
1336 s3call
->response
->data
.num_entries
= num_groups
;
1337 s3call
->response
->extra_data
.data
= gr
;
1338 s3call
->response
->length
+= extra_len
;
1341 wbsrv_samba3_async_epilogue(status
, s3call
);
1344 NTSTATUS
wbsrv_samba3_endgrent(struct wbsrv_samba3_call
*s3call
)
1346 DEBUG(5, ("wbsrv_samba3_endgrent called\n"));
1347 s3call
->response
->result
= WINBINDD_OK
;
1348 return NT_STATUS_OK
;
1351 static void sid2uid_recv(struct composite_context
*ctx
);
1353 NTSTATUS
wbsrv_samba3_sid2uid(struct wbsrv_samba3_call
*s3call
)
1355 struct composite_context
*ctx
;
1356 struct wbsrv_service
*service
=
1357 s3call
->wbconn
->listen_socket
->service
;
1358 struct dom_sid
*sid
;
1360 DEBUG(5, ("wbsrv_samba3_sid2uid called\n"));
1362 sid
= dom_sid_parse_talloc(s3call
, s3call
->request
->data
.sid
);
1363 NT_STATUS_HAVE_NO_MEMORY(sid
);
1365 ctx
= wb_sid2uid_send(s3call
, service
, sid
);
1366 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1375 static void sid2uid_recv(struct composite_context
*ctx
)
1377 struct wbsrv_samba3_call
*s3call
=
1378 talloc_get_type(ctx
->async
.private_data
,
1379 struct wbsrv_samba3_call
);
1382 DEBUG(5, ("sid2uid_recv called\n"));
1384 status
= wb_sid2uid_recv(ctx
, &s3call
->response
->data
.uid
);
1386 wbsrv_samba3_async_epilogue(status
, s3call
);
1389 static void sid2gid_recv(struct composite_context
*ctx
);
1391 NTSTATUS
wbsrv_samba3_sid2gid(struct wbsrv_samba3_call
*s3call
)
1393 struct composite_context
*ctx
;
1394 struct wbsrv_service
*service
=
1395 s3call
->wbconn
->listen_socket
->service
;
1396 struct dom_sid
*sid
;
1398 DEBUG(5, ("wbsrv_samba3_sid2gid called\n"));
1400 sid
= dom_sid_parse_talloc(s3call
, s3call
->request
->data
.sid
);
1401 NT_STATUS_HAVE_NO_MEMORY(sid
);
1403 ctx
= wb_sid2gid_send(s3call
, service
, sid
);
1404 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1413 static void sid2gid_recv(struct composite_context
*ctx
)
1415 struct wbsrv_samba3_call
*s3call
=
1416 talloc_get_type(ctx
->async
.private_data
,
1417 struct wbsrv_samba3_call
);
1420 DEBUG(5, ("sid2gid_recv called\n"));
1422 status
= wb_sid2gid_recv(ctx
, &s3call
->response
->data
.gid
);
1424 wbsrv_samba3_async_epilogue(status
, s3call
);
1427 static void uid2sid_recv(struct composite_context
*ctx
);
1429 NTSTATUS
wbsrv_samba3_uid2sid(struct wbsrv_samba3_call
*s3call
)
1431 struct composite_context
*ctx
;
1432 struct wbsrv_service
*service
=
1433 s3call
->wbconn
->listen_socket
->service
;
1435 DEBUG(5, ("wbsrv_samba3_uid2sid called\n"));
1437 ctx
= wb_uid2sid_send(s3call
, service
, s3call
->request
->data
.uid
);
1438 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1447 static void uid2sid_recv(struct composite_context
*ctx
)
1449 struct wbsrv_samba3_call
*s3call
=
1450 talloc_get_type(ctx
->async
.private_data
,
1451 struct wbsrv_samba3_call
);
1453 struct dom_sid
*sid
;
1456 DEBUG(5, ("uid2sid_recv called\n"));
1458 status
= wb_uid2sid_recv(ctx
, s3call
, &sid
);
1459 if(NT_STATUS_IS_OK(status
)) {
1460 sid_str
= dom_sid_string(s3call
, sid
);
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
);
1466 /* But we assume this worked, so we'll set the string. Work
1468 WBSRV_SAMBA3_SET_STRING(s3call
->response
->data
.sid
.sid
, sid_str
);
1469 s3call
->response
->data
.sid
.type
= SID_NAME_USER
;
1472 wbsrv_samba3_async_epilogue(status
, s3call
);
1475 static void gid2sid_recv(struct composite_context
*ctx
);
1477 NTSTATUS
wbsrv_samba3_gid2sid(struct wbsrv_samba3_call
*s3call
)
1479 struct composite_context
*ctx
;
1480 struct wbsrv_service
*service
=
1481 s3call
->wbconn
->listen_socket
->service
;
1483 DEBUG(5, ("wbsrv_samba3_gid2sid called\n"));
1485 ctx
= wb_gid2sid_send(s3call
, service
, s3call
->request
->data
.gid
);
1486 NT_STATUS_HAVE_NO_MEMORY(ctx
);
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
;
1495 static void gid2sid_recv(struct composite_context
*ctx
)
1497 struct wbsrv_samba3_call
*s3call
=
1498 talloc_get_type(ctx
->async
.private_data
,
1499 struct wbsrv_samba3_call
);
1501 struct dom_sid
*sid
;
1504 DEBUG(5, ("gid2sid_recv called\n"));
1506 status
= wb_gid2sid_recv(ctx
, s3call
, &sid
);
1507 if(NT_STATUS_IS_OK(status
)) {
1508 sid_str
= dom_sid_string(s3call
, sid
);
1510 if (sid_str
== NULL
)
1511 wbsrv_samba3_async_epilogue(NT_STATUS_NO_MEMORY
,s3call
);
1513 WBSRV_SAMBA3_SET_STRING(s3call
->response
->data
.sid
.sid
, sid_str
);
1514 s3call
->response
->data
.sid
.type
= SID_NAME_DOMAIN
;
1517 wbsrv_samba3_async_epilogue(status
, s3call
);
1520 static void sids2xids_recv(struct composite_context
*ctx
)
1522 struct wbsrv_samba3_call
*s3call
=
1523 talloc_get_type(ctx
->async
.private_data
,
1524 struct wbsrv_samba3_call
);
1528 struct winbindd_response
*resp
= s3call
->response
;
1530 DEBUG(5, ("sids2xids_recv called\n"));
1532 status
= wb_sids2xids_recv(ctx
, &ids
, &count
);
1533 if (!NT_STATUS_IS_OK(status
)) {
1537 /* fill in extra_data with the list of IDs. Each is prefixed
1538 * by 'U' or 'G' for user and group, and followed by a
1540 resp
->extra_data
.data
= talloc_strdup(resp
, "");
1541 if (resp
->extra_data
.data
== NULL
) {
1542 status
= NT_STATUS_NO_MEMORY
;
1546 for (i
=0; i
<count
; i
++) {
1547 char type_char
= '*';
1548 if (ids
[i
].status
!= ID_MAPPED
) {
1549 resp
->extra_data
.data
= talloc_asprintf_append_buffer(resp
->extra_data
.data
, "\n");
1550 if (resp
->extra_data
.data
== NULL
) {
1551 status
= NT_STATUS_NO_MEMORY
;
1556 switch (ids
[i
].xid
.type
) {
1566 case ID_TYPE_NOT_SPECIFIED
:
1570 resp
->extra_data
.data
= talloc_asprintf_append_buffer(resp
->extra_data
.data
, "%c%u\n",
1571 type_char
, (unsigned)ids
[i
].xid
.id
);
1572 if (resp
->extra_data
.data
== NULL
) {
1573 status
= NT_STATUS_NO_MEMORY
;
1577 resp
->length
+= strlen(resp
->extra_data
.data
) + 1;
1580 wbsrv_samba3_async_epilogue(status
, s3call
);
1584 NTSTATUS
wbsrv_samba3_sids2xids(struct wbsrv_samba3_call
*s3call
)
1586 struct composite_context
*ctx
;
1587 struct wbsrv_service
*service
=
1588 s3call
->wbconn
->listen_socket
->service
;
1589 struct id_map
*ids
= NULL
;
1591 char *saveptr
= NULL
;
1594 DEBUG(5, ("wbsrv_samba3_sids2xids called\n"));
1596 for (sidstr
= strtok_r(s3call
->request
->extra_data
.data
, "\n", &saveptr
);
1598 sidstr
= strtok_r(NULL
, "\n", &saveptr
)) {
1600 ids
= talloc_realloc(s3call
, ids
, struct id_map
, count
);
1601 NT_STATUS_HAVE_NO_MEMORY(ids
);
1602 ids
[count
-1].sid
= dom_sid_parse_talloc(ids
, sidstr
);
1603 NT_STATUS_HAVE_NO_MEMORY(ids
->sid
);
1606 ctx
= wb_sids2xids_send(s3call
, service
, count
, ids
);
1607 NT_STATUS_HAVE_NO_MEMORY(ctx
);
1609 ctx
->async
.fn
= sids2xids_recv
;
1610 ctx
->async
.private_data
= s3call
;
1611 s3call
->flags
|= WBSRV_CALL_FLAGS_REPLY_ASYNC
;
1612 return NT_STATUS_OK
;