r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need
[vlendec/samba-autobuild/.git] / source3 / 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 2 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                             const char *domain_name,
88                             const char *name,
89                             DOM_SID *sid,
90                             enum SID_NAME_USE *type)
91 {
92         NTSTATUS result;
93
94         result = msrpc_methods.name_to_sid(domain, mem_ctx,
95                                            domain_name, name,
96                                            sid, type);
97
98         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
99                 result = msrpc_methods.name_to_sid(domain, mem_ctx,
100                                                    domain_name, name,
101                                                    sid, type);
102
103         return result;
104 }
105
106 /*
107   convert a domain SID to a user or group name
108 */
109 static NTSTATUS sid_to_name(struct winbindd_domain *domain,
110                             TALLOC_CTX *mem_ctx,
111                             const DOM_SID *sid,
112                             char **domain_name,
113                             char **name,
114                             enum SID_NAME_USE *type)
115 {
116         NTSTATUS result;
117
118         result = msrpc_methods.sid_to_name(domain, mem_ctx, sid,
119                                            domain_name, name, type);
120
121         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
122                 result = msrpc_methods.sid_to_name(domain, mem_ctx, sid,
123                                                    domain_name, name, type);
124
125         return result;
126 }
127
128 static NTSTATUS rids_to_names(struct winbindd_domain *domain,
129                               TALLOC_CTX *mem_ctx,
130                               const DOM_SID *sid,
131                               uint32 *rids,
132                               size_t num_rids,
133                               char **domain_name,
134                               char ***names,
135                               enum SID_NAME_USE **types)
136 {
137         NTSTATUS result;
138
139         result = msrpc_methods.rids_to_names(domain, mem_ctx, sid,
140                                              rids, num_rids,
141                                              domain_name, names, types);
142         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) {
143                 result = msrpc_methods.rids_to_names(domain, mem_ctx, sid,
144                                                      rids, num_rids,
145                                                      domain_name, names,
146                                                      types);
147         }
148
149         return result;
150 }
151
152 /* Lookup user information from a rid or username. */
153 static NTSTATUS query_user(struct winbindd_domain *domain, 
154                            TALLOC_CTX *mem_ctx, 
155                            const DOM_SID *user_sid,
156                            WINBIND_USERINFO *user_info)
157 {
158         NTSTATUS result;
159
160         result = msrpc_methods.query_user(domain, mem_ctx, user_sid,
161                                           user_info);
162
163         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
164                 result = msrpc_methods.query_user(domain, mem_ctx, user_sid,
165                                                   user_info);
166
167         return result;
168 }
169
170 /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
171 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
172                                   TALLOC_CTX *mem_ctx,
173                                   const DOM_SID *user_sid,
174                                   uint32 *num_groups, DOM_SID **user_gids)
175 {
176         NTSTATUS result;
177
178         result = msrpc_methods.lookup_usergroups(domain, mem_ctx,
179                                                  user_sid, num_groups,
180                                                  user_gids);
181
182         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
183                 result = msrpc_methods.lookup_usergroups(domain, mem_ctx,
184                                                          user_sid, num_groups,
185                                                          user_gids);
186
187         return result;
188 }
189
190 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
191                                    TALLOC_CTX *mem_ctx,
192                                    uint32 num_sids, const DOM_SID *sids,
193                                    uint32 *num_aliases, uint32 **alias_rids)
194 {
195         NTSTATUS result;
196
197         result = msrpc_methods.lookup_useraliases(domain, mem_ctx,
198                                                   num_sids, sids,
199                                                   num_aliases,
200                                                   alias_rids);
201
202         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
203                 result = msrpc_methods.lookup_useraliases(domain, mem_ctx,
204                                                           num_sids, sids,
205                                                           num_aliases,
206                                                           alias_rids);
207
208         return result;
209 }
210
211 /* Lookup group membership given a rid.   */
212 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
213                                 TALLOC_CTX *mem_ctx,
214                                 const DOM_SID *group_sid, uint32 *num_names, 
215                                 DOM_SID **sid_mem, char ***names, 
216                                 uint32 **name_types)
217 {
218         NTSTATUS result;
219
220         result = msrpc_methods.lookup_groupmem(domain, mem_ctx,
221                                                group_sid, num_names,
222                                                sid_mem, names,
223                                                name_types);
224
225         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
226                 result = msrpc_methods.lookup_groupmem(domain, mem_ctx,
227                                                        group_sid, num_names,
228                                                        sid_mem, names,
229                                                        name_types);
230
231         return result;
232 }
233
234 /* find the sequence number for a domain */
235 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
236 {
237         NTSTATUS result;
238
239         result = msrpc_methods.sequence_number(domain, seq);
240
241         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
242                 result = msrpc_methods.sequence_number(domain, seq);
243
244         return result;
245 }
246
247 /* find the lockout policy of a domain */
248 static NTSTATUS lockout_policy(struct winbindd_domain *domain, 
249                                TALLOC_CTX *mem_ctx,
250                                SAM_UNK_INFO_12 *policy)
251 {
252         NTSTATUS result;
253
254         result = msrpc_methods.lockout_policy(domain, mem_ctx, policy);
255
256         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
257                 result = msrpc_methods.lockout_policy(domain, mem_ctx, policy);
258
259         return result;
260 }
261
262 /* find the password policy of a domain */
263 static NTSTATUS password_policy(struct winbindd_domain *domain, 
264                                 TALLOC_CTX *mem_ctx,
265                                 SAM_UNK_INFO_1 *policy)
266 {
267         NTSTATUS result;
268  
269         result = msrpc_methods.password_policy(domain, mem_ctx, policy);
270
271         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
272                 result = msrpc_methods.password_policy(domain, mem_ctx, policy);
273         
274         return result;
275 }
276
277 /* get a list of trusted domains */
278 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
279                                 TALLOC_CTX *mem_ctx,
280                                 uint32 *num_domains,
281                                 char ***names,
282                                 char ***alt_names,
283                                 DOM_SID **dom_sids)
284 {
285         NTSTATUS result;
286
287         result = msrpc_methods.trusted_domains(domain, mem_ctx,
288                                                num_domains, names,
289                                                alt_names, dom_sids);
290
291         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
292                 result = msrpc_methods.trusted_domains(domain, mem_ctx,
293                                                        num_domains, names,
294                                                        alt_names, dom_sids);
295
296         return result;
297 }
298
299 /* the rpc backend methods are exposed via this structure */
300 struct winbindd_methods reconnect_methods = {
301         False,
302         query_user_list,
303         enum_dom_groups,
304         enum_local_groups,
305         name_to_sid,
306         sid_to_name,
307         rids_to_names,
308         query_user,
309         lookup_usergroups,
310         lookup_useraliases,
311         lookup_groupmem,
312         sequence_number,
313         lockout_policy,
314         password_policy,
315         trusted_domains,
316 };