preparing for release of 2.2.3a
[Samba.git] / source / nsswitch / winbindd_misc.c
blob2718a753856a2864ea4e2019c340ae3e8eecf1f0
1 /*
2 Unix SMB/Netbios implementation.
3 Version 2.0
5 Winbind daemon - miscellaneous other functions
7 Copyright (C) Tim Potter 2000
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 2 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, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "winbindd.h"
26 extern pstring global_myname;
28 /************************************************************************
29 Routine to get the trust account password for a domain
30 ************************************************************************/
31 static BOOL _get_trust_account_password(char *domain, unsigned char *ret_pwd,
32 time_t *pass_last_set_time)
34 struct machine_acct_pass *pass;
35 size_t size;
37 if (!(pass = secrets_fetch(trust_keystr(domain), &size)) ||
38 size != sizeof(*pass))
39 return False;
41 if (pass_last_set_time)
42 *pass_last_set_time = pass->mod_time;
44 memcpy(ret_pwd, pass->hash, 16);
45 SAFE_FREE(pass);
47 return True;
50 /* Check the machine account password is valid */
52 enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *state)
54 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
55 uchar trust_passwd[16];
56 int num_retries = 0;
57 struct cli_state *cli;
58 DEBUG(3, ("[%5d]: check machine account\n", state->pid));
60 /* Get trust account password */
62 again:
63 if (!_get_trust_account_password(lp_workgroup(), trust_passwd,
64 NULL)) {
65 result = NT_STATUS_INTERNAL_ERROR;
66 goto done;
69 /* This call does a cli_nt_setup_creds() which implicitly checks
70 the trust account password. */
72 result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
74 if (!NT_STATUS_IS_OK(result)) {
75 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
76 goto done;
79 cli_shutdown(cli);
81 /* There is a race condition between fetching the trust account
82 password and joining the domain so it's possible that the trust
83 account password has been changed on us. We are returned
84 NT_STATUS_ACCESS_DENIED if this happens. */
86 #define MAX_RETRIES 8
88 if ((num_retries < MAX_RETRIES) &&
89 NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
90 num_retries++;
91 goto again;
94 /* Pass back result code - zero for success, other values for
95 specific failures. */
97 DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(result) ?
98 "good" : "bad"));
100 done:
101 state->response.data.num_entries = NT_STATUS_V(result);
103 return WINBINDD_OK;
106 enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
107 *state)
109 struct winbindd_domain *domain;
110 int total_entries = 0, extra_data_len = 0;
111 char *ted, *extra_data = NULL;
113 DEBUG(3, ("[%5d]: list trusted domains\n", state->pid));
115 if (domain_list == NULL)
116 get_domain_info();
118 for(domain = domain_list; domain; domain = domain->next) {
120 /* Skip own domain */
122 if (strequal(domain->name, lp_workgroup())) continue;
124 /* Add domain to list */
126 total_entries++;
127 ted = Realloc(extra_data, sizeof(fstring) *
128 total_entries);
130 if (!ted) {
131 DEBUG(0,("winbindd_list_trusted_domains: failed to enlarge buffer!\n"));
132 SAFE_FREE(extra_data);
133 return WINBINDD_ERROR;
134 } else
135 extra_data = ted;
137 memcpy(&extra_data[extra_data_len], domain->name,
138 strlen(domain->name));
140 extra_data_len += strlen(domain->name);
141 extra_data[extra_data_len++] = ',';
144 if (extra_data) {
145 if (extra_data_len > 1)
146 extra_data[extra_data_len - 1] = '\0';
147 state->response.extra_data = extra_data;
148 state->response.length += extra_data_len;
151 return WINBINDD_OK;