s3:pylibsmb: Don't return '.'/'..' in .list()
[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         struct dom_sid_buf buf;
98
99         memcpy(&dom_sid, sid, sizeof(dom_sid));
100
101         result = wbcLookupSid(&dom_sid, &domain_name, &account_name, &type);
102         if (result != WBC_ERR_SUCCESS)
103                 return false;
104
105         /* Copy out result */
106
107         if (domain) {
108                 *domain = talloc_strdup(mem_ctx, domain_name);
109         }
110         if (name) {
111                 *name = talloc_strdup(mem_ctx, account_name);
112         }
113         *name_type = (enum lsa_SidType)type;
114
115         DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
116                    dom_sid_str_buf(sid, &buf), domain_name, account_name));
117
118         wbcFreeMemory(domain_name);
119         wbcFreeMemory(account_name);
120
121         if ((domain && !*domain) || (name && !*name)) {
122                 DEBUG(0,("winbind_lookup_sid: talloc() failed!\n"));
123                 return false;
124         }
125
126
127         return true;
128 }
129
130 /* Ping winbindd to see it is alive */
131
132 bool winbind_ping(void)
133 {
134         wbcErr result = wbcPing();
135
136         return (result == WBC_ERR_SUCCESS);
137 }
138
139 /* Call winbindd to convert SID to uid */
140
141 bool winbind_sid_to_uid(uid_t *puid, const struct dom_sid *sid)
142 {
143         struct wbcDomainSid dom_sid;
144         wbcErr result;
145
146         memcpy(&dom_sid, sid, sizeof(dom_sid));
147
148         result = wbcSidToUid(&dom_sid, puid);
149
150         return (result == WBC_ERR_SUCCESS);
151 }
152
153 /* Call winbindd to convert uid to sid */
154
155 bool winbind_uid_to_sid(struct dom_sid *sid, uid_t uid)
156 {
157         struct wbcDomainSid dom_sid;
158         wbcErr result;
159
160         result = wbcUidToSid(uid, &dom_sid);
161         if (result == WBC_ERR_SUCCESS) {
162                 memcpy(sid, &dom_sid, sizeof(struct dom_sid));
163         } else {
164                 sid_copy(sid, &global_sid_NULL);
165         }
166
167         return (result == WBC_ERR_SUCCESS);
168 }
169
170 /* Call winbindd to convert SID to gid */
171
172 bool winbind_sid_to_gid(gid_t *pgid, const struct dom_sid *sid)
173 {
174         struct wbcDomainSid dom_sid;
175         wbcErr result;
176
177         memcpy(&dom_sid, sid, sizeof(dom_sid));
178
179         result = wbcSidToGid(&dom_sid, pgid);
180
181         return (result == WBC_ERR_SUCCESS);
182 }
183
184 /* Call winbindd to convert gid to sid */
185
186 bool winbind_gid_to_sid(struct dom_sid *sid, gid_t gid)
187 {
188         struct wbcDomainSid dom_sid;
189         wbcErr result;
190
191         result = wbcGidToSid(gid, &dom_sid);
192         if (result == WBC_ERR_SUCCESS) {
193                 memcpy(sid, &dom_sid, sizeof(struct dom_sid));
194         } else {
195                 sid_copy(sid, &global_sid_NULL);
196         }
197
198         return (result == WBC_ERR_SUCCESS);
199 }
200
201 /* Check for a trusted domain */
202
203 wbcErr wb_is_trusted_domain(const char *domain)
204 {
205         wbcErr result;
206         struct wbcDomainInfo *info = NULL;
207
208         result = wbcDomainInfo(domain, &info);
209
210         if (WBC_ERROR_IS_OK(result)) {
211                 wbcFreeMemory(info);
212         }
213
214         return result;
215 }
216
217 /* Lookup a set of rids in a given domain */
218
219 bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
220                          const struct dom_sid *domain_sid,
221                          int num_rids, uint32_t *rids,
222                          const char **domain_name,
223                          const char ***names, enum lsa_SidType **types)
224 {
225         const char *dom_name = NULL;
226         const char **namelist = NULL;
227         enum wbcSidType *name_types = NULL;
228         struct wbcDomainSid dom_sid;
229         wbcErr ret;
230         int i;
231
232         memcpy(&dom_sid, domain_sid, sizeof(struct wbcDomainSid));
233
234         ret = wbcLookupRids(&dom_sid, num_rids, rids,
235                             &dom_name, &namelist, &name_types);
236         if (ret != WBC_ERR_SUCCESS) {
237                 return false;
238         }
239
240         *domain_name = talloc_strdup(mem_ctx, dom_name);
241         *names       = talloc_array(mem_ctx, const char*, num_rids);
242         *types       = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
243
244         for(i=0; i<num_rids; i++) {
245                 (*names)[i] = talloc_strdup(*names, namelist[i]);
246                 (*types)[i] = (enum lsa_SidType)name_types[i];
247         }
248
249         wbcFreeMemory(discard_const_p(char, dom_name));
250         wbcFreeMemory(namelist);
251         wbcFreeMemory(name_types);
252
253         return true;
254 }
255
256 /* Ask Winbind to allocate a new uid for us */
257
258 bool winbind_allocate_uid(uid_t *uid)
259 {
260         wbcErr ret;
261
262         ret = wbcAllocateUid(uid);
263
264         return (ret == WBC_ERR_SUCCESS);
265 }
266
267 /* Ask Winbind to allocate a new gid for us */
268
269 bool winbind_allocate_gid(gid_t *gid)
270 {
271         wbcErr ret;
272
273         ret = wbcAllocateGid(gid);
274
275         return (ret == WBC_ERR_SUCCESS);
276 }
277
278 bool winbind_lookup_usersids(TALLOC_CTX *mem_ctx,
279                              const struct dom_sid *user_sid,
280                              uint32_t *p_num_sids,
281                              struct dom_sid **p_sids)
282 {
283         wbcErr ret;
284         struct wbcDomainSid dom_sid;
285         struct wbcDomainSid *sid_list = NULL;
286         uint32_t num_sids;
287
288         memcpy(&dom_sid, user_sid, sizeof(dom_sid));
289
290         ret = wbcLookupUserSids(&dom_sid,
291                                 false,
292                                 &num_sids,
293                                 &sid_list);
294         if (ret != WBC_ERR_SUCCESS) {
295                 return false;
296         }
297
298         *p_sids = talloc_array(mem_ctx, struct dom_sid, num_sids);
299         if (*p_sids == NULL) {
300                 wbcFreeMemory(sid_list);
301                 return false;
302         }
303
304         memcpy(*p_sids, sid_list, sizeof(dom_sid) * num_sids);
305
306         *p_num_sids = num_sids;
307         wbcFreeMemory(sid_list);
308
309         return true;
310 }
311
312 #else      /* WITH_WINBIND */
313
314 struct passwd * winbind_getpwnam(const char * name)
315 {
316         return NULL;
317 }
318
319 struct passwd * winbind_getpwsid(const struct dom_sid *sid)
320 {
321         return NULL;
322 }
323
324 bool winbind_lookup_name(const char *dom_name, const char *name, struct dom_sid *sid,
325                          enum lsa_SidType *name_type)
326 {
327         return false;
328 }
329
330 /* Call winbindd to convert sid to name */
331
332 bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
333                         const char **domain, const char **name,
334                         enum lsa_SidType *name_type)
335 {
336         return false;
337 }
338
339 /* Ping winbindd to see it is alive */
340
341 bool winbind_ping(void)
342 {
343         return false;
344 }
345
346 /* Call winbindd to convert SID to uid */
347
348 bool winbind_sid_to_uid(uid_t *puid, const struct dom_sid *sid)
349 {
350         return false;
351 }
352
353 /* Call winbindd to convert uid to sid */
354
355 bool winbind_uid_to_sid(struct dom_sid *sid, uid_t uid)
356 {
357         return false;
358 }
359
360 /* Call winbindd to convert SID to gid */
361
362 bool winbind_sid_to_gid(gid_t *pgid, const struct dom_sid *sid)
363 {
364         return false;
365 }
366
367 /* Call winbindd to convert gid to sid */
368
369 bool winbind_gid_to_sid(struct dom_sid *sid, gid_t gid)
370 {
371         return false;
372 }
373
374 /* Check for a trusted domain */
375
376 wbcErr wb_is_trusted_domain(const char *domain)
377 {
378         return WBC_ERR_UNKNOWN_FAILURE;
379 }
380
381 /* Lookup a set of rids in a given domain */
382
383 bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
384                          const struct dom_sid *domain_sid,
385                          int num_rids, uint32_t *rids,
386                          const char **domain_name,
387                          const char ***names, enum lsa_SidType **types)
388 {
389         return false;
390 }
391
392 /* Ask Winbind to allocate a new uid for us */
393
394 bool winbind_allocate_uid(uid_t *uid)
395 {
396         return false;
397 }
398
399 /* Ask Winbind to allocate a new gid for us */
400
401 bool winbind_allocate_gid(gid_t *gid)
402 {
403         return false;
404 }
405
406 bool winbind_lookup_usersids(TALLOC_CTX *mem_ctx,
407                              const struct dom_sid *user_sid,
408                              uint32_t *p_num_sids,
409                              struct dom_sid **p_sids)
410 {
411         return false;
412 }
413
414 #endif     /* WITH_WINBIND */