s3/packaging: pam_winbind has been moved to section 8.
[Samba/gebeck_regimport.git] / source3 / winbindd / winbindd_misc.c
blob3f71910023a611530e85819b3d2097e5ddcd3036
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind daemon - miscellaneous other functions
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Bartlett 2002
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/>.
23 #include "includes.h"
24 #include "winbindd.h"
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_WINBIND
29 /* Check the machine account password is valid */
31 void winbindd_check_machine_acct(struct winbindd_cli_state *state)
33 DEBUG(3, ("[%5lu]: check machine account\n",
34 (unsigned long)state->pid));
36 sendto_domain(state, find_our_domain());
39 enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *domain,
40 struct winbindd_cli_state *state)
42 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
43 int num_retries = 0;
44 struct winbindd_domain *contact_domain;
46 DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid));
48 /* Get trust account password */
50 again:
52 contact_domain = find_our_domain();
54 /* This call does a cli_nt_setup_creds() which implicitly checks
55 the trust account password. */
57 invalidate_cm_connection(&contact_domain->conn);
60 struct rpc_pipe_client *netlogon_pipe;
61 result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
64 if (!NT_STATUS_IS_OK(result)) {
65 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
66 goto done;
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. */
74 #define MAX_RETRIES 8
76 if ((num_retries < MAX_RETRIES) &&
77 NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
78 num_retries++;
79 goto again;
82 /* Pass back result code - zero for success, other values for
83 specific failures. */
85 DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(result) ?
86 "good" : "bad"));
88 done:
89 set_auth_errors(state->response, result);
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));
94 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
97 /* Helpers for listing user and group names */
99 const char *ent_type_strings[] = {"users",
100 "groups"};
102 static const char *get_ent_type_string(enum ent_type type)
104 return ent_type_strings[type];
107 struct 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;
116 static void listent_recv(void *private_data, bool success, fstring dom_name,
117 char *extra_data);
119 /* List domain users/groups without mapping to unix ids */
120 void winbindd_list_ent(struct winbindd_cli_state *state, enum ent_type type)
122 struct winbindd_domain *domain;
123 const char *which_domain;
124 struct listent_state *ent_state;
126 DEBUG(3, ("[%5lu]: list %s\n", (unsigned long)state->pid,
127 get_ent_type_string(type)));
129 /* Ensure null termination */
130 state->request->domain_name[sizeof(state->request->domain_name)-1]='\0';
131 which_domain = state->request->domain_name;
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;
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;
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;
159 ent_state->domain_count++;
162 /* Make sure we're enumerating at least one domain */
163 if (!ent_state->domain_count) {
164 request_ok(state);
165 return;
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;
174 winbindd_listent_async(state->mem_ctx, domain,
175 listent_recv, ent_state, type);
179 static void listent_recv(void *private_data, bool success, fstring dom_name,
180 char *extra_data)
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);
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;
201 else {
202 DEBUG(5, ("listent_recv: %s returned no %s.\n",
203 dom_name, get_ent_type_string(state->type)));
206 if (--state->domain_count)
207 /* Still waiting for some child domains to return */
208 return;
210 /* Return list of all users/groups to the client */
211 if (state->extra_data) {
212 state->cli_state->response->extra_data.data = state->extra_data;
213 state->cli_state->response->length += state->extra_data_len;
216 request_ok(state->cli_state);
219 /* Constants and helper functions for determining domain trust types */
221 enum trust_type {
222 EXTERNAL = 0,
223 FOREST,
224 IN_FOREST,
225 NONE,
228 const char *trust_type_strings[] = {"External",
229 "Forest",
230 "In Forest",
231 "None"};
233 static enum trust_type get_trust_type(struct winbindd_tdc_domain *domain)
235 if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN)
236 return EXTERNAL;
237 else if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)
238 return FOREST;
239 else if (((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == NETR_TRUST_FLAG_IN_FOREST) &&
240 ((domain->trust_flags & NETR_TRUST_FLAG_PRIMARY) == 0x0))
241 return IN_FOREST;
242 return NONE;
245 static const char *get_trust_type_string(struct winbindd_tdc_domain *domain)
247 return trust_type_strings[get_trust_type(domain)];
250 static bool trust_is_inbound(struct winbindd_tdc_domain *domain)
252 return (domain->trust_flags == 0x0) ||
253 ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) ==
254 NETR_TRUST_FLAG_IN_FOREST) ||
255 ((domain->trust_flags & NETR_TRUST_FLAG_INBOUND) ==
256 NETR_TRUST_FLAG_INBOUND);
259 static bool trust_is_outbound(struct winbindd_tdc_domain *domain)
261 return (domain->trust_flags == 0x0) ||
262 ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) ==
263 NETR_TRUST_FLAG_IN_FOREST) ||
264 ((domain->trust_flags & NETR_TRUST_FLAG_OUTBOUND) ==
265 NETR_TRUST_FLAG_OUTBOUND);
268 static bool trust_is_transitive(struct winbindd_tdc_domain *domain)
270 if ((domain->trust_attribs == NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE) ||
271 (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) ||
272 (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL))
273 return False;
274 return True;
277 void winbindd_list_trusted_domains(struct winbindd_cli_state *state)
279 struct winbindd_tdc_domain *dom_list = NULL;
280 struct winbindd_tdc_domain *d = NULL;
281 size_t num_domains = 0;
282 int extra_data_len = 0;
283 char *extra_data = NULL;
284 int i = 0;
286 DEBUG(3, ("[%5lu]: list trusted domains\n",
287 (unsigned long)state->pid));
289 if( !wcache_tdc_fetch_list( &dom_list, &num_domains )) {
290 request_error(state);
291 goto done;
294 for ( i = 0; i < num_domains; i++ ) {
295 struct winbindd_domain *domain;
296 bool is_online = true;
298 d = &dom_list[i];
299 domain = find_domain_from_name_noinit(d->domain_name);
300 if (domain) {
301 is_online = domain->online;
304 if ( !extra_data ) {
305 extra_data = talloc_asprintf(state->mem_ctx,
306 "%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s",
307 d->domain_name,
308 d->dns_name ? d->dns_name : d->domain_name,
309 sid_string_talloc(state->mem_ctx, &d->sid),
310 get_trust_type_string(d),
311 trust_is_transitive(d) ? "Yes" : "No",
312 trust_is_inbound(d) ? "Yes" : "No",
313 trust_is_outbound(d) ? "Yes" : "No",
314 is_online ? "Online" : "Offline" );
315 } else {
316 extra_data = talloc_asprintf(state->mem_ctx,
317 "%s\n%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s",
318 extra_data,
319 d->domain_name,
320 d->dns_name ? d->dns_name : d->domain_name,
321 sid_string_talloc(state->mem_ctx, &d->sid),
322 get_trust_type_string(d),
323 trust_is_transitive(d) ? "Yes" : "No",
324 trust_is_inbound(d) ? "Yes" : "No",
325 trust_is_outbound(d) ? "Yes" : "No",
326 is_online ? "Online" : "Offline" );
330 extra_data_len = 0;
331 if (extra_data != NULL) {
332 extra_data_len = strlen(extra_data);
335 if (extra_data_len > 0) {
336 state->response->extra_data.data = extra_data;
337 state->response->length += extra_data_len+1;
340 request_ok(state);
341 done:
342 TALLOC_FREE( dom_list );
345 enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain,
346 struct winbindd_cli_state *state)
348 uint32 i, num_domains;
349 char **names, **alt_names;
350 DOM_SID *sids;
351 int extra_data_len = 0;
352 char *extra_data;
353 NTSTATUS result;
354 bool have_own_domain = False;
356 DEBUG(3, ("[%5lu]: list trusted domains\n",
357 (unsigned long)state->pid));
359 result = domain->methods->trusted_domains(domain, state->mem_ctx,
360 &num_domains, &names,
361 &alt_names, &sids);
363 if (!NT_STATUS_IS_OK(result)) {
364 DEBUG(3, ("winbindd_dual_list_trusted_domains: trusted_domains returned %s\n",
365 nt_errstr(result) ));
366 return WINBINDD_ERROR;
369 extra_data = talloc_strdup(state->mem_ctx, "");
371 if (num_domains > 0)
372 extra_data = talloc_asprintf(
373 state->mem_ctx, "%s\\%s\\%s",
374 names[0], alt_names[0] ? alt_names[0] : names[0],
375 sid_string_talloc(state->mem_ctx, &sids[0]));
377 for (i=1; i<num_domains; i++)
378 extra_data = talloc_asprintf(
379 state->mem_ctx, "%s\n%s\\%s\\%s",
380 extra_data, names[i],
381 alt_names[i] ? alt_names[i] : names[i],
382 sid_string_talloc(state->mem_ctx, &sids[i]));
384 /* add our primary domain */
386 for (i=0; i<num_domains; i++) {
387 if (strequal(names[i], domain->name)) {
388 have_own_domain = True;
389 break;
393 if (state->request->data.list_all_domains && !have_own_domain) {
394 extra_data = talloc_asprintf(
395 state->mem_ctx, "%s\n%s\\%s\\%s",
396 extra_data, domain->name,
397 domain->alt_name ? domain->alt_name : domain->name,
398 sid_string_talloc(state->mem_ctx, &domain->sid));
401 /* This is a bit excessive, but the extra data sooner or later will be
402 talloc'ed */
404 extra_data_len = 0;
405 if (extra_data != NULL) {
406 extra_data_len = strlen(extra_data);
409 if (extra_data_len > 0) {
410 state->response->extra_data.data = extra_data;
411 state->response->length += extra_data_len+1;
414 return WINBINDD_OK;
417 void winbindd_getdcname(struct winbindd_cli_state *state)
419 struct winbindd_domain *domain;
421 state->request->domain_name
422 [sizeof(state->request->domain_name)-1] = '\0';
424 DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid,
425 state->request->domain_name));
427 domain = find_domain_from_name_noinit(state->request->domain_name);
428 if (domain && domain->internal) {
429 fstrcpy(state->response->data.dc_name, global_myname());
430 request_ok(state);
431 return;
434 sendto_domain(state, find_our_domain());
437 enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
438 struct winbindd_cli_state *state)
440 const char *dcname_slash = NULL;
441 const char *p;
442 struct rpc_pipe_client *netlogon_pipe;
443 NTSTATUS result;
444 WERROR werr;
445 unsigned int orig_timeout;
446 struct winbindd_domain *req_domain;
448 state->request->domain_name
449 [sizeof(state->request->domain_name)-1] = '\0';
451 DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid,
452 state->request->domain_name));
454 result = cm_connect_netlogon(domain, &netlogon_pipe);
456 if (!NT_STATUS_IS_OK(result)) {
457 DEBUG(1, ("Can't contact the NETLOGON pipe\n"));
458 return WINBINDD_ERROR;
461 /* This call can take a long time - allow the server to time out.
462 35 seconds should do it. */
464 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
466 req_domain = find_domain_from_name_noinit(state->request->domain_name);
467 if (req_domain == domain) {
468 result = rpccli_netr_GetDcName(netlogon_pipe,
469 state->mem_ctx,
470 domain->dcname,
471 state->request->domain_name,
472 &dcname_slash,
473 &werr);
474 } else {
475 result = rpccli_netr_GetAnyDCName(netlogon_pipe,
476 state->mem_ctx,
477 domain->dcname,
478 state->request->domain_name,
479 &dcname_slash,
480 &werr);
482 /* And restore our original timeout. */
483 rpccli_set_timeout(netlogon_pipe, orig_timeout);
485 if (!NT_STATUS_IS_OK(result)) {
486 DEBUG(5,("Error requesting DCname for domain %s: %s\n",
487 state->request->domain_name, nt_errstr(result)));
488 return WINBINDD_ERROR;
491 if (!W_ERROR_IS_OK(werr)) {
492 DEBUG(5, ("Error requesting DCname for domain %s: %s\n",
493 state->request->domain_name, win_errstr(werr)));
494 return WINBINDD_ERROR;
497 p = dcname_slash;
498 if (*p == '\\') {
499 p+=1;
501 if (*p == '\\') {
502 p+=1;
505 fstrcpy(state->response->data.dc_name, p);
506 return WINBINDD_OK;
509 struct sequence_state {
510 TALLOC_CTX *mem_ctx;
511 struct winbindd_cli_state *cli_state;
512 struct winbindd_domain *domain;
513 struct winbindd_request *request;
514 struct winbindd_response *response;
515 char *extra_data;
518 static void sequence_recv(void *private_data, bool success);
520 void winbindd_show_sequence(struct winbindd_cli_state *state)
522 struct sequence_state *seq;
524 /* Ensure null termination */
525 state->request->domain_name[sizeof(state->request->domain_name)-1]='\0';
527 if (strlen(state->request->domain_name) > 0) {
528 struct winbindd_domain *domain;
529 domain = find_domain_from_name_noinit(
530 state->request->domain_name);
531 if (domain == NULL) {
532 request_error(state);
533 return;
535 sendto_domain(state, domain);
536 return;
539 /* Ask all domains in sequence, collect the results in sequence_recv */
541 seq = TALLOC_P(state->mem_ctx, struct sequence_state);
542 if (seq == NULL) {
543 DEBUG(0, ("talloc failed\n"));
544 request_error(state);
545 return;
548 seq->mem_ctx = state->mem_ctx;
549 seq->cli_state = state;
550 seq->domain = domain_list();
551 if (seq->domain == NULL) {
552 DEBUG(0, ("domain list empty\n"));
553 request_error(state);
554 return;
556 seq->request = TALLOC_ZERO_P(state->mem_ctx,
557 struct winbindd_request);
558 seq->response = TALLOC_ZERO_P(state->mem_ctx,
559 struct winbindd_response);
560 seq->extra_data = talloc_strdup(state->mem_ctx, "");
562 if ((seq->request == NULL) || (seq->response == NULL) ||
563 (seq->extra_data == NULL)) {
564 DEBUG(0, ("talloc failed\n"));
565 request_error(state);
566 return;
569 seq->request->length = sizeof(*seq->request);
570 seq->request->cmd = WINBINDD_SHOW_SEQUENCE;
571 fstrcpy(seq->request->domain_name, seq->domain->name);
573 async_domain_request(state->mem_ctx, seq->domain,
574 seq->request, seq->response,
575 sequence_recv, seq);
578 static void sequence_recv(void *private_data, bool success)
580 struct sequence_state *state =
581 (struct sequence_state *)private_data;
582 uint32 seq = DOM_SEQUENCE_NONE;
584 if ((success) && (state->response->result == WINBINDD_OK))
585 seq = state->response->data.sequence_number;
587 if (seq == DOM_SEQUENCE_NONE) {
588 state->extra_data = talloc_asprintf(state->mem_ctx,
589 "%s%s : DISCONNECTED\n",
590 state->extra_data,
591 state->domain->name);
592 } else {
593 state->extra_data = talloc_asprintf(state->mem_ctx,
594 "%s%s : %d\n",
595 state->extra_data,
596 state->domain->name, seq);
599 state->domain->sequence_number = seq;
601 state->domain = state->domain->next;
603 if (state->domain == NULL) {
604 struct winbindd_cli_state *cli_state = state->cli_state;
605 cli_state->response->length =
606 sizeof(struct winbindd_response) +
607 strlen(state->extra_data) + 1;
608 cli_state->response->extra_data.data = state->extra_data;
609 request_ok(cli_state);
610 return;
613 /* Ask the next domain */
614 fstrcpy(state->request->domain_name, state->domain->name);
615 async_domain_request(state->mem_ctx, state->domain,
616 state->request, state->response,
617 sequence_recv, state);
620 /* This is the child-only version of --sequence. It only allows for a single
621 * domain (ie "our" one) to be displayed. */
623 enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain,
624 struct winbindd_cli_state *state)
626 DEBUG(3, ("[%5lu]: show sequence\n", (unsigned long)state->pid));
628 /* Ensure null termination */
629 state->request->domain_name[sizeof(state->request->domain_name)-1]='\0';
631 domain->methods->sequence_number(domain, &domain->sequence_number);
633 state->response->data.sequence_number =
634 domain->sequence_number;
636 return WINBINDD_OK;
639 struct domain_info_state {
640 struct winbindd_domain *domain;
641 struct winbindd_cli_state *cli;
642 struct winbindd_request ping_request;
645 static void domain_info_done(struct tevent_req *req);
647 void winbindd_domain_info(struct winbindd_cli_state *cli)
649 struct domain_info_state *state;
650 struct winbindd_domain *domain;
651 struct tevent_req *req;
653 DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)cli->pid,
654 cli->request->domain_name));
656 domain = find_domain_from_name_noinit(cli->request->domain_name);
658 if (domain == NULL) {
659 DEBUG(3, ("Did not find domain [%s]\n",
660 cli->request->domain_name));
661 request_error(cli);
662 return;
665 if (domain->initialized) {
666 fstrcpy(cli->response->data.domain_info.name,
667 domain->name);
668 fstrcpy(cli->response->data.domain_info.alt_name,
669 domain->alt_name);
670 sid_to_fstring(cli->response->data.domain_info.sid,
671 &domain->sid);
672 cli->response->data.domain_info.native_mode =
673 domain->native_mode;
674 cli->response->data.domain_info.active_directory =
675 domain->active_directory;
676 cli->response->data.domain_info.primary =
677 domain->primary;
678 request_ok(cli);
679 return;
682 state = talloc_zero(cli->mem_ctx, struct domain_info_state);
683 if (state == NULL) {
684 DEBUG(0, ("talloc failed\n"));
685 request_error(cli);
686 return;
689 state->cli = cli;
690 state->domain = domain;
691 state->ping_request.cmd = WINBINDD_PING;
694 * Send a ping down. This implicitly initializes the domain.
697 req = wb_domain_request_send(state, winbind_event_context(),
698 domain, &state->ping_request);
699 if (req == NULL) {
700 DEBUG(3, ("wb_domain_request_send failed\n"));
701 request_error(cli);
703 tevent_req_set_callback(req, domain_info_done, state);
706 static void domain_info_done(struct tevent_req *req)
708 struct domain_info_state *state = tevent_req_callback_data(
709 req, struct domain_info_state);
710 struct winbindd_response *response;
711 int ret, err;
713 ret = wb_domain_request_recv(req, req, &response, &err);
714 TALLOC_FREE(req);
715 if (ret == -1) {
716 DEBUG(10, ("wb_domain_request failed: %s\n", strerror(errno)));
717 request_error(state->cli);
718 return;
720 if (!state->domain->initialized) {
721 DEBUG(5, ("wb_domain_request did not initialize domain %s\n",
722 state->domain->name));
723 request_error(state->cli);
724 return;
727 fstrcpy(state->cli->response->data.domain_info.name,
728 state->domain->name);
729 fstrcpy(state->cli->response->data.domain_info.alt_name,
730 state->domain->alt_name);
731 sid_to_fstring(state->cli->response->data.domain_info.sid,
732 &state->domain->sid);
734 state->cli->response->data.domain_info.native_mode =
735 state->domain->native_mode;
736 state->cli->response->data.domain_info.active_directory =
737 state->domain->active_directory;
738 state->cli->response->data.domain_info.primary =
739 state->domain->primary;
741 request_ok(state->cli);
744 void winbindd_ping(struct winbindd_cli_state *state)
746 DEBUG(3, ("[%5lu]: ping\n", (unsigned long)state->pid));
747 request_ok(state);
750 /* List various tidbits of information */
752 void winbindd_info(struct winbindd_cli_state *state)
755 DEBUG(3, ("[%5lu]: request misc info\n", (unsigned long)state->pid));
757 state->response->data.info.winbind_separator = *lp_winbind_separator();
758 fstrcpy(state->response->data.info.samba_version, samba_version_string());
759 request_ok(state);
762 /* Tell the client the current interface version */
764 void winbindd_interface_version(struct winbindd_cli_state *state)
766 DEBUG(3, ("[%5lu]: request interface version\n",
767 (unsigned long)state->pid));
769 state->response->data.interface_version = WINBIND_INTERFACE_VERSION;
770 request_ok(state);
773 /* What domain are we a member of? */
775 void winbindd_domain_name(struct winbindd_cli_state *state)
777 DEBUG(3, ("[%5lu]: request domain name\n", (unsigned long)state->pid));
779 fstrcpy(state->response->data.domain_name, lp_workgroup());
780 request_ok(state);
783 /* What's my name again? */
785 void winbindd_netbios_name(struct winbindd_cli_state *state)
787 DEBUG(3, ("[%5lu]: request netbios name\n",
788 (unsigned long)state->pid));
790 fstrcpy(state->response->data.netbios_name, global_myname());
791 request_ok(state);
794 /* Where can I find the privilaged pipe? */
796 void winbindd_priv_pipe_dir(struct winbindd_cli_state *state)
798 char *priv_dir;
799 DEBUG(3, ("[%5lu]: request location of privileged pipe\n",
800 (unsigned long)state->pid));
802 priv_dir = get_winbind_priv_pipe_dir();
803 state->response->extra_data.data = talloc_move(state->mem_ctx,
804 &priv_dir);
806 /* must add one to length to copy the 0 for string termination */
807 state->response->length +=
808 strlen((char *)state->response->extra_data.data) + 1;
810 request_ok(state);