~ubuntu-branches/ubuntu/wily/libuser/wily

« back to all changes in this revision

Viewing changes to lib/user.c

  • Committer: Bazaar Package Importer
  • Author(s): Pierre Habouzit
  • Date: 2006-09-03 21:58:15 UTC
  • mto: (2.1.1 edgy) (1.1.5 upstream) (3.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20060903215815-rtvvfzhaer8ymyp4
Tags: upstream-0.54.6-2.1.dfsg.1
ImportĀ upstreamĀ versionĀ 0.54.6-2.1.dfsg.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2002, 2004 Red Hat, Inc.
 
1
/* Copyright (C) 2000-2002, 2004, 2005, 2006 Red Hat, Inc.
2
2
 *
3
3
 * This is free software; you can redistribute it and/or modify it under
4
4
 * the terms of the GNU Library General Public License as published by
15
15
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
16
 */
17
17
 
18
 
#ident "$Id: user.c,v 1.78 2005/09/12 23:24:37 mitr Exp $"
 
18
#ident "$Id: user.c,v 1.81 2006/03/06 03:02:52 mitr Exp $"
19
19
 
20
20
#ifdef HAVE_CONFIG_H
21
21
#include "../config.h"
79
79
         lu_prompt_fn *prompter, gpointer prompter_data,
80
80
         struct lu_error **error)
81
81
{
82
 
        struct lu_context *ctx = NULL;
 
82
        struct lu_context *ctx;
83
83
 
84
84
        LU_ERROR_CHECK(error);
85
85
 
92
92
        /* Allocate space for the context. */
93
93
        ctx = g_malloc0(sizeof(struct lu_context));
94
94
 
 
95
        ctx->scache = lu_string_cache_new(TRUE);
 
96
 
95
97
        /* Create a configuration structure. */
96
 
        if (lu_cfg_init(ctx, error) == FALSE) {
 
98
        if (lu_cfg_init(ctx, error) == FALSE)
97
99
                /* If there's an error, lu_cfg_init() sets it. */
98
 
                g_free(ctx);
99
 
                return NULL;
100
 
        }
101
 
 
102
 
        /* Initialize the rest of the fields. */
103
 
        ctx->scache = lu_string_cache_new(TRUE);
 
100
                goto err_scache;
104
101
 
105
102
        ctx->auth_name = ctx->scache->cache(ctx->scache, auth_name);
106
103
        ctx->auth_type = auth_type;
124
121
        }
125
122
 
126
123
        /* Load the modules. */
127
 
        if (!lu_modules_load(ctx, modules, &ctx->module_names, error)) {
128
 
                /* lu_module_load sets errors */
129
 
                g_free(ctx);
130
 
                return NULL;
131
 
        }
 
124
        if (!lu_modules_load(ctx, modules, &ctx->module_names, error))
 
125
                goto err_modules; /* lu_module_load sets errors */
132
126
        if (!lu_modules_load(ctx, create_modules, &ctx->create_module_names,
133
 
                             error)) {
134
 
                /* lu_module_load sets errors */
135
 
                g_free(ctx);
136
 
                return NULL;
137
 
        }
 
127
                             error))
 
128
                goto err_module_names; /* lu_module_load sets errors */
138
129
 
139
130
        return ctx;
 
131
 
 
132
err_module_names:
 
133
        g_value_array_free(ctx->module_names);
 
134
        g_tree_foreach(ctx->modules, lu_module_unload, NULL);
 
135
err_modules:
 
136
        g_tree_destroy(ctx->modules);
 
137
err_scache:
 
138
        ctx->scache->free(ctx->scache);
 
139
        g_free(ctx);
 
140
        return NULL;
140
141
}
141
142
 
