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

Last change on this file was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

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