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