Initial import
[samba] / 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 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 /* Lookup user information from a rid or username. */
129 static NTSTATUS query_user(struct winbindd_domain *domain, 
130                            TALLOC_CTX *mem_ctx, 
131                            const DOM_SID *user_sid,
132                            WINBIND_USERINFO *user_info)
133 {
134         NTSTATUS result;
135
136         result = msrpc_methods.query_user(domain, mem_ctx, user_sid,
137                                           user_info);
138
139         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
140                 result = msrpc_methods.query_user(domain, mem_ctx, user_sid,
141                                                   user_info);
142
143         return result;
144 }
145
146 /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
147 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
148                                   TALLOC_CTX *mem_ctx,
149                                   const DOM_SID *user_sid,
150                                   uint32 *num_groups, DOM_SID **user_gids)
151 {
152         NTSTATUS result;
153
154         result = msrpc_methods.lookup_usergroups(domain, mem_ctx,
155                                                  user_sid, num_groups,
156                                                  user_gids);
157
158         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
159                 result = msrpc_methods.lookup_usergroups(domain, mem_ctx,
160                                                          user_sid, num_groups,
161                                                          user_gids);
162
163         return result;
164 }
165
166 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
167                                    TALLOC_CTX *mem_ctx,
168                                    uint32 num_sids, const DOM_SID *sids,
169                                    uint32 *num_aliases, uint32 **alias_rids)
170 {
171         NTSTATUS result;
172
173         result = msrpc_methods.lookup_useraliases(domain, mem_ctx,
174                                                   num_sids, sids,
175                                                   num_aliases,
176                                                   alias_rids);
177
178         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
179                 result = msrpc_methods.lookup_useraliases(domain, mem_ctx,
180                                                           num_sids, sids,
181                                                           num_aliases,
182                                                           alias_rids);
183
184         return result;
185 }
186
187 /* Lookup group membership given a rid.   */
188 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
189                                 TALLOC_CTX *mem_ctx,
190                                 const DOM_SID *group_sid, uint32 *num_names, 
191                                 DOM_SID **sid_mem, char ***names, 
192                                 uint32 **name_types)
193 {
194         NTSTATUS result;
195
196         result = msrpc_methods.lookup_groupmem(domain, mem_ctx,
197                                                group_sid, num_names,
198                                                sid_mem, names,
199                                                name_types);
200
201         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
202                 result = msrpc_methods.lookup_groupmem(domain, mem_ctx,
203                                                        group_sid, num_names,
204                                                        sid_mem, names,
205                                                        name_types);
206
207         return result;
208 }
209
210 /* find the sequence number for a domain */
211 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
212 {
213         NTSTATUS result;
214
215         result = msrpc_methods.sequence_number(domain, seq);
216
217         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
218                 result = msrpc_methods.sequence_number(domain, seq);
219
220         return result;
221 }
222
223 /* get a list of trusted domains */
224 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
225                                 TALLOC_CTX *mem_ctx,
226                                 uint32 *num_domains,
227                                 char ***names,
228                                 char ***alt_names,
229                                 DOM_SID **dom_sids)
230 {
231         NTSTATUS result;
232
233         result = msrpc_methods.trusted_domains(domain, mem_ctx,
234                                                num_domains, names,
235                                                alt_names, dom_sids);
236
237         if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))
238                 result = msrpc_methods.trusted_domains(domain, mem_ctx,
239                                                        num_domains, names,
240                                                        alt_names, dom_sids);
241
242         return result;
243 }
244
245 /* the rpc backend methods are exposed via this structure */
246 struct winbindd_methods reconnect_methods = {
247         False,
248         query_user_list,
249         enum_dom_groups,
250         enum_local_groups,
251         name_to_sid,
252         sid_to_name,
253         query_user,
254         lookup_usergroups,
255         lookup_useraliases,
256         lookup_groupmem,
257         sequence_number,
258         trusted_domains,
259 };