lib/util/util_pw: share more code between lib/util/util_pw.c and source3/lib/username.c
[samba.git] / source3 / lib / winbind_util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Winbind Utility functions
4
5    Copyright (C) Gerald (Jerry) Carter   2007
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "../libcli/security/security.h"
23 #include "../lib/util/util_pw.h"
24
25 #if defined(WITH_WINBIND)
26
27 #include "nsswitch/libwbclient/wbclient.h"
28
29 struct passwd * winbind_getpwnam(const char * name)
30 {
31         wbcErr result;
32         struct passwd * tmp_pwd = NULL;
33         struct passwd * pwd = NULL;
34
35         result = wbcGetpwnam(name, &tmp_pwd);
36         if (result != WBC_ERR_SUCCESS)
37                 return pwd;
38
39         pwd = tcopy_passwd(talloc_tos(), tmp_pwd);
40
41         wbcFreeMemory(tmp_pwd);
42
43         return pwd;
44 }
45
46 struct passwd * winbind_getpwsid(const struct dom_sid *sid)
47 {
48         wbcErr result;
49         struct passwd * tmp_pwd = NULL;
50         struct passwd * pwd = NULL;
51         struct wbcDomainSid dom_sid;
52
53         memcpy(&dom_sid, sid, sizeof(dom_sid));
54
55         result = wbcGetpwsid(&dom_sid, &tmp_pwd);
56         if (result != WBC_ERR_SUCCESS)
57                 return pwd;
58
59         pwd = tcopy_passwd(talloc_tos(), tmp_pwd);
60
61         wbcFreeMemory(tmp_pwd);
62
63         return pwd;
64 }
65
66 /* Call winbindd to convert a name to a sid */
67
68 bool winbind_lookup_name(const char *dom_name, const char *name, struct dom_sid *sid,
69                          enum lsa_SidType *name_type)
70 {
71         struct wbcDomainSid dom_sid;
72         wbcErr result;
73         enum wbcSidType type;   
74
75         result = wbcLookupName(dom_name, name, &dom_sid, &type);
76         if (result != WBC_ERR_SUCCESS)
77                 return false;
78
79         memcpy(sid, &dom_sid, sizeof(struct dom_sid));
80         *name_type = (enum lsa_SidType)type;    
81
82         return true;    
83 }
84
85 /* Call winbindd to convert sid to name */
86
87 bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
88                         const char **domain, const char **name,
89                         enum lsa_SidType *name_type)
90 {
91         struct wbcDomainSid dom_sid;
92         wbcErr result;
93         enum wbcSidType type;
94         char *domain_name = NULL;
95         char *account_name = NULL;
96
97         memcpy(&dom_sid, sid, sizeof(dom_sid)); 
98
99         result = wbcLookupSid(&dom_sid, &domain_name, &account_name, &type);
100         if (result != WBC_ERR_SUCCESS)
101                 return false;
102
103         /* Copy out result */
104
105         if (domain) {           
106                 *domain = talloc_strdup(mem_ctx, domain_name);
107         }
108         if (name) {
109                 *name = talloc_strdup(mem_ctx, account_name);
110         }
111         *name_type = (enum lsa_SidType)type;
112
113         DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n", 
114                    sid_string_dbg(sid), domain_name, account_name));
115
116         wbcFreeMemory(domain_name);
117         wbcFreeMemory(account_name);
118
119         if ((domain && !*domain) || (name && !*name)) {         
120                 DEBUG(0,("winbind_lookup_sid: talloc() failed!\n"));
121                 return false;
122         }       
123
124
125         return true;
126 }
127
128 /* Ping winbindd to see it is alive */
129
130 bool winbind_ping(void)
131 {
132         wbcErr result = wbcPing();
133
134         return (result == WBC_ERR_SUCCESS);
135 }
136
137 /* Call winbindd to convert SID to uid */
138
139 bool winbind_sid_to_uid(uid_t *puid, const struct dom_sid *sid)
140 {
141         struct wbcDomainSid dom_sid;
142         wbcErr result;
143
144         memcpy(&dom_sid, sid, sizeof(dom_sid)); 
145
146         result = wbcSidToUid(&dom_sid, puid);   
147
148         return (result == WBC_ERR_SUCCESS);     
149 }
150
151 /* Call winbindd to convert uid to sid */
152
153 bool winbind_uid_to_sid(struct dom_sid *sid, uid_t uid)
154 {
155         struct wbcDomainSid dom_sid;
156         wbcErr result;
157
158         result = wbcUidToSid(uid, &dom_sid);
159         if (result == WBC_ERR_SUCCESS) {
160                 memcpy(sid, &dom_sid, sizeof(struct dom_sid));
161         } else {
162                 sid_copy(sid, &global_sid_NULL);
163         }
164
165         return (result == WBC_ERR_SUCCESS);
166 }
167
168 /* Call winbindd to convert SID to gid */
169
170 bool winbind_sid_to_gid(gid_t *pgid, const struct dom_sid *sid)
171 {
172         struct wbcDomainSid dom_sid;
173         wbcErr result;
174
175         memcpy(&dom_sid, sid, sizeof(dom_sid)); 
176
177         result = wbcSidToGid(&dom_sid, pgid);   
178
179         return (result == WBC_ERR_SUCCESS);     
180 }
181
182 /* Call winbindd to convert gid to sid */
183
184 bool winbind_gid_to_sid(struct dom_sid *sid, gid_t gid)
185 {
186         struct wbcDomainSid dom_sid;
187         wbcErr result;
188
189         result = wbcGidToSid(gid, &dom_sid);
190         if (result == WBC_ERR_SUCCESS) {
191                 memcpy(sid, &dom_sid, sizeof(struct dom_sid));
192         } else {
193                 sid_copy(sid, &global_sid_NULL);
194         }
195
196         return (result == WBC_ERR_SUCCESS);
197 }
198
199 /* Check for a trusted domain */
200
201 wbcErr wb_is_trusted_domain(const char *domain)
202 {
203         wbcErr result;
204         struct wbcDomainInfo *info = NULL;
205
206         result = wbcDomainInfo(domain, &info);
207
208         if (WBC_ERROR_IS_OK(result)) {
209                 wbcFreeMemory(info);
210         }
211
212         return result;  
213 }
214
215 /* Lookup a set of rids in a given domain */
216
217 bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
218                          const struct dom_sid *domain_sid,
219                          int num_rids, uint32 *rids,
220                          const char **domain_name,
221                          const char ***names, enum lsa_SidType **types)
222 {
223         const char *dom_name = NULL;
224         const char **namelist = NULL;
225         enum wbcSidType *name_types = NULL;
226         struct wbcDomainSid dom_sid;
227         wbcErr ret;
228         int i;  
229
230         memcpy(&dom_sid, domain_sid, sizeof(struct wbcDomainSid));
231
232         ret = wbcLookupRids(&dom_sid, num_rids, rids,
233                             &dom_name, &namelist, &name_types);
234         if (ret != WBC_ERR_SUCCESS) {           
235                 return false;
236         }       
237
238         *domain_name = talloc_strdup(mem_ctx, dom_name);
239         *names       = TALLOC_ARRAY(mem_ctx, const char*, num_rids);
240         *types       = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
241
242         for(i=0; i<num_rids; i++) {
243                 (*names)[i] = talloc_strdup(*names, namelist[i]);
244                 (*types)[i] = (enum lsa_SidType)name_types[i];
245         }
246
247         wbcFreeMemory(CONST_DISCARD(char*, dom_name));
248         wbcFreeMemory(namelist);
249         wbcFreeMemory(name_types);
250
251         return true;    
252 }
253
254 /* Ask Winbind to allocate a new uid for us */
255
256 bool winbind_allocate_uid(uid_t *uid)
257 {
258         wbcErr ret;
259
260         ret = wbcAllocateUid(uid);
261
262         return (ret == WBC_ERR_SUCCESS);
263 }
264
265 /* Ask Winbind to allocate a new gid for us */
266
267 bool winbind_allocate_gid(gid_t *gid)
268 {
269         wbcErr ret;
270
271         ret = wbcAllocateGid(gid);
272
273         return (ret == WBC_ERR_SUCCESS);
274 }
275
276 bool winbind_get_groups(TALLOC_CTX * mem_ctx, const char *account, uint32_t *num_groups, gid_t **_groups)
277 {
278         wbcErr ret;
279         uint32_t ngroups;
280         gid_t *group_list = NULL;
281
282         ret = wbcGetGroups(account, &ngroups, &group_list);
283         if (ret != WBC_ERR_SUCCESS)
284                 return false;
285
286         *_groups = TALLOC_ARRAY(mem_ctx, gid_t, ngroups);
287         if (*_groups == NULL) {
288             wbcFreeMemory(group_list);
289             return false;
290         }
291
292         memcpy(*_groups, group_list, ngroups* sizeof(gid_t));
293         *num_groups = ngroups;
294
295         wbcFreeMemory(group_list);
296         return true;
297 }
298
299 bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx,
300                              const struct dom_sid *dom_sid,
301                              const struct dom_sid *members,
302                              size_t num_members,
303                              uint32_t **pp_alias_rids,
304                              size_t *p_num_alias_rids)
305 {
306         wbcErr ret;
307         struct wbcDomainSid domain_sid;
308         struct wbcDomainSid *sid_list = NULL;
309         size_t i;
310         uint32_t * rids;
311         uint32_t num_rids;
312
313         memcpy(&domain_sid, dom_sid, sizeof(*dom_sid));
314
315         sid_list = TALLOC_ARRAY(mem_ctx, struct wbcDomainSid, num_members);
316
317         for (i=0; i < num_members; i++) {
318             memcpy(&sid_list[i], &members[i], sizeof(sid_list[i]));
319         }
320
321         ret = wbcGetSidAliases(&domain_sid,
322                                sid_list,
323                                num_members,
324                                &rids,
325                                &num_rids);
326         if (ret != WBC_ERR_SUCCESS) {
327                 return false;
328         }
329
330         *pp_alias_rids = TALLOC_ARRAY(mem_ctx, uint32_t, num_rids);
331         if (*pp_alias_rids == NULL) {
332                 wbcFreeMemory(rids);
333                 return false;
334         }
335
336         memcpy(*pp_alias_rids, rids, sizeof(uint32_t) * num_rids);
337
338         *p_num_alias_rids = num_rids;
339         wbcFreeMemory(rids);
340
341         return true;
342 }
343
344 #else      /* WITH_WINBIND */
345
346 struct passwd * winbind_getpwnam(const char * name)
347 {
348         return NULL;
349 }
350
351 struct passwd * winbind_getpwsid(const struct dom_sid *sid)
352 {
353         return NULL;
354 }
355
356 bool winbind_lookup_name(const char *dom_name, const char *name, struct dom_sid *sid,
357                          enum lsa_SidType *name_type)
358 {
359         return false;
360 }
361
362 /* Call winbindd to convert sid to name */
363
364 bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
365                         const char **domain, const char **name,
366                         enum lsa_SidType *name_type)
367 {
368         return false;
369 }
370
371 /* Ping winbindd to see it is alive */
372
373 bool winbind_ping(void)
374 {
375         return false;
376 }
377
378 /* Call winbindd to convert SID to uid */
379
380 bool winbind_sid_to_uid(uid_t *puid, const struct dom_sid *sid)
381 {
382         return false;
383 }
384
385 /* Call winbindd to convert uid to sid */
386
387 bool winbind_uid_to_sid(struct dom_sid *sid, uid_t uid)
388 {
389         return false;
390 }
391
392 /* Call winbindd to convert SID to gid */
393
394 bool winbind_sid_to_gid(gid_t *pgid, const struct dom_sid *sid)
395 {
396         return false;   
397 }
398
399 /* Call winbindd to convert gid to sid */
400
401 bool winbind_gid_to_sid(struct dom_sid *sid, gid_t gid)
402 {
403         return false;
404 }
405
406 /* Check for a trusted domain */
407
408 wbcErr wb_is_trusted_domain(const char *domain)
409 {
410         return WBC_ERR_UNKNOWN_FAILURE;
411 }
412
413 /* Lookup a set of rids in a given domain */
414
415 bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
416                          const struct dom_sid *domain_sid,
417                          int num_rids, uint32 *rids,
418                          const char **domain_name,
419                          const char ***names, enum lsa_SidType **types)
420 {
421         return false;
422 }
423
424 /* Ask Winbind to allocate a new uid for us */
425
426 bool winbind_allocate_uid(uid_t *uid)
427 {
428         return false;
429 }
430
431 /* Ask Winbind to allocate a new gid for us */
432
433 bool winbind_allocate_gid(gid_t *gid)
434 {
435         return false;
436 }
437
438 bool winbind_get_groups(TALLOC_CTX *mem_ctx, const char *account, uint32_t *num_groups, gid_t **_groups)
439 {
440         return false;
441 }
442
443 bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx,
444                              const struct dom_sid *dom_sid,
445                              const struct dom_sid *members,
446                              size_t num_members,
447                              uint32_t **pp_alias_rids,
448                              size_t *p_num_alias_rids)
449 {
450         return false;
451 }
452
453 #endif     /* WITH_WINBIND */