Compare commits

..

9 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 8da8996181 gpt-auto-generator: improve log message
We said "exiting", but then the program continues to do other operations
and log additional messages.
2024-11-20 15:05:16 +01:00
Zbigniew Jędrzejewski-Szmek fb1ad8c2df shared/exec-util: fix logging of the args of an executed program
The debug logs has lots of "About to execute /some/path (null)". This
occurs when the args array is empty. Instead, only print "(null)" if
we failed with oom.

Having strv_skip() return NULL makes this pleasant to write without repeating
strv_isempty() a few times.
2024-11-20 15:05:16 +01:00
Zbigniew Jędrzejewski-Szmek 7a5997bad1 test-execve: minor simplification 2024-11-20 15:05:16 +01:00
Zbigniew Jędrzejewski-Szmek 64e225d4c3 various: handle the positive condition after strv_skip() first 2024-11-20 15:05:16 +01:00
Zbigniew Jędrzejewski-Szmek d9cb7338f9 busctl: use RET_GATHER 2024-11-20 15:05:16 +01:00
Zbigniew Jędrzejewski-Szmek 654fa34796 busctl: use STRV_FOREACH in the usual fashion
Also put positive branch first, do not use 'i' as a char** variable name.
2024-11-20 15:05:16 +01:00
Zbigniew Jędrzejewski-Szmek 0638a45ec9 analyze: use STRV_FOREACH in consistent fashion
Also put positive condition first.
2024-11-20 15:05:16 +01:00
Zbigniew Jędrzejewski-Szmek e97f1ad4c9 basic/strv: return NULL from strv_skip
strv_skip was written to carefully return the original array, but this turns
out to be an unnecessary complication. After the previous patch, no caller
cares about the distinction between NULL and { NULL }, but various callers need
to wrap the process the returned value with strv_isempty(), sometimes more than
once. Let's always return NULL for an empty result to allow callers to be
simplified.
2024-11-20 15:05:16 +01:00
Zbigniew Jędrzejewski-Szmek 48e5aec4a3 homectl: split out inspect_home() and authenticate_home()
mangle_user_list() was doing a microoptimization of avoiding of copying of a
single string by constructing the strv object manually. This seems like more
trouble than it's worth, considering that this is called once in the program's
life.

Rework the code to have inspect_home() and authenticate_home() that handle a
single home name and call them in a loop from the outer function.
2024-11-20 14:58:56 +01:00
1 changed files with 91 additions and 122 deletions

View File

