systemctl: systemctl show --property' needs verification of property (#3364)
authorSusant Sahani <ssahani@users.noreply.github.com>
Tue, 31 May 2016 16:20:25 +0000 (21:50 +0530)
committerLennart Poettering <lennart@poettering.net>
Tue, 31 May 2016 16:20:25 +0000 (18:20 +0200)
systemctl --property doesn't validate if a requested property is valid or not,
and always returns with an exit code of 0, regardless of whether the requested
property exists or not.

How reproducible:

This works fine:

Id=multi-user.target
But put in a non-existing property:

Id=default.targets.service
Id=default.targets.service
0
[root@shou18lkvm8 ~]# systemctl show --property Id this.is.rubbish; echo $?
Id=this.is.rubbish.service
0

After:

sus@maximus bz-95593]$ ./systemctl show --property Id this.is.rubbish; echo $?
Can't display property this.is.rubbish. Unit this.is.rubbish.service does not
exist.
4

fixes #2295

src/systemctl/systemctl.c

index e4b4e07..e8f487e 100644 (file)
@@ -4561,6 +4561,14 @@ static int show_one(
                 .tasks_current = (uint64_t) -1,
                 .tasks_max = (uint64_t) -1,
         };
+        struct property_info {
+                const char *load_state, *active_state;
+        } property_info = {};
+        static const struct bus_properties_map property_map[] = {
+                { "LoadState",   "s", NULL, offsetof(struct property_info, load_state)   },
+                { "ActiveState", "s", NULL, offsetof(struct property_info, active_state) },
+                {}
+        };
         ExecStatusInfo *p;
         int r;
 
@@ -4581,6 +4589,17 @@ static int show_one(
         if (r < 0)
                 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
 
+        r = bus_message_map_all_properties(reply, property_map, &property_info);
+        if (r < 0)
+                return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
+
+        if (streq_ptr(property_info.load_state, "not-found") && streq_ptr(property_info.active_state, "inactive"))
+                return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN;
+
+        r = sd_bus_message_rewind(reply, true);
+        if (r < 0)
+                return log_error_errno(r, "Failed to rewind: %s", bus_error_message(&error, r));
+
         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
         if (r < 0)
                 return bus_log_parse_error(r);
@@ -4889,6 +4908,9 @@ static int show(int argc, char *argv[], void *userdata) {
                                         return r;
                                 else if (r > 0 && ret == 0)
                                         ret = r;
+
+                                if (r == EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN)
+                                        log_error("Can't display property %s. Unit %s does not exist.", *patterns, *name);
                         }
                 }
         }