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