source: vendor/current/source3/winbindd/winbindd_reconnect.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 8.9 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 Wrapper around winbindd_rpc.c to centralize retry logic.
5
6 Copyright (C) Volker Lendecke 2005
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "includes.h"
23#include "winbindd.h"
24
25#undef DBGC_CLASS
26#define DBGC_CLASS DBGC_WINBIND
27
28extern struct winbindd_methods msrpc_methods;
29
30bool reconnect_need_retry(NTSTATUS status, struct winbindd_domain *domain)
31{
32 if (NT_STATUS_IS_OK(status)) {
33 return false;
34 }
35
36 if (!NT_STATUS_IS_ERR(status)) {
37 return false;
38 }
39
40 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
41 return false;
42 }
43
44 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
45 return false;
46 }
47
48 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_GROUP)) {
49 return false;
50 }
51
52 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_ALIAS)) {
53 return false;
54 }
55
56 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_MEMBER)) {
57 return false;
58 }
59
60 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
61 return false;
62 }
63
64 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_PRIVILEGE)) {
65 return false;
66 }
67
68 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
69 return false;
70 }
71
72 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR)) {
73 /*
74 * RPC call sent on expired session, needs
75 * reauthentication.
76 */
77 invalidate_cm_connection(domain);
78 }
79
80 return true;
81}
82
83/* List all users */
84static NTSTATUS query_user_list(struct winbindd_domain *domain,
85 TALLOC_CTX *mem_ctx,
86 uint32_t *num_entries,
87 struct wbint_userinfo **info)
88{
89 NTSTATUS result;
90
91 result = msrpc_methods.query_user_list(domain, mem_ctx,
92 num_entries, info);
93
94 if (reconnect_need_retry(result, domain))
95 result = msrpc_methods.query_user_list(domain, mem_ctx,
96 num_entries, info);
97 return result;
98}
99
100/* list all domain groups */
101static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
102 TALLOC_CTX *mem_ctx,
103 uint32_t *num_entries,
104 struct wb_acct_info **info)
105{
106 NTSTATUS result;
107
108 result = msrpc_methods.enum_dom_groups(domain, mem_ctx,
109 num_entries, info);
110
111 if (reconnect_need_retry(result, domain))
112 result = msrpc_methods.enum_dom_groups(domain, mem_ctx,
113 num_entries, info);
114 return result;
115}
116
117/* List all domain groups */
118
119static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
120 TALLOC_CTX *mem_ctx,
121 uint32_t *num_entries,
122 struct wb_acct_info **info)
123{
124 NTSTATUS result;
125
126 result = msrpc_methods.enum_local_groups(domain, mem_ctx,
127 num_entries, info);
128
129 if (reconnect_need_retry(result, domain))
130 result = msrpc_methods.enum_local_groups(domain, mem_ctx,
131 num_entries, info);
132
133 return result;
134}
135
136/* convert a single name to a sid in a domain */
137static NTSTATUS name_to_sid(struct winbindd_domain *domain,
138 TALLOC_CTX *mem_ctx,
139 const char *domain_name,
140 const char *name,
141 uint32_t flags,
142 struct dom_sid *sid,
143 enum lsa_SidType *type)
144{
145 NTSTATUS result;
146
147 result = msrpc_methods.name_to_sid(domain, mem_ctx, domain_name, name,
148 flags, sid, type);
149
150 if (reconnect_need_retry(result, domain))
151 result = msrpc_methods.name_to_sid(domain, mem_ctx,
152 domain_name, name, flags,
153 sid, type);
154
155 return result;
156}
157
158/*
159 convert a domain SID to a user or group name
160*/
161static NTSTATUS sid_to_name(struct winbindd_domain *domain,
162 TALLOC_CTX *mem_ctx,
163 const struct dom_sid *sid,
164 char **domain_name,
165 char **name,
166 enum lsa_SidType *type)
167{
168 NTSTATUS result;
169
170 result = msrpc_methods.sid_to_name(domain, mem_ctx, sid,
171 domain_name, name, type);
172
173 if (reconnect_need_retry(result, domain))
174 result = msrpc_methods.sid_to_name(domain, mem_ctx, sid,
175 domain_name, name, type);
176
177 return result;
178}
179
180static NTSTATUS rids_to_names(struct winbindd_domain *domain,
181 TALLOC_CTX *mem_ctx,
182 const struct dom_sid *sid,
183 uint32_t *rids,
184 size_t num_rids,
185 char **domain_name,
186 char ***names,
187 enum lsa_SidType **types)
188{
189 NTSTATUS result;
190
191 result = msrpc_methods.rids_to_names(domain, mem_ctx, sid,
192 rids, num_rids,
193 domain_name, names, types);
194 if (reconnect_need_retry(result, domain)) {
195 result = msrpc_methods.rids_to_names(domain, mem_ctx, sid,
196 rids, num_rids,
197 domain_name, names,
198 types);
199 }
200
201 return result;
202}
203
204/* Lookup user information from a rid or username. */
205static NTSTATUS query_user(struct winbindd_domain *domain,
206 TALLOC_CTX *mem_ctx,
207 const struct dom_sid *user_sid,
208 struct wbint_userinfo *user_info)
209{
210 NTSTATUS result;
211
212 result = msrpc_methods.query_user(domain, mem_ctx, user_sid,
213 user_info);
214
215 if (reconnect_need_retry(result, domain))
216 result = msrpc_methods.query_user(domain, mem_ctx, user_sid,
217 user_info);
218
219 return result;
220}
221
222/* Lookup groups a user is a member of. I wish Unix had a call like this! */
223static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
224 TALLOC_CTX *mem_ctx,
225 const struct dom_sid *user_sid,
226 uint32_t *num_groups, struct dom_sid **user_gids)
227{
228 NTSTATUS result;
229
230 result = msrpc_methods.lookup_usergroups(domain, mem_ctx,
231 user_sid, num_groups,
232 user_gids);
233
234 if (reconnect_need_retry(result, domain))
235 result = msrpc_methods.lookup_usergroups(domain, mem_ctx,
236 user_sid, num_groups,
237 user_gids);
238
239 return result;
240}
241
242static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
243 TALLOC_CTX *mem_ctx,
244 uint32_t num_sids, const struct dom_sid *sids,
245 uint32_t *num_aliases, uint32_t **alias_rids)
246{
247 NTSTATUS result;
248
249 result = msrpc_methods.lookup_useraliases(domain, mem_ctx,
250 num_sids, sids,
251 num_aliases,
252 alias_rids);
253
254 if (reconnect_need_retry(result, domain))
255 result = msrpc_methods.lookup_useraliases(domain, mem_ctx,
256 num_sids, sids,
257 num_aliases,
258 alias_rids);
259
260 return result;
261}
262
263/* Lookup group membership given a rid. */
264static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
265 TALLOC_CTX *mem_ctx,
266 const struct dom_sid *group_sid,
267 enum lsa_SidType type,
268 uint32_t *num_names,
269 struct dom_sid **sid_mem, char ***names,
270 uint32_t **name_types)
271{
272 NTSTATUS result;
273
274 result = msrpc_methods.lookup_groupmem(domain, mem_ctx,
275 group_sid, type, num_names,
276 sid_mem, names,
277 name_types);
278
279 if (reconnect_need_retry(result, domain))
280 result = msrpc_methods.lookup_groupmem(domain, mem_ctx,
281 group_sid, type,
282 num_names,
283 sid_mem, names,
284 name_types);
285
286 return result;
287}
288
289/* find the sequence number for a domain */
290static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32_t *seq)
291{
292 NTSTATUS result;
293
294 result = msrpc_methods.sequence_number(domain, seq);
295
296 if (reconnect_need_retry(result, domain))
297 result = msrpc_methods.sequence_number(domain, seq);
298
299 return result;
300}
301
302/* find the lockout policy of a domain */
303static NTSTATUS lockout_policy(struct winbindd_domain *domain,
304 TALLOC_CTX *mem_ctx,
305 struct samr_DomInfo12 *policy)
306{
307 NTSTATUS result;
308
309 result = msrpc_methods.lockout_policy(domain, mem_ctx, policy);
310
311 if (reconnect_need_retry(result, domain))
312 result = msrpc_methods.lockout_policy(domain, mem_ctx, policy);
313
314 return result;
315}
316
317/* find the password policy of a domain */
318static NTSTATUS password_policy(struct winbindd_domain *domain,
319 TALLOC_CTX *mem_ctx,
320 struct samr_DomInfo1 *policy)
321{
322 NTSTATUS result;
323
324 result = msrpc_methods.password_policy(domain, mem_ctx, policy);
325
326 if (reconnect_need_retry(result, domain))
327 result = msrpc_methods.password_policy(domain, mem_ctx, policy);
328
329 return result;
330}
331
332/* get a list of trusted domains */
333static NTSTATUS trusted_domains(struct winbindd_domain *domain,
334 TALLOC_CTX *mem_ctx,
335 struct netr_DomainTrustList *trusts)
336{
337 NTSTATUS result;
338
339 result = msrpc_methods.trusted_domains(domain, mem_ctx, trusts);
340
341 if (reconnect_need_retry(result, domain))
342 result = msrpc_methods.trusted_domains(domain, mem_ctx,
343 trusts);
344
345 return result;
346}
347
348/* the rpc backend methods are exposed via this structure */
349struct winbindd_methods reconnect_methods = {
350 False,
351 query_user_list,
352 enum_dom_groups,
353 enum_local_groups,
354 name_to_sid,
355 sid_to_name,
356 rids_to_names,
357 query_user,
358 lookup_usergroups,
359 lookup_useraliases,
360 lookup_groupmem,
361 sequence_number,
362 lockout_policy,
363 password_policy,
364 trusted_domains,
365};
Note: See TracBrowser for help on using the repository browser.