qga/commands-posix: qmp_guest_set_user_password: use ga_run_command helper
There's no need to check for the existence of the "chpasswd", "pw" executables, as the exec() call will do that for us. Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Konstantin Kostiuk <kkostiuk@redhat.com> Link: https://lore.kernel.org/r/20240320161648.158226-8-andrey.drobyshev@virtuozzo.com Signed-off-by: Konstantin Kostiuk <kkostiuk@redhat.com>
This commit is contained in:
parent
2048129625
commit
0e5b75a390
@ -2151,14 +2151,8 @@ void qmp_guest_set_user_password(const char *username,
|
|||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
char *passwd_path = NULL;
|
g_autofree char *rawpasswddata = NULL;
|
||||||
pid_t pid;
|
|
||||||
int status;
|
|
||||||
int datafd[2] = { -1, -1 };
|
|
||||||
char *rawpasswddata = NULL;
|
|
||||||
size_t rawpasswdlen;
|
size_t rawpasswdlen;
|
||||||
char *chpasswddata = NULL;
|
|
||||||
size_t chpasswdlen;
|
|
||||||
|
|
||||||
rawpasswddata = (char *)qbase64_decode(password, -1, &rawpasswdlen, errp);
|
rawpasswddata = (char *)qbase64_decode(password, -1, &rawpasswdlen, errp);
|
||||||
if (!rawpasswddata) {
|
if (!rawpasswddata) {
|
||||||
@ -2169,95 +2163,31 @@ void qmp_guest_set_user_password(const char *username,
|
|||||||
|
|
||||||
if (strchr(rawpasswddata, '\n')) {
|
if (strchr(rawpasswddata, '\n')) {
|
||||||
error_setg(errp, "forbidden characters in raw password");
|
error_setg(errp, "forbidden characters in raw password");
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strchr(username, '\n') ||
|
if (strchr(username, '\n') ||
|
||||||
strchr(username, ':')) {
|
strchr(username, ':')) {
|
||||||
error_setg(errp, "forbidden characters in username");
|
error_setg(errp, "forbidden characters in username");
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
chpasswddata = g_strdup(rawpasswddata);
|
g_autofree char *chpasswdata = g_strdup(rawpasswddata);
|
||||||
passwd_path = g_find_program_in_path("pw");
|
const char *crypt_flag = crypted ? "-H" : "-h";
|
||||||
|
const char *argv[] = {"pw", "usermod", "-n", username,
|
||||||
|
crypt_flag, "0", NULL};
|
||||||
#else
|
#else
|
||||||
chpasswddata = g_strdup_printf("%s:%s\n", username, rawpasswddata);
|
g_autofree char *chpasswddata = g_strdup_printf("%s:%s\n", username,
|
||||||
passwd_path = g_find_program_in_path("chpasswd");
|
rawpasswddata);
|
||||||
|
const char *crypt_flag = crypted ? "-e" : NULL;
|
||||||
|
const char *argv[] = {"chpasswd", crypt_flag, NULL};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
chpasswdlen = strlen(chpasswddata);
|
ga_run_command(argv, chpasswddata, "set user password", &local_err);
|
||||||
|
|
||||||
if (!passwd_path) {
|
|
||||||
error_setg(errp, "cannot find 'passwd' program in PATH");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_unix_open_pipe(datafd, FD_CLOEXEC, NULL)) {
|
|
||||||
error_setg(errp, "cannot create pipe FDs");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
pid = fork();
|
|
||||||
if (pid == 0) {
|
|
||||||
close(datafd[1]);
|
|
||||||
/* child */
|
|
||||||
setsid();
|
|
||||||
dup2(datafd[0], 0);
|
|
||||||
reopen_fd_to_null(1);
|
|
||||||
reopen_fd_to_null(2);
|
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
const char *h_arg;
|
|
||||||
h_arg = (crypted) ? "-H" : "-h";
|
|
||||||
execl(passwd_path, "pw", "usermod", "-n", username, h_arg, "0", NULL);
|
|
||||||
#else
|
|
||||||
if (crypted) {
|
|
||||||
execl(passwd_path, "chpasswd", "-e", NULL);
|
|
||||||
} else {
|
|
||||||
execl(passwd_path, "chpasswd", NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
_exit(EXIT_FAILURE);
|
|
||||||
} else if (pid < 0) {
|
|
||||||
error_setg_errno(errp, errno, "failed to create child process");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
close(datafd[0]);
|
|
||||||
datafd[0] = -1;
|
|
||||||
|
|
||||||
if (qemu_write_full(datafd[1], chpasswddata, chpasswdlen) != chpasswdlen) {
|
|
||||||
error_setg_errno(errp, errno, "cannot write new account password");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
close(datafd[1]);
|
|
||||||
datafd[1] = -1;
|
|
||||||
|
|
||||||
ga_wait_child(pid, &status, &local_err);
|
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
goto out;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (!WIFEXITED(status)) {
|
|
||||||
error_setg(errp, "child process has terminated abnormally");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WEXITSTATUS(status)) {
|
|
||||||
error_setg(errp, "child process has failed to set user password");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
g_free(chpasswddata);
|
|
||||||
g_free(rawpasswddata);
|
|
||||||
g_free(passwd_path);
|
|
||||||
if (datafd[0] != -1) {
|
|
||||||
close(datafd[0]);
|
|
||||||
}
|
|
||||||
if (datafd[1] != -1) {
|
|
||||||
close(datafd[1]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* __linux__ || __FreeBSD__ */
|
#else /* __linux__ || __FreeBSD__ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user