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