Line data Source code
1 : /*
2 : Authors:
3 : Jakub Hrozek <jhrozek@redhat.com>
4 :
5 : Copyright (C) 2009 Red Hat
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 <tevent.h>
22 : #include <talloc.h>
23 : #include <sys/types.h>
24 :
25 : #include "util/util.h"
26 : #include "db/sysdb.h"
27 : #include "tools/sss_sync_ops.h"
28 :
29 : /* Default settings for user attributes */
30 : #define DFL_SHELL_VAL "/bin/bash"
31 : #define DFL_BASEDIR_VAL "/home"
32 : #define DFL_CREATE_HOMEDIR true
33 : #define DFL_REMOVE_HOMEDIR true
34 : #define DFL_UMASK 077
35 : #define DFL_SKEL_DIR "/etc/skel"
36 : #define DFL_MAIL_DIR "/var/spool/mail"
37 :
38 : #define ATTR_NAME_SEP '='
39 : #define ATTR_VAL_SEP ','
40 :
41 : #define VAR_CHECK(var, val, attr, msg) do { \
42 : if (var != (val)) { \
43 : DEBUG(SSSDBG_CRIT_FAILURE, msg" attribute: %s\n", attr); \
44 : return val; \
45 : } \
46 : } while(0)
47 :
48 0 : static int attr_name_val_split(TALLOC_CTX *mem_ctx, const char *nameval,
49 : char **_name, char ***_values, int *_nvals)
50 : {
51 : char *name;
52 : char **values;
53 : const char *vals;
54 : int nvals;
55 : TALLOC_CTX *tmp_ctx;
56 : errno_t ret;
57 :
58 0 : tmp_ctx = talloc_new(NULL);
59 0 : if (tmp_ctx == NULL) return ENOMEM;
60 :
61 0 : vals = strchr(nameval, ATTR_NAME_SEP);
62 0 : if (vals == NULL) {
63 0 : ret = EINVAL;
64 0 : goto done;
65 : }
66 :
67 0 : name = talloc_strndup(tmp_ctx, nameval, vals-nameval);
68 0 : if (name == NULL) {
69 0 : ret = ENOMEM;
70 0 : goto done;
71 : }
72 0 : vals++;
73 :
74 0 : ret = split_on_separator(tmp_ctx, vals, ATTR_VAL_SEP, true, true,
75 : &values, &nvals);
76 0 : if (ret != EOK) {
77 0 : goto done;
78 : }
79 :
80 0 : *_name = talloc_steal(mem_ctx, name);
81 0 : *_values = talloc_steal(mem_ctx, values);
82 0 : *_nvals = nvals;
83 0 : ret = EOK;
84 : done:
85 0 : talloc_free(tmp_ctx);
86 0 : return ret;
87 : }
88 :
89 0 : static int attr_op(struct ops_ctx *octx, const char *nameval, int op)
90 : {
91 : TALLOC_CTX *tmp_ctx;
92 : errno_t ret;
93 : struct sysdb_attrs *attrs;
94 : char *name;
95 : char **vals;
96 : int nvals;
97 : int i;
98 :
99 0 : switch(op) {
100 : case SYSDB_MOD_ADD:
101 : case SYSDB_MOD_DEL:
102 : case SYSDB_MOD_REP:
103 0 : break;
104 : default:
105 0 : return EINVAL;
106 : }
107 :
108 0 : tmp_ctx = talloc_new(NULL);
109 0 : if (tmp_ctx == NULL) return ENOMEM;
110 :
111 0 : attrs = sysdb_new_attrs(tmp_ctx);
112 0 : if (attrs == NULL) {
113 0 : ret = ENOMEM;
114 0 : goto done;
115 : }
116 :
117 0 : ret = attr_name_val_split(tmp_ctx, nameval, &name, &vals, &nvals);
118 0 : if (ret != EOK) {
119 0 : goto done;
120 : }
121 :
122 0 : for (i=0; i < nvals; i++) {
123 0 : ret = sysdb_attrs_add_string(attrs, name, vals[i]);
124 0 : if (ret != EOK) {
125 0 : DEBUG(SSSDBG_MINOR_FAILURE,
126 : "Could not add %s to %s\n", vals[i], name);
127 0 : continue;
128 : }
129 : }
130 :
131 0 : ret = sysdb_set_user_attr(octx->domain, octx->name, attrs, op);
132 : done:
133 0 : talloc_free(tmp_ctx);
134 0 : return ret;
135 : }
136 : /*
137 : * Generic modify groups member
138 : */
139 0 : static int mod_groups_member(struct sss_domain_info *dom,
140 : char **grouplist,
141 : struct ldb_dn *member_dn,
142 : int optype)
143 : {
144 : TALLOC_CTX *tmpctx;
145 : struct ldb_dn *parent_dn;
146 : int ret;
147 : int i;
148 :
149 0 : tmpctx = talloc_new(NULL);
150 0 : if (!tmpctx) {
151 0 : return ENOMEM;
152 : }
153 :
154 : /* FIXME: add transaction around loop */
155 0 : for (i = 0; grouplist[i]; i++) {
156 :
157 0 : parent_dn = sysdb_group_dn(tmpctx, dom, grouplist[i]);
158 0 : if (!parent_dn) {
159 0 : ret = ENOMEM;
160 0 : goto done;
161 : }
162 :
163 0 : ret = sysdb_mod_group_member(dom, member_dn, parent_dn, optype);
164 0 : if (ret) {
165 0 : goto done;
166 : }
167 : }
168 :
169 0 : ret = EOK;
170 :
171 : done:
172 0 : talloc_zfree(tmpctx);
173 0 : return ret;
174 : }
175 :
176 : #define add_to_groups(data, member_dn) \
177 : mod_groups_member(data->domain, data->addgroups, member_dn, \
178 : LDB_FLAG_MOD_ADD)
179 : #define remove_from_groups(data, member_dn) \
180 : mod_groups_member(data->domain, data->rmgroups, member_dn, \
181 : LDB_FLAG_MOD_DELETE)
182 :
183 : /*
184 : * Modify a user
185 : */
186 : struct user_mod_state {
187 : struct sysdb_ctx *sysdb;
188 :
189 : struct sysdb_attrs *attrs;
190 : struct ldb_dn *member_dn;
191 :
192 : struct ops_ctx *data;
193 : };
194 :
195 0 : static int usermod_build_attrs(TALLOC_CTX *mem_ctx,
196 : const char *gecos,
197 : const char *home,
198 : const char *shell,
199 : uid_t uid,
200 : gid_t gid,
201 : int lock,
202 : struct sysdb_attrs **_attrs)
203 : {
204 : int ret;
205 : struct sysdb_attrs *attrs;
206 :
207 0 : attrs = sysdb_new_attrs(mem_ctx);
208 0 : if (attrs == NULL) {
209 0 : return ENOMEM;
210 : }
211 :
212 0 : if (shell) {
213 0 : ret = sysdb_attrs_add_string(attrs,
214 : SYSDB_SHELL,
215 : shell);
216 0 : VAR_CHECK(ret, EOK, SYSDB_SHELL,
217 : "Could not add attribute to changeset\n");
218 : }
219 :
220 0 : if (home) {
221 0 : ret = sysdb_attrs_add_string(attrs,
222 : SYSDB_HOMEDIR,
223 : home);
224 0 : VAR_CHECK(ret, EOK, SYSDB_HOMEDIR,
225 : "Could not add attribute to changeset\n");
226 : }
227 :
228 0 : if (gecos) {
229 0 : ret = sysdb_attrs_add_string(attrs,
230 : SYSDB_GECOS,
231 : gecos);
232 0 : VAR_CHECK(ret, EOK, SYSDB_GECOS,
233 : "Could not add attribute to changeset\n");
234 : }
235 :
236 0 : if (uid) {
237 0 : ret = sysdb_attrs_add_long(attrs,
238 : SYSDB_UIDNUM,
239 : uid);
240 0 : VAR_CHECK(ret, EOK, SYSDB_UIDNUM,
241 : "Could not add attribute to changeset\n");
242 : }
243 :
244 0 : if (gid) {
245 0 : ret = sysdb_attrs_add_long(attrs,
246 : SYSDB_GIDNUM,
247 : gid);
248 0 : VAR_CHECK(ret, EOK, SYSDB_GIDNUM,
249 : "Could not add attribute to changeset\n");
250 : }
251 :
252 0 : if (lock == DO_LOCK) {
253 0 : ret = sysdb_attrs_add_string(attrs,
254 : SYSDB_DISABLED,
255 : "true");
256 0 : VAR_CHECK(ret, EOK, SYSDB_DISABLED,
257 : "Could not add attribute to changeset\n");
258 : }
259 :
260 0 : if (lock == DO_UNLOCK) {
261 : /* PAM code checks for 'false' value in SYSDB_DISABLED attribute */
262 0 : ret = sysdb_attrs_add_string(attrs,
263 : SYSDB_DISABLED,
264 : "false");
265 0 : VAR_CHECK(ret, EOK, SYSDB_DISABLED,
266 : "Could not add attribute to changeset\n");
267 : }
268 :
269 0 : *_attrs = attrs;
270 0 : return EOK;
271 : }
272 :
273 : /*
274 : * Public interface for modifying users
275 : */
276 0 : int usermod(TALLOC_CTX *mem_ctx,
277 : struct ops_ctx *data)
278 : {
279 0 : struct sysdb_attrs *attrs = NULL;
280 0 : struct ldb_dn *member_dn = NULL;
281 : int ret;
282 :
283 0 : if (data->addgroups || data->rmgroups) {
284 0 : member_dn = sysdb_user_dn(mem_ctx, data->domain, data->name);
285 0 : if (!member_dn) {
286 0 : return ENOMEM;
287 : }
288 : }
289 :
290 0 : ret = usermod_build_attrs(mem_ctx,
291 0 : data->gecos,
292 0 : data->home,
293 0 : data->shell,
294 : data->uid,
295 : data->gid,
296 : data->lock,
297 : &attrs);
298 0 : if (ret != EOK) {
299 0 : return ret;
300 : }
301 :
302 0 : if (attrs->num != 0) {
303 0 : ret = sysdb_set_user_attr(data->domain, data->name,
304 : attrs, SYSDB_MOD_REP);
305 0 : if (ret) {
306 0 : return ret;
307 : }
308 : }
309 :
310 0 : if (data->rmgroups != NULL) {
311 0 : ret = remove_from_groups(data, member_dn);
312 0 : if (ret) {
313 0 : return ret;
314 : }
315 : }
316 :
317 0 : if (data->addgroups != NULL) {
318 0 : ret = add_to_groups(data, member_dn);
319 0 : if (ret) {
320 0 : return ret;
321 : }
322 : }
323 :
324 0 : if (data->addattr) {
325 0 : ret = attr_op(data, data->addattr, SYSDB_MOD_ADD);
326 0 : if (ret) {
327 0 : return ret;
328 : }
329 : }
330 :
331 0 : if (data->setattr) {
332 0 : ret = attr_op(data, data->setattr, SYSDB_MOD_REP);
333 0 : if (ret) {
334 0 : return ret;
335 : }
336 :
337 : }
338 :
339 0 : if (data->delattr) {
340 0 : ret = attr_op(data, data->delattr, SYSDB_MOD_DEL);
341 0 : if (ret) {
342 0 : return ret;
343 : }
344 : }
345 :
346 0 : flush_nscd_cache(NSCD_DB_PASSWD);
347 0 : flush_nscd_cache(NSCD_DB_GROUP);
348 :
349 0 : return EOK;
350 : }
351 :
352 : /*
353 : * Public interface for modifying groups
354 : */
355 0 : int groupmod(TALLOC_CTX *mem_ctx,
356 : struct ops_ctx *data)
357 : {
358 0 : struct sysdb_attrs *attrs = NULL;
359 0 : struct ldb_dn *member_dn = NULL;
360 : int ret;
361 :
362 0 : if (data->addgroups || data->rmgroups) {
363 0 : member_dn = sysdb_group_dn(mem_ctx, data->domain, data->name);
364 0 : if (!member_dn) {
365 0 : return ENOMEM;
366 : }
367 : }
368 :
369 0 : if (data->gid != 0) {
370 0 : attrs = sysdb_new_attrs(mem_ctx);
371 0 : if (!attrs) {
372 0 : return ENOMEM;
373 : }
374 0 : ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, data->gid);
375 0 : if (ret) {
376 0 : return ret;
377 : }
378 :
379 0 : ret = sysdb_set_group_attr(data->domain, data->name,
380 : attrs, SYSDB_MOD_REP);
381 0 : if (ret) {
382 0 : return ret;
383 : }
384 : }
385 :
386 0 : if (data->rmgroups != NULL) {
387 0 : ret = remove_from_groups(data, member_dn);
388 0 : if (ret) {
389 0 : return ret;
390 : }
391 : }
392 :
393 0 : if (data->addgroups != NULL) {
394 0 : ret = add_to_groups(data, member_dn);
395 0 : if (ret) {
396 0 : return ret;
397 : }
398 : }
399 :
400 0 : flush_nscd_cache(NSCD_DB_GROUP);
401 :
402 0 : return EOK;
403 : }
404 :
405 0 : int userdel_defaults(TALLOC_CTX *mem_ctx,
406 : struct confdb_ctx *confdb,
407 : struct ops_ctx *data,
408 : int remove_home)
409 : {
410 : int ret;
411 : char *conf_path;
412 : bool dfl_remove_home;
413 :
414 0 : conf_path = talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL, data->domain->name);
415 0 : if (!conf_path) {
416 0 : return ENOMEM;
417 : }
418 :
419 : /* remove homedir on user creation? */
420 0 : if (!remove_home) {
421 0 : ret = confdb_get_bool(confdb,
422 : conf_path, CONFDB_LOCAL_REMOVE_HOMEDIR,
423 : DFL_REMOVE_HOMEDIR, &dfl_remove_home);
424 0 : if (ret != EOK) {
425 0 : goto done;
426 : }
427 0 : data->remove_homedir = dfl_remove_home;
428 : } else {
429 0 : data->remove_homedir = (remove_home == DO_REMOVE_HOME);
430 : }
431 :
432 : /* a directory to remove mail spools from */
433 0 : ret = confdb_get_string(confdb, mem_ctx,
434 : conf_path, CONFDB_LOCAL_MAIL_DIR,
435 : DFL_MAIL_DIR, &data->maildir);
436 0 : if (ret != EOK) {
437 0 : goto done;
438 : }
439 :
440 0 : ret = EOK;
441 : done:
442 0 : talloc_free(conf_path);
443 0 : return ret;
444 : }
445 :
446 : /*
447 : * Default values for add operations
448 : */
449 0 : int useradd_defaults(TALLOC_CTX *mem_ctx,
450 : struct confdb_ctx *confdb,
451 : struct ops_ctx *data,
452 : const char *gecos,
453 : const char *homedir,
454 : const char *shell,
455 : int create_home,
456 : const char *skeldir)
457 : {
458 : int ret;
459 0 : char *basedir = NULL;
460 0 : char *conf_path = NULL;
461 :
462 0 : conf_path = talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL, data->domain->name);
463 0 : if (!conf_path) {
464 0 : return ENOMEM;
465 : }
466 :
467 : /* gecos */
468 0 : data->gecos = talloc_strdup(mem_ctx, gecos ? gecos : data->name);
469 0 : if (!data->gecos) {
470 0 : ret = ENOMEM;
471 0 : goto done;
472 : }
473 0 : DEBUG(SSSDBG_TRACE_LIBS, "Gecos: %s\n", data->gecos);
474 :
475 : /* homedir */
476 0 : if (homedir) {
477 0 : data->home = talloc_strdup(data, homedir);
478 : } else {
479 0 : ret = confdb_get_string(confdb, mem_ctx,
480 : conf_path, CONFDB_LOCAL_DEFAULT_BASEDIR,
481 : DFL_BASEDIR_VAL, &basedir);
482 0 : if (ret != EOK) {
483 0 : goto done;
484 : }
485 0 : data->home = talloc_asprintf(mem_ctx, "%s/%s", basedir, data->name);
486 : }
487 0 : if (!data->home) {
488 0 : ret = ENOMEM;
489 0 : goto done;
490 : }
491 0 : DEBUG(SSSDBG_TRACE_LIBS, "Homedir: %s\n", data->home);
492 :
493 : /* default shell */
494 0 : if (!shell) {
495 0 : ret = confdb_get_string(confdb, mem_ctx,
496 : conf_path, CONFDB_LOCAL_DEFAULT_SHELL,
497 : DFL_SHELL_VAL, &data->shell);
498 0 : if (ret != EOK) {
499 0 : goto done;
500 : }
501 : } else {
502 0 : data->shell = talloc_strdup(mem_ctx, shell);
503 0 : if (!data->shell) {
504 0 : ret = ENOMEM;
505 0 : goto done;
506 : }
507 : }
508 0 : DEBUG(SSSDBG_TRACE_LIBS, "Shell: %s\n", data->shell);
509 :
510 : /* create homedir on user creation? */
511 0 : if (!create_home) {
512 0 : ret = confdb_get_bool(confdb,
513 : conf_path, CONFDB_LOCAL_CREATE_HOMEDIR,
514 : DFL_CREATE_HOMEDIR, &data->create_homedir);
515 0 : if (ret != EOK) {
516 0 : goto done;
517 : }
518 : } else {
519 0 : data->create_homedir = (create_home == DO_CREATE_HOME);
520 : }
521 0 : DEBUG(SSSDBG_TRACE_LIBS,
522 : "Auto create homedir: %s\n", data->create_homedir?"True":"False");
523 :
524 : /* umask to create homedirs */
525 0 : ret = confdb_get_int(confdb,
526 : conf_path, CONFDB_LOCAL_UMASK,
527 0 : DFL_UMASK, (int *) &data->umask);
528 0 : if (ret != EOK) {
529 0 : goto done;
530 : }
531 0 : DEBUG(SSSDBG_TRACE_LIBS, "Umask: %o\n", data->umask);
532 :
533 : /* a directory to create mail spools in */
534 0 : ret = confdb_get_string(confdb, mem_ctx,
535 : conf_path, CONFDB_LOCAL_MAIL_DIR,
536 : DFL_MAIL_DIR, &data->maildir);
537 0 : if (ret != EOK) {
538 0 : goto done;
539 : }
540 0 : DEBUG(SSSDBG_TRACE_LIBS, "Mail dir: %s\n", data->maildir);
541 :
542 : /* skeleton dir */
543 0 : if (!skeldir) {
544 0 : ret = confdb_get_string(confdb, mem_ctx,
545 : conf_path, CONFDB_LOCAL_SKEL_DIR,
546 : DFL_SKEL_DIR, &data->skeldir);
547 0 : if (ret != EOK) {
548 0 : goto done;
549 : }
550 : } else {
551 0 : data->skeldir = talloc_strdup(mem_ctx, skeldir);
552 0 : if (!data->skeldir) {
553 0 : ret = ENOMEM;
554 0 : goto done;
555 : }
556 : }
557 0 : DEBUG(SSSDBG_TRACE_LIBS, "Skeleton dir: %s\n", data->skeldir);
558 :
559 0 : ret = EOK;
560 : done:
561 0 : talloc_free(basedir);
562 0 : talloc_free(conf_path);
563 0 : return ret;
564 : }
565 :
566 : /*
567 : * Public interface for adding users
568 : */
569 0 : int useradd(TALLOC_CTX *mem_ctx,
570 : struct ops_ctx *data)
571 : {
572 : int ret;
573 :
574 0 : ret = sysdb_add_user(data->domain, data->name, data->uid, data->gid,
575 0 : data->gecos, data->home, data->shell,
576 : NULL, NULL, 0, 0);
577 0 : if (ret) {
578 0 : goto done;
579 : }
580 :
581 0 : if (data->addgroups) {
582 : struct ldb_dn *member_dn;
583 :
584 0 : member_dn = sysdb_user_dn(mem_ctx, data->domain, data->name);
585 0 : if (!member_dn) {
586 0 : ret = ENOMEM;
587 0 : goto done;
588 : }
589 :
590 0 : ret = add_to_groups(data, member_dn);
591 0 : if (ret) {
592 0 : goto done;
593 : }
594 : }
595 :
596 0 : flush_nscd_cache(NSCD_DB_PASSWD);
597 0 : flush_nscd_cache(NSCD_DB_GROUP);
598 :
599 : done:
600 0 : return ret;
601 : }
602 :
603 : /*
604 : * Public interface for deleting users
605 : */
606 0 : int userdel(TALLOC_CTX *mem_ctx,
607 : struct sysdb_ctx *sysdb,
608 : struct ops_ctx *data)
609 : {
610 : struct ldb_dn *user_dn;
611 : int ret;
612 :
613 0 : user_dn = sysdb_user_dn(mem_ctx, data->domain, data->name);
614 0 : if (!user_dn) {
615 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct a user DN\n");
616 0 : return ENOMEM;
617 : }
618 :
619 0 : ret = sysdb_delete_entry(sysdb, user_dn, false);
620 0 : if (ret) {
621 0 : DEBUG(SSSDBG_OP_FAILURE,
622 : "Removing user failed: %s (%d)\n", strerror(ret), ret);
623 : }
624 :
625 0 : flush_nscd_cache(NSCD_DB_PASSWD);
626 0 : flush_nscd_cache(NSCD_DB_GROUP);
627 :
628 0 : return ret;
629 : }
630 :
631 : /*
632 : * Public interface for adding groups
633 : */
634 0 : int groupadd(struct ops_ctx *data)
635 : {
636 : int ret;
637 :
638 0 : ret = sysdb_add_group(data->domain, data->name, data->gid, NULL, 0, 0);
639 0 : if (ret == EOK) {
640 0 : flush_nscd_cache(NSCD_DB_GROUP);
641 : }
642 0 : return ret;
643 : }
644 :
645 : /*
646 : * Public interface for deleting groups
647 : */
648 0 : int groupdel(TALLOC_CTX *mem_ctx,
649 : struct sysdb_ctx *sysdb,
650 : struct ops_ctx *data)
651 : {
652 : struct ldb_dn *group_dn;
653 : int ret;
654 :
655 0 : group_dn = sysdb_group_dn(mem_ctx, data->domain, data->name);
656 0 : if (group_dn == NULL) {
657 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct a group DN\n");
658 0 : return ENOMEM;
659 : }
660 :
661 0 : ret = sysdb_delete_entry(sysdb, group_dn, false);
662 0 : if (ret) {
663 0 : DEBUG(SSSDBG_OP_FAILURE,
664 : "Removing group failed: %s (%d)\n", strerror(ret), ret);
665 : }
666 :
667 0 : flush_nscd_cache(NSCD_DB_GROUP);
668 :
669 0 : return ret;
670 : }
671 :
672 : /*
673 : * getpwnam, getgrnam and friends
674 : */
675 0 : int sysdb_getpwnam_sync(TALLOC_CTX *mem_ctx,
676 : const char *name,
677 : struct ops_ctx *out)
678 : {
679 : struct ldb_result *res;
680 : const char *str;
681 : int ret;
682 :
683 0 : ret = sysdb_getpwnam(mem_ctx, out->domain, name, &res);
684 0 : if (ret) {
685 0 : return ret;
686 : }
687 :
688 0 : switch (res->count) {
689 : case 0:
690 0 : DEBUG(SSSDBG_CRIT_FAILURE, "No result for sysdb_getpwnam call\n");
691 0 : return ENOENT;
692 :
693 : case 1:
694 : /* fill ops_ctx */
695 0 : out->uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 0);
696 :
697 0 : out->gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM, 0);
698 :
699 0 : str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL);
700 0 : out->name = talloc_strdup(out, str);
701 0 : if (out->name == NULL) {
702 0 : return ENOMEM;
703 : }
704 :
705 0 : str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_GECOS, NULL);
706 0 : out->gecos = talloc_strdup(out, str);
707 0 : if (out->gecos == NULL) {
708 0 : return ENOMEM;
709 : }
710 :
711 0 : str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_HOMEDIR, NULL);
712 0 : out->home = talloc_strdup(out, str);
713 0 : if (out->home == NULL) {
714 0 : return ENOMEM;
715 : }
716 :
717 0 : str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL);
718 0 : out->shell = talloc_strdup(out, str);
719 0 : if (out->shell == NULL) {
720 0 : return ENOMEM;
721 : }
722 :
723 0 : str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_DISABLED, NULL);
724 0 : if (str == NULL) {
725 0 : out->lock = DO_UNLOCK;
726 : } else {
727 0 : if (strcasecmp(str, "true") == 0) {
728 0 : out->lock = DO_LOCK;
729 0 : } else if (strcasecmp(str, "false") == 0) {
730 0 : out->lock = DO_UNLOCK;
731 : } else { /* Invalid value */
732 0 : DEBUG(SSSDBG_OP_FAILURE, "Invalid value for %s attribute: %s\n",
733 : SYSDB_DISABLED, str ? str : "NULL");
734 0 : return EIO;
735 : }
736 : }
737 0 : break;
738 :
739 : default:
740 0 : DEBUG(SSSDBG_CRIT_FAILURE,
741 : "More than one result for sysdb_getpwnam call\n");
742 0 : return EIO;
743 : }
744 :
745 0 : return EOK;
746 : }
747 :
748 0 : int sysdb_getgrnam_sync(TALLOC_CTX *mem_ctx,
749 : const char *name,
750 : struct ops_ctx *out)
751 : {
752 : struct ldb_result *res;
753 : const char *str;
754 : int ret;
755 :
756 0 : ret = sysdb_getgrnam(mem_ctx, out->domain, name, &res);
757 0 : if (ret) {
758 0 : return ret;
759 : }
760 :
761 0 : switch (res->count) {
762 : case 0:
763 0 : DEBUG(SSSDBG_CRIT_FAILURE, "No result for sysdb_getgrnam call\n");
764 0 : return ENOENT;
765 :
766 : case 1:
767 : /* fill ops_ctx */
768 0 : out->gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM, 0);
769 0 : str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL);
770 0 : out->name = talloc_strdup(out, str);
771 0 : if (out->name == NULL) {
772 0 : return ENOMEM;
773 : }
774 0 : break;
775 :
776 : default:
777 0 : DEBUG(SSSDBG_CRIT_FAILURE,
778 : "More than one result for sysdb_getgrnam call\n");
779 0 : return EIO;
780 : }
781 :
782 0 : return EOK;
783 : }
784 :
|