]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/userdb.c
run: also show a pretty string for main exit status, if any
[thirdparty/systemd.git] / src / shared / userdb.c
index 3e08b339f5b861aabf0a21d1b598d56d671f0d00..75dece3442935ae71f658f23105ff8f31d2e03c0 100644 (file)
@@ -90,7 +90,7 @@ UserDBIterator* userdb_iterator_free(UserDBIterator *iterator) {
                 break;
 
         default:
-                assert_not_reached("Unexpected state?");
+                assert_not_reached();
         }
 
         sd_event_unref(iterator->event);
@@ -114,6 +114,8 @@ static UserDBIterator* userdb_iterator_new(LookupWhat what, UserDBFlags flags) {
         *i = (UserDBIterator) {
                 .what = what,
                 .flags = flags,
+                .synthesize_root = !FLAGS_SET(flags, USERDB_DONT_SYNTHESIZE),
+                .synthesize_nobody = !FLAGS_SET(flags, USERDB_DONT_SYNTHESIZE),
         };
 
         return i;
@@ -140,10 +142,20 @@ struct user_group_data {
         bool incomplete;
 };
 
-static void user_group_data_release(struct user_group_data *d) {
+static void user_group_data_done(struct user_group_data *d) {
         json_variant_unref(d->record);
 }
 
+struct membership_data {
+        char *user_name;
+        char *group_name;
+};
+
+static void membership_data_done(struct membership_data *d) {
+        free(d->user_name);
+        free(d->group_name);
+}
+
 static int userdb_on_query_reply(
                 Varlink *link,
                 JsonVariant *parameters,
@@ -151,11 +163,9 @@ static int userdb_on_query_reply(
                 VarlinkReplyFlags flags,
                 void *userdata) {
 
-        UserDBIterator *iterator = userdata;
+        UserDBIterator *iterator = ASSERT_PTR(userdata);
         int r;
 
-        assert(iterator);
-
         if (error_id) {
                 log_debug("Got lookup error: %s", error_id);
 
@@ -178,7 +188,7 @@ static int userdb_on_query_reply(
         switch (iterator->what) {
 
         case LOOKUP_USER: {
-                _cleanup_(user_group_data_release) struct user_group_data user_data = {};
+                _cleanup_(user_group_data_done) struct user_group_data user_data = {};
 
                 static const JsonDispatch dispatch_table[] = {
                         { "record",     _JSON_VARIANT_TYPE_INVALID, json_dispatch_variant, offsetof(struct user_group_data, record),     0 },
@@ -189,7 +199,7 @@ static int userdb_on_query_reply(
 
                 assert_se(!iterator->found_user);
 
-                r = json_dispatch(parameters, dispatch_table, NULL, 0, &user_data);
+                r = json_dispatch(parameters, dispatch_table, JSON_ALLOW_EXTENSIONS, &user_data);
                 if (r < 0)
                         goto finish;
 
@@ -235,7 +245,7 @@ static int userdb_on_query_reply(
         }
 
         case LOOKUP_GROUP: {
-                _cleanup_(user_group_data_release) struct user_group_data group_data = {};
+                _cleanup_(user_group_data_done) struct user_group_data group_data = {};
 
                 static const JsonDispatch dispatch_table[] = {
                         { "record",     _JSON_VARIANT_TYPE_INVALID, json_dispatch_variant, offsetof(struct user_group_data, record),     0 },
@@ -246,7 +256,7 @@ static int userdb_on_query_reply(
 
                 assert_se(!iterator->found_group);
 
-                r = json_dispatch(parameters, dispatch_table, NULL, 0, &group_data);
+                r = json_dispatch(parameters, dispatch_table, JSON_ALLOW_EXTENSIONS, &group_data);
                 if (r < 0)
                         goto finish;
 
@@ -288,39 +298,23 @@ static int userdb_on_query_reply(
         }
 
         case LOOKUP_MEMBERSHIP: {
-                struct membership_data {
-                        const char *user_name;
-                        const char *group_name;
-                } membership_data = {};
+                _cleanup_(membership_data_done) struct membership_data membership_data = {};
 
                 static const JsonDispatch dispatch_table[] = {
-                        { "userName",  JSON_VARIANT_STRING, json_dispatch_const_string, offsetof(struct membership_data, user_name),  JSON_SAFE },
-                        { "groupName", JSON_VARIANT_STRING, json_dispatch_const_string, offsetof(struct membership_data, group_name), JSON_SAFE },
+                        { "userName",  JSON_VARIANT_STRING, json_dispatch_user_group_name, offsetof(struct membership_data, user_name),  JSON_RELAX },
+                        { "groupName", JSON_VARIANT_STRING, json_dispatch_user_group_name, offsetof(struct membership_data, group_name), JSON_RELAX },
                         {}
                 };
 
                 assert(!iterator->found_user_name);
                 assert(!iterator->found_group_name);
 
-                r = json_dispatch(parameters, dispatch_table, NULL, 0, &membership_data);
+                r = json_dispatch(parameters, dispatch_table, JSON_ALLOW_EXTENSIONS, &membership_data);
                 if (r < 0)
                         goto finish;
 
-                iterator->found_user_name = mfree(iterator->found_user_name);
-                iterator->found_group_name = mfree(iterator->found_group_name);
-
-                iterator->found_user_name = strdup(membership_data.user_name);
-                if (!iterator->found_user_name) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
-
-                iterator->found_group_name = strdup(membership_data.group_name);
-                if (!iterator->found_group_name) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
-
+                iterator->found_user_name = TAKE_PTR(membership_data.user_name);
+                iterator->found_group_name = TAKE_PTR(membership_data.group_name);
                 iterator->n_found++;
 
                 if (FLAGS_SET(flags, VARLINK_REPLY_CONTINUES))
@@ -331,7 +325,7 @@ static int userdb_on_query_reply(
         }
 
         default:
-                assert_not_reached("unexpected lookup");
+                assert_not_reached();
         }
 
 finish:
@@ -401,9 +395,8 @@ static int userdb_start_query(
                 JsonVariant *query,
                 UserDBFlags flags) {
 
-        _cleanup_(strv_freep) char **except = NULL, **only = NULL;
-        _cleanup_(closedirp) DIR *d = NULL;
-        struct dirent *de;
+        _cleanup_strv_free_ char **except = NULL, **only = NULL;
+        _cleanup_closedir_ DIR *d = NULL;
         const char *e;
         int r, ret = 0;
 
@@ -470,7 +463,7 @@ static int userdb_start_query(
                     streq(de->d_name, "io.systemd.DynamicUser"))
                         continue;
 
-                /* Avoid NSS is this is requested. Note that we also skip NSS when we were asked to skip the
+                /* Avoid NSS if this is requested. Note that we also skip NSS when we were asked to skip the
                  * multiplexer, since in that case it's safer to do NSS in the client side emulation below
                  * (and when we run as part of systemd-userdbd.service we don't want to talk to ourselves
                  * anyway). */
@@ -510,7 +503,7 @@ static int userdb_start_query(
         }
 
         if (set_isempty(iterator->links))
-                return ret; /* propagate last error we saw if we couldn't connect to anything. */
+                return ret < 0 ? ret : -ESRCH; /* propagate last error we saw if we couldn't connect to anything. */
 
         /* We connected to some services, in this case, ignore the ones we failed on */
         return 0;
@@ -598,22 +591,22 @@ static int userdb_process(
 static int synthetic_root_user_build(UserRecord **ret) {
         return user_record_build(
                         ret,
-                        JSON_BUILD_OBJECT(JSON_BUILD_PAIR("userName", JSON_BUILD_STRING("root")),
+                        JSON_BUILD_OBJECT(JSON_BUILD_PAIR("userName", JSON_BUILD_CONST_STRING("root")),
                                           JSON_BUILD_PAIR("uid", JSON_BUILD_UNSIGNED(0)),
                                           JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(0)),
-                                          JSON_BUILD_PAIR("homeDirectory", JSON_BUILD_STRING("/root")),
-                                          JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("intrinsic"))));
+                                          JSON_BUILD_PAIR("homeDirectory", JSON_BUILD_CONST_STRING("/root")),
+                                          JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("intrinsic"))));
 }
 
 static int synthetic_nobody_user_build(UserRecord **ret) {
         return user_record_build(
                         ret,
-                        JSON_BUILD_OBJECT(JSON_BUILD_PAIR("userName", JSON_BUILD_STRING(NOBODY_USER_NAME)),
+                        JSON_BUILD_OBJECT(JSON_BUILD_PAIR("userName", JSON_BUILD_CONST_STRING(NOBODY_USER_NAME)),
                                           JSON_BUILD_PAIR("uid", JSON_BUILD_UNSIGNED(UID_NOBODY)),
                                           JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(GID_NOBODY)),
-                                          JSON_BUILD_PAIR("shell", JSON_BUILD_STRING(NOLOGIN)),
+                                          JSON_BUILD_PAIR("shell", JSON_BUILD_CONST_STRING(NOLOGIN)),
                                           JSON_BUILD_PAIR("locked", JSON_BUILD_BOOLEAN(true)),
-                                          JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("intrinsic"))));
+                                          JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("intrinsic"))));
 }
 
 int userdb_by_name(const char *name, UserDBFlags flags, UserRecord **ret) {
@@ -730,8 +723,6 @@ int userdb_all(UserDBFlags flags, UserDBIterator **ret) {
         if (!iterator)
                 return -ENOMEM;
 
-        iterator->synthesize_root = iterator->synthesize_nobody = !FLAGS_SET(flags, USERDB_DONT_SYNTHESIZE);
-
         qr = userdb_start_query(iterator, "io.systemd.UserDatabase.GetUserRecord", true, NULL, flags);
 
         if (!FLAGS_SET(flags, USERDB_EXCLUDE_NSS) && (qr < 0 || !iterator->nss_covered)) {
@@ -878,17 +869,17 @@ int userdb_iterator_get(UserDBIterator *iterator, UserRecord **ret) {
 static int synthetic_root_group_build(GroupRecord **ret) {
         return group_record_build(
                         ret,
-                        JSON_BUILD_OBJECT(JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING("root")),
+                        JSON_BUILD_OBJECT(JSON_BUILD_PAIR("groupName", JSON_BUILD_CONST_STRING("root")),
                                           JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(0)),
-                                          JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("intrinsic"))));
+                                          JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("intrinsic"))));
 }
 
 static int synthetic_nobody_group_build(GroupRecord **ret) {
         return group_record_build(
                         ret,
-                        JSON_BUILD_OBJECT(JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(NOBODY_GROUP_NAME)),
+                        JSON_BUILD_OBJECT(JSON_BUILD_PAIR("groupName", JSON_BUILD_CONST_STRING(NOBODY_GROUP_NAME)),
                                           JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(GID_NOBODY)),
-                                          JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("intrinsic"))));
+                                          JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("intrinsic"))));
 }
 
 int groupdb_by_name(const char *name, UserDBFlags flags, GroupRecord **ret) {
@@ -1002,8 +993,6 @@ int groupdb_all(UserDBFlags flags, UserDBIterator **ret) {
         if (!iterator)
                 return -ENOMEM;
 
-        iterator->synthesize_root = iterator->synthesize_nobody = !FLAGS_SET(flags, USERDB_DONT_SYNTHESIZE);
-
         qr = userdb_start_query(iterator, "io.systemd.UserDatabase.GetGroupRecord", true, NULL, flags);
 
         if (!FLAGS_SET(flags, USERDB_EXCLUDE_NSS) && (qr < 0 || !iterator->nss_covered)) {
@@ -1459,14 +1448,16 @@ int userdb_block_nss_systemd(int b) {
 
         /* Note that we might be called from libnss_systemd.so.2 itself, but that should be fine, really. */
 
-        dl = dlopen(ROOTLIBDIR "/libnss_systemd.so.2", RTLD_LAZY|RTLD_NODELETE);
+        dl = dlopen(LIBDIR "/libnss_systemd.so.2", RTLD_LAZY|RTLD_NODELETE);
         if (!dl) {
                 /* If the file isn't installed, don't complain loudly */
                 log_debug("Failed to dlopen(libnss_systemd.so.2), ignoring: %s", dlerror());
                 return 0;
         }
 
-        call = (int (*)(bool b)) dlsym(dl, "_nss_systemd_block");
+        log_debug("Loaded '%s' via dlopen()", LIBDIR "/libnss_systemd.so.2");
+
+        call = dlsym(dl, "_nss_systemd_block");
         if (!call)
                 /* If the file is installed but lacks the symbol we expect, things are weird, let's complain */
                 return log_debug_errno(SYNTHETIC_ERRNO(ELIBBAD),