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/>.
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;
44 struct winbindd_domain *contact_domain;
46 DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid));
48 /* Get trust account password */
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"));
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. */
76 if ((num_retries < MAX_RETRIES) &&
77 NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
82 /* Pass back result code - zero for success, other values for
85 DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(result) ?
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 void winbindd_ping_dc(struct winbindd_cli_state *state)
99 DEBUG(3, ("[%5lu]: ping dc\n", (unsigned long)state->pid));
101 sendto_domain(state, find_our_domain());
104 enum winbindd_result winbindd_dual_ping_dc(struct winbindd_domain *domain,
105 struct winbindd_cli_state *state)
107 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
108 struct winbindd_domain *contact_domain;
109 struct rpc_pipe_client *netlogon_pipe;
110 union netr_CONTROL_QUERY_INFORMATION info;
112 fstring logon_server;
114 DEBUG(3, ("[%5lu]: ping dc\n", (unsigned long)state->pid));
116 contact_domain = find_our_domain();
118 status = cm_connect_netlogon(contact_domain, &netlogon_pipe);
119 if (!NT_STATUS_IS_OK(status)) {
120 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
121 return WINBINDD_ERROR;
124 fstr_sprintf(logon_server, "\\\\%s", domain->dcname);
127 * This provokes a WERR_NOT_SUPPORTED error message. This is
128 * documented in the wspp docs. I could not get a successful
129 * call to work, but the main point here is testing that the
130 * netlogon pipe works.
132 status = rpccli_netr_LogonControl(netlogon_pipe, state->mem_ctx,
133 logon_server, NETLOGON_CONTROL_QUERY,
136 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
137 DEBUG(2, ("rpccli_netr_LogonControl timed out\n"));
138 invalidate_cm_connection(&contact_domain->conn);
139 return WINBINDD_ERROR;
142 if (!NT_STATUS_EQUAL(status, NT_STATUS_CTL_FILE_NOT_SUPPORTED)) {
143 DEBUG(2, ("rpccli_netr_LogonControl returned %s, expected "
144 "NT_STATUS_CTL_FILE_NOT_SUPPORTED\n",
146 return WINBINDD_ERROR;
149 DEBUG(5, ("winbindd_dual_ping_dc succeeded\n"));
153 /* Helpers for listing user and group names */
155 const char *ent_type_strings[] = {"users",
158 static const char *get_ent_type_string(enum ent_type type)
160 return ent_type_strings[type];
163 struct listent_state {
165 struct winbindd_cli_state *cli_state;
169 uint32_t extra_data_len;
172 static void listent_recv(void *private_data, bool success, fstring dom_name,
175 /* List domain users/groups without mapping to unix ids */
176 void winbindd_list_ent(struct winbindd_cli_state *state, enum ent_type type)
178 struct winbindd_domain *domain;
179 const char *which_domain;
180 struct listent_state *ent_state;
182 DEBUG(3, ("[%5lu]: list %s\n", (unsigned long)state->pid,
183 get_ent_type_string(type)));
185 /* Ensure null termination */
186 state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
187 which_domain = state->request.domain_name;
189 /* Initialize listent_state */
190 ent_state = TALLOC_P(state->mem_ctx, struct listent_state);
191 if (ent_state == NULL) {
192 DEBUG(0, ("talloc failed\n"));
193 request_error(state);
197 ent_state->mem_ctx = state->mem_ctx;
198 ent_state->cli_state = state;
199 ent_state->type = type;
200 ent_state->domain_count = 0;
201 ent_state->extra_data = NULL;
202 ent_state->extra_data_len = 0;
204 /* Must count the full list of expected domains before we request data
205 * from any of them. Otherwise it's possible for a connection to the
206 * first domain to fail, call listent_recv(), and return to the
207 * client without checking any other domains. */
208 for (domain = domain_list(); domain; domain = domain->next) {
209 /* if we have a domain name restricting the request and this
210 one in the list doesn't match, then just bypass the remainder
212 if ( *which_domain && !strequal(which_domain, domain->name) )
215 ent_state->domain_count++;
218 /* Make sure we're enumerating at least one domain */
219 if (!ent_state->domain_count) {
224 /* Enumerate list of trusted domains and request user/group list from
226 for (domain = domain_list(); domain; domain = domain->next) {
227 if ( *which_domain && !strequal(which_domain, domain->name) )
230 winbindd_listent_async(state->mem_ctx, domain,
231 listent_recv, ent_state, type);
235 static void listent_recv(void *private_data, bool success, fstring dom_name,
238 /* extra_data comes to us as a '\0' terminated string of comma
239 separated users or groups */
240 struct listent_state *state = talloc_get_type_abort(
241 private_data, struct listent_state);
243 /* Append users/groups from one domain onto the whole list */
245 DEBUG(5, ("listent_recv: %s returned %s.\n",
246 dom_name, get_ent_type_string(state->type)));
247 if (!state->extra_data)
248 state->extra_data = talloc_asprintf(state->mem_ctx,
251 state->extra_data = talloc_asprintf_append(
254 /* Add one for the '\0' and each additional ',' */
255 state->extra_data_len += strlen(extra_data) + 1;
258 DEBUG(5, ("listent_recv: %s returned no %s.\n",
259 dom_name, get_ent_type_string(state->type)));
262 if (--state->domain_count)
263 /* Still waiting for some child domains to return */
266 /* Return list of all users/groups to the client */
267 if (state->extra_data) {
268 state->cli_state->response.extra_data.data =
269 SMB_STRDUP(state->extra_data);
270 state->cli_state->response.length += state->extra_data_len;
273 request_ok(state->cli_state);
276 /* Constants and helper functions for determining domain trust types */
285 const char *trust_type_strings[] = {"External",
290 static enum trust_type get_trust_type(struct winbindd_tdc_domain *domain)
292 if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN)
294 else if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)
296 else if (((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == NETR_TRUST_FLAG_IN_FOREST) &&
297 ((domain->trust_flags & NETR_TRUST_FLAG_PRIMARY) == 0x0))
302 static const char *get_trust_type_string(struct winbindd_tdc_domain *domain)
304 return trust_type_strings[get_trust_type(domain)];
307 static bool trust_is_inbound(struct winbindd_tdc_domain *domain)
309 return (domain->trust_flags == 0x0) ||
310 ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) ==
311 NETR_TRUST_FLAG_IN_FOREST) ||
312 ((domain->trust_flags & NETR_TRUST_FLAG_INBOUND) ==
313 NETR_TRUST_FLAG_INBOUND);
316 static bool trust_is_outbound(struct winbindd_tdc_domain *domain)
318 return (domain->trust_flags == 0x0) ||
319 ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) ==
320 NETR_TRUST_FLAG_IN_FOREST) ||
321 ((domain->trust_flags & NETR_TRUST_FLAG_OUTBOUND) ==
322 NETR_TRUST_FLAG_OUTBOUND);
325 static bool trust_is_transitive(struct winbindd_tdc_domain *domain)
327 if ((domain->trust_attribs == NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE) ||
328 (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) ||
329 (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL))
334 void winbindd_list_trusted_domains(struct winbindd_cli_state *state)
336 struct winbindd_tdc_domain *dom_list = NULL;
337 struct winbindd_tdc_domain *d = NULL;
338 size_t num_domains = 0;
339 int extra_data_len = 0;
340 char *extra_data = NULL;
343 DEBUG(3, ("[%5lu]: list trusted domains\n",
344 (unsigned long)state->pid));
346 if( !wcache_tdc_fetch_list( &dom_list, &num_domains )) {
347 request_error(state);
351 for ( i = 0; i < num_domains; i++ ) {
352 struct winbindd_domain *domain;
353 bool is_online = true;
356 domain = find_domain_from_name_noinit(d->domain_name);
358 is_online = domain->online;
362 extra_data = talloc_asprintf(state->mem_ctx,
363 "%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s",
365 d->dns_name ? d->dns_name : d->domain_name,
366 sid_string_talloc(state->mem_ctx, &d->sid),
367 get_trust_type_string(d),
368 trust_is_transitive(d) ? "Yes" : "No",
369 trust_is_inbound(d) ? "Yes" : "No",
370 trust_is_outbound(d) ? "Yes" : "No",
371 is_online ? "Online" : "Offline" );
373 extra_data = talloc_asprintf(state->mem_ctx,
374 "%s\n%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s",
377 d->dns_name ? d->dns_name : d->domain_name,
378 sid_string_talloc(state->mem_ctx, &d->sid),
379 get_trust_type_string(d),
380 trust_is_transitive(d) ? "Yes" : "No",
381 trust_is_inbound(d) ? "Yes" : "No",
382 trust_is_outbound(d) ? "Yes" : "No",
383 is_online ? "Online" : "Offline" );
388 if (extra_data != NULL) {
389 extra_data_len = strlen(extra_data);
392 if (extra_data_len > 0) {
393 state->response.extra_data.data = SMB_STRDUP(extra_data);
394 state->response.length += extra_data_len+1;
399 TALLOC_FREE( dom_list );
400 TALLOC_FREE( extra_data );
403 enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain,
404 struct winbindd_cli_state *state)
406 uint32 i, num_domains;
407 char **names, **alt_names;
409 int extra_data_len = 0;
412 bool have_own_domain = False;
414 DEBUG(3, ("[%5lu]: list trusted domains\n",
415 (unsigned long)state->pid));
417 result = domain->methods->trusted_domains(domain, state->mem_ctx,
418 &num_domains, &names,
421 if (!NT_STATUS_IS_OK(result)) {
422 DEBUG(3, ("winbindd_dual_list_trusted_domains: trusted_domains returned %s\n",
423 nt_errstr(result) ));
424 return WINBINDD_ERROR;
427 extra_data = talloc_strdup(state->mem_ctx, "");
430 extra_data = talloc_asprintf(
431 state->mem_ctx, "%s\\%s\\%s",
432 names[0], alt_names[0] ? alt_names[0] : names[0],
433 sid_string_talloc(state->mem_ctx, &sids[0]));
435 for (i=1; i<num_domains; i++)
436 extra_data = talloc_asprintf(
437 state->mem_ctx, "%s\n%s\\%s\\%s",
438 extra_data, names[i],
439 alt_names[i] ? alt_names[i] : names[i],
440 sid_string_talloc(state->mem_ctx, &sids[i]));
442 /* add our primary domain */
444 for (i=0; i<num_domains; i++) {
445 if (strequal(names[i], domain->name)) {
446 have_own_domain = True;
451 if (state->request.data.list_all_domains && !have_own_domain) {
452 extra_data = talloc_asprintf(
453 state->mem_ctx, "%s\n%s\\%s\\%s",
454 extra_data, domain->name,
455 domain->alt_name ? domain->alt_name : domain->name,
456 sid_string_talloc(state->mem_ctx, &domain->sid));
459 /* This is a bit excessive, but the extra data sooner or later will be
463 if (extra_data != NULL) {
464 extra_data_len = strlen(extra_data);
467 if (extra_data_len > 0) {
468 state->response.extra_data.data = SMB_STRDUP(extra_data);
469 state->response.length += extra_data_len+1;
475 void winbindd_getdcname(struct winbindd_cli_state *state)
477 struct winbindd_domain *domain;
479 state->request.domain_name
480 [sizeof(state->request.domain_name)-1] = '\0';
482 DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid,
483 state->request.domain_name));
485 domain = find_domain_from_name_noinit(state->request.domain_name);
486 if (domain && domain->internal) {
487 fstrcpy(state->response.data.dc_name, global_myname());
492 sendto_domain(state, find_our_domain());
495 enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
496 struct winbindd_cli_state *state)
498 const char *dcname_slash = NULL;
500 struct rpc_pipe_client *netlogon_pipe;
503 unsigned int orig_timeout;
504 struct winbindd_domain *req_domain;
506 state->request.domain_name
507 [sizeof(state->request.domain_name)-1] = '\0';
509 DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid,
510 state->request.domain_name));
512 result = cm_connect_netlogon(domain, &netlogon_pipe);
514 if (!NT_STATUS_IS_OK(result)) {
515 DEBUG(1, ("Can't contact the NETLOGON pipe\n"));
516 return WINBINDD_ERROR;
519 /* This call can take a long time - allow the server to time out.
520 35 seconds should do it. */
522 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
524 req_domain = find_domain_from_name_noinit(state->request.domain_name);
525 if (req_domain == domain) {
526 result = rpccli_netr_GetDcName(netlogon_pipe,
529 state->request.domain_name,
533 result = rpccli_netr_GetAnyDCName(netlogon_pipe,
536 state->request.domain_name,
540 /* And restore our original timeout. */
541 rpccli_set_timeout(netlogon_pipe, orig_timeout);
543 if (!NT_STATUS_IS_OK(result)) {
544 DEBUG(5,("Error requesting DCname for domain %s: %s\n",
545 state->request.domain_name, nt_errstr(result)));
546 return WINBINDD_ERROR;
549 if (!W_ERROR_IS_OK(werr)) {
550 DEBUG(5, ("Error requesting DCname for domain %s: %s\n",
551 state->request.domain_name, win_errstr(werr)));
552 return WINBINDD_ERROR;
563 fstrcpy(state->response.data.dc_name, p);
567 struct sequence_state {
569 struct winbindd_cli_state *cli_state;
570 struct winbindd_domain *domain;
571 struct winbindd_request *request;
572 struct winbindd_response *response;
576 static void sequence_recv(void *private_data, bool success);
578 void winbindd_show_sequence(struct winbindd_cli_state *state)
580 struct sequence_state *seq;
582 /* Ensure null termination */
583 state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
585 if (strlen(state->request.domain_name) > 0) {
586 struct winbindd_domain *domain;
587 domain = find_domain_from_name_noinit(
588 state->request.domain_name);
589 if (domain == NULL) {
590 request_error(state);
593 sendto_domain(state, domain);
597 /* Ask all domains in sequence, collect the results in sequence_recv */
599 seq = TALLOC_P(state->mem_ctx, struct sequence_state);
601 DEBUG(0, ("talloc failed\n"));
602 request_error(state);
606 seq->mem_ctx = state->mem_ctx;
607 seq->cli_state = state;
608 seq->domain = domain_list();
609 if (seq->domain == NULL) {
610 DEBUG(0, ("domain list empty\n"));
611 request_error(state);
614 seq->request = TALLOC_ZERO_P(state->mem_ctx,
615 struct winbindd_request);
616 seq->response = TALLOC_ZERO_P(state->mem_ctx,
617 struct winbindd_response);
618 seq->extra_data = talloc_strdup(state->mem_ctx, "");
620 if ((seq->request == NULL) || (seq->response == NULL) ||
621 (seq->extra_data == NULL)) {
622 DEBUG(0, ("talloc failed\n"));
623 request_error(state);
627 seq->request->length = sizeof(*seq->request);
628 seq->request->cmd = WINBINDD_SHOW_SEQUENCE;
629 fstrcpy(seq->request->domain_name, seq->domain->name);
631 async_domain_request(state->mem_ctx, seq->domain,
632 seq->request, seq->response,
636 static void sequence_recv(void *private_data, bool success)
638 struct sequence_state *state =
639 (struct sequence_state *)private_data;
640 uint32 seq = DOM_SEQUENCE_NONE;
642 if ((success) && (state->response->result == WINBINDD_OK))
643 seq = state->response->data.sequence_number;
645 if (seq == DOM_SEQUENCE_NONE) {
646 state->extra_data = talloc_asprintf(state->mem_ctx,
647 "%s%s : DISCONNECTED\n",
649 state->domain->name);
651 state->extra_data = talloc_asprintf(state->mem_ctx,
654 state->domain->name, seq);
657 state->domain->sequence_number = seq;
659 state->domain = state->domain->next;
661 if (state->domain == NULL) {
662 struct winbindd_cli_state *cli_state = state->cli_state;
663 cli_state->response.length =
664 sizeof(cli_state->response) +
665 strlen(state->extra_data) + 1;
666 cli_state->response.extra_data.data =
667 SMB_STRDUP(state->extra_data);
668 request_ok(cli_state);
672 /* Ask the next domain */
673 fstrcpy(state->request->domain_name, state->domain->name);
674 async_domain_request(state->mem_ctx, state->domain,
675 state->request, state->response,
676 sequence_recv, state);
679 /* This is the child-only version of --sequence. It only allows for a single
680 * domain (ie "our" one) to be displayed. */
682 enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain,
683 struct winbindd_cli_state *state)
685 DEBUG(3, ("[%5lu]: show sequence\n", (unsigned long)state->pid));
687 /* Ensure null termination */
688 state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
690 domain->methods->sequence_number(domain, &domain->sequence_number);
692 state->response.data.sequence_number =
693 domain->sequence_number;
698 struct domain_info_state {
699 struct winbindd_domain *domain;
700 struct winbindd_cli_state *cli_state;
703 static void domain_info_init_recv(void *private_data, bool success);
705 void winbindd_domain_info(struct winbindd_cli_state *state)
707 struct winbindd_domain *domain;
709 DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)state->pid,
710 state->request.domain_name));
712 domain = find_domain_from_name_noinit(state->request.domain_name);
714 if (domain == NULL) {
715 DEBUG(3, ("Did not find domain [%s]\n",
716 state->request.domain_name));
717 request_error(state);
721 if (!domain->initialized) {
722 struct domain_info_state *istate;
724 istate = TALLOC_P(state->mem_ctx, struct domain_info_state);
725 if (istate == NULL) {
726 DEBUG(0, ("talloc failed\n"));
727 request_error(state);
731 istate->cli_state = state;
732 istate->domain = domain;
734 init_child_connection(domain, domain_info_init_recv, istate);
739 fstrcpy(state->response.data.domain_info.name,
741 fstrcpy(state->response.data.domain_info.alt_name,
743 sid_to_fstring(state->response.data.domain_info.sid, &domain->sid);
745 state->response.data.domain_info.native_mode =
747 state->response.data.domain_info.active_directory =
748 domain->active_directory;
749 state->response.data.domain_info.primary =
755 static void domain_info_init_recv(void *private_data, bool success)
757 struct domain_info_state *istate =
758 (struct domain_info_state *)private_data;
759 struct winbindd_cli_state *state = istate->cli_state;
760 struct winbindd_domain *domain = istate->domain;
762 DEBUG(10, ("Got back from child init: %d\n", success));
764 if ((!success) || (!domain->initialized)) {
765 DEBUG(5, ("Could not init child for domain %s\n",
767 request_error(state);
771 fstrcpy(state->response.data.domain_info.name,
773 fstrcpy(state->response.data.domain_info.alt_name,
775 sid_to_fstring(state->response.data.domain_info.sid, &domain->sid);
777 state->response.data.domain_info.native_mode =
779 state->response.data.domain_info.active_directory =
780 domain->active_directory;
781 state->response.data.domain_info.primary =
787 void winbindd_ping(struct winbindd_cli_state *state)
789 DEBUG(3, ("[%5lu]: ping\n", (unsigned long)state->pid));
793 void winbindd_dc_info(struct winbindd_cli_state *cli)
795 struct winbindd_domain *domain;
796 char *dc_name, *dc_ip;
800 cli->request.domain_name[sizeof(cli->request.domain_name-1)] = '\0';
802 DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)cli->pid,
803 cli->request.domain_name));
805 if (cli->request.domain_name[0] != '\0') {
806 domain = find_domain_from_name_noinit(
807 cli->request.domain_name);
808 DEBUG(10, ("Could not find domain %s\n",
809 cli->request.domain_name));
810 if (domain == NULL) {
815 domain = find_our_domain();
818 if (!fetch_current_dc_from_gencache(
819 talloc_tos(), domain->name, &dc_name, &dc_ip)) {
820 DEBUG(10, ("fetch_current_dc_from_gencache(%s) failed\n",
826 ret = (asprintf(&extra, "%s\n%s\n", dc_name, dc_ip) > 0);
828 TALLOC_FREE(dc_name);
836 cli->response.data.num_entries = 1;
837 cli->response.extra_data.data = extra;
839 /* must add one to length to copy the 0 for string termination */
840 cli->response.length +=
841 strlen((char *)cli->response.extra_data.data) + 1;
846 /* List various tidbits of information */
848 void winbindd_info(struct winbindd_cli_state *state)
851 DEBUG(3, ("[%5lu]: request misc info\n", (unsigned long)state->pid));
853 state->response.data.info.winbind_separator = *lp_winbind_separator();
854 fstrcpy(state->response.data.info.samba_version, samba_version_string());
858 /* Tell the client the current interface version */
860 void winbindd_interface_version(struct winbindd_cli_state *state)
862 DEBUG(3, ("[%5lu]: request interface version\n",
863 (unsigned long)state->pid));
865 state->response.data.interface_version = WINBIND_INTERFACE_VERSION;
869 /* What domain are we a member of? */
871 void winbindd_domain_name(struct winbindd_cli_state *state)
873 DEBUG(3, ("[%5lu]: request domain name\n", (unsigned long)state->pid));
875 fstrcpy(state->response.data.domain_name, lp_workgroup());
879 /* What's my name again? */
881 void winbindd_netbios_name(struct winbindd_cli_state *state)
883 DEBUG(3, ("[%5lu]: request netbios name\n",
884 (unsigned long)state->pid));
886 fstrcpy(state->response.data.netbios_name, global_myname());
890 /* Where can I find the privilaged pipe? */
892 void winbindd_priv_pipe_dir(struct winbindd_cli_state *state)
895 DEBUG(3, ("[%5lu]: request location of privileged pipe\n",
896 (unsigned long)state->pid));
898 state->response.extra_data.data = SMB_STRDUP(get_winbind_priv_pipe_dir());
899 if (!state->response.extra_data.data) {
900 DEBUG(0, ("malloc failed\n"));
901 request_error(state);
905 /* must add one to length to copy the 0 for string termination */
906 state->response.length +=
907 strlen((char *)state->response.extra_data.data) + 1;