systemctl: systemctl show --property' needs verification of property (#3364)

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
This commit is contained in:
Susant Sahani 2016-05-31 21:50:25 +05:30 committed by Lennart Poettering
parent b613907ea9
commit e33a06a1eb

View 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);
}
}
}