r23779: Change from v2 or later to v3 or later.
[sfrench/samba-autobuild/.git] / source / nsswitch / winbindd_reconnect.c
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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "winbindd.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_WINBIND
28
29 extern struct winbindd_methods msrpc_methods;
30
31 /* List all users */
32 static NTSTATUS query_user_list(struct winbindd_domain *domain,
33                                 TALLOC_CTX *mem_ctx,
34                                 uint32 *num_entries, 
35                                 WINBIND_USERINFO **info)
36 {
37         NTSTATUS result;
38
39         result = msrpc_methods.query_user_list(domain, mem_ctx,
40                                                num_entries, info);
41
42         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
43                 result = msrpc_methods.query_user_list(domain, mem_ctx,
44                                                        num_entries, info);
45         return result;
46 }
47
48 /* list all domain groups */
49 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
50                                 TALLOC_CTX *mem_ctx,
51                                 uint32 *num_entries, 
52                                 struct acct_info **info)
53 {
54         NTSTATUS result;
55
56         result = msrpc_methods.enum_dom_groups(domain, mem_ctx,
57                                                num_entries, info);
58
59         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
60                 result = msrpc_methods.enum_dom_groups(domain, mem_ctx,
61                                                        num_entries, info);
62         return result;
63 }
64
65 /* List all domain groups */
66
67 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
68                                   TALLOC_CTX *mem_ctx,
69                                   uint32 *num_entries, 
70                                   struct acct_info **info)
71 {
72         NTSTATUS result;
73
74         result = msrpc_methods.enum_local_groups(domain, mem_ctx,
75                                                  num_entries, info);
76
77         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
78                 result = msrpc_methods.enum_local_groups(domain, mem_ctx,
79                                                          num_entries, info);
80
81         return result;
82 }
83
84 /* convert a single name to a sid in a domain */
85 static NTSTATUS name_to_sid(struct winbindd_domain *domain,
86                             TALLOC_CTX *mem_ctx,
87                             enum winbindd_cmd orig_cmd,
88                             const char *domain_name,
89                             const char *name,
90                             DOM_SID *sid,
91                             enum lsa_SidType *type)
92 {
93         NTSTATUS result;
94
95         result = msrpc_methods.name_to_sid(domain, mem_ctx, orig_cmd,
96                                            domain_name, name,
97                                            sid, type);
98
99         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
100                 result = msrpc_methods.name_to_sid(domain, mem_ctx, orig_cmd,
101                                                    domain_name, name,
102                                                    sid, type);
103
104         return result;
105 }
106
107 /*
108   convert a domain SID to a user or group name
109 */
110 static NTSTATUS sid_to_name(struct winbindd_domain *domain,
111                             TALLOC_CTX *mem_ctx,
112                             const DOM_SID *sid,
113                             char **domain_name,
114                             char **name,
115                             enum lsa_SidType *type)
116 {
117         NTSTATUS result;
118
119         result = msrpc_methods.sid_to_name(domain, mem_ctx, sid,
120                                            domain_name, name, type);
121
122         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
123                 result = msrpc_methods.sid_to_name(domain, mem_ctx, sid,
124                                                    domain_name, name, type);
125
126         return result;
127 }
128
129 static NTSTATUS rids_to_names(struct winbindd_domain *domain,
130                               TALLOC_CTX *mem_ctx,
131                               const DOM_SID *sid,
132                               uint32 *rids,
133                               size_t num_rids,
134                               char **domain_name,
135                               char ***names,
136                               enum lsa_SidType **types)
137 {
138         NTSTATUS result;
139
140         result = msrpc_methods.rids_to_names(domain, mem_ctx, sid,
141                                              rids, num_rids,
142                                              domain_name, names, types);
143         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) {
144                 result = msrpc_methods.rids_to_names(domain, mem_ctx, sid,
145                                                      rids, num_rids,
146                                                      domain_name, names,
147                                                      types);
148         }
149
150         return result;
151 }
152
153 /* Lookup user information from a rid or username. */
154 static NTSTATUS query_user(struct winbindd_domain *domain, 
155                            TALLOC_CTX *mem_ctx, 
156                            const DOM_SID *user_sid,
157                            WINBIND_USERINFO *user_info)
158 {
159         NTSTATUS result;
160
161         result = msrpc_methods.query_user(domain, mem_ctx, user_sid,
162                                           user_info);
163
164         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
165                 result = msrpc_methods.query_user(domain, mem_ctx, user_sid,
166                                                   user_info);
167
168         return result;
169 }
170
171 /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
172 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
173                                   TALLOC_CTX *mem_ctx,
174                                   const DOM_SID *user_sid,
175                                   uint32 *num_groups, DOM_SID **user_gids)
176 {
177         NTSTATUS result;
178
179         result = msrpc_methods.lookup_usergroups(domain, mem_ctx,
180                                                  user_sid, num_groups,
181                                                  user_gids);
182
183         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
184                 result = msrpc_methods.lookup_usergroups(domain, mem_ctx,
185                                                          user_sid, num_groups,
186                                                          user_gids);
187
188         return result;
189 }
190
191 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
192                                    TALLOC_CTX *mem_ctx,
193                                    uint32 num_sids, const DOM_SID *sids,
194                                    uint32 *num_aliases, uint32 **alias_rids)
195 {
196         NTSTATUS result;
197
198         result = msrpc_methods.lookup_useraliases(domain, mem_ctx,
199                                                   num_sids, sids,
200                                                   num_aliases,
201                                                   alias_rids);
202
203         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
204                 result = msrpc_methods.lookup_useraliases(domain, mem_ctx,
205                                                           num_sids, sids,
206                                                           num_aliases,
207                                                           alias_rids);
208
209         return result;
210 }
211
212 /* Lookup group membership given a rid.   */
213 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
214                                 TALLOC_CTX *mem_ctx,
215                                 const DOM_SID *group_sid, uint32 *num_names, 
216                                 DOM_SID **sid_mem, char ***names, 
217                                 uint32 **name_types)
218 {
219         NTSTATUS result;
220
221         result = msrpc_methods.lookup_groupmem(domain, mem_ctx,
222                                                group_sid, num_names,
223                                                sid_mem, names,
224                                                name_types);
225
226         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
227                 result = msrpc_methods.lookup_groupmem(domain, mem_ctx,
228                                                        group_sid, num_names,
229                                                        sid_mem, names,
230                                                        name_types);
231
232         return result;
233 }
234
235 /* find the sequence number for a domain */
236 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
237 {
238         NTSTATUS result;
239
240         result = msrpc_methods.sequence_number(domain, seq);
241
242         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
243                 result = msrpc_methods.sequence_number(domain, seq);
244
245         return result;
246 }
247
248 /* find the lockout policy of a domain */
249 static NTSTATUS lockout_policy(struct winbindd_domain *domain, 
250                                TALLOC_CTX *mem_ctx,
251                                SAM_UNK_INFO_12 *policy)
252 {
253         NTSTATUS result;
254
255         result = msrpc_methods.lockout_policy(domain, mem_ctx, policy);
256
257         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
258                 result = msrpc_methods.lockout_policy(domain, mem_ctx, policy);
259
260         return result;
261 }
262
263 /* find the password policy of a domain */
264 static NTSTATUS password_policy(struct winbindd_domain *domain, 
265                                 TALLOC_CTX *mem_ctx,
266                                 SAM_UNK_INFO_1 *policy)
267 {
268         NTSTATUS result;
269  
270         result = msrpc_methods.password_policy(domain, mem_ctx, policy);
271
272         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
273                 result = msrpc_methods.password_policy(domain, mem_ctx, policy);
274         
275         return result;
276 }
277
278 /* get a list of trusted domains */
279 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
280                                 TALLOC_CTX *mem_ctx,
281                                 uint32 *num_domains,
282                                 char ***names,
283                                 char ***alt_names,
284                                 DOM_SID **dom_sids)
285 {
286         NTSTATUS result;
287
288         result = msrpc_methods.trusted_domains(domain, mem_ctx,
289                                                num_domains, names,
290                                                alt_names, dom_sids);
291
292         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
293                 result = msrpc_methods.trusted_domains(domain, mem_ctx,
294                                                        num_domains, names,
295                                                        alt_names, dom_sids);
296
297         return result;
298 }
299
300 /* the rpc backend methods are exposed via this structure */
301 struct winbindd_methods reconnect_methods = {
302         False,
303         query_user_list,
304         enum_dom_groups,
305         enum_local_groups,
306         name_to_sid,
307         sid_to_name,
308         rids_to_names,
309         query_user,
310         lookup_usergroups,
311         lookup_useraliases,
312         lookup_groupmem,
313         sequence_number,
314         lockout_policy,
315         password_policy,
316         trusted_domains,
317 };