Branch data Line data Source code
1 : : /*
2 : : SSSD
3 : :
4 : : System Database
5 : :
6 : : Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
7 : :
8 : : This program is free software; you can redistribute it and/or modify
9 : : it under the terms of the GNU General Public License as published by
10 : : the Free Software Foundation; either version 3 of the License, or
11 : : (at your option) any later version.
12 : :
13 : : This program is distributed in the hope that it will be useful,
14 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : GNU General Public License for more details.
17 : :
18 : : You should have received a copy of the GNU General Public License
19 : : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #include "util/util.h"
23 : : #include "db/sysdb_private.h"
24 : : #include "confdb/confdb.h"
25 : : #include <time.h>
26 : : #include <ctype.h>
27 : :
28 : : /* users */
29 : :
30 : 44 : int sysdb_getpwnam(TALLOC_CTX *mem_ctx,
31 : : struct sysdb_ctx *sysdb,
32 : : const char *name,
33 : : struct ldb_result **_res)
34 : : {
35 : : TALLOC_CTX *tmp_ctx;
36 : : static const char *attrs[] = SYSDB_PW_ATTRS;
37 : : struct ldb_dn *base_dn;
38 : : struct ldb_result *res;
39 : : char *sanitized_name;
40 : : int ret;
41 : :
42 : 44 : tmp_ctx = talloc_new(NULL);
43 [ + - ]: 44 : if (!tmp_ctx) {
44 : : return ENOMEM;
45 : : }
46 : :
47 : 44 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
48 : 44 : SYSDB_TMPL_USER_BASE, sysdb->domain->name);
49 [ + - ]: 44 : if (!base_dn) {
50 : : ret = ENOMEM;
51 : : goto done;
52 : : }
53 : :
54 : 44 : ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name);
55 [ + - ]: 44 : if (ret != EOK) {
56 : : goto done;
57 : : }
58 : :
59 : 44 : ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn,
60 : : LDB_SCOPE_SUBTREE, attrs, SYSDB_PWNAM_FILTER,
61 : : sanitized_name, sanitized_name);
62 [ - + ]: 44 : if (ret) {
63 : 0 : ret = sysdb_error_to_errno(ret);
64 : : goto done;
65 : : }
66 : :
67 : 44 : *_res = talloc_steal(mem_ctx, res);
68 : :
69 : : done:
70 : 44 : talloc_zfree(tmp_ctx);
71 : : return ret;
72 : : }
73 : :
74 : 10 : int sysdb_getpwuid(TALLOC_CTX *mem_ctx,
75 : : struct sysdb_ctx *sysdb,
76 : : uid_t uid,
77 : : struct ldb_result **_res)
78 : : {
79 : : TALLOC_CTX *tmp_ctx;
80 : 10 : unsigned long int ul_uid = uid;
81 : : static const char *attrs[] = SYSDB_PW_ATTRS;
82 : : struct ldb_dn *base_dn;
83 : : struct ldb_result *res;
84 : : int ret;
85 : :
86 : 10 : tmp_ctx = talloc_new(NULL);
87 [ + - ]: 10 : if (!tmp_ctx) {
88 : : return ENOMEM;
89 : : }
90 : :
91 : 10 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
92 : 10 : SYSDB_TMPL_USER_BASE, sysdb->domain->name);
93 [ + - ]: 10 : if (!base_dn) {
94 : : ret = ENOMEM;
95 : : goto done;
96 : : }
97 : :
98 : 10 : ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn,
99 : : LDB_SCOPE_SUBTREE, attrs, SYSDB_PWUID_FILTER, ul_uid);
100 [ - + ]: 10 : if (ret) {
101 : 0 : ret = sysdb_error_to_errno(ret);
102 : : goto done;
103 : : }
104 : :
105 : 10 : *_res = talloc_steal(mem_ctx, res);
106 : :
107 : : done:
108 : 10 : talloc_zfree(tmp_ctx);
109 : : return ret;
110 : : }
111 : :
112 : 1 : int sysdb_enumpwent(TALLOC_CTX *mem_ctx,
113 : : struct sysdb_ctx *sysdb,
114 : : struct ldb_result **_res)
115 : : {
116 : : TALLOC_CTX *tmp_ctx;
117 : : static const char *attrs[] = SYSDB_PW_ATTRS;
118 : : struct ldb_dn *base_dn;
119 : : struct ldb_result *res;
120 : : int ret;
121 : :
122 : 1 : tmp_ctx = talloc_new(NULL);
123 [ + - ]: 1 : if (!tmp_ctx) {
124 : : return ENOMEM;
125 : : }
126 : :
127 : 1 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
128 : 1 : SYSDB_TMPL_USER_BASE, sysdb->domain->name);
129 [ + - ]: 1 : if (!base_dn) {
130 : : ret = ENOMEM;
131 : : goto done;
132 : : }
133 : :
134 : 1 : ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn,
135 : : LDB_SCOPE_SUBTREE, attrs, SYSDB_PWENT_FILTER);
136 [ - + ]: 1 : if (ret) {
137 : 0 : ret = sysdb_error_to_errno(ret);
138 : : goto done;
139 : : }
140 : :
141 : 1 : *_res = talloc_steal(mem_ctx, res);
142 : :
143 : : done:
144 : 1 : talloc_zfree(tmp_ctx);
145 : : return ret;
146 : : }
147 : :
148 : : /* groups */
149 : :
150 : 43 : static int mpg_convert(struct ldb_message *msg)
151 : : {
152 : : struct ldb_message_element *el;
153 : : struct ldb_val *val;
154 : : int i;
155 : :
156 : 43 : el = ldb_msg_find_element(msg, "objectClass");
157 [ + - ]: 43 : if (!el) return EINVAL;
158 : :
159 : : /* see if this is a user to convert to a group */
160 [ + + ]: 76 : for (i = 0; i < el->num_values; i++) {
161 : 43 : val = &(el->values[i]);
162 [ + + ]: 43 : if (strncasecmp(SYSDB_USER_CLASS,
163 : 43 : (char *)val->data, val->length) == 0) {
164 : : break;
165 : : }
166 : : }
167 : : /* no, leave as is */
168 [ + + ]: 43 : if (i == el->num_values) return EOK;
169 : :
170 : : /* yes, convert */
171 : 10 : val->data = (uint8_t *)talloc_strdup(msg, SYSDB_GROUP_CLASS);
172 [ + - ]: 10 : if (val->data == NULL) return ENOMEM;
173 : 10 : val->length = strlen(SYSDB_GROUP_CLASS);
174 : :
175 : 43 : return EOK;
176 : : }
177 : :
178 : 35 : static int mpg_res_convert(struct ldb_result *res)
179 : : {
180 : : int ret;
181 : : int i;
182 : :
183 [ + + ]: 78 : for (i = 0; i < res->count; i++) {
184 : 43 : ret = mpg_convert(res->msgs[i]);
185 [ + - ]: 43 : if (ret) {
186 : : return ret;
187 : : }
188 : : }
189 : : return EOK;
190 : : }
191 : :
192 : 24 : int sysdb_getgrnam(TALLOC_CTX *mem_ctx,
193 : : struct sysdb_ctx *sysdb,
194 : : const char *name,
195 : : struct ldb_result **_res)
196 : : {
197 : : TALLOC_CTX *tmp_ctx;
198 : : static const char *attrs[] = SYSDB_GRSRC_ATTRS;
199 : : const char *fmt_filter;
200 : : char *sanitized_name;
201 : : struct ldb_dn *base_dn;
202 : : struct ldb_result *res;
203 : : int ret;
204 : :
205 : 24 : tmp_ctx = talloc_new(NULL);
206 [ + - ]: 24 : if (!tmp_ctx) {
207 : : return ENOMEM;
208 : : }
209 : :
210 [ + - ]: 24 : if (sysdb->mpg) {
211 : 24 : fmt_filter = SYSDB_GRNAM_MPG_FILTER;
212 : 24 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
213 : 24 : SYSDB_DOM_BASE, sysdb->domain->name);
214 : : } else {
215 : 0 : fmt_filter = SYSDB_GRNAM_FILTER;
216 : 0 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
217 : 0 : SYSDB_TMPL_GROUP_BASE, sysdb->domain->name);
218 : : }
219 [ + - ]: 24 : if (!base_dn) {
220 : : ret = ENOMEM;
221 : : goto done;
222 : : }
223 : :
224 : 24 : ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name);
225 [ + - ]: 24 : if (ret != EOK) {
226 : : goto done;
227 : : }
228 : :
229 : 24 : ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn,
230 : : LDB_SCOPE_SUBTREE, attrs, fmt_filter,
231 : : sanitized_name, sanitized_name);
232 [ - + ]: 24 : if (ret) {
233 : 0 : ret = sysdb_error_to_errno(ret);
234 : : goto done;
235 : : }
236 : :
237 : 24 : ret = mpg_res_convert(res);
238 [ + - ]: 24 : if (ret) {
239 : : goto done;
240 : : }
241 : :
242 : 24 : *_res = talloc_steal(mem_ctx, res);
243 : :
244 : : done:
245 : 24 : talloc_zfree(tmp_ctx);
246 : : return ret;
247 : : }
248 : :
249 : 10 : int sysdb_getgrgid(TALLOC_CTX *mem_ctx,
250 : : struct sysdb_ctx *sysdb,
251 : : gid_t gid,
252 : : struct ldb_result **_res)
253 : : {
254 : : TALLOC_CTX *tmp_ctx;
255 : 10 : unsigned long int ul_gid = gid;
256 : : static const char *attrs[] = SYSDB_GRSRC_ATTRS;
257 : : const char *fmt_filter;
258 : : struct ldb_dn *base_dn;
259 : : struct ldb_result *res;
260 : : int ret;
261 : :
262 : 10 : tmp_ctx = talloc_new(NULL);
263 [ + - ]: 10 : if (!tmp_ctx) {
264 : : return ENOMEM;
265 : : }
266 : :
267 [ + - ]: 10 : if (sysdb->mpg) {
268 : 10 : fmt_filter = SYSDB_GRGID_MPG_FILTER;
269 : 10 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
270 : 10 : SYSDB_DOM_BASE, sysdb->domain->name);
271 : : } else {
272 : 0 : fmt_filter = SYSDB_GRGID_FILTER;
273 : 0 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
274 : 0 : SYSDB_TMPL_GROUP_BASE, sysdb->domain->name);
275 : : }
276 [ + - ]: 10 : if (!base_dn) {
277 : : ret = ENOMEM;
278 : : goto done;
279 : : }
280 : :
281 : 10 : ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn,
282 : : LDB_SCOPE_SUBTREE, attrs, fmt_filter, ul_gid);
283 [ - + ]: 10 : if (ret) {
284 : 0 : ret = sysdb_error_to_errno(ret);
285 : : goto done;
286 : : }
287 : :
288 : 10 : ret = mpg_res_convert(res);
289 [ + - ]: 10 : if (ret) {
290 : : goto done;
291 : : }
292 : :
293 : 10 : *_res = talloc_steal(mem_ctx, res);
294 : :
295 : : done:
296 : 10 : talloc_zfree(tmp_ctx);
297 : : return ret;
298 : : }
299 : :
300 : 1 : int sysdb_enumgrent(TALLOC_CTX *mem_ctx,
301 : : struct sysdb_ctx *sysdb,
302 : : struct ldb_result **_res)
303 : : {
304 : : TALLOC_CTX *tmp_ctx;
305 : : static const char *attrs[] = SYSDB_GRSRC_ATTRS;
306 : : const char *fmt_filter;
307 : : struct ldb_dn *base_dn;
308 : : struct ldb_result *res;
309 : : int ret;
310 : :
311 : 1 : tmp_ctx = talloc_new(NULL);
312 [ + - ]: 1 : if (!tmp_ctx) {
313 : : return ENOMEM;
314 : : }
315 : :
316 [ + - ]: 1 : if (sysdb->mpg) {
317 : 1 : fmt_filter = SYSDB_GRENT_MPG_FILTER;
318 : 1 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
319 : 1 : SYSDB_DOM_BASE, sysdb->domain->name);
320 : : } else {
321 : 0 : fmt_filter = SYSDB_GRENT_FILTER;
322 : 0 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
323 : 0 : SYSDB_TMPL_GROUP_BASE, sysdb->domain->name);
324 : : }
325 [ + - ]: 1 : if (!base_dn) {
326 : : ret = ENOMEM;
327 : : goto done;
328 : : }
329 : :
330 : 1 : ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn,
331 : : LDB_SCOPE_SUBTREE, attrs, "%s", fmt_filter);
332 [ - + ]: 1 : if (ret) {
333 : 0 : ret = sysdb_error_to_errno(ret);
334 : : goto done;
335 : : }
336 : :
337 : 1 : ret = mpg_res_convert(res);
338 [ + - ]: 1 : if (ret) {
339 : : goto done;
340 : : }
341 : :
342 : 1 : *_res = talloc_steal(mem_ctx, res);
343 : :
344 : : done:
345 : 1 : talloc_zfree(tmp_ctx);
346 : : return ret;
347 : : }
348 : :
349 : 0 : int sysdb_initgroups(TALLOC_CTX *mem_ctx,
350 : : struct sysdb_ctx *sysdb,
351 : : const char *name,
352 : : struct ldb_result **_res)
353 : : {
354 : : TALLOC_CTX *tmp_ctx;
355 : : struct ldb_result *res;
356 : : struct ldb_dn *user_dn;
357 : : struct ldb_request *req;
358 : : struct ldb_control **ctrl;
359 : : struct ldb_asq_control *control;
360 : : static const char *attrs[] = SYSDB_INITGR_ATTRS;
361 : : int ret;
362 : :
363 : 0 : tmp_ctx = talloc_new(NULL);
364 [ # # ]: 0 : if (!tmp_ctx) {
365 : : return ENOMEM;
366 : : }
367 : :
368 : : /* if this is a subdomain we need to search for the fully qualified
369 : : * name in the database */
370 : 0 : ret = sysdb_subdom_getpwnam(tmp_ctx, sysdb, name, &res);
371 [ # # ]: 0 : if (ret != EOK) {
372 [ # # ][ # # ]: 0 : DEBUG(1, ("sysdb_getpwnam failed: [%d][%s]\n",
[ # # ][ # # ]
[ # # ]
373 : : ret, strerror(ret)));
374 : : goto done;
375 : : }
376 : :
377 [ # # ]: 0 : if (res->count == 0) {
378 : : /* User is not cached yet */
379 : 0 : *_res = talloc_steal(mem_ctx, res);
380 : 0 : ret = EOK;
381 : 0 : goto done;
382 : :
383 [ # # ]: 0 : } else if (res->count != 1) {
384 : 0 : ret = EIO;
385 [ # # ][ # # ]: 0 : DEBUG(1, ("sysdb_getpwnam returned count: [%d]\n", res->count));
[ # # ][ # # ]
[ # # ]
386 : : goto done;
387 : : }
388 : :
389 : : /* no need to steal the dn, we are not freeing the result */
390 : 0 : user_dn = res->msgs[0]->dn;
391 : :
392 : : /* note we count on the fact that the default search callback
393 : : * will just keep appending values. This is by design and can't
394 : : * change so it is ok to already have a result (from the getpwnam)
395 : : * even before we call the next search */
396 : :
397 : 0 : ctrl = talloc_array(tmp_ctx, struct ldb_control *, 2);
398 [ # # ]: 0 : if (!ctrl) {
399 : : ret = ENOMEM;
400 : : goto done;
401 : : }
402 : 0 : ctrl[1] = NULL;
403 : 0 : ctrl[0] = talloc(ctrl, struct ldb_control);
404 [ # # ]: 0 : if (!ctrl[0]) {
405 : : ret = ENOMEM;
406 : : goto done;
407 : : }
408 : 0 : ctrl[0]->oid = LDB_CONTROL_ASQ_OID;
409 : 0 : ctrl[0]->critical = 1;
410 : 0 : control = talloc(ctrl[0], struct ldb_asq_control);
411 [ # # ]: 0 : if (!control) {
412 : : ret = ENOMEM;
413 : : goto done;
414 : : }
415 : 0 : control->request = 1;
416 : 0 : control->source_attribute = talloc_strdup(control, SYSDB_INITGR_ATTR);
417 [ # # ]: 0 : if (!control->source_attribute) {
418 : : ret = ENOMEM;
419 : : goto done;
420 : : }
421 : 0 : control->src_attr_len = strlen(control->source_attribute);
422 : 0 : ctrl[0]->data = control;
423 : :
424 : 0 : ret = ldb_build_search_req(&req, sysdb->ldb, tmp_ctx,
425 : : user_dn, LDB_SCOPE_BASE,
426 : : SYSDB_INITGR_FILTER, attrs, ctrl,
427 : : res, ldb_search_default_callback,
428 : : NULL);
429 [ # # ]: 0 : if (ret != LDB_SUCCESS) {
430 : 0 : ret = sysdb_error_to_errno(ret);
431 : : goto done;
432 : : }
433 : :
434 : 0 : ret = ldb_request(sysdb->ldb, req);
435 [ # # ]: 0 : if (ret == LDB_SUCCESS) {
436 : 0 : ret = ldb_wait(req->handle, LDB_WAIT_ALL);
437 : : }
438 [ # # ]: 0 : if (ret != LDB_SUCCESS) {
439 : 0 : ret = sysdb_error_to_errno(ret);
440 : : goto done;
441 : : }
442 : :
443 : 0 : *_res = talloc_steal(mem_ctx, res);
444 : :
445 : : done:
446 : 0 : talloc_zfree(tmp_ctx);
447 : : return ret;
448 : : }
449 : :
450 : 21 : int sysdb_get_user_attr(TALLOC_CTX *mem_ctx,
451 : : struct sysdb_ctx *sysdb,
452 : : const char *name,
453 : : const char **attributes,
454 : : struct ldb_result **_res)
455 : : {
456 : : TALLOC_CTX *tmp_ctx;
457 : : struct ldb_dn *base_dn;
458 : : struct ldb_result *res;
459 : : char *sanitized_name;
460 : : int ret;
461 : :
462 : 21 : tmp_ctx = talloc_new(NULL);
463 [ + - ]: 21 : if (!tmp_ctx) {
464 : : return ENOMEM;
465 : : }
466 : :
467 : 21 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
468 : 21 : SYSDB_TMPL_USER_BASE, sysdb->domain->name);
469 [ + - ]: 21 : if (!base_dn) {
470 : : ret = ENOMEM;
471 : : goto done;
472 : : }
473 : :
474 : 21 : ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name);
475 [ + - ]: 21 : if (ret != EOK) {
476 : : goto done;
477 : : }
478 : :
479 : 21 : ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn,
480 : : LDB_SCOPE_SUBTREE, attributes,
481 : : SYSDB_PWNAM_FILTER, sanitized_name,
482 : : sanitized_name);
483 [ - + ]: 21 : if (ret) {
484 : 0 : ret = sysdb_error_to_errno(ret);
485 : : goto done;
486 : : }
487 : :
488 : 21 : *_res = talloc_steal(mem_ctx, res);
489 : :
490 : : done:
491 : 21 : talloc_zfree(tmp_ctx);
492 : : return ret;
493 : : }
494 : :
495 : : /* This function splits a three-tuple into three strings
496 : : * It assumes that any whitespace between the parentheses
497 : : * and commas are intentional and does not attempt to
498 : : * strip them out. Leading and trailing whitespace is
499 : : * ignored.
500 : : *
501 : : * This behavior is compatible with nss_ldap's
502 : : * implementation.
503 : : */
504 : 37 : static errno_t sysdb_netgr_split_triple(TALLOC_CTX *mem_ctx,
505 : : const char *triple,
506 : : char **hostname,
507 : : char **username,
508 : : char **domainname)
509 : : {
510 : : errno_t ret;
511 : : TALLOC_CTX *tmp_ctx;
512 : 37 : const char *p = triple;
513 : : const char *p_host;
514 : : const char *p_user;
515 : : const char *p_domain;
516 : : size_t len;
517 : :
518 : 37 : char *host = NULL;
519 : 37 : char *user = NULL;
520 : 37 : char *domain = NULL;
521 : :
522 : : /* Pre-set the values to NULL here so if they are not
523 : : * copied, we don't return garbage below.
524 : : */
525 : 37 : *hostname = NULL;
526 : 37 : *username = NULL;
527 : 37 : *domainname = NULL;
528 : :
529 : 37 : tmp_ctx = talloc_new(NULL);
530 [ + - ]: 37 : if (!tmp_ctx) {
531 : : return ENOMEM;
532 : : }
533 : :
534 : : /* Remove any leading whitespace */
535 [ + - ][ - + ]: 37 : while (*p && isspace(*p)) p++;
536 : :
537 [ + - ]: 37 : if (*p != '(') {
538 : : /* Triple must start and end with parentheses */
539 : : ret = EINVAL;
540 : : goto done;
541 : : }
542 : 37 : p++;
543 : 37 : p_host = p;
544 : :
545 : : /* Find the first comma */
546 [ + + ]: 518 : while (*p && *p != ',') p++;
547 : :
548 [ + - ]: 37 : if (!*p) {
549 : : /* No comma was found: parse error */
550 : : ret = EINVAL;
551 : : goto done;
552 : : }
553 : :
554 : 37 : len = p - p_host;
555 : :
556 [ + - ]: 37 : if (len > 0) {
557 : : /* Copy the host string */
558 : 37 : host = talloc_strndup(tmp_ctx, p_host, len);
559 [ + - ]: 37 : if (!host) {
560 : : ret = ENOMEM;
561 : : goto done;
562 : : }
563 : : }
564 : 37 : p++;
565 : 37 : p_user = p;
566 : :
567 : : /* Find the second comma */
568 [ + + ]: 518 : while (*p && *p != ',') p++;
569 : :
570 [ + - ]: 37 : if (!*p) {
571 : : /* No comma was found: parse error */
572 : : ret = EINVAL;
573 : : goto done;
574 : : }
575 : :
576 : 37 : len = p - p_user;
577 : :
578 [ + - ]: 37 : if (len > 0) {
579 : : /* Copy the user string */
580 : 37 : user = talloc_strndup(tmp_ctx, p_user, len);
581 [ + - ]: 37 : if (!user) {
582 : : ret = ENOMEM;
583 : : goto done;
584 : : }
585 : : }
586 : 37 : p++;
587 : 37 : p_domain = p;
588 : :
589 : : /* Find the closing parenthesis */
590 [ + + ]: 592 : while (*p && *p != ')') p++;
591 [ + - ]: 37 : if (*p != ')') {
592 : : /* No trailing parenthesis: parse error */
593 : : ret = EINVAL;
594 : : goto done;
595 : : }
596 : :
597 : 37 : len = p - p_domain;
598 : :
599 [ + - ]: 37 : if (len > 0) {
600 : : /* Copy the domain string */
601 : 37 : domain = talloc_strndup(tmp_ctx, p_domain, len);
602 [ + - ]: 37 : if (!domain) {
603 : : ret = ENOMEM;
604 : : goto done;
605 : : }
606 : : }
607 : 37 : p++;
608 : :
609 : : /* skip trailing whitespace */
610 [ - + ][ # # ]: 37 : while (*p && isspace(*p)) p++;
611 : :
612 [ + - ]: 37 : if (*p) {
613 : : /* Extra data after the closing parenthesis
614 : : * is a parse error
615 : : */
616 : : ret = EINVAL;
617 : : goto done;
618 : : }
619 : :
620 : : /* Return any non-NULL values */
621 [ + - ]: 37 : if (host) {
622 : 37 : *hostname = talloc_steal(mem_ctx, host);
623 : : }
624 : :
625 [ + - ]: 37 : if (user) {
626 : 37 : *username = talloc_steal(mem_ctx, user);
627 : : }
628 : :
629 [ + - ]: 37 : if (domain) {
630 : 37 : *domainname = talloc_steal(mem_ctx, domain);
631 : : }
632 : :
633 : : ret = EOK;
634 : :
635 : : done:
636 : 37 : talloc_free(tmp_ctx);
637 : 37 : return ret;
638 : : }
639 : :
640 : 38 : errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx,
641 : : struct ldb_result *res,
642 : : struct sysdb_netgroup_ctx ***entries)
643 : : {
644 : : errno_t ret;
645 : 38 : size_t size = 0;
646 : 38 : size_t c = 0;
647 : : char *triple_str;
648 : : TALLOC_CTX *tmp_ctx;
649 : 38 : struct sysdb_netgroup_ctx **tmp_entry = NULL;
650 : : struct ldb_message_element *el;
651 : : int i, j;
652 : :
653 [ + - ][ + - ]: 38 : if(!res || res->count == 0) {
654 : : return ENOENT;
655 : : }
656 : :
657 : 38 : tmp_ctx = talloc_new(NULL);
658 [ + - ]: 38 : if (!tmp_ctx) {
659 : : return ENOMEM;
660 : : }
661 : :
662 [ + + ]: 85 : for (i=0; i < res->count; i++) {
663 : 47 : el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_TRIPLE);
664 [ + + ]: 47 : if (el != NULL) {
665 : 37 : size += el->num_values;
666 : : }
667 : 47 : el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_MEMBER);
668 [ - + ]: 47 : if (el != NULL) {
669 : 0 : size += el->num_values;
670 : : }
671 : : }
672 : :
673 : 38 : tmp_entry = talloc_array(tmp_ctx, struct sysdb_netgroup_ctx *, size + 1);
674 [ + - ]: 38 : if (tmp_entry == NULL) {
675 : : ret = ENOMEM;
676 : : goto done;
677 : : }
678 : :
679 [ + + ]: 38 : if (size != 0) {
680 [ + + ]: 65 : for (i=0; i < res->count; i++) {
681 : 37 : el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_TRIPLE);
682 [ + - ]: 37 : if (el != NULL) {
683 : : /* Copy in all of the entries */
684 [ + + ]: 74 : for(j = 0; j < el->num_values; j++) {
685 : 37 : triple_str = talloc_strndup(tmp_ctx,
686 : 37 : (const char *)el->values[j].data,
687 : 37 : el->values[j].length);
688 [ + - ]: 37 : if (!triple_str) {
689 : : ret = ENOMEM;
690 : : goto done;
691 : : }
692 : :
693 : 37 : tmp_entry[c] = talloc_zero(tmp_entry,
694 : : struct sysdb_netgroup_ctx);
695 [ + - ]: 37 : if (!tmp_entry[c]) {
696 : : ret = ENOMEM;
697 : : goto done;
698 : : }
699 : :
700 : 37 : tmp_entry[c]->type = SYSDB_NETGROUP_TRIPLE_VAL;
701 : 37 : ret = sysdb_netgr_split_triple(tmp_entry[c],
702 : : triple_str,
703 : : &tmp_entry[c]->value.triple.hostname,
704 : : &tmp_entry[c]->value.triple.username,
705 : 37 : &tmp_entry[c]->value.triple.domainname);
706 [ + - ]: 37 : if (ret != EOK) {
707 : : goto done;
708 : : }
709 : :
710 : 37 : c++;
711 : : }
712 : : }
713 : 37 : el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_MEMBER);
714 [ - + ]: 37 : if (el != NULL) {
715 [ # # ]: 0 : for(j = 0; j < el->num_values; j++) {
716 : 0 : tmp_entry[c] = talloc_zero(tmp_entry,
717 : : struct sysdb_netgroup_ctx);
718 [ # # ]: 0 : if (!tmp_entry[c]) {
719 : : ret = ENOMEM;
720 : : goto done;
721 : : }
722 : :
723 : 0 : tmp_entry[c]->type = SYSDB_NETGROUP_GROUP_VAL;
724 : 0 : tmp_entry[c]->value.groupname = talloc_strndup(tmp_entry[c],
725 : 0 : (const char *)el->values[j].data,
726 : 0 : el->values[j].length);
727 [ # # ]: 0 : if (tmp_entry[c]->value.groupname == NULL) {
728 : : ret = ENOMEM;
729 : : goto done;
730 : : }
731 : :
732 : 0 : c++;
733 : : }
734 : : }
735 : : }
736 : : }
737 : :
738 : : /* Add NULL terminator */
739 : 38 : tmp_entry[c] = NULL;
740 : :
741 : 38 : *entries = talloc_steal(mem_ctx, tmp_entry);
742 : 38 : ret = EOK;
743 : :
744 : : done:
745 : 38 : talloc_free(tmp_ctx);
746 : 38 : return ret;
747 : : }
748 : :
749 : 39 : errno_t sysdb_getnetgr(TALLOC_CTX *mem_ctx,
750 : : struct sysdb_ctx *sysdb,
751 : : const char *netgroup,
752 : : struct ldb_result **res)
753 : : {
754 : : TALLOC_CTX *tmp_ctx;
755 : : static const char *attrs[] = SYSDB_NETGR_ATTRS;
756 : : struct ldb_dn *base_dn;
757 : : struct ldb_result *result;
758 : : char *sanitized_netgroup;
759 : : char *netgroup_dn;
760 : : int lret;
761 : : errno_t ret;
762 : :
763 : 39 : tmp_ctx = talloc_new(NULL);
764 [ + - ]: 39 : if (!tmp_ctx) {
765 : : return ENOMEM;
766 : : }
767 : :
768 : 39 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
769 : : SYSDB_TMPL_NETGROUP_BASE,
770 : 39 : sysdb->domain->name);
771 [ + - ]: 39 : if (!base_dn) {
772 : : ret = ENOMEM;
773 : : goto done;
774 : : }
775 : :
776 : 39 : ret = sss_filter_sanitize(tmp_ctx, netgroup, &sanitized_netgroup);
777 [ + - ]: 39 : if (ret != EOK) {
778 : : goto done;
779 : : }
780 : :
781 : 39 : netgroup_dn = talloc_asprintf(tmp_ctx, SYSDB_TMPL_NETGROUP,
782 : 39 : sanitized_netgroup, sysdb->domain->name);
783 [ + - ]: 39 : if (!netgroup_dn) {
784 : : ret = ENOMEM;
785 : : goto done;
786 : : }
787 : :
788 : 39 : lret = ldb_search(sysdb->ldb, tmp_ctx, &result, base_dn,
789 : : LDB_SCOPE_SUBTREE, attrs,
790 : : SYSDB_NETGR_TRIPLES_FILTER,
791 : : sanitized_netgroup, sanitized_netgroup,
792 : : netgroup_dn);
793 : 39 : ret = sysdb_error_to_errno(lret);
794 [ + - ]: 39 : if (ret != EOK) {
795 : : goto done;
796 : : }
797 : :
798 : 39 : *res = talloc_steal(mem_ctx, result);
799 : 39 : ret = EOK;
800 : :
801 : : done:
802 : 39 : talloc_zfree(tmp_ctx);
803 : : return ret;
804 : : }
805 : :
806 : 11 : int sysdb_get_netgroup_attr(TALLOC_CTX *mem_ctx,
807 : : struct sysdb_ctx *sysdb,
808 : : const char *netgrname,
809 : : const char **attributes,
810 : : struct ldb_result **res)
811 : : {
812 : : TALLOC_CTX *tmp_ctx;
813 : : struct ldb_dn *base_dn;
814 : : struct ldb_result *result;
815 : : char *sanitized_netgroup;
816 : : int ret;
817 : :
818 : 11 : tmp_ctx = talloc_new(NULL);
819 [ + - ]: 11 : if (!tmp_ctx) {
820 : : return ENOMEM;
821 : : }
822 : :
823 : 11 : base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
824 : 11 : SYSDB_TMPL_NETGROUP_BASE, sysdb->domain->name);
825 [ + - ]: 11 : if (!base_dn) {
826 : : ret = ENOMEM;
827 : : goto done;
828 : : }
829 : :
830 : 11 : ret = sss_filter_sanitize(tmp_ctx, netgrname, &sanitized_netgroup);
831 [ + - ]: 11 : if (ret != EOK) {
832 : : goto done;
833 : : }
834 : :
835 : 11 : ret = ldb_search(sysdb->ldb, tmp_ctx, &result, base_dn,
836 : : LDB_SCOPE_SUBTREE, attributes,
837 : : SYSDB_NETGR_FILTER,
838 : : sanitized_netgroup,
839 : : sanitized_netgroup);
840 [ - + ]: 11 : if (ret) {
841 : 0 : ret = sysdb_error_to_errno(ret);
842 : : goto done;
843 : : }
844 : :
845 : 11 : *res = talloc_steal(mem_ctx, result);
846 : : done:
847 : 11 : talloc_zfree(tmp_ctx);
848 : : return ret;
849 : : }
850 : :
851 : 0 : errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx,
852 : : struct sysdb_ctx *sysdb,
853 : : struct sss_domain_info *dom,
854 : : enum sysdb_member_type mtype,
855 : : const char *name,
856 : : char ***_direct_parents)
857 : : {
858 : : errno_t ret;
859 : : const char *dn;
860 : : char *sanitized_dn;
861 : : struct ldb_dn *basedn;
862 : : static const char *group_attrs[] = { SYSDB_NAME, NULL };
863 : : const char *member_filter;
864 : 0 : size_t direct_sysdb_count = 0;
865 : 0 : struct ldb_message **direct_sysdb_groups = NULL;
866 : 0 : char **direct_parents = NULL;
867 : 0 : TALLOC_CTX *tmp_ctx = NULL;
868 : : int i, pi;
869 : : const char *tmp_str;
870 : :
871 : 0 : tmp_ctx = talloc_new(NULL);
872 [ # # ]: 0 : if (!tmp_ctx) return ENOMEM;
873 : :
874 [ # # ]: 0 : if (mtype == SYSDB_MEMBER_USER) {
875 : 0 : dn = sysdb_user_strdn(tmp_ctx, dom->name, name);
876 [ # # ]: 0 : } else if (mtype == SYSDB_MEMBER_GROUP) {
877 : 0 : dn = sysdb_group_strdn(tmp_ctx, dom->name, name);
878 : : } else {
879 [ # # ][ # # ]: 0 : DEBUG(1, ("Unknown member type\n"));
[ # # ][ # # ]
[ # # ]
880 : : ret = EINVAL;
881 : : goto done;
882 : : }
883 : :
884 [ # # ]: 0 : if (!dn) {
885 : : ret = ENOMEM;
886 : : goto done;
887 : : }
888 : :
889 : 0 : ret = sss_filter_sanitize(tmp_ctx, dn, &sanitized_dn);
890 [ # # ]: 0 : if (ret != EOK) {
891 : : goto done;
892 : : }
893 : :
894 : 0 : member_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%s))",
895 : : SYSDB_OBJECTCLASS, SYSDB_GROUP_CLASS,
896 : : SYSDB_MEMBER, sanitized_dn);
897 [ # # ]: 0 : if (!member_filter) {
898 : : ret = ENOMEM;
899 : : goto done;
900 : : }
901 : :
902 : 0 : basedn = ldb_dn_new_fmt(tmp_ctx, sysdb_ctx_get_ldb(sysdb),
903 : : SYSDB_TMPL_GROUP_BASE, dom->name);
904 [ # # ]: 0 : if (!basedn) {
905 : : ret = ENOMEM;
906 : : goto done;
907 : : }
908 : :
909 [ # # ][ # # ]: 0 : DEBUG(8, ("searching sysdb with filter [%s]\n", member_filter));
[ # # ][ # # ]
[ # # ]
910 : :
911 : 0 : ret = sysdb_search_entry(tmp_ctx, sysdb, basedn,
912 : : LDB_SCOPE_SUBTREE, member_filter, group_attrs,
913 : : &direct_sysdb_count, &direct_sysdb_groups);
914 [ # # ]: 0 : if (ret == ENOENT) {
915 : 0 : direct_sysdb_count = 0;
916 [ # # ]: 0 : } else if (ret != EOK && ret != ENOENT) {
917 [ # # ][ # # ]: 0 : DEBUG(2, ("sysdb_search_entry failed: [%d]: %s\n",
[ # # ][ # # ]
[ # # ]
918 : : ret, strerror(ret)));
919 : : goto done;
920 : : }
921 : :
922 : : /* EOK */
923 : : /* Get the list of sysdb groups by name */
924 : 0 : direct_parents = talloc_array(tmp_ctx, char *, direct_sysdb_count+1);
925 [ # # ]: 0 : if (!direct_parents) {
926 : : ret = ENOMEM;
927 : : goto done;
928 : : }
929 : :
930 : : pi = 0;
931 [ # # ]: 0 : for(i = 0; i < direct_sysdb_count; i++) {
932 : 0 : tmp_str = ldb_msg_find_attr_as_string(direct_sysdb_groups[i],
933 : : SYSDB_NAME, NULL);
934 [ # # ]: 0 : if (!tmp_str) {
935 : : /* This should never happen, but if it does, just continue */
936 : 0 : continue;
937 : : }
938 : :
939 : 0 : direct_parents[pi] = talloc_strdup(direct_parents, tmp_str);
940 [ # # ]: 0 : if (!direct_parents[pi]) {
941 [ # # ][ # # ]: 0 : DEBUG(1, ("A group with no name?\n"));
[ # # ][ # # ]
[ # # ]
942 : : ret = EIO;
943 : : goto done;
944 : : }
945 : 0 : pi++;
946 : : }
947 : 0 : direct_parents[pi] = NULL;
948 : :
949 [ # # ][ # # ]: 0 : DEBUG(7, ("%s is a member of %d sysdb groups\n",
[ # # ][ # # ]
[ # # ]
950 : : name, direct_sysdb_count));
951 : 0 : *_direct_parents = talloc_steal(mem_ctx, direct_parents);
952 : 0 : ret = EOK;
953 : : done:
954 : 0 : talloc_free(tmp_ctx);
955 : : return ret;
956 : 35 : }
|