@ -691,34 +691,51 @@ static void dump_home_record(UserRecord *hr) {
} }
} }
static int mangle_user_list(char **list, char ***ret) { static int inspect_home(sd_bus *bus, const char *name) {
char **l; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
_cleanup_(user_record_unrefp) UserRecord *hr = NULL;
const char *json;
int incomplete;
uid_t uid;
int r;
if (strv_isempty(list)) { r = parse_uid(name, &uid);
_cleanup_free_ char *myself = NULL; if (r < 0) {
if (!valid_user_group_name(name, 0))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid user name '%s'.", name);
myself = getusername_malloc(); r = bus_call_method(bus, bus_mgr, "GetUserRecordByName", &error, &reply, "s", name);
if (!myself)
return log_oom();
l = strv_new(myself);
} else } else
l = strv_copy(list); r = bus_call_method(bus, bus_mgr, "GetUserRecordByUID", &error, &reply, "u", (uint32_t) uid);
if (!l) if (r < 0)
return log_error_errno(r, "Failed to inspect home: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "sbo", &json, &incomplete, NULL);
if (r < 0)
return bus_log_parse_error(r);
r = sd_json_parse(json, SD_JSON_PARSE_SENSITIVE, &v, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to parse JSON identity: %m");
hr = user_record_new();
if (!hr)
return log_oom(); return log_oom();
*ret = l; r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
hr->incomplete = incomplete;
dump_home_record(hr);
return 0; return 0;
} }
static int inspect_home(int argc, char *argv[], void *userdata) { static int inspect_homes(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_strv_free_ char **items = NULL; int r;
int r, ret = 0;
r = mangle_user_list(strv_skip(argv, 1), &items);
if (r < 0)
return r;
r = acquire_bus(&bus); r = acquire_bus(&bus);
if (r < 0) if (r < 0)
@ -726,126 +743,78 @@ static int inspect_home(int argc, char *argv[], void *userdata) {
pager_open(arg_pager_flags); pager_open(arg_pager_flags);
STRV_FOREACH(i, items) { char **args = strv_skip(argv, 1);
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; if (args) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_free_ char *myself = getusername_malloc();
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; if (!myself)
_cleanup_(user_record_unrefp) UserRecord *hr = NULL;
const char *json;
int incomplete;
uid_t uid;
r = parse_uid(*i, &uid);
if (r < 0) {
if (!valid_user_group_name(*i, 0)) {
log_error("Invalid user name '%s'.", *i);
if (ret == 0)
ret = -EINVAL;
continue;
}
r = bus_call_method(bus, bus_mgr, "GetUserRecordByName", &error, &reply, "s", *i);
} else
r = bus_call_method(bus, bus_mgr, "GetUserRecordByUID", &error, &reply, "u", (uint32_t) uid);
if (r < 0) {
log_error_errno(r, "Failed to inspect home: %s", bus_error_message(&error, r));
if (ret == 0)
ret = r;
continue;
}
r = sd_bus_message_read(reply, "sbo", &json, &incomplete, NULL);
if (r < 0) {
bus_log_parse_error(r);
if (ret == 0)
ret = r;
continue;
}
r = sd_json_parse(json, SD_JSON_PARSE_SENSITIVE, &v, NULL, NULL);
if (r < 0) {
log_error_errno(r, "Failed to parse JSON identity: %m");
if (ret == 0)
ret = r;
continue;
}
hr = user_record_new();
if (!hr)
return log_oom(); return log_oom();
r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE); return inspect_home(bus, myself);
if (r < 0) { } else {
if (ret == 0) STRV_FOREACH(arg, args)
ret = r; RET_GATHER(r, inspect_home(bus, *arg));
continue; return r;
}
hr->incomplete = incomplete;
dump_home_record(hr);
} }
return ret;
} }
static int authenticate_home(int argc, char *argv[], void *userdata) { static int authenticate_home(sd_bus *bus, const char *name) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(user_record_unrefp) UserRecord *secret = NULL;
_cleanup_strv_free_ char **items = NULL; int r;
int r, ret = 0;
r = mangle_user_list(strv_skip(argv, 1), &items); r = acquire_passed_secrets(name, &secret);
if (r < 0) if (r < 0)
return r; return r;
for (;;) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
r = bus_message_new_method_call(bus, &m, bus_mgr, "AuthenticateHome");
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_append(m, "s", name);
if (r < 0)
return bus_log_create_error(r);
r = bus_message_append_secret(m, secret);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_call(bus, m, HOME_SLOW_BUS_CALL_TIMEOUT_USEC, &error, NULL);
if (r < 0) {
r = handle_generic_user_record_error(name, secret, &error, r, false);
if (r >= 0)
continue;
}
return r;
}
}
static int authenticate_homes(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r;
r = acquire_bus(&bus); r = acquire_bus(&bus);
if (r < 0) if (r < 0)
return r; return r;
(void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
STRV_FOREACH(i, items) { char **args = strv_skip(argv, 1);
_cleanup_(user_record_unrefp) UserRecord *secret = NULL; if (args) {
_cleanup_free_ char *myself = getusername_malloc();
if (!myself)
return log_oom();
r = acquire_passed_secrets(*i, &secret); return authenticate_home(bus, myself);
if (r < 0) } else {
return r; STRV_FOREACH(arg, args)
RET_GATHER(r, authenticate_home(bus, *arg));
for (;;) { return r;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
r = bus_message_new_method_call(bus, &m, bus_mgr, "AuthenticateHome");
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_append(m, "s", *i);
if (r < 0)
return bus_log_create_error(r);
r = bus_message_append_secret(m, secret);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_call(bus, m, HOME_SLOW_BUS_CALL_TIMEOUT_USEC, &error, NULL);
if (r < 0) {
r = handle_generic_user_record_error(*i, secret, &error, r, false);
if (r < 0) {
if (ret == 0)
ret = r;
break;
}
} else
break;
}
} }
return ret;
} }
static int update_last_change(sd_json_variant **v, bool with_password, bool override) { static int update_last_change(sd_json_variant **v, bool with_password, bool override) {
@ -4721,8 +4690,8 @@ static int run(int argc, char *argv[]) {
{ "list", VERB_ANY, 1, VERB_DEFAULT, list_homes }, { "list", VERB_ANY, 1, VERB_DEFAULT, list_homes },
{ "activate", 2, VERB_ANY, 0, activate_home }, { "activate", 2, VERB_ANY, 0, activate_home },
{ "deactivate", 2, VERB_ANY, 0, deactivate_home }, { "deactivate", 2, VERB_ANY, 0, deactivate_home },
{ "inspect", VERB_ANY, VERB_ANY, 0, inspect_home }, { "inspect", VERB_ANY, VERB_ANY, 0, inspect_homes },
{ "authenticate", VERB_ANY, VERB_ANY, 0, authenticate_home }, { "authenticate", VERB_ANY, VERB_ANY, 0, authenticate_homes },
{ "create", VERB_ANY, 2, 0, create_home }, { "create", VERB_ANY, 2, 0, create_home },
{ "remove", 2, VERB_ANY, 0, remove_home }, { "remove", 2, VERB_ANY, 0, remove_home },
{ "update", VERB_ANY, 2, 0, update_home }, { "update", VERB_ANY, 2, 0, update_home },