142
143
void
144
145
{
145
146
        g_assert(context != NULL);
146
147
 
147
 
        if (context->modules != NULL) {
148
 
                g_tree_foreach(context->modules, lu_module_unload, NULL);
149
 
                g_tree_destroy(context->modules);
150
 
        }
 
148
        g_tree_foreach(context->modules, lu_module_unload, NULL);
 
149
        g_tree_destroy(context->modules);
151
150
 
152
151
        g_value_array_free(context->create_module_names);
153
152
        g_value_array_free(context->module_names);
154
153
 
155
154
        lu_cfg_done(context);
156
155
 
157
 
        if (context->scache != NULL) {
158
 
                context->scache->free(context->scache);
159
 
        }
 
156
        context->scache->free(context->scache);
160
157
 
161
158
        memset(context, 0, sizeof(struct lu_context));
162
159
 
175
172
        if (array == NULL) {
176
173
                array = lu_ent_get_current(ent,
177
174
                                           ent->type == lu_user ? LU_USERNAME : LU_GROUPNAME);
 
175
                if (array == NULL)
 
176
                        return NULL;
178
177
        }
179
 
        g_return_val_if_fail(array != NULL, NULL);
180
178
        value = g_value_array_get_nth(array, 0);
181
179
        g_return_val_if_fail(value != NULL, NULL);
182
180
        return ent->cache->cache(ent->cache, g_value_get_string(value));
269
267
        if (array == NULL) {
270
268
                array = lu_ent_get_current(ent,
271
269
                                           ent->type == lu_user ? LU_UIDNUMBER : LU_GIDNUMBER);
 
270
                if (array == NULL)
 
271
                        return LU_VALUE_INVALID_ID;
272
272
        }
273
 
        g_return_val_if_fail(array != NULL, LU_VALUE_INVALID_ID);
274
273
        value = g_value_array_get_nth(array, 0);
275
274
        g_return_val_if_fail(value != NULL, LU_VALUE_INVALID_ID);
276
275
        return lu_value_get_id(value);
277
276
}
278
277
 
279
278
static uid_t
280
 
convert_user_name_to_id(struct lu_context *context, const char *sdata)
 
279
convert_user_name_to_id(struct lu_context *context, const char *sdata,
 
280
                        struct lu_error **error)
