2 Unix SMB/CIFS implementation.
4 In-Child server implementation of the routines defined in wbint.idl
6 Copyright (C) Volker Lendecke 2009
7 Copyright (C) Guenther Deschner 2009
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "winbindd/winbindd.h"
25 #include "winbindd/winbindd_proto.h"
26 #include "rpc_client/cli_pipe.h"
28 #include "librpc/gen_ndr/srv_winbind.h"
29 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
31 #include "../libcli/security/security.h"
32 #include "../libcli/auth/netlogon_creds_cli.h"
34 void _wbint_Ping(struct pipes_struct *p, struct wbint_Ping *r)
36 *r->out.out_data = r->in.in_data;
39 static bool reset_cm_connection_on_error(struct winbindd_domain *domain,
42 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
43 invalidate_cm_connection(domain);
44 /* We invalidated the connection. */
50 NTSTATUS _wbint_LookupSid(struct pipes_struct *p, struct wbint_LookupSid *r)
52 struct winbindd_domain *domain = wb_child_domain();
55 enum lsa_SidType type;
59 return NT_STATUS_REQUEST_NOT_ACCEPTED;
62 status = domain->methods->sid_to_name(domain, p->mem_ctx, r->in.sid,
63 &dom_name, &name, &type);
64 reset_cm_connection_on_error(domain, status);
65 if (!NT_STATUS_IS_OK(status)) {
69 *r->out.domain = dom_name;
75 NTSTATUS _wbint_LookupSids(struct pipes_struct *p, struct wbint_LookupSids *r)
77 struct winbindd_domain *domain = wb_child_domain();
78 struct lsa_RefDomainList *domains = r->out.domains;
82 return NT_STATUS_REQUEST_NOT_ACCEPTED;
86 * This breaks the winbindd_domain->methods abstraction: This
87 * is only called for remote domains, and both winbindd_msrpc
88 * and winbindd_ad call into lsa_lookupsids anyway. Caching is
89 * done at the wbint RPC layer.
91 status = rpc_lookup_sids(p->mem_ctx, domain, r->in.sids,
92 &domains, &r->out.names);
94 if (domains != NULL) {
95 r->out.domains = domains;
98 reset_cm_connection_on_error(domain, status);
102 NTSTATUS _wbint_LookupName(struct pipes_struct *p, struct wbint_LookupName *r)
104 struct winbindd_domain *domain = wb_child_domain();
107 if (domain == NULL) {
108 return NT_STATUS_REQUEST_NOT_ACCEPTED;
111 status = domain->methods->name_to_sid(
112 domain, p->mem_ctx, r->in.domain, r->in.name, r->in.flags,
113 r->out.sid, r->out.type);
114 reset_cm_connection_on_error(domain, status);
118 NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p,
119 struct wbint_Sids2UnixIDs *r)
122 struct id_map *ids = NULL;
123 struct id_map **id_ptrs = NULL;
124 struct dom_sid *sids = NULL;
125 uint32_t *id_idx = NULL;
126 NTSTATUS status = NT_STATUS_NO_MEMORY;
128 for (i=0; i<r->in.domains->count; i++) {
129 struct lsa_DomainInfo *d = &r->in.domains->domains[i];
130 struct idmap_domain *dom;
133 dom = idmap_find_domain_with_sid(d->name.string, d->sid);
135 DEBUG(10, ("idmap domain %s:%s not found\n",
136 d->name.string, sid_string_dbg(d->sid)));
142 for (j=0; j<r->in.ids->num_ids; j++) {
143 if (r->in.ids->ids[j].domain_index == i) {
148 ids = talloc_realloc(talloc_tos(), ids,
149 struct id_map, num_ids);
153 id_ptrs = talloc_realloc(talloc_tos(), id_ptrs,
154 struct id_map *, num_ids+1);
155 if (id_ptrs == NULL) {
158 id_idx = talloc_realloc(talloc_tos(), id_idx,
160 if (id_idx == NULL) {
163 sids = talloc_realloc(talloc_tos(), sids,
164 struct dom_sid, num_ids);
172 * Convert the input data into a list of
173 * id_map structs suitable for handing in
174 * to the idmap sids_to_unixids method.
176 for (j=0; j<r->in.ids->num_ids; j++) {
177 struct wbint_TransID *id = &r->in.ids->ids[j];
179 if (id->domain_index != i) {
183 id_ptrs[num_ids] = &ids[num_ids];
185 ids[num_ids].sid = &sids[num_ids];
186 sid_compose(ids[num_ids].sid, d->sid, id->rid);
187 ids[num_ids].xid.type = id->type;
188 ids[num_ids].status = ID_UNKNOWN;
191 id_ptrs[num_ids] = NULL;
193 status = dom->methods->sids_to_unixids(dom, id_ptrs);
194 DEBUG(10, ("sids_to_unixids returned %s\n",
198 * Extract the results for handing them back to the caller.
200 for (j=0; j<num_ids; j++) {
201 struct wbint_TransID *id = &r->in.ids->ids[id_idx[j]];
203 if (ids[j].status != ID_MAPPED) {
204 id->xid.id = UINT32_MAX;
205 id->xid.type = ID_TYPE_NOT_SPECIFIED;
209 id->xid = ids[j].xid;
212 status = NT_STATUS_OK;
215 TALLOC_FREE(id_ptrs);
221 NTSTATUS _wbint_Uid2Sid(struct pipes_struct *p, struct wbint_Uid2Sid *r)
223 return idmap_uid_to_sid(r->in.dom_name ? r->in.dom_name : "",
224 r->out.sid, r->in.uid);
227 NTSTATUS _wbint_Gid2Sid(struct pipes_struct *p, struct wbint_Gid2Sid *r)
229 return idmap_gid_to_sid(r->in.dom_name ? r->in.dom_name : "",
230 r->out.sid, r->in.gid);
233 NTSTATUS _wbint_AllocateUid(struct pipes_struct *p, struct wbint_AllocateUid *r)
238 status = idmap_allocate_uid(&xid);
239 if (!NT_STATUS_IS_OK(status)) {
242 *r->out.uid = xid.id;
246 NTSTATUS _wbint_AllocateGid(struct pipes_struct *p, struct wbint_AllocateGid *r)
251 status = idmap_allocate_gid(&xid);
252 if (!NT_STATUS_IS_OK(status)) {
255 *r->out.gid = xid.id;
259 NTSTATUS _wbint_QueryUser(struct pipes_struct *p, struct wbint_QueryUser *r)
261 struct winbindd_domain *domain = wb_child_domain();
264 if (domain == NULL) {
265 return NT_STATUS_REQUEST_NOT_ACCEPTED;
268 status = domain->methods->query_user(domain, p->mem_ctx, r->in.sid,
270 reset_cm_connection_on_error(domain, status);
274 NTSTATUS _wbint_LookupUserAliases(struct pipes_struct *p,
275 struct wbint_LookupUserAliases *r)
277 struct winbindd_domain *domain = wb_child_domain();
280 if (domain == NULL) {
281 return NT_STATUS_REQUEST_NOT_ACCEPTED;
284 status = domain->methods->lookup_useraliases(
285 domain, p->mem_ctx, r->in.sids->num_sids, r->in.sids->sids,
286 &r->out.rids->num_rids, &r->out.rids->rids);
287 reset_cm_connection_on_error(domain, status);
291 NTSTATUS _wbint_LookupUserGroups(struct pipes_struct *p,
292 struct wbint_LookupUserGroups *r)
294 struct winbindd_domain *domain = wb_child_domain();
297 if (domain == NULL) {
298 return NT_STATUS_REQUEST_NOT_ACCEPTED;
301 status = domain->methods->lookup_usergroups(
302 domain, p->mem_ctx, r->in.sid,
303 &r->out.sids->num_sids, &r->out.sids->sids);
304 reset_cm_connection_on_error(domain, status);
308 NTSTATUS _wbint_QuerySequenceNumber(struct pipes_struct *p,
309 struct wbint_QuerySequenceNumber *r)
311 struct winbindd_domain *domain = wb_child_domain();
314 if (domain == NULL) {
315 return NT_STATUS_REQUEST_NOT_ACCEPTED;
318 status = domain->methods->sequence_number(domain, r->out.sequence);
319 reset_cm_connection_on_error(domain, status);
323 NTSTATUS _wbint_LookupGroupMembers(struct pipes_struct *p,
324 struct wbint_LookupGroupMembers *r)
326 struct winbindd_domain *domain = wb_child_domain();
327 uint32_t i, num_names;
328 struct dom_sid *sid_mem;
330 uint32_t *name_types;
333 if (domain == NULL) {
334 return NT_STATUS_REQUEST_NOT_ACCEPTED;
337 status = domain->methods->lookup_groupmem(
338 domain, p->mem_ctx, r->in.sid, r->in.type,
339 &num_names, &sid_mem, &names, &name_types);
340 reset_cm_connection_on_error(domain, status);
341 if (!NT_STATUS_IS_OK(status)) {
345 r->out.members->num_principals = num_names;
346 r->out.members->principals = talloc_array(
347 r->out.members, struct wbint_Principal, num_names);
348 if (r->out.members->principals == NULL) {
349 return NT_STATUS_NO_MEMORY;
352 for (i=0; i<num_names; i++) {
353 struct wbint_Principal *m = &r->out.members->principals[i];
354 sid_copy(&m->sid, &sid_mem[i]);
355 m->name = talloc_move(r->out.members->principals, &names[i]);
356 m->type = (enum lsa_SidType)name_types[i];
362 NTSTATUS _wbint_QueryUserList(struct pipes_struct *p,
363 struct wbint_QueryUserList *r)
365 struct winbindd_domain *domain = wb_child_domain();
368 if (domain == NULL) {
369 return NT_STATUS_REQUEST_NOT_ACCEPTED;
372 status = domain->methods->query_user_list(
373 domain, p->mem_ctx, &r->out.users->num_userinfos,
374 &r->out.users->userinfos);
375 reset_cm_connection_on_error(domain, status);
379 NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p,
380 struct wbint_QueryGroupList *r)
382 struct winbindd_domain *domain = wb_child_domain();
384 uint32_t num_local_groups = 0;
385 struct wb_acct_info *local_groups = NULL;
386 uint32_t num_dom_groups = 0;
387 struct wb_acct_info *dom_groups = NULL;
389 uint64_t num_total = 0;
390 struct wbint_Principal *result;
392 bool include_local_groups = false;
394 if (domain == NULL) {
395 return NT_STATUS_REQUEST_NOT_ACCEPTED;
398 switch (lp_server_role()) {
399 case ROLE_ACTIVE_DIRECTORY_DC:
400 if (domain->internal) {
402 * we want to include local groups
403 * for BUILTIN and WORKGROUP
405 include_local_groups = true;
410 * We might include local groups in more
411 * setups later, but that requires more work
417 if (include_local_groups) {
418 status = domain->methods->enum_local_groups(domain, talloc_tos(),
421 reset_cm_connection_on_error(domain, status);
422 if (!NT_STATUS_IS_OK(status)) {
427 status = domain->methods->enum_dom_groups(domain, talloc_tos(),
430 reset_cm_connection_on_error(domain, status);
431 if (!NT_STATUS_IS_OK(status)) {
435 num_total = num_local_groups + num_dom_groups;
436 if (num_total > UINT32_MAX) {
437 return NT_STATUS_INTERNAL_ERROR;
440 result = talloc_array(r->out.groups, struct wbint_Principal,
442 if (result == NULL) {
443 return NT_STATUS_NO_MEMORY;
446 for (i = 0; i < num_local_groups; i++) {
447 struct wb_acct_info *lg = &local_groups[i];
448 struct wbint_Principal *rg = &result[ti++];
450 sid_compose(&rg->sid, &domain->sid, lg->rid);
451 rg->type = SID_NAME_ALIAS;
452 rg->name = talloc_strdup(result, lg->acct_name);
453 if (rg->name == NULL) {
455 TALLOC_FREE(dom_groups);
456 TALLOC_FREE(local_groups);
457 return NT_STATUS_NO_MEMORY;
460 num_local_groups = 0;
461 TALLOC_FREE(local_groups);
463 for (i = 0; i < num_dom_groups; i++) {
464 struct wb_acct_info *dg = &dom_groups[i];
465 struct wbint_Principal *rg = &result[ti++];
467 sid_compose(&rg->sid, &domain->sid, dg->rid);
468 rg->type = SID_NAME_DOM_GRP;
469 rg->name = talloc_strdup(result, dg->acct_name);
470 if (rg->name == NULL) {
472 TALLOC_FREE(dom_groups);
473 TALLOC_FREE(local_groups);
474 return NT_STATUS_NO_MEMORY;
478 TALLOC_FREE(dom_groups);
480 r->out.groups->num_principals = ti;
481 r->out.groups->principals = result;
486 NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct wbint_DsGetDcName *r)
488 struct winbindd_domain *domain = wb_child_domain();
489 struct rpc_pipe_client *netlogon_pipe;
490 struct netr_DsRGetDCNameInfo *dc_info;
493 unsigned int orig_timeout;
494 struct dcerpc_binding_handle *b;
496 if (domain == NULL) {
497 return dsgetdcname(p->mem_ctx, winbind_messaging_context(),
498 r->in.domain_name, r->in.domain_guid,
499 r->in.site_name ? r->in.site_name : "",
504 status = cm_connect_netlogon(domain, &netlogon_pipe);
506 reset_cm_connection_on_error(domain, status);
507 if (!NT_STATUS_IS_OK(status)) {
508 DEBUG(10, ("Can't contact the NETLOGON pipe\n"));
512 b = netlogon_pipe->binding_handle;
514 /* This call can take a long time - allow the server to time out.
515 35 seconds should do it. */
517 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
519 if (domain->active_directory) {
520 status = dcerpc_netr_DsRGetDCName(b,
521 p->mem_ctx, domain->dcname,
522 r->in.domain_name, NULL, r->in.domain_guid,
523 r->in.flags, r->out.dc_info, &werr);
524 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(werr)) {
527 if (reset_cm_connection_on_error(domain, status)) {
529 status = cm_connect_netlogon(domain, &netlogon_pipe);
531 reset_cm_connection_on_error(domain, status);
532 if (!NT_STATUS_IS_OK(status)) {
533 DEBUG(10, ("Can't contact the NETLOGON pipe\n"));
537 b = netlogon_pipe->binding_handle;
539 /* This call can take a long time - allow the server to time out.
540 35 seconds should do it. */
542 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
547 * Fallback to less capable methods
550 dc_info = talloc_zero(r->out.dc_info, struct netr_DsRGetDCNameInfo);
551 if (dc_info == NULL) {
552 status = NT_STATUS_NO_MEMORY;
556 if (r->in.flags & DS_PDC_REQUIRED) {
557 status = dcerpc_netr_GetDcName(b,
558 p->mem_ctx, domain->dcname,
559 r->in.domain_name, &dc_info->dc_unc, &werr);
561 status = dcerpc_netr_GetAnyDCName(b,
562 p->mem_ctx, domain->dcname,
563 r->in.domain_name, &dc_info->dc_unc, &werr);
566 reset_cm_connection_on_error(domain, status);
567 if (!NT_STATUS_IS_OK(status)) {
568 DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
572 if (!W_ERROR_IS_OK(werr)) {
573 DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
575 status = werror_to_ntstatus(werr);
579 *r->out.dc_info = dc_info;
580 status = NT_STATUS_OK;
583 /* And restore our original timeout. */
584 rpccli_set_timeout(netlogon_pipe, orig_timeout);
589 NTSTATUS _wbint_LookupRids(struct pipes_struct *p, struct wbint_LookupRids *r)
591 struct winbindd_domain *domain = wb_child_domain();
594 enum lsa_SidType *types;
595 struct wbint_Principal *result;
599 if (domain == NULL) {
600 return NT_STATUS_REQUEST_NOT_ACCEPTED;
603 status = domain->methods->rids_to_names(
604 domain, talloc_tos(), r->in.domain_sid, r->in.rids->rids,
605 r->in.rids->num_rids, &domain_name, &names, &types);
606 reset_cm_connection_on_error(domain, status);
607 if (!NT_STATUS_IS_OK(status)) {
611 *r->out.domain_name = talloc_move(r->out.domain_name, &domain_name);
613 result = talloc_array(p->mem_ctx, struct wbint_Principal,
614 r->in.rids->num_rids);
615 if (result == NULL) {
616 return NT_STATUS_NO_MEMORY;
619 for (i=0; i<r->in.rids->num_rids; i++) {
620 sid_compose(&result[i].sid, r->in.domain_sid,
621 r->in.rids->rids[i]);
622 result[i].type = types[i];
623 result[i].name = talloc_move(result, &names[i]);
628 r->out.names->num_principals = r->in.rids->num_rids;
629 r->out.names->principals = result;
633 NTSTATUS _wbint_CheckMachineAccount(struct pipes_struct *p,
634 struct wbint_CheckMachineAccount *r)
636 struct winbindd_domain *domain;
640 domain = wb_child_domain();
641 if (domain == NULL) {
642 return NT_STATUS_REQUEST_NOT_ACCEPTED;
646 invalidate_cm_connection(domain);
647 domain->conn.netlogon_force_reauth = true;
650 struct rpc_pipe_client *netlogon_pipe;
651 status = cm_connect_netlogon(domain, &netlogon_pipe);
654 /* There is a race condition between fetching the trust account
655 password and the periodic machine password change. So it's
656 possible that the trust account password has been changed on us.
657 We are returned NT_STATUS_ACCESS_DENIED if this happens. */
659 #define MAX_RETRIES 3
661 if ((num_retries < MAX_RETRIES)
662 && NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
667 if (!NT_STATUS_IS_OK(status)) {
668 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
672 /* Pass back result code - zero for success, other values for
673 specific failures. */
675 DEBUG(3,("domain %s secret is %s\n", domain->name,
676 NT_STATUS_IS_OK(status) ? "good" : "bad"));
679 DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2,
680 ("Checking the trust account password for domain %s returned %s\n",
681 domain->name, nt_errstr(status)));
686 NTSTATUS _wbint_ChangeMachineAccount(struct pipes_struct *p,
687 struct wbint_ChangeMachineAccount *r)
689 struct messaging_context *msg_ctx = winbind_messaging_context();
690 struct winbindd_domain *domain;
692 struct rpc_pipe_client *netlogon_pipe;
694 domain = wb_child_domain();
695 if (domain == NULL) {
696 return NT_STATUS_REQUEST_NOT_ACCEPTED;
699 status = cm_connect_netlogon(domain, &netlogon_pipe);
700 if (!NT_STATUS_IS_OK(status)) {
701 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
705 status = trust_pw_change(domain->conn.netlogon_creds,
707 netlogon_pipe->binding_handle,
711 /* Pass back result code - zero for success, other values for
712 specific failures. */
714 DEBUG(3,("domain %s secret %s\n", domain->name,
715 NT_STATUS_IS_OK(status) ? "changed" : "unchanged"));
718 DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2,
719 ("Changing the trust account password for domain %s returned %s\n",
720 domain->name, nt_errstr(status)));
725 NTSTATUS _wbint_PingDc(struct pipes_struct *p, struct wbint_PingDc *r)
728 struct winbindd_domain *domain;
729 struct rpc_pipe_client *netlogon_pipe;
730 union netr_CONTROL_QUERY_INFORMATION info;
732 fstring logon_server;
733 struct dcerpc_binding_handle *b;
736 domain = wb_child_domain();
737 if (domain == NULL) {
738 return NT_STATUS_REQUEST_NOT_ACCEPTED;
742 status = cm_connect_netlogon(domain, &netlogon_pipe);
743 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
745 * Retry to open new connection with new kerberos ticket.
747 invalidate_cm_connection(domain);
748 status = cm_connect_netlogon(domain, &netlogon_pipe);
751 reset_cm_connection_on_error(domain, status);
752 if (!NT_STATUS_IS_OK(status)) {
753 DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n",
758 b = netlogon_pipe->binding_handle;
760 fstr_sprintf(logon_server, "\\\\%s", domain->dcname);
761 *r->out.dcname = talloc_strdup(p->mem_ctx, domain->dcname);
762 if (*r->out.dcname == NULL) {
763 DEBUG(2, ("Could not allocate memory\n"));
764 return NT_STATUS_NO_MEMORY;
768 * This provokes a WERR_NOT_SUPPORTED error message. This is
769 * documented in the wspp docs. I could not get a successful
770 * call to work, but the main point here is testing that the
771 * netlogon pipe works.
773 status = dcerpc_netr_LogonControl(b, p->mem_ctx,
774 logon_server, NETLOGON_CONTROL_QUERY,
777 if (!dcerpc_binding_handle_is_connected(b) && !retry) {
778 DEBUG(10, ("Session might have expired. "
779 "Reconnect and retry once.\n"));
780 invalidate_cm_connection(domain);
785 reset_cm_connection_on_error(domain, status);
786 if (!NT_STATUS_IS_OK(status)) {
787 DEBUG(2, ("dcerpc_netr_LogonControl failed: %s\n",
792 if (!W_ERROR_EQUAL(werr, WERR_NOT_SUPPORTED)) {
793 DEBUG(2, ("dcerpc_netr_LogonControl returned %s, expected "
794 "WERR_NOT_SUPPORTED\n",
796 return werror_to_ntstatus(werr);
799 DEBUG(5, ("winbindd_dual_ping_dc succeeded\n"));
803 NTSTATUS _winbind_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
804 struct winbind_DsrUpdateReadOnlyServerDnsRecords *r)
806 struct winbindd_domain *domain;
808 struct rpc_pipe_client *netlogon_pipe;
810 domain = wb_child_domain();
811 if (domain == NULL) {
812 return NT_STATUS_REQUEST_NOT_ACCEPTED;
815 status = cm_connect_netlogon(domain, &netlogon_pipe);
816 if (!NT_STATUS_IS_OK(status)) {
817 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
821 status = netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords(domain->conn.netlogon_creds,
822 netlogon_pipe->binding_handle,
827 /* Pass back result code - zero for success, other values for
828 specific failures. */
830 DEBUG(3,("DNS records for domain %s %s\n", domain->name,
831 NT_STATUS_IS_OK(status) ? "changed" : "unchanged"));
834 DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2,
835 ("Update of DNS records via RW DC %s returned %s\n",
836 domain->name, nt_errstr(status)));
841 NTSTATUS _winbind_SamLogon(struct pipes_struct *p,
842 struct winbind_SamLogon *r)
844 struct winbindd_domain *domain;
846 DATA_BLOB lm_response, nt_response;
847 domain = wb_child_domain();
848 if (domain == NULL) {
849 return NT_STATUS_REQUEST_NOT_ACCEPTED;
852 /* TODO: Handle interactive logons here */
853 if (r->in.validation_level != 3 ||
854 r->in.logon.network == NULL ||
855 (r->in.logon_level != NetlogonNetworkInformation
856 && r->in.logon_level != NetlogonNetworkTransitiveInformation)) {
857 return NT_STATUS_REQUEST_NOT_ACCEPTED;
861 lm_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
862 nt_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
864 status = winbind_dual_SamLogon(domain, p->mem_ctx,
865 r->in.logon.network->identity_info.parameter_control,
866 r->in.logon.network->identity_info.account_name.string,
867 r->in.logon.network->identity_info.domain_name.string,
868 r->in.logon.network->identity_info.workstation.string,
869 r->in.logon.network->challenge,
870 lm_response, nt_response, &r->out.validation.sam3);
874 WERROR _winbind_LogonControl(struct pipes_struct *p,
875 struct winbind_LogonControl *r)
877 struct winbindd_domain *domain;
879 domain = wb_child_domain();
880 if (domain == NULL) {
881 return WERR_NO_SUCH_DOMAIN;
884 return WERR_NOT_SUPPORTED;