92
92
/* Allocate space for the context. */
93
93
ctx = g_malloc0(sizeof(struct lu_context));
95
ctx->scache = lu_string_cache_new(TRUE);
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. */
102
/* Initialize the rest of the fields. */
103
ctx->scache = lu_string_cache_new(TRUE);
105
102
ctx->auth_name = ctx->scache->cache(ctx->scache, auth_name);
106
103
ctx->auth_type = auth_type;
126
123
/* Load the modules. */
127
if (!lu_modules_load(ctx, modules, &ctx->module_names, error)) {
128
/* lu_module_load sets errors */
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,
134
/* lu_module_load sets errors */
128
goto err_module_names; /* lu_module_load sets errors */
133
g_value_array_free(ctx->module_names);
134
g_tree_foreach(ctx->modules, lu_module_unload, NULL);
136
g_tree_destroy(ctx->modules);
138
ctx->scache->free(ctx->scache);
145
146
g_assert(context != NULL);
147
if (context->modules != NULL) {
148
g_tree_foreach(context->modules, lu_module_unload, NULL);
149
g_tree_destroy(context->modules);
148
g_tree_foreach(context->modules, lu_module_unload, NULL);
149
g_tree_destroy(context->modules);
152
151
g_value_array_free(context->create_module_names);
153
152
g_value_array_free(context->module_names);
155
154
lu_cfg_done(context);
157
if (context->scache != NULL) {
158
context->scache->free(context->scache);
156
context->scache->free(context->scache);
161
158
memset(context, 0, sizeof(struct lu_context));
269
267
if (array == NULL) {
270
268
array = lu_ent_get_current(ent,
271
269
ent->type == lu_user ? LU_UIDNUMBER : LU_GIDNUMBER);
271
return LU_VALUE_INVALID_ID;
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);
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)
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;
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);
294
297
lu_ent_free(ent);
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)
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;
306
310
if ((getgrnam_r(sdata, &group, buf, sizeof(buf), &err) == 0) &&
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);
313
320
lu_ent_free(ent);
324
static gboolean ent_has_name_and_id(struct lu_ent *ent,
325
struct lu_error **error)
330
g_return_val_if_fail(ent->type == lu_user || ent->type == lu_group,
332
name = extract_name(ent);
333
id = extract_id(ent);
334
if (name != NULL && id != LU_VALUE_INVALID_ID)
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"),
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);
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"));
317
352
static gboolean lu_refresh_int(struct lu_context *context,
318
353
struct lu_ent *entity,
319
354
struct lu_error **error);
609
648
static GPtrArray *
610
649
merge_ent_array_duplicates(GPtrArray *array)
612
GPtrArray *ret = NULL;
615
struct lu_ent *current, *saved;
618
GList *attributes, *list;
619
GTree *users, *groups, *tree;
653
GTree *users, *groups;
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;
630
668
current = g_ptr_array_index(array, i);
883
929
g_assert_not_reached();
885
931
sdata = extract_name(entity);
886
ldata = extract_id(entity);
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);
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,
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,
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)
995
1038
/* Run the checks and preps. */
996
if (run_list(context, context->create_module_names,
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,
999
1042
if (entity != NULL) {
1000
1043
lu_ent_copy(tmp, entity);
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)
1013
1053
/* Add the account. */
1014
1054
if (run_list(context, context->create_module_names,
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);
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
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)
1033
1069
/* Make the changes. */
1034
1070
g_assert(entity != NULL);
1035
if (run_list(context, entity->modules,
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)
1057
1089
/* Make the changes. */
1058
1090
g_assert(entity != NULL);
1059
if (run_list(context, entity->modules,
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,
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)
1092
1119
/* Run the checks. */
1093
1120
g_assert(entity != NULL);
1094
if (run_list(context, entity->modules,
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;
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);
1108
if (id == groups_enumerate_by_user) {
1109
ldata = convert_user_name_to_id(context, sdata);
1131
if (id == users_enumerate_by_group)
1132
ldata = convert_group_name_to_id(context, sdata,
1134
else if (id == groups_enumerate_by_user)
1135
ldata = convert_user_name_to_id(context, sdata, error);
1111
1137
g_assert_not_reached();
1113
g_return_val_if_fail(ldata != LU_VALUE_INVALID_ID, FALSE);
1138
if (ldata == LU_VALUE_INVALID_ID)
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);
1132
if (id == groups_enumerate_by_user_full) {
1133
ldata = convert_user_name_to_id(context, sdata);
1155
if (id == users_enumerate_by_group)
1156
ldata = convert_group_name_to_id(context, sdata,
1158
else if (id == groups_enumerate_by_user)
1159
ldata = convert_user_name_to_id(context, sdata, error);
1135
1161
g_assert_not_reached();
1137
g_return_val_if_fail(ldata != LU_VALUE_INVALID_ID, FALSE);
1162
if (ldata == LU_VALUE_INVALID_ID)
1138
1164
/* fall through */
1139
1165
case users_enumerate_full:
1140
1166
case groups_enumerate_full: