source: trunk/server/source3/winbindd/winbindd_dual_srv.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: 19.5 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 In-Child server implementation of the routines defined in wbint.idl
5
6 Copyright (C) Volker Lendecke 2009
7 Copyright (C) Guenther Deschner 2009
8
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.
13
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.
18
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/>.
21*/
22
23#include "includes.h"
24#include "winbindd/winbindd.h"
25#include "winbindd/winbindd_proto.h"
26#include "rpc_client/cli_pipe.h"
27#include "ntdomain.h"
28#include "librpc/gen_ndr/srv_wbint.h"
29#include "../librpc/gen_ndr/ndr_netlogon_c.h"
30#include "idmap.h"
31#include "../libcli/security/security.h"
32
33void _wbint_Ping(struct pipes_struct *p, struct wbint_Ping *r)
34{
35 *r->out.out_data = r->in.in_data;
36}
37
38static bool reset_cm_connection_on_error(struct winbindd_domain *domain,
39 NTSTATUS status)
40{
41 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
42 invalidate_cm_connection(&domain->conn);
43 /* We invalidated the connection. */
44 return true;
45 }
46 return false;
47}
48
49NTSTATUS _wbint_LookupSid(struct pipes_struct *p, struct wbint_LookupSid *r)
50{
51 struct winbindd_domain *domain = wb_child_domain();
52 char *dom_name;
53 char *name;
54 enum lsa_SidType type;
55 NTSTATUS status;
56
57 if (domain == NULL) {
58 return NT_STATUS_REQUEST_NOT_ACCEPTED;
59 }
60
61 status = domain->methods->sid_to_name(domain, p->mem_ctx, r->in.sid,
62 &dom_name, &name, &type);
63 reset_cm_connection_on_error(domain, status);
64 if (!NT_STATUS_IS_OK(status)) {
65 return status;
66 }
67
68 *r->out.domain = dom_name;
69 *r->out.name = name;
70 *r->out.type = type;
71 return NT_STATUS_OK;
72}
73
74NTSTATUS _wbint_LookupSids(struct pipes_struct *p, struct wbint_LookupSids *r)
75{
76 struct winbindd_domain *domain = wb_child_domain();
77 NTSTATUS status;
78
79 if (domain == NULL) {
80 return NT_STATUS_REQUEST_NOT_ACCEPTED;
81 }
82
83 /*
84 * This breaks the winbindd_domain->methods abstraction: This
85 * is only called for remote domains, and both winbindd_msrpc
86 * and winbindd_ad call into lsa_lookupsids anyway. Caching is
87 * done at the wbint RPC layer.
88 */
89 status = rpc_lookup_sids(p->mem_ctx, domain, r->in.sids,
90 &r->out.domains, &r->out.names);
91 reset_cm_connection_on_error(domain, status);
92 return status;
93}
94
95NTSTATUS _wbint_LookupName(struct pipes_struct *p, struct wbint_LookupName *r)
96{
97 struct winbindd_domain *domain = wb_child_domain();
98 NTSTATUS status;
99
100 if (domain == NULL) {
101 return NT_STATUS_REQUEST_NOT_ACCEPTED;
102 }
103
104 status = domain->methods->name_to_sid(
105 domain, p->mem_ctx, r->in.domain, r->in.name, r->in.flags,
106 r->out.sid, r->out.type);
107 reset_cm_connection_on_error(domain, status);
108 return status;
109}
110
111NTSTATUS _wbint_Sid2Uid(struct pipes_struct *p, struct wbint_Sid2Uid *r)
112{
113 uid_t uid;
114 NTSTATUS status;
115
116 status = idmap_sid_to_uid(r->in.dom_name ? r->in.dom_name : "",
117 r->in.sid, &uid);
118 if (!NT_STATUS_IS_OK(status)) {
119 return status;
120 }
121 *r->out.uid = uid;
122 return NT_STATUS_OK;
123}
124
125NTSTATUS _wbint_Sid2Gid(struct pipes_struct *p, struct wbint_Sid2Gid *r)
126{
127 gid_t gid;
128 NTSTATUS status;
129
130 status = idmap_sid_to_gid(r->in.dom_name ? r->in.dom_name : "",
131 r->in.sid, &gid);
132 if (!NT_STATUS_IS_OK(status)) {
133 return status;
134 }
135 *r->out.gid = gid;
136 return NT_STATUS_OK;
137}
138
139NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p,
140 struct wbint_Sids2UnixIDs *r)
141{
142 uint32_t i, j;
143 struct id_map *ids = NULL;
144 struct id_map **id_ptrs = NULL;
145 struct dom_sid *sids = NULL;
146 uint32_t *id_idx = NULL;
147 NTSTATUS status = NT_STATUS_NO_MEMORY;
148
149 for (i=0; i<r->in.domains->count; i++) {
150 struct lsa_DomainInfo *d = &r->in.domains->domains[i];
151 struct idmap_domain *dom;
152 uint32_t num_ids;
153
154 dom = idmap_find_domain(d->name.string);
155 if (dom == NULL) {
156 DEBUG(10, ("idmap domain %s not found\n",
157 d->name.string));
158 continue;
159 }
160
161 num_ids = 0;
162
163 for (j=0; j<r->in.ids->num_ids; j++) {
164 if (r->in.ids->ids[j].domain_index == i) {
165 num_ids += 1;
166 }
167 }
168
169 ids = TALLOC_REALLOC_ARRAY(talloc_tos(), ids,
170 struct id_map, num_ids);
171 if (ids == NULL) {
172 goto nomem;
173 }
174 id_ptrs = TALLOC_REALLOC_ARRAY(talloc_tos(), id_ptrs,
175 struct id_map *, num_ids+1);
176 if (id_ptrs == NULL) {
177 goto nomem;
178 }
179 id_idx = TALLOC_REALLOC_ARRAY(talloc_tos(), id_idx,
180 uint32_t, num_ids);
181 if (id_idx == NULL) {
182 goto nomem;
183 }
184 sids = TALLOC_REALLOC_ARRAY(talloc_tos(), sids,
185 struct dom_sid, num_ids);
186 if (sids == NULL) {
187 goto nomem;
188 }
189
190 num_ids = 0;
191
192 for (j=0; j<r->in.ids->num_ids; j++) {
193 struct wbint_TransID *id = &r->in.ids->ids[j];
194
195 if (id->domain_index != i) {
196 continue;
197 }
198 id_idx[num_ids] = j;
199 id_ptrs[num_ids] = &ids[num_ids];
200
201 ids[num_ids].sid = &sids[num_ids];
202 sid_compose(ids[num_ids].sid, d->sid, id->rid);
203 ids[num_ids].xid.type = id->type;
204 ids[num_ids].status = ID_UNKNOWN;
205 num_ids += 1;
206 }
207 id_ptrs[num_ids] = NULL;
208
209 status = dom->methods->sids_to_unixids(dom, id_ptrs);
210 DEBUG(10, ("sids_to_unixids returned %s\n",
211 nt_errstr(status)));
212
213 for (j=0; j<num_ids; j++) {
214 struct wbint_TransID *id = &r->in.ids->ids[id_idx[j]];
215
216 if (ids[j].status != ID_MAPPED) {
217 continue;
218 }
219 id->unix_id = ids[j].xid.id;
220 }
221 }
222 status = NT_STATUS_OK;
223nomem:
224 TALLOC_FREE(ids);
225 TALLOC_FREE(id_ptrs);
226 TALLOC_FREE(id_idx);
227 TALLOC_FREE(sids);
228 return status;
229}
230
231NTSTATUS _wbint_Uid2Sid(struct pipes_struct *p, struct wbint_Uid2Sid *r)
232{
233 return idmap_uid_to_sid(r->in.dom_name ? r->in.dom_name : "",
234 r->out.sid, r->in.uid);
235}
236
237NTSTATUS _wbint_Gid2Sid(struct pipes_struct *p, struct wbint_Gid2Sid *r)
238{
239 return idmap_gid_to_sid(r->in.dom_name ? r->in.dom_name : "",
240 r->out.sid, r->in.gid);
241}
242
243NTSTATUS _wbint_AllocateUid(struct pipes_struct *p, struct wbint_AllocateUid *r)
244{
245 struct unixid xid;
246 NTSTATUS status;
247
248 status = idmap_allocate_uid(&xid);
249 if (!NT_STATUS_IS_OK(status)) {
250 return status;
251 }
252 *r->out.uid = xid.id;
253 return NT_STATUS_OK;
254}
255
256NTSTATUS _wbint_AllocateGid(struct pipes_struct *p, struct wbint_AllocateGid *r)
257{
258 struct unixid xid;
259 NTSTATUS status;
260
261 status = idmap_allocate_gid(&xid);
262 if (!NT_STATUS_IS_OK(status)) {
263 return status;
264 }
265 *r->out.gid = xid.id;
266 return NT_STATUS_OK;
267}
268
269NTSTATUS _wbint_QueryUser(struct pipes_struct *p, struct wbint_QueryUser *r)
270{
271 struct winbindd_domain *domain = wb_child_domain();
272 NTSTATUS status;
273
274 if (domain == NULL) {
275 return NT_STATUS_REQUEST_NOT_ACCEPTED;
276 }
277
278 status = domain->methods->query_user(domain, p->mem_ctx, r->in.sid,
279 r->out.info);
280 reset_cm_connection_on_error(domain, status);
281 return status;
282}
283
284NTSTATUS _wbint_LookupUserAliases(struct pipes_struct *p,
285 struct wbint_LookupUserAliases *r)
286{
287 struct winbindd_domain *domain = wb_child_domain();
288 NTSTATUS status;
289
290 if (domain == NULL) {
291 return NT_STATUS_REQUEST_NOT_ACCEPTED;
292 }
293
294 status = domain->methods->lookup_useraliases(
295 domain, p->mem_ctx, r->in.sids->num_sids, r->in.sids->sids,
296 &r->out.rids->num_rids, &r->out.rids->rids);
297 reset_cm_connection_on_error(domain, status);
298 return status;
299}
300
301NTSTATUS _wbint_LookupUserGroups(struct pipes_struct *p,
302 struct wbint_LookupUserGroups *r)
303{
304 struct winbindd_domain *domain = wb_child_domain();
305 NTSTATUS status;
306
307 if (domain == NULL) {
308 return NT_STATUS_REQUEST_NOT_ACCEPTED;
309 }
310
311 status = domain->methods->lookup_usergroups(
312 domain, p->mem_ctx, r->in.sid,
313 &r->out.sids->num_sids, &r->out.sids->sids);
314 reset_cm_connection_on_error(domain, status);
315 return status;
316}
317
318NTSTATUS _wbint_QuerySequenceNumber(struct pipes_struct *p,
319 struct wbint_QuerySequenceNumber *r)
320{
321 struct winbindd_domain *domain = wb_child_domain();
322 NTSTATUS status;
323
324 if (domain == NULL) {
325 return NT_STATUS_REQUEST_NOT_ACCEPTED;
326 }
327
328 status = domain->methods->sequence_number(domain, r->out.sequence);
329 reset_cm_connection_on_error(domain, status);
330 return status;
331}
332
333NTSTATUS _wbint_LookupGroupMembers(struct pipes_struct *p,
334 struct wbint_LookupGroupMembers *r)
335{
336 struct winbindd_domain *domain = wb_child_domain();
337 uint32_t i, num_names;
338 struct dom_sid *sid_mem;
339 char **names;
340 uint32_t *name_types;
341 NTSTATUS status;
342
343 if (domain == NULL) {
344 return NT_STATUS_REQUEST_NOT_ACCEPTED;
345 }
346
347 status = domain->methods->lookup_groupmem(
348 domain, p->mem_ctx, r->in.sid, r->in.type,
349 &num_names, &sid_mem, &names, &name_types);
350 reset_cm_connection_on_error(domain, status);
351 if (!NT_STATUS_IS_OK(status)) {
352 return status;
353 }
354
355 r->out.members->num_principals = num_names;
356 r->out.members->principals = talloc_array(
357 r->out.members, struct wbint_Principal, num_names);
358 if (r->out.members->principals == NULL) {
359 return NT_STATUS_NO_MEMORY;
360 }
361
362 for (i=0; i<num_names; i++) {
363 struct wbint_Principal *m = &r->out.members->principals[i];
364 sid_copy(&m->sid, &sid_mem[i]);
365 m->name = talloc_move(r->out.members->principals, &names[i]);
366 m->type = (enum lsa_SidType)name_types[i];
367 }
368
369 return NT_STATUS_OK;
370}
371
372NTSTATUS _wbint_QueryUserList(struct pipes_struct *p,
373 struct wbint_QueryUserList *r)
374{
375 struct winbindd_domain *domain = wb_child_domain();
376 NTSTATUS status;
377
378 if (domain == NULL) {
379 return NT_STATUS_REQUEST_NOT_ACCEPTED;
380 }
381
382 status = domain->methods->query_user_list(
383 domain, p->mem_ctx, &r->out.users->num_userinfos,
384 &r->out.users->userinfos);
385 reset_cm_connection_on_error(domain, status);
386 return status;
387}
388
389NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p,
390 struct wbint_QueryGroupList *r)
391{
392 struct winbindd_domain *domain = wb_child_domain();
393 uint32_t i, num_groups;
394 struct wb_acct_info *groups;
395 struct wbint_Principal *result;
396 NTSTATUS status;
397
398 if (domain == NULL) {
399 return NT_STATUS_REQUEST_NOT_ACCEPTED;
400 }
401
402 status = domain->methods->enum_dom_groups(domain, talloc_tos(),
403 &num_groups, &groups);
404 reset_cm_connection_on_error(domain, status);
405 if (!NT_STATUS_IS_OK(status)) {
406 return status;
407 }
408
409 result = talloc_array(r->out.groups, struct wbint_Principal,
410 num_groups);
411 if (result == NULL) {
412 return NT_STATUS_NO_MEMORY;
413 }
414
415 for (i=0; i<num_groups; i++) {
416 sid_compose(&result[i].sid, &domain->sid, groups[i].rid);
417 result[i].type = SID_NAME_DOM_GRP;
418 result[i].name = talloc_strdup(result, groups[i].acct_name);
419 if (result[i].name == NULL) {
420 TALLOC_FREE(result);
421 TALLOC_FREE(groups);
422 return NT_STATUS_NO_MEMORY;
423 }
424 }
425
426 r->out.groups->num_principals = num_groups;
427 r->out.groups->principals = result;
428
429 TALLOC_FREE(groups);
430 return NT_STATUS_OK;
431}
432
433NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct wbint_DsGetDcName *r)
434{
435 struct winbindd_domain *domain = wb_child_domain();
436 struct rpc_pipe_client *netlogon_pipe;
437 struct netr_DsRGetDCNameInfo *dc_info;
438 NTSTATUS status;
439 WERROR werr;
440 unsigned int orig_timeout;
441 struct dcerpc_binding_handle *b;
442
443 if (domain == NULL) {
444 return dsgetdcname(p->mem_ctx, winbind_messaging_context(),
445 r->in.domain_name, r->in.domain_guid,
446 r->in.site_name ? r->in.site_name : "",
447 r->in.flags,
448 r->out.dc_info);
449 }
450
451 status = cm_connect_netlogon(domain, &netlogon_pipe);
452
453 reset_cm_connection_on_error(domain, status);
454 if (!NT_STATUS_IS_OK(status)) {
455 DEBUG(10, ("Can't contact the NETLOGON pipe\n"));
456 return status;
457 }
458
459 b = netlogon_pipe->binding_handle;
460
461 /* This call can take a long time - allow the server to time out.
462 35 seconds should do it. */
463
464 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
465
466 if (domain->active_directory) {
467 status = dcerpc_netr_DsRGetDCName(b,
468 p->mem_ctx, domain->dcname,
469 r->in.domain_name, NULL, r->in.domain_guid,
470 r->in.flags, r->out.dc_info, &werr);
471 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(werr)) {
472 goto done;
473 }
474 if (reset_cm_connection_on_error(domain, status)) {
475 /* Re-initialize. */
476 status = cm_connect_netlogon(domain, &netlogon_pipe);
477
478 reset_cm_connection_on_error(domain, status);
479 if (!NT_STATUS_IS_OK(status)) {
480 DEBUG(10, ("Can't contact the NETLOGON pipe\n"));
481 return status;
482 }
483
484 b = netlogon_pipe->binding_handle;
485
486 /* This call can take a long time - allow the server to time out.
487 35 seconds should do it. */
488
489 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
490 }
491 }
492
493 /*
494 * Fallback to less capable methods
495 */
496
497 dc_info = talloc_zero(r->out.dc_info, struct netr_DsRGetDCNameInfo);
498 if (dc_info == NULL) {
499 status = NT_STATUS_NO_MEMORY;
500 goto done;
501 }
502
503 if (r->in.flags & DS_PDC_REQUIRED) {
504 status = dcerpc_netr_GetDcName(b,
505 p->mem_ctx, domain->dcname,
506 r->in.domain_name, &dc_info->dc_unc, &werr);
507 } else {
508 status = dcerpc_netr_GetAnyDCName(b,
509 p->mem_ctx, domain->dcname,
510 r->in.domain_name, &dc_info->dc_unc, &werr);
511 }
512
513 reset_cm_connection_on_error(domain, status);
514 if (!NT_STATUS_IS_OK(status)) {
515 DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
516 nt_errstr(status)));
517 goto done;
518 }
519 if (!W_ERROR_IS_OK(werr)) {
520 DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
521 win_errstr(werr)));
522 status = werror_to_ntstatus(werr);
523 goto done;
524 }
525
526 *r->out.dc_info = dc_info;
527 status = NT_STATUS_OK;
528
529done:
530 /* And restore our original timeout. */
531 rpccli_set_timeout(netlogon_pipe, orig_timeout);
532
533 return status;
534}
535
536NTSTATUS _wbint_LookupRids(struct pipes_struct *p, struct wbint_LookupRids *r)
537{
538 struct winbindd_domain *domain = wb_child_domain();
539 char *domain_name;
540 char **names;
541 enum lsa_SidType *types;
542 struct wbint_Principal *result;
543 NTSTATUS status;
544 int i;
545
546 if (domain == NULL) {
547 return NT_STATUS_REQUEST_NOT_ACCEPTED;
548 }
549
550 status = domain->methods->rids_to_names(
551 domain, talloc_tos(), r->in.domain_sid, r->in.rids->rids,
552 r->in.rids->num_rids, &domain_name, &names, &types);
553 reset_cm_connection_on_error(domain, status);
554 if (!NT_STATUS_IS_OK(status)) {
555 return status;
556 }
557
558 *r->out.domain_name = talloc_move(r->out.domain_name, &domain_name);
559
560 result = talloc_array(p->mem_ctx, struct wbint_Principal,
561 r->in.rids->num_rids);
562 if (result == NULL) {
563 return NT_STATUS_NO_MEMORY;
564 }
565
566 for (i=0; i<r->in.rids->num_rids; i++) {
567 sid_compose(&result[i].sid, r->in.domain_sid,
568 r->in.rids->rids[i]);
569 result[i].type = types[i];
570 result[i].name = talloc_move(result, &names[i]);
571 }
572 TALLOC_FREE(types);
573 TALLOC_FREE(names);
574
575 r->out.names->num_principals = r->in.rids->num_rids;
576 r->out.names->principals = result;
577 return NT_STATUS_OK;
578}
579
580NTSTATUS _wbint_CheckMachineAccount(struct pipes_struct *p,
581 struct wbint_CheckMachineAccount *r)
582{
583 struct winbindd_domain *domain;
584 int num_retries = 0;
585 NTSTATUS status;
586
587 domain = wb_child_domain();
588 if (domain == NULL) {
589 return NT_STATUS_REQUEST_NOT_ACCEPTED;
590 }
591
592again:
593 invalidate_cm_connection(&domain->conn);
594
595 {
596 struct rpc_pipe_client *netlogon_pipe;
597 status = cm_connect_netlogon(domain, &netlogon_pipe);
598 }
599
600 /* There is a race condition between fetching the trust account
601 password and the periodic machine password change. So it's
602 possible that the trust account password has been changed on us.
603 We are returned NT_STATUS_ACCESS_DENIED if this happens. */
604
605#define MAX_RETRIES 3
606
607 if ((num_retries < MAX_RETRIES)
608 && NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
609 num_retries++;
610 goto again;
611 }
612
613 if (!NT_STATUS_IS_OK(status)) {
614 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
615 goto done;
616 }
617
618 /* Pass back result code - zero for success, other values for
619 specific failures. */
620
621 DEBUG(3,("domain %s secret is %s\n", domain->name,
622 NT_STATUS_IS_OK(status) ? "good" : "bad"));
623
624 done:
625 DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2,
626 ("Checking the trust account password for domain %s returned %s\n",
627 domain->name, nt_errstr(status)));
628
629 return status;
630}
631
632NTSTATUS _wbint_ChangeMachineAccount(struct pipes_struct *p,
633 struct wbint_ChangeMachineAccount *r)
634{
635 struct winbindd_domain *domain;
636 int num_retries = 0;
637 NTSTATUS status;
638 struct rpc_pipe_client *netlogon_pipe;
639 TALLOC_CTX *tmp_ctx;
640
641again:
642 domain = wb_child_domain();
643 if (domain == NULL) {
644 return NT_STATUS_REQUEST_NOT_ACCEPTED;
645 }
646
647 invalidate_cm_connection(&domain->conn);
648
649 {
650 status = cm_connect_netlogon(domain, &netlogon_pipe);
651 }
652
653 /* There is a race condition between fetching the trust account
654 password and the periodic machine password change. So it's
655 possible that the trust account password has been changed on us.
656 We are returned NT_STATUS_ACCESS_DENIED if this happens. */
657
658#define MAX_RETRIES 3
659
660 if ((num_retries < MAX_RETRIES)
661 && NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
662 num_retries++;
663 goto again;
664 }
665
666 if (!NT_STATUS_IS_OK(status)) {
667 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
668 goto done;
669 }
670
671 tmp_ctx = talloc_new(p->mem_ctx);
672
673 status = trust_pw_find_change_and_store_it(netlogon_pipe,
674 tmp_ctx,
675 domain->name);
676 talloc_destroy(tmp_ctx);
677
678 /* Pass back result code - zero for success, other values for
679 specific failures. */
680
681 DEBUG(3,("domain %s secret %s\n", domain->name,
682 NT_STATUS_IS_OK(status) ? "changed" : "unchanged"));
683
684 done:
685 DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2,
686 ("Changing the trust account password for domain %s returned %s\n",
687 domain->name, nt_errstr(status)));
688
689 return status;
690}
691
692NTSTATUS _wbint_PingDc(struct pipes_struct *p, struct wbint_PingDc *r)
693{
694 NTSTATUS status;
695 struct winbindd_domain *domain;
696 struct rpc_pipe_client *netlogon_pipe;
697 union netr_CONTROL_QUERY_INFORMATION info;
698 WERROR werr;
699 fstring logon_server;
700 struct dcerpc_binding_handle *b;
701
702 domain = wb_child_domain();
703 if (domain == NULL) {
704 return NT_STATUS_REQUEST_NOT_ACCEPTED;
705 }
706
707 status = cm_connect_netlogon(domain, &netlogon_pipe);
708 reset_cm_connection_on_error(domain, status);
709 if (!NT_STATUS_IS_OK(status)) {
710 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
711 return status;
712 }
713
714 b = netlogon_pipe->binding_handle;
715
716 fstr_sprintf(logon_server, "\\\\%s", domain->dcname);
717
718 /*
719 * This provokes a WERR_NOT_SUPPORTED error message. This is
720 * documented in the wspp docs. I could not get a successful
721 * call to work, but the main point here is testing that the
722 * netlogon pipe works.
723 */
724 status = dcerpc_netr_LogonControl(b, p->mem_ctx,
725 logon_server, NETLOGON_CONTROL_QUERY,
726 2, &info, &werr);
727
728 reset_cm_connection_on_error(domain, status);
729 if (!NT_STATUS_IS_OK(status)) {
730 DEBUG(2, ("dcerpc_netr_LogonControl failed: %s\n",
731 nt_errstr(status)));
732 return status;
733 }
734
735 if (!W_ERROR_EQUAL(werr, WERR_NOT_SUPPORTED)) {
736 DEBUG(2, ("dcerpc_netr_LogonControl returned %s, expected "
737 "WERR_NOT_SUPPORTED\n",
738 win_errstr(werr)));
739 return werror_to_ntstatus(werr);
740 }
741
742 DEBUG(5, ("winbindd_dual_ping_dc succeeded\n"));
743 return NT_STATUS_OK;
744}
Note: See TracBrowser for help on using the repository browser.