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