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 #include "lib/winbind_util.h"
27
28 #if defined(WITH_WINBIND)
29
winbind_getpwnam(const char * name)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
winbind_getpwsid(const struct dom_sid * sid)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
winbind_lookup_name(const char * dom_name,const char * name,struct dom_sid * sid,enum lsa_SidType * name_type)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
winbind_lookup_sid(TALLOC_CTX * mem_ctx,const struct dom_sid * sid,const char ** domain,const char ** name,enum lsa_SidType * name_type)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
winbind_ping(void)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
winbind_sid_to_uid(uid_t * puid,const struct dom_sid * sid)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 SID to gid */
154
winbind_sid_to_gid(gid_t * pgid,const struct dom_sid * sid)155 bool winbind_sid_to_gid(gid_t *pgid, const struct dom_sid *sid)
156 {
157 struct wbcDomainSid dom_sid;
158 wbcErr result;
159
160 memcpy(&dom_sid, sid, sizeof(dom_sid));
161
162 result = wbcSidToGid(&dom_sid, pgid);
163
164 return (result == WBC_ERR_SUCCESS);
165 }
166
winbind_xid_to_sid(struct dom_sid * sid,const struct unixid * xid)167 bool winbind_xid_to_sid(struct dom_sid *sid, const struct unixid *xid)
168 {
169 struct wbcUnixId wbc_xid;
170 struct wbcDomainSid dom_sid;
171 wbcErr result;
172
173 switch (xid->type) {
174 case ID_TYPE_UID:
175 wbc_xid = (struct wbcUnixId) {
176 .type = WBC_ID_TYPE_UID, .id.uid = xid->id
177 };
178 break;
179 case ID_TYPE_GID:
180 wbc_xid = (struct wbcUnixId) {
181 .type = WBC_ID_TYPE_GID, .id.gid = xid->id
182 };
183 break;
184 default:
185 return false;
186 }
187
188 result = wbcUnixIdsToSids(&wbc_xid, 1, &dom_sid);
189 if (result != WBC_ERR_SUCCESS) {
190 return false;
191 }
192
193 memcpy(sid, &dom_sid, sizeof(struct dom_sid));
194 return true;
195 }
196
197 /* Check for a trusted domain */
198
wb_is_trusted_domain(const char * domain)199 wbcErr wb_is_trusted_domain(const char *domain)
200 {
201 wbcErr result;
202 struct wbcDomainInfo *info = NULL;
203
204 result = wbcDomainInfo(domain, &info);
205
206 if (WBC_ERROR_IS_OK(result)) {
207 wbcFreeMemory(info);
208 }
209
210 return result;
211 }
212
213 /* Lookup a set of rids in a given domain */
214
winbind_lookup_rids(TALLOC_CTX * mem_ctx,const struct dom_sid * domain_sid,int num_rids,uint32_t * rids,const char ** domain_name,const char *** names,enum lsa_SidType ** types)215 bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
216 const struct dom_sid *domain_sid,
217 int num_rids, uint32_t *rids,
218 const char **domain_name,
219 const char ***names, enum lsa_SidType **types)
220 {
221 const char *dom_name = NULL;
222 const char **namelist = NULL;
223 enum wbcSidType *name_types = NULL;
224 struct wbcDomainSid dom_sid;
225 wbcErr ret;
226 int i;
227
228 memcpy(&dom_sid, domain_sid, sizeof(struct wbcDomainSid));
229
230 ret = wbcLookupRids(&dom_sid, num_rids, rids,
231 &dom_name, &namelist, &name_types);
232 if (ret != WBC_ERR_SUCCESS) {
233 return false;
234 }
235
236 *domain_name = talloc_strdup(mem_ctx, dom_name);
237 *names = talloc_array(mem_ctx, const char*, num_rids);
238 *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
239
240 for(i=0; i<num_rids; i++) {
241 (*names)[i] = talloc_strdup(*names, namelist[i]);
242 (*types)[i] = (enum lsa_SidType)name_types[i];
243 }
244
245 wbcFreeMemory(discard_const_p(char, dom_name));
246 wbcFreeMemory(namelist);
247 wbcFreeMemory(name_types);
248
249 return true;
250 }
251
252 /* Ask Winbind to allocate a new uid for us */
253
winbind_allocate_uid(uid_t * uid)254 bool winbind_allocate_uid(uid_t *uid)
255 {
256 wbcErr ret;
257
258 ret = wbcAllocateUid(uid);
259
260 return (ret == WBC_ERR_SUCCESS);
261 }
262
263 /* Ask Winbind to allocate a new gid for us */
264
winbind_allocate_gid(gid_t * gid)265 bool winbind_allocate_gid(gid_t *gid)
266 {
267 wbcErr ret;
268
269 ret = wbcAllocateGid(gid);
270
271 return (ret == WBC_ERR_SUCCESS);
272 }
273
winbind_lookup_usersids(TALLOC_CTX * mem_ctx,const struct dom_sid * user_sid,uint32_t * p_num_sids,struct dom_sid ** p_sids)274 bool winbind_lookup_usersids(TALLOC_CTX *mem_ctx,
275 const struct dom_sid *user_sid,
276 uint32_t *p_num_sids,
277 struct dom_sid **p_sids)
278 {
279 wbcErr ret;
280 struct wbcDomainSid dom_sid;
281 struct wbcDomainSid *sid_list = NULL;
282 uint32_t num_sids;
283
284 memcpy(&dom_sid, user_sid, sizeof(dom_sid));
285
286 ret = wbcLookupUserSids(&dom_sid,
287 false,
288 &num_sids,
289 &sid_list);
290 if (ret != WBC_ERR_SUCCESS) {
291 return false;
292 }
293
294 *p_sids = talloc_array(mem_ctx, struct dom_sid, num_sids);
295 if (*p_sids == NULL) {
296 wbcFreeMemory(sid_list);
297 return false;
298 }
299
300 memcpy(*p_sids, sid_list, sizeof(dom_sid) * num_sids);
301
302 *p_num_sids = num_sids;
303 wbcFreeMemory(sid_list);
304
305 return true;
306 }
307
308 #else /* WITH_WINBIND */
309
winbind_getpwnam(const char * name)310 struct passwd * winbind_getpwnam(const char * name)
311 {
312 return NULL;
313 }
314
winbind_getpwsid(const struct dom_sid * sid)315 struct passwd * winbind_getpwsid(const struct dom_sid *sid)
316 {
317 return NULL;
318 }
319
winbind_lookup_name(const char * dom_name,const char * name,struct dom_sid * sid,enum lsa_SidType * name_type)320 bool winbind_lookup_name(const char *dom_name, const char *name, struct dom_sid *sid,
321 enum lsa_SidType *name_type)
322 {
323 return false;
324 }
325
326 /* Call winbindd to convert sid to name */
327
winbind_lookup_sid(TALLOC_CTX * mem_ctx,const struct dom_sid * sid,const char ** domain,const char ** name,enum lsa_SidType * name_type)328 bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
329 const char **domain, const char **name,
330 enum lsa_SidType *name_type)
331 {
332 return false;
333 }
334
335 /* Ping winbindd to see it is alive */
336
winbind_ping(void)337 bool winbind_ping(void)
338 {
339 return false;
340 }
341
342 /* Call winbindd to convert SID to uid */
343
winbind_sid_to_uid(uid_t * puid,const struct dom_sid * sid)344 bool winbind_sid_to_uid(uid_t *puid, const struct dom_sid *sid)
345 {
346 return false;
347 }
348
349 /* Call winbindd to convert SID to gid */
350
winbind_sid_to_gid(gid_t * pgid,const struct dom_sid * sid)351 bool winbind_sid_to_gid(gid_t *pgid, const struct dom_sid *sid)
352 {
353 return false;
354 }
355
356 /* Call winbindd to convert uid or gid to SID */
357
winbind_xid_to_sid(struct dom_sid * sid,const struct unixid * xid)358 bool winbind_xid_to_sid(struct dom_sid *sid, const struct unixid *xid)
359 {
360 return false;
361 }
362
363 /* Check for a trusted domain */
364
wb_is_trusted_domain(const char * domain)365 wbcErr wb_is_trusted_domain(const char *domain)
366 {
367 return WBC_ERR_UNKNOWN_FAILURE;
368 }
369
370 /* Lookup a set of rids in a given domain */
371
winbind_lookup_rids(TALLOC_CTX * mem_ctx,const struct dom_sid * domain_sid,int num_rids,uint32_t * rids,const char ** domain_name,const char *** names,enum lsa_SidType ** types)372 bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
373 const struct dom_sid *domain_sid,
374 int num_rids, uint32_t *rids,
375 const char **domain_name,
376 const char ***names, enum lsa_SidType **types)
377 {
378 return false;
379 }
380
381 /* Ask Winbind to allocate a new uid for us */
382
winbind_allocate_uid(uid_t * uid)383 bool winbind_allocate_uid(uid_t *uid)
384 {
385 return false;
386 }
387
388 /* Ask Winbind to allocate a new gid for us */
389
winbind_allocate_gid(gid_t * gid)390 bool winbind_allocate_gid(gid_t *gid)
391 {
392 return false;
393 }
394
winbind_lookup_usersids(TALLOC_CTX * mem_ctx,const struct dom_sid * user_sid,uint32_t * p_num_sids,struct dom_sid ** p_sids)395 bool winbind_lookup_usersids(TALLOC_CTX *mem_ctx,
396 const struct dom_sid *user_sid,
397 uint32_t *p_num_sids,
398 struct dom_sid **p_sids)
399 {
400 return false;
401 }
402
403 #endif /* WITH_WINBIND */
404