source: branches/samba-3.2.x/source/winbindd/winbindd_misc.c

Last change on this file was 138, checked in by Paul Smedley, 17 years ago

Update source to 3.2.0 GA level

File size: 23.2 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 Winbind daemon - miscellaneous other functions
5
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Bartlett 2002
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.h"
25
26#undef DBGC_CLASS
27#define DBGC_CLASS DBGC_WINBIND
28
29/* Check the machine account password is valid */
30
31void winbindd_check_machine_acct(struct winbindd_cli_state *state)
32{
33 DEBUG(3, ("[%5lu]: check machine account\n",
34 (unsigned long)state->pid));
35
36 sendto_domain(state, find_our_domain());
37}
38
39enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *domain,
40 struct winbindd_cli_state *state)
41{
42 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
43 int num_retries = 0;
44 struct winbindd_domain *contact_domain;
45
46 DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid));
47
48 /* Get trust account password */
49
50 again:
51
52 contact_domain = find_our_domain();
53
54 /* This call does a cli_nt_setup_creds() which implicitly checks
55 the trust account password. */
56
57 invalidate_cm_connection(&contact_domain->conn);
58
59 {
60 struct rpc_pipe_client *netlogon_pipe;
61 result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
62 }
63
64 if (!NT_STATUS_IS_OK(result)) {
65 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
66 goto done;
67 }
68
69 /* There is a race condition between fetching the trust account
70 password and the periodic machine password change. So it's
71 possible that the trust account password has been changed on us.
72 We are returned NT_STATUS_ACCESS_DENIED if this happens. */
73
74#define MAX_RETRIES 8
75
76 if ((num_retries < MAX_RETRIES) &&
77 NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
78 num_retries++;
79 goto again;
80 }
81
82 /* Pass back result code - zero for success, other values for
83 specific failures. */
84
85 DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(result) ?
86 "good" : "bad"));
87
88 done:
89 state->response.data.auth.nt_status = NT_STATUS_V(result);
90 fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
91 fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
92 state->response.data.auth.pam_error = nt_status_to_pam(result);
93
94 DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Checking the trust account password returned %s\n",
95 state->response.data.auth.nt_status_string));
96
97 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
98}
99
100/* Helpers for listing user and group names */
101
102const char *ent_type_strings[] = {"users",
103 "groups"};
104
105static const char *get_ent_type_string(enum ent_type type)
106{
107 return ent_type_strings[type];
108}
109
110struct listent_state {
111 TALLOC_CTX *mem_ctx;
112 struct winbindd_cli_state *cli_state;
113 enum ent_type type;
114 int domain_count;
115 char *extra_data;
116 uint32_t extra_data_len;
117};
118
119static void listent_recv(void *private_data, bool success, fstring dom_name,
120 char *extra_data);
121
122/* List domain users/groups without mapping to unix ids */
123void winbindd_list_ent(struct winbindd_cli_state *state, enum ent_type type)
124{
125 struct winbindd_domain *domain;
126 const char *which_domain;
127 struct listent_state *ent_state;
128
129 DEBUG(3, ("[%5lu]: list %s\n", (unsigned long)state->pid,
130 get_ent_type_string(type)));
131
132 /* Ensure null termination */
133 state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
134 which_domain = state->request.domain_name;
135
136 /* Initialize listent_state */
137 ent_state = TALLOC_P(state->mem_ctx, struct listent_state);
138 if (ent_state == NULL) {
139 DEBUG(0, ("talloc failed\n"));
140 request_error(state);
141 return;
142 }
143
144 ent_state->mem_ctx = state->mem_ctx;
145 ent_state->cli_state = state;
146 ent_state->type = type;
147 ent_state->domain_count = 0;
148 ent_state->extra_data = NULL;
149 ent_state->extra_data_len = 0;
150
151 /* Must count the full list of expected domains before we request data
152 * from any of them. Otherwise it's possible for a connection to the
153 * first domain to fail, call listent_recv(), and return to the
154 * client without checking any other domains. */
155 for (domain = domain_list(); domain; domain = domain->next) {
156 /* if we have a domain name restricting the request and this
157 one in the list doesn't match, then just bypass the remainder
158 of the loop */
159 if ( *which_domain && !strequal(which_domain, domain->name) )
160 continue;
161
162 ent_state->domain_count++;
163 }
164
165 /* Make sure we're enumerating at least one domain */
166 if (!ent_state->domain_count) {
167 request_ok(state);
168 return;
169 }
170
171 /* Enumerate list of trusted domains and request user/group list from
172 * each */
173 for (domain = domain_list(); domain; domain = domain->next) {
174 if ( *which_domain && !strequal(which_domain, domain->name) )
175 continue;
176
177 winbindd_listent_async(state->mem_ctx, domain,
178 listent_recv, ent_state, type);
179 }
180}
181
182static void listent_recv(void *private_data, bool success, fstring dom_name,
183 char *extra_data)
184{
185 /* extra_data comes to us as a '\0' terminated string of comma
186 separated users or groups */
187 struct listent_state *state = talloc_get_type_abort(
188 private_data, struct listent_state);
189
190 /* Append users/groups from one domain onto the whole list */
191 if (extra_data) {
192 DEBUG(5, ("listent_recv: %s returned %s.\n",
193 dom_name, get_ent_type_string(state->type)));
194 if (!state->extra_data)
195 state->extra_data = talloc_asprintf(state->mem_ctx,
196 "%s", extra_data);
197 else
198 state->extra_data = talloc_asprintf_append(
199 state->extra_data,
200 ",%s", extra_data);
201 /* Add one for the '\0' and each additional ',' */
202 state->extra_data_len += strlen(extra_data) + 1;
203 }
204 else {
205 DEBUG(5, ("listent_recv: %s returned no %s.\n",
206 dom_name, get_ent_type_string(state->type)));
207 }
208
209 if (--state->domain_count)
210 /* Still waiting for some child domains to return */
211 return;
212
213 /* Return list of all users/groups to the client */
214 if (state->extra_data) {
215 state->cli_state->response.extra_data.data =
216 SMB_STRDUP(state->extra_data);
217 state->cli_state->response.length += state->extra_data_len;
218 }
219
220 request_ok(state->cli_state);
221}
222
223/* Constants and helper functions for determining domain trust types */
224
225enum trust_type {
226 EXTERNAL = 0,
227 FOREST,
228 IN_FOREST,
229 NONE,
230};
231
232const char *trust_type_strings[] = {"External",
233 "Forest",
234 "In Forest",
235 "None"};
236
237static enum trust_type get_trust_type(struct winbindd_tdc_domain *domain)
238{
239 if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN)
240 return EXTERNAL;
241 else if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)
242 return FOREST;
243 else if (((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == NETR_TRUST_FLAG_IN_FOREST) &&
244 ((domain->trust_flags & NETR_TRUST_FLAG_PRIMARY) == 0x0))
245 return IN_FOREST;
246 return NONE;
247}
248
249static const char *get_trust_type_string(struct winbindd_tdc_domain *domain)
250{
251 return trust_type_strings[get_trust_type(domain)];
252}
253
254static bool trust_is_inbound(struct winbindd_tdc_domain *domain)
255{
256 return (domain->trust_flags == 0x0) ||
257 ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) ==
258 NETR_TRUST_FLAG_IN_FOREST) ||
259 ((domain->trust_flags & NETR_TRUST_FLAG_INBOUND) ==
260 NETR_TRUST_FLAG_INBOUND);
261}
262
263static bool trust_is_outbound(struct winbindd_tdc_domain *domain)
264{
265 return (domain->trust_flags == 0x0) ||
266 ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) ==
267 NETR_TRUST_FLAG_IN_FOREST) ||
268 ((domain->trust_flags & NETR_TRUST_FLAG_OUTBOUND) ==
269 NETR_TRUST_FLAG_OUTBOUND);
270}
271
272static bool trust_is_transitive(struct winbindd_tdc_domain *domain)
273{
274 if ((domain->trust_attribs == NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE) ||
275 (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) ||
276 (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL))
277 return False;
278 return True;
279}
280
281void winbindd_list_trusted_domains(struct winbindd_cli_state *state)
282{
283 struct winbindd_tdc_domain *dom_list = NULL;
284 struct winbindd_tdc_domain *d = NULL;
285 size_t num_domains = 0;
286 int extra_data_len = 0;
287 char *extra_data = NULL;
288 int i = 0;
289
290 DEBUG(3, ("[%5lu]: list trusted domains\n",
291 (unsigned long)state->pid));
292
293 if( !wcache_tdc_fetch_list( &dom_list, &num_domains )) {
294 request_error(state);
295 goto done;
296 }
297
298 for ( i = 0; i < num_domains; i++ ) {
299 struct winbindd_domain *domain;
300 bool is_online = true;
301
302 d = &dom_list[i];
303 domain = find_domain_from_name_noinit(d->domain_name);
304 if (domain) {
305 is_online = domain->online;
306 }
307
308 if ( !extra_data ) {
309 extra_data = talloc_asprintf(state->mem_ctx,
310 "%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s",
311 d->domain_name,
312 d->dns_name ? d->dns_name : d->domain_name,
313 sid_string_talloc(state->mem_ctx, &d->sid),
314 get_trust_type_string(d),
315 trust_is_transitive(d) ? "Yes" : "No",
316 trust_is_inbound(d) ? "Yes" : "No",
317 trust_is_outbound(d) ? "Yes" : "No",
318 is_online ? "Online" : "Offline" );
319 } else {
320 extra_data = talloc_asprintf(state->mem_ctx,
321 "%s\n%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s",
322 extra_data,
323 d->domain_name,
324 d->dns_name ? d->dns_name : d->domain_name,
325 sid_string_talloc(state->mem_ctx, &d->sid),
326 get_trust_type_string(d),
327 trust_is_transitive(d) ? "Yes" : "No",
328 trust_is_inbound(d) ? "Yes" : "No",
329 trust_is_outbound(d) ? "Yes" : "No",
330 is_online ? "Online" : "Offline" );
331 }
332 }
333
334 extra_data_len = 0;
335 if (extra_data != NULL) {
336 extra_data_len = strlen(extra_data);
337 }
338
339 if (extra_data_len > 0) {
340 state->response.extra_data.data = SMB_STRDUP(extra_data);
341 state->response.length += extra_data_len+1;
342 }
343
344 request_ok(state);
345done:
346 TALLOC_FREE( dom_list );
347 TALLOC_FREE( extra_data );
348}
349
350enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain,
351 struct winbindd_cli_state *state)
352{
353 uint32 i, num_domains;
354 char **names, **alt_names;
355 DOM_SID *sids;
356 int extra_data_len = 0;
357 char *extra_data;
358 NTSTATUS result;
359 bool have_own_domain = False;
360
361 DEBUG(3, ("[%5lu]: list trusted domains\n",
362 (unsigned long)state->pid));
363
364 result = domain->methods->trusted_domains(domain, state->mem_ctx,
365 &num_domains, &names,
366 &alt_names, &sids);
367
368 if (!NT_STATUS_IS_OK(result)) {
369 DEBUG(3, ("winbindd_dual_list_trusted_domains: trusted_domains returned %s\n",
370 nt_errstr(result) ));
371 return WINBINDD_ERROR;
372 }
373
374 extra_data = talloc_strdup(state->mem_ctx, "");
375
376 if (num_domains > 0)
377 extra_data = talloc_asprintf(
378 state->mem_ctx, "%s\\%s\\%s",
379 names[0], alt_names[0] ? alt_names[0] : names[0],
380 sid_string_talloc(state->mem_ctx, &sids[0]));
381
382 for (i=1; i<num_domains; i++)
383 extra_data = talloc_asprintf(
384 state->mem_ctx, "%s\n%s\\%s\\%s",
385 extra_data, names[i],
386 alt_names[i] ? alt_names[i] : names[i],
387 sid_string_talloc(state->mem_ctx, &sids[i]));
388
389 /* add our primary domain */
390
391 for (i=0; i<num_domains; i++) {
392 if (strequal(names[i], domain->name)) {
393 have_own_domain = True;
394 break;
395 }
396 }
397
398 if (state->request.data.list_all_domains && !have_own_domain) {
399 extra_data = talloc_asprintf(
400 state->mem_ctx, "%s\n%s\\%s\\%s",
401 extra_data, domain->name,
402 domain->alt_name ? domain->alt_name : domain->name,
403 sid_string_talloc(state->mem_ctx, &domain->sid));
404 }
405
406 /* This is a bit excessive, but the extra data sooner or later will be
407 talloc'ed */
408
409 extra_data_len = 0;
410 if (extra_data != NULL) {
411 extra_data_len = strlen(extra_data);
412 }
413
414 if (extra_data_len > 0) {
415 state->response.extra_data.data = SMB_STRDUP(extra_data);
416 state->response.length += extra_data_len+1;
417 }
418
419 return WINBINDD_OK;
420}
421
422void winbindd_getdcname(struct winbindd_cli_state *state)
423{
424 struct winbindd_domain *domain;
425
426 state->request.domain_name
427 [sizeof(state->request.domain_name)-1] = '\0';
428
429 DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid,
430 state->request.domain_name));
431
432 domain = find_domain_from_name_noinit(state->request.domain_name);
433 if (domain && domain->internal) {
434 fstrcpy(state->response.data.dc_name, global_myname());
435 request_ok(state);
436 return;
437 }
438
439 sendto_domain(state, find_our_domain());
440}
441
442enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
443 struct winbindd_cli_state *state)
444{
445 const char *dcname_slash = NULL;
446 const char *p;
447 struct rpc_pipe_client *netlogon_pipe;
448 NTSTATUS result;
449 WERROR werr;
450 unsigned int orig_timeout;
451 struct winbindd_domain *req_domain;
452
453 state->request.domain_name
454 [sizeof(state->request.domain_name)-1] = '\0';
455
456 DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid,
457 state->request.domain_name));
458
459 result = cm_connect_netlogon(domain, &netlogon_pipe);
460
461 if (!NT_STATUS_IS_OK(result)) {
462 DEBUG(1, ("Can't contact the NETLOGON pipe\n"));
463 return WINBINDD_ERROR;
464 }
465
466 /* This call can take a long time - allow the server to time out.
467 35 seconds should do it. */
468
469 orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);
470
471 req_domain = find_domain_from_name_noinit(state->request.domain_name);
472 if (req_domain == domain) {
473 result = rpccli_netr_GetDcName(netlogon_pipe,
474 state->mem_ctx,
475 domain->dcname,
476 state->request.domain_name,
477 &dcname_slash,
478 &werr);
479 } else {
480 result = rpccli_netr_GetAnyDCName(netlogon_pipe,
481 state->mem_ctx,
482 domain->dcname,
483 state->request.domain_name,
484 &dcname_slash,
485 &werr);
486 }
487 /* And restore our original timeout. */
488 cli_set_timeout(netlogon_pipe->cli, orig_timeout);
489
490 if (!NT_STATUS_IS_OK(result)) {
491 DEBUG(5,("Error requesting DCname for domain %s: %s\n",
492 state->request.domain_name, nt_errstr(result)));
493 return WINBINDD_ERROR;
494 }
495
496 if (!W_ERROR_IS_OK(werr)) {
497 DEBUG(5, ("Error requesting DCname for domain %s: %s\n",
498 state->request.domain_name, dos_errstr(werr)));
499 return WINBINDD_ERROR;
500 }
501
502 p = dcname_slash;
503 if (*p == '\\') {
504 p+=1;
505 }
506 if (*p == '\\') {
507 p+=1;
508 }
509
510 fstrcpy(state->response.data.dc_name, p);
511 return WINBINDD_OK;
512}
513
514struct sequence_state {
515 TALLOC_CTX *mem_ctx;
516 struct winbindd_cli_state *cli_state;
517 struct winbindd_domain *domain;
518 struct winbindd_request *request;
519 struct winbindd_response *response;
520 char *extra_data;
521};
522
523static void sequence_recv(void *private_data, bool success);
524
525void winbindd_show_sequence(struct winbindd_cli_state *state)
526{
527 struct sequence_state *seq;
528
529 /* Ensure null termination */
530 state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
531
532 if (strlen(state->request.domain_name) > 0) {
533 struct winbindd_domain *domain;
534 domain = find_domain_from_name_noinit(
535 state->request.domain_name);
536 if (domain == NULL) {
537 request_error(state);
538 return;
539 }
540 sendto_domain(state, domain);
541 return;
542 }
543
544 /* Ask all domains in sequence, collect the results in sequence_recv */
545
546 seq = TALLOC_P(state->mem_ctx, struct sequence_state);
547 if (seq == NULL) {
548 DEBUG(0, ("talloc failed\n"));
549 request_error(state);
550 return;
551 }
552
553 seq->mem_ctx = state->mem_ctx;
554 seq->cli_state = state;
555 seq->domain = domain_list();
556 if (seq->domain == NULL) {
557 DEBUG(0, ("domain list empty\n"));
558 request_error(state);
559 return;
560 }
561 seq->request = TALLOC_ZERO_P(state->mem_ctx,
562 struct winbindd_request);
563 seq->response = TALLOC_ZERO_P(state->mem_ctx,
564 struct winbindd_response);
565 seq->extra_data = talloc_strdup(state->mem_ctx, "");
566
567 if ((seq->request == NULL) || (seq->response == NULL) ||
568 (seq->extra_data == NULL)) {
569 DEBUG(0, ("talloc failed\n"));
570 request_error(state);
571 return;
572 }
573
574 seq->request->length = sizeof(*seq->request);
575 seq->request->cmd = WINBINDD_SHOW_SEQUENCE;
576 fstrcpy(seq->request->domain_name, seq->domain->name);
577
578 async_domain_request(state->mem_ctx, seq->domain,
579 seq->request, seq->response,
580 sequence_recv, seq);
581}
582
583static void sequence_recv(void *private_data, bool success)
584{
585 struct sequence_state *state =
586 (struct sequence_state *)private_data;
587 uint32 seq = DOM_SEQUENCE_NONE;
588
589 if ((success) && (state->response->result == WINBINDD_OK))
590 seq = state->response->data.sequence_number;
591
592 if (seq == DOM_SEQUENCE_NONE) {
593 state->extra_data = talloc_asprintf(state->mem_ctx,
594 "%s%s : DISCONNECTED\n",
595 state->extra_data,
596 state->domain->name);
597 } else {
598 state->extra_data = talloc_asprintf(state->mem_ctx,
599 "%s%s : %d\n",
600 state->extra_data,
601 state->domain->name, seq);
602 }
603
604 state->domain->sequence_number = seq;
605
606 state->domain = state->domain->next;
607
608 if (state->domain == NULL) {
609 struct winbindd_cli_state *cli_state = state->cli_state;
610 cli_state->response.length =
611 sizeof(cli_state->response) +
612 strlen(state->extra_data) + 1;
613 cli_state->response.extra_data.data =
614 SMB_STRDUP(state->extra_data);
615 request_ok(cli_state);
616 return;
617 }
618
619 /* Ask the next domain */
620 fstrcpy(state->request->domain_name, state->domain->name);
621 async_domain_request(state->mem_ctx, state->domain,
622 state->request, state->response,
623 sequence_recv, state);
624}
625
626/* This is the child-only version of --sequence. It only allows for a single
627 * domain (ie "our" one) to be displayed. */
628
629enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain,
630 struct winbindd_cli_state *state)
631{
632 DEBUG(3, ("[%5lu]: show sequence\n", (unsigned long)state->pid));
633
634 /* Ensure null termination */
635 state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
636
637 domain->methods->sequence_number(domain, &domain->sequence_number);
638
639 state->response.data.sequence_number =
640 domain->sequence_number;
641
642 return WINBINDD_OK;
643}
644
645struct domain_info_state {
646 struct winbindd_domain *domain;
647 struct winbindd_cli_state *cli_state;
648};
649
650static void domain_info_init_recv(void *private_data, bool success);
651
652void winbindd_domain_info(struct winbindd_cli_state *state)
653{
654 struct winbindd_domain *domain;
655
656 DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)state->pid,
657 state->request.domain_name));
658
659 domain = find_domain_from_name_noinit(state->request.domain_name);
660
661 if (domain == NULL) {
662 DEBUG(3, ("Did not find domain [%s]\n",
663 state->request.domain_name));
664 request_error(state);
665 return;
666 }
667
668 if (!domain->initialized) {
669 struct domain_info_state *istate;
670
671 istate = TALLOC_P(state->mem_ctx, struct domain_info_state);
672 if (istate == NULL) {
673 DEBUG(0, ("talloc failed\n"));
674 request_error(state);
675 return;
676 }
677
678 istate->cli_state = state;
679 istate->domain = domain;
680
681 init_child_connection(domain, domain_info_init_recv, istate);
682
683 return;
684 }
685
686 fstrcpy(state->response.data.domain_info.name,
687 domain->name);
688 fstrcpy(state->response.data.domain_info.alt_name,
689 domain->alt_name);
690 sid_to_fstring(state->response.data.domain_info.sid, &domain->sid);
691
692 state->response.data.domain_info.native_mode =
693 domain->native_mode;
694 state->response.data.domain_info.active_directory =
695 domain->active_directory;
696 state->response.data.domain_info.primary =
697 domain->primary;
698
699 request_ok(state);
700}
701
702static void domain_info_init_recv(void *private_data, bool success)
703{
704 struct domain_info_state *istate =
705 (struct domain_info_state *)private_data;
706 struct winbindd_cli_state *state = istate->cli_state;
707 struct winbindd_domain *domain = istate->domain;
708
709 DEBUG(10, ("Got back from child init: %d\n", success));
710
711 if ((!success) || (!domain->initialized)) {
712 DEBUG(5, ("Could not init child for domain %s\n",
713 domain->name));
714 request_error(state);
715 return;
716 }
717
718 fstrcpy(state->response.data.domain_info.name,
719 domain->name);
720 fstrcpy(state->response.data.domain_info.alt_name,
721 domain->alt_name);
722 sid_to_fstring(state->response.data.domain_info.sid, &domain->sid);
723
724 state->response.data.domain_info.native_mode =
725 domain->native_mode;
726 state->response.data.domain_info.active_directory =
727 domain->active_directory;
728 state->response.data.domain_info.primary =
729 domain->primary;
730
731 request_ok(state);
732}
733
734void winbindd_ping(struct winbindd_cli_state *state)
735{
736 DEBUG(3, ("[%5lu]: ping\n", (unsigned long)state->pid));
737 request_ok(state);
738}
739
740/* List various tidbits of information */
741
742void winbindd_info(struct winbindd_cli_state *state)
743{
744
745 DEBUG(3, ("[%5lu]: request misc info\n", (unsigned long)state->pid));
746
747 state->response.data.info.winbind_separator = *lp_winbind_separator();
748 fstrcpy(state->response.data.info.samba_version, SAMBA_VERSION_STRING);
749 request_ok(state);
750}
751
752/* Tell the client the current interface version */
753
754void winbindd_interface_version(struct winbindd_cli_state *state)
755{
756 DEBUG(3, ("[%5lu]: request interface version\n",
757 (unsigned long)state->pid));
758
759 state->response.data.interface_version = WINBIND_INTERFACE_VERSION;
760 request_ok(state);
761}
762
763/* What domain are we a member of? */
764
765void winbindd_domain_name(struct winbindd_cli_state *state)
766{
767 DEBUG(3, ("[%5lu]: request domain name\n", (unsigned long)state->pid));
768
769 fstrcpy(state->response.data.domain_name, lp_workgroup());
770 request_ok(state);
771}
772
773/* What's my name again? */
774
775void winbindd_netbios_name(struct winbindd_cli_state *state)
776{
777 DEBUG(3, ("[%5lu]: request netbios name\n",
778 (unsigned long)state->pid));
779
780 fstrcpy(state->response.data.netbios_name, global_myname());
781 request_ok(state);
782}
783
784/* Where can I find the privilaged pipe? */
785
786void winbindd_priv_pipe_dir(struct winbindd_cli_state *state)
787{
788
789 DEBUG(3, ("[%5lu]: request location of privileged pipe\n",
790 (unsigned long)state->pid));
791
792 state->response.extra_data.data = SMB_STRDUP(get_winbind_priv_pipe_dir());
793 if (!state->response.extra_data.data) {
794 DEBUG(0, ("malloc failed\n"));
795 request_error(state);
796 return;
797 }
798
799 /* must add one to length to copy the 0 for string termination */
800 state->response.length +=
801 strlen((char *)state->response.extra_data.data) + 1;
802
803 request_ok(state);
804}
805
Note: See TracBrowser for help on using the repository browser.