281
281
{
282
282
        struct lu_ent *ent;
283
283
        uid_t ret = LU_VALUE_INVALID_ID;
284
284
        char buf[LINE_MAX * 4];
285
285
        struct passwd *err, passwd;
286
 
        struct lu_error *error = NULL;
 
286
 
287
287
        if ((getpwnam_r(sdata, &passwd, buf, sizeof(buf), &err) == 0) &&
288
288
            (err == &passwd))
289
289
                return passwd.pw_uid;
290
290
        ent = lu_ent_new();
291
 
        if (lu_user_lookup_name(context, sdata, ent, &error) == TRUE) {
 
291
        if (lu_user_lookup_name(context, sdata, ent, error) == TRUE) {
292
292
                ret = extract_id(ent);
 
293
                if (ret == LU_VALUE_INVALID_ID)
 
294
                        lu_error_new(error, lu_error_generic,
 
295
                                     _("user %s has no UID"), sdata);
293
296
        }
294
297
        lu_ent_free(ent);
295
298
        return ret;
296
299
}
297
300
 
298
301
static gid_t
299
 
convert_group_name_to_id(struct lu_context *context, const char *sdata)
 
302
convert_group_name_to_id(struct lu_context *context, const char *sdata,
 
303
                         struct lu_error **error)
300
304
{
301
305
        struct lu_ent *ent;
302
306
        gid_t ret = LU_VALUE_INVALID_ID;
303
307
        char buf[LINE_MAX * 4];
304
308
        struct group *err, group;
305
 
        struct lu_error *error = NULL;
 
309
 
306
310
        if ((getgrnam_r(sdata, &group, buf, sizeof(buf), &err) == 0) &&
307
311
            (err == &group))
308
312
                return group.gr_gid;
309
313
        ent = lu_ent_new();
310
 
        if (lu_group_lookup_name(context, sdata, ent, &error) == TRUE) {
 
314
        if (lu_group_lookup_name(context, sdata, ent, error) == TRUE) {
311
315
                ret = extract_id(ent);
 
316
                if (ret == LU_VALUE_INVALID_ID)
 
317
                        lu_error_new(error, lu_error_generic,
 
318
                                     _("group %s has no GID"), sdata);
312
319
        }
313
320
        lu_ent_free(ent);
314
321
        return ret;
315
322
}
316
323
 
 
324
static gboolean ent_has_name_and_id(struct lu_ent *ent,
 
325
                                    struct lu_error **error)
 
326
{
 
327
        const char *name;
 
328
        id_t id;
 
329
 
 
330
        g_return_val_if_fail(ent->type == lu_user || ent->type == lu_group,
 
331
                             FALSE);
 
332
        name = extract_name(ent);
 
333
        id = extract_id(ent);
 
334
        if (name != NULL && id != LU_VALUE_INVALID_ID)
 
335
                return TRUE;
 
336
        if (id != LU_VALUE_INVALID_ID)
 
337
                lu_error_new(error, lu_error_generic,
 
338
                             ent->type == lu_user ? _("user %jd has no name")
 
339
                             : _("group %jd has no name"),
 
340
                             (intmax_t)id);
 
341
        else if (name != NULL)
 
342
                lu_error_new(error, lu_error_generic, ent->type == lu_user
 
343
                             ? _("user %s has no UID")
 
344
                             : _("group %s has no GID"), name);
 
345
        else
 
346
                lu_error_new(error, lu_error_generic, ent->type == lu_user
 
347
                             ? _("user has neither a name nor an UID")
 
348
                             : _("group has neither a name nor a GID"));
 
349
        return FALSE;
 
350
}
 
351
 
317
352
static gboolean lu_refresh_int(struct lu_context *context,
318
353
                               struct lu_ent *entity,
319
354
                               struct lu_error **error);
583
618
static void
584
619
remove_duplicate_values(GValueArray *array)
585
620
{
586
 
        size_t i, j;
587
 
        GValue *ivalue, *jvalue;
 
621
        size_t i;
588
622
 
589
623
        for (i = 0; i < array->n_values; i++) {
 
624
                size_t j;
 
625
                GValue *ivalue;
 
626
 
590
627
                ivalue = g_value_array_get_nth(array, i);
591
628
                for (j = i + 1; j < array->n_values; j++) {
 
629
                        GValue *jvalue;
 
630
 
592
631
                        jvalue = g_value_array_get_nth(array, j);
593
632
                        if (G_VALUE_TYPE(ivalue) == G_VALUE_TYPE(jvalue)
594
633
                            && lu_values_equal(ivalue, jvalue)) {
609
648
static GPtrArray *
610
649
merge_ent_array_duplicates(GPtrArray *array)
611
650
{
612
 
        GPtrArray *ret = NULL;
613
 
        size_t i, j;
614
 
        const char *attr;
615
 
        struct lu_ent *current, *saved;
616
 
        GValueArray *values;
617
 
        GValue *value;
618
 
        GList *attributes, *list;
619
 
        GTree *users, *groups, *tree;
 
651
        GPtrArray *ret;
 
652
        size_t i;
 
653
        GTree *users, *groups;
 
654
 
620
655
        g_return_val_if_fail(array != NULL, NULL);
621
 
        /* We need four trees to hold the known entities. */
622
656
        users = g_tree_new_full(compare_strings, NULL, g_free, NULL);
623
657
        groups = g_tree_new_full(compare_strings, NULL, g_free, NULL);
624
658
        /* A structure to hold the new list. */
625
659
        ret = g_ptr_array_new();
626
660
        /* Iterate over every entity in the incoming list. */
627
661
        for (i = 0; i < array->len; i++) {
 
662
                struct lu_ent *current, *saved;
628
663
                char *key;
 
664
                GValueArray *values;
 
665
                GValue *value;
 
666
                GTree *tree;
629
667
 
630
668
                current = g_ptr_array_index(array, i);
631
669
                key = NULL;
644
682
                        g_assert_not_reached();
645
683
                }
646
684
                value = g_value_array_get_nth(values, 0);
647
 
                /* Convert that name or number to a quark. */
648
685
                key = lu_value_strdup(value);
649
686
                /* Check if there's already an entity with that name. */
650
687
                saved = g_tree_lookup(tree, key);
653
690
                        g_tree_insert(tree, key, current);
654
691
                        g_ptr_array_add(ret, current);
655
692
                } else {
 
693
                        GList *attributes, *list;
 
694
                        const char *attr;
 
695
                        size_t j;
 
696
 
656
697
                        g_free (key);
657
698
                        /* Merge all of its data into the existing one; first,
658
699
                         * the current data. */
671
712
                        g_list_free(list);
672
713
                        /* Merge the pending data. */
673
714
                        attributes = lu_ent_get_attributes(current);
 
715
                        list = attributes;
674
716
                        while (attributes != NULL) {
675
717
                                attr = (const char *)attributes->data;
676
718
                                values = lu_ent_get(current, attr);
708
750
         gpointer ret,
709
751
         struct lu_error **firsterror)
710
752
{
711
 
        struct lu_module *module;
712
 
        GPtrArray *ptr_array = NULL, *tmp_ptr_array = NULL;
713
 
        GValueArray *value_array = NULL, *tmp_value_array = NULL;
714
 
        GValue *value;
715
 
        gpointer scratch;
716
 
        struct lu_ent *tmp_ent;
717
 
        char *name;
718
 
        gboolean success, tsuccess;
 
753
        gboolean success;
719
754
        struct lu_error *lasterror = NULL;
720
 
        size_t i, j;
 
755
        size_t i;
721
756
 
722
757
        LU_ERROR_CHECK(firsterror);
723
758
 
764
799
 
765
800
        success = FALSE;
766
801
        for (i = 0; i < list->n_values; i++) {
 
802
                struct lu_module *module;
 
803
                gpointer scratch;
 
804
                GValue *value;
 
805
                char *name;
 
806
                gboolean tsuccess;
 
807
 
767
808
                value = g_value_array_get_nth(list, i);
768
809
                name = g_value_dup_string(value);
769
810
                module = g_tree_lookup(context->modules, name);
774
815
                                      sdata, ldata, entity, &scratch,
775
816
                                      &lasterror);
776
817
                if (scratch != NULL) switch (id) {
 
818
                        GPtrArray *ptr_array, *tmp_ptr_array;
 
819
                        GValueArray *value_array, *tmp_value_array;
 
820
                        size_t j;
 
821
 
777
822
                        case users_enumerate:
778
823
                        case users_enumerate_by_group:
779
824
                        case groups_enumerate:
807
852
                                }
808
853
                                if (tmp_ptr_array != NULL) {
809
854
                                        for (j = 0; j < tmp_ptr_array->len; j++) {
 
855
                                                struct lu_ent *tmp_ent;
 
856
 
810
857
                                                tmp_ent = g_ptr_array_index(tmp_ptr_array,
811
858
                                                                            j);
812
859
                                                g_ptr_array_add(ptr_array, tmp_ent);
869
916
{
870
917
        enum lu_dispatch_id id = 0;
871
918
        const char *sdata;
872
 
        id_t ldata;
873
919
        gpointer scratch = NULL;
874
920
        g_return_val_if_fail((entity->type == lu_user) ||
875
921
                             (entity->type == lu_group),
883
929
                g_assert_not_reached();
884
930
        }
885
931
        sdata = extract_name(entity);
886
 
        ldata = extract_id(entity);
 
932
        if (sdata == NULL)
 
933
                return FALSE;
887
934
        if (run_list(context, entity->modules, logic_and, id,
888
 
                     sdata, ldata, entity, &scratch, error)) {
 
935
                     sdata, LU_VALUE_INVALID_ID, entity, &scratch, error)) {
889
936
                lu_ent_revert(entity);
890
937
                return TRUE;
891
938
        }
900
947
            gpointer ret,
901
948
            struct lu_error **error)
902
949
{
903
 
        struct lu_ent *tmp = NULL;
 
950
        struct lu_ent *tmp;
904
951
        gboolean success;
905
952
        GValueArray *values = NULL;
906
953
        GPtrArray *ptrs = NULL;
907
 
        GValue *value = NULL;
908
954
        gpointer scratch = NULL;
909
 
        size_t i;
910
955
 
911
956
        LU_ERROR_CHECK(error);
912
957
 
942
987
                        }
943
988
                        values = lu_ent_get_current(tmp, attr);
944
989
                        if (values != NULL) {
 
990
                                GValue *value;
 
991
 
945
992
                                value = g_value_array_get_nth(values, 0);
946
993
                                attr = g_value_get_string(value);
947
994
                                sdata = tmp->cache->cache(tmp->cache, attr);
958
1005
        case group_lookup_name:
959
1006
                /* Make sure data items are right for this call. */
960
1007
                g_assert(sdata != NULL);
961
 
                ldata = LU_VALUE_INVALID_ID;
962
1008
                /* Run the list. */
963
 
                if (run_list(context, context->module_names,
964
 
                            logic_or, id,
965
 
                            sdata, ldata, tmp, &scratch, error)) {
 
1009
                if (run_list(context, context->module_names, logic_or, id,
 
1010
                             sdata, LU_VALUE_INVALID_ID, tmp, &scratch,
 
1011
                             error)) {
966
1012
                        if (entity != NULL) {
967
1013
                                lu_ent_revert(tmp);
968
1014
                                lu_ent_copy(tmp, entity);
987
1033
        case user_add_prep:
988
1034
        case group_add_prep:
989
1035
                /* Make sure we have both name and ID here. */
990
 
                sdata = sdata ?: extract_name(tmp);
991
 
                if (ldata == LU_VALUE_INVALID_ID)
992
 
                        ldata = extract_id(tmp);
993
 
                g_return_val_if_fail(sdata != NULL, FALSE);
994
 
                g_return_val_if_fail(ldata != LU_VALUE_INVALID_ID, FALSE);
 
1036
                if (ent_has_name_and_id(tmp, error) == FALSE)
 
1037
                        break;
995
1038
                /* Run the checks and preps. */
996
 
                if (run_list(context, context->create_module_names,
997
 
                            logic_and, id,
998
 
                            sdata, ldata, tmp, &scratch, error)) {
 
1039
                if (run_list(context, context->create_module_names, logic_and,
 
1040
                             id, NULL, LU_VALUE_INVALID_ID, tmp, &scratch,
 
1041
                             error)) {
999
1042
                        if (entity != NULL) {
1000
1043
                                lu_ent_copy(tmp, entity);
1001
1044
                        }
1005
1048
        case user_add:
1006
1049
        case group_add:
1007
1050
                /* Make sure we have both name and ID here. */
1008
 
                sdata = sdata ?: extract_name(tmp);
1009
 
                if (ldata == LU_VALUE_INVALID_ID)
1010
 
                        ldata = extract_id(tmp);
1011
 
                g_return_val_if_fail(sdata != NULL, FALSE);
1012
 
                g_return_val_if_fail(ldata != LU_VALUE_INVALID_ID, FALSE);
 
1051
                if (ent_has_name_and_id(tmp, error) == FALSE)
 
1052
                        break;
1013
1053
                /* Add the account. */
1014
1054
                if (run_list(context, context->create_module_names,
1015
 
                            logic_and, id,
1016
 
                            sdata, ldata, tmp, &scratch, error)) {
 
1055
                             logic_and, id, NULL, LU_VALUE_INVALID_ID,
 
1056
                             tmp, &scratch, error)) {
1017
1057
                        if (entity != NULL) {
1018
1058
                                lu_ent_copy(tmp, entity);
1019
1059
                        }
1023
1063
        case user_mod:
1024
1064
        case group_mod:
1025
1065
                /* Make sure we have both name and ID here. */
1026
 
                /* FIXME: sdata, ldata contain new values (and are not even
1027
 
                   used). */
1028
 
                sdata = sdata ?: extract_name(tmp);
1029
 
                if (ldata == LU_VALUE_INVALID_ID)
1030
 
                        ldata = extract_id(tmp);
1031
 
                g_return_val_if_fail(sdata != NULL, FALSE);
1032
 
                g_return_val_if_fail(ldata != LU_VALUE_INVALID_ID, FALSE);
 
1066
                /* FIXME: this checks current, not pending values */
 
1067
                if (ent_has_name_and_id(tmp, error) == FALSE)
 
1068
                        break;
1033
1069
                /* Make the changes. */
1034
1070
                g_assert(entity != NULL);
1035
 
                if (run_list(context, entity->modules,
1036
 
                            logic_and, id,
1037
 
                            sdata, ldata, tmp, &scratch, error)) {
 
1071
                if (run_list(context, entity->modules, logic_and, id, NULL,
 
1072
                             LU_VALUE_INVALID_ID, tmp, &scratch, error)) {
1038
1073
                        lu_ent_commit(tmp);
1039
1074
                        lu_ent_copy(tmp, entity);
1040
1075
                        success = TRUE;
1049
1084
        case group_unlock:
1050
1085
        case group_unlock_nonempty:
1051
1086
                /* Make sure we have both name and ID here. */
1052
 
                sdata = sdata ?: extract_name(tmp);
1053
 
                if (ldata == LU_VALUE_INVALID_ID)
1054
 
                        ldata = extract_id(tmp);
1055
 
                g_return_val_if_fail(sdata != NULL, FALSE);
1056
 
                g_return_val_if_fail(ldata != LU_VALUE_INVALID_ID, FALSE);
 
1087
                if (ent_has_name_and_id(tmp, error) == FALSE)
 
1088
                        break;
1057
1089
                /* Make the changes. */
1058
1090
                g_assert(entity != NULL);
1059
 
                if (run_list(context, entity->modules,
1060
 
                            logic_and, id,
1061
 
                            sdata, ldata, tmp, &scratch, error)) {
 
1091
                if (run_list(context, entity->modules, logic_and, id, NULL,
 
1092
                             LU_VALUE_INVALID_ID, tmp, &scratch, error)) {
1062
1093
                        lu_ent_revert(tmp);
1063
1094
                        lu_ent_copy(tmp, entity);
1064
1095
                        success = TRUE;
1073
1104
        case group_removepass:
1074
1105
                /* Make the changes. */
1075
1106
                g_assert(entity != NULL);
1076
 
                if (run_list(context, entity->modules,
1077
 
                            logic_and, id,
1078
 
                            sdata, ldata, tmp, &scratch, error)) {
 
1107
                if (run_list(context, entity->modules, logic_and, id, sdata,
 
1108
                             LU_VALUE_INVALID_ID, tmp, &scratch, error)) {
1079
1109
                        lu_ent_revert(tmp);
1080
1110
                        lu_ent_copy(tmp, entity);
1081
1111
                        success = TRUE;
1084
1114
        case user_is_locked:
1085
1115
        case group_is_locked:
1086
1116
                /* Make sure we have both name and ID here. */
1087
 
                sdata = sdata ?: extract_name(tmp);
1088
 
                if (ldata == LU_VALUE_INVALID_ID)
1089
 
                        ldata = extract_id(tmp);
1090
 
                g_return_val_if_fail(sdata != NULL, FALSE);
1091
 
                g_return_val_if_fail(ldata != LU_VALUE_INVALID_ID, FALSE);
 
1117
                if (ent_has_name_and_id(tmp, error) == FALSE)
 
1118
                        break;
1092
1119
                /* Run the checks. */
1093
1120
                g_assert(entity != NULL);
1094
 
                if (run_list(context, entity->modules,
1095
 
                            logic_or, id,
1096
 
                            sdata, ldata, tmp, &scratch, error)) {
 
1121
                if (run_list(context, entity->modules, logic_or, id, NULL,
 
1122
                             LU_VALUE_INVALID_ID, tmp, &scratch, error)) {
1097
1123
                        lu_ent_copy(tmp, entity);
1098
1124
                        success = TRUE;
1099
1125
                }
1102
1128
        case groups_enumerate_by_user:
1103
1129
                /* Make sure we have both name and ID here. */
1104
1130
                g_return_val_if_fail(sdata != NULL, FALSE);
1105
 
                if (id == users_enumerate_by_group) {
1106
 
                        ldata = convert_group_name_to_id(context, sdata);
1107
 
                } else
1108
 
                if (id == groups_enumerate_by_user) {
1109
 
                        ldata = convert_user_name_to_id(context, sdata);
1110
 
                } else {
 
1131
                if (id == users_enumerate_by_group)
 
1132
                        ldata = convert_group_name_to_id(context, sdata,
 
1133
                                                         error);
 
1134
                else if (id == groups_enumerate_by_user)
 
1135
                        ldata = convert_user_name_to_id(context, sdata, error);
 
1136
                else
1111
1137
                        g_assert_not_reached();
1112
 
                }
1113
 
                g_return_val_if_fail(ldata != LU_VALUE_INVALID_ID, FALSE);
 
1138
                if (ldata == LU_VALUE_INVALID_ID)
 
1139
                        break;
1114
1140
                /* fall through */
1115
1141
        case users_enumerate:
1116
1142
        case groups_enumerate:
1126
1152
        case groups_enumerate_by_user_full:
1127
1153
                /* Make sure we have both name and ID here. */
1128
1154
                g_return_val_if_fail(sdata != NULL, FALSE);
1129
 
                if (id == users_enumerate_by_group_full) {
1130
 
                        ldata = convert_group_name_to_id(context, sdata);
1131
 
                } else
1132
 
                if (id == groups_enumerate_by_user_full) {
1133
 
                        ldata = convert_user_name_to_id(context, sdata);
1134
 
                } else {
 
1155
                if (id == users_enumerate_by_group)
 
1156
                        ldata = convert_group_name_to_id(context, sdata,
 
1157
                                                         error);
 
1158
                else if (id == groups_enumerate_by_user)
 
1159
                        ldata = convert_user_name_to_id(context, sdata, error);
 
1160
                else
1135
1161
                        g_assert_not_reached();
1136
 
                }
1137
 
                g_return_val_if_fail(ldata != LU_VALUE_INVALID_ID, FALSE);
 
1162
                if (ldata == LU_VALUE_INVALID_ID)
 
1163
                        break;
1138
1164
                /* fall through */
1139
1165
        case users_enumerate_full:
1140
1166
        case groups_enumerate_full:
1143
1169
                            logic_or, id,
1144
1170
                            sdata, ldata, tmp, &ptrs, error)) {
1145
1171
                        if (ptrs != NULL) {
 
1172
                                size_t i;
 
1173
 
1146
1174
                                for (i = 0; i < ptrs->len; i++) {
1147
1175
                                        struct lu_ent *ent;
1148
1176
                                        ent = g_ptr_array_index(ptrs, i);
1166
1194
                }
1167
1195
                break;
1168
1196
        default:
1169
 
                g_assert(0);    /* not reached */
 
1197
                g_assert_not_reached();
1170
1198
                break;
1171
1199
        }
1172
1200
        lu_ent_free(tmp);
1665
1693
 
1666
1694
        ent = lu_ent_new();
1667
1695
        if (type == lu_user) {
1668
 
                struct passwd pwd, *err;
1669
1696
                struct lu_error *error = NULL;
1670
1697
                do {
 
1698
                        struct passwd pwd, *err;
 
1699
 
1671
1700
                        /* There may be read-only sources of user information
1672
1701
                         * on the system, and we want to avoid allocating an ID
1673
1702
                         * that's already in use by a service we can't write
1690
1719
                        break;
1691
1720
                } while (id != (id_t)-1);
1692
1721
        } else if (type == lu_group) {
1693
 
                struct group grp, *err;
1694
1722
                struct lu_error *error = NULL;
1695
1723
                do {
 
1724
                        struct group grp, *err;
 
1725
 
1696
1726
                        /* There may be read-only sources of user information
1697
1727
                         * on the system, and we want to avoid allocating an ID
1698
1728
                         * that's already in use by a service we can't write
1726
1756
{
1727
1757
        GList *keys, *p;
1728
1758
        GValue value;
1729
 
        char *cfgkey, *tmp, *end;
1730
 
        char buf[LINE_MAX * 4];
1731
 
        const char *top, *idkey, *idkeystring, *val, *key;
 
1759
        char *cfgkey;
 
1760
        const char *top, *idkey, *idkeystring, *val;
1732
1761
        id_t id = DEFAULT_ID;
1733
1762
        struct group grp, *err;
1734
1763
        struct lu_error *error = NULL;
1752
1781
        g_value_init(&value, G_TYPE_STRING);
1753
1782
        g_value_set_string(&value, name);
1754
1783
        if (ent->type == lu_user) {
 
1784
                char buf[LINE_MAX * 4];
 
1785
 
1755
1786
                lu_ent_clear(ent, LU_USERNAME);
1756
1787
                lu_ent_add(ent, LU_USERNAME, &value);
1757
1788
                /* Additionally, pick a default default group. */
1799
1830
                }
1800
1831
                if (val != NULL) {
1801
1832
                        intmax_t imax;
 
1833
                        char *end;
1802
1834
 
1803
1835
                        errno = 0;
1804
 
                        imax = strtoimax(val, &tmp, 10);
1805
 
                        if (errno == 0 && *tmp == 0 && tmp != val
 
1836
                        imax = strtoimax(val, &end, 10);
 
1837
                        if (errno == 0 && *end == 0 && end != val
1806
1838
                            && (id_t)imax == imax)
1807
1839
                                id = imax;
1808
1840
                        else
1821
1853
        /* Now iterate to find the rest. */
1822
1854
        keys = lu_cfg_read_keys(context, top);
1823
1855
        for (p = keys; p && p->data; p = g_list_next(p)) {
1824
 
                intmax_t imax;
1825
 
 
1826
 
                struct {
 
1856
                static const struct {
1827
1857
                        const char *realkey, *configkey;
1828
1858
                } keymap[] = {
1829
1859
                        {LU_USERNAME, G_STRINGIFY_ARG(LU_USERNAME)},
1860
1890
                        {LU_HOMEPHONE, G_STRINGIFY_ARG(LU_HOMEPHONE)},
1861
1891
                        {LU_EMAIL, G_STRINGIFY_ARG(LU_EMAIL)},
1862
1892
                };
 
1893
 
 
1894
                intmax_t imax;
 
1895
                char *end, *tmp;
 
1896
                const char *key;
1863
1897
                struct {
1864
1898
                        const char *format;
1865
1899
                        const char *value;
1871
1905
                };
1872
1906
 
1873
1907
                /* Possibly map the key to an internal name. */
1874
 
                key = (const char *) p->data;
 
1908
                key = p->data;
1875
1909
                for (i = 0; i < G_N_ELEMENTS(keymap); i++) {
1876
1910
                        if (strcmp(key, keymap[i].configkey) == 0) {
1877
1911
                                key = keymap[i].realkey;