mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 09:57:41 +00:00
Use the user-ID instead of user-name for the timestamp and lecture file.
This avoids problems if the user name itself contains a path separator.
This commit is contained in:
parent
94b80e3ad4
commit
7363ad7b32
@ -25,7 +25,7 @@
|
|||||||
.nr BA @BAMAN@
|
.nr BA @BAMAN@
|
||||||
.nr LC @LCMAN@
|
.nr LC @LCMAN@
|
||||||
.nr PS @PSMAN@
|
.nr PS @PSMAN@
|
||||||
.TH "SUDOERS" "@mansectform@" "August 28, 2023" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
.TH "SUDOERS" "@mansectform@" "September 20, 2023" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||||
.nh
|
.nh
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
@ -6199,7 +6199,7 @@ line in the
|
|||||||
sudo.conf(@mansectform@)
|
sudo.conf(@mansectform@)
|
||||||
file.
|
file.
|
||||||
.TP 3n
|
.TP 3n
|
||||||
unable to open @rundir@/ts/username
|
unable to open @rundir@/ts/user-ID
|
||||||
\fBsudoers\fR
|
\fBsudoers\fR
|
||||||
was unable to read or create the user's time stamp file.
|
was unable to read or create the user's time stamp file.
|
||||||
This can happen when
|
This can happen when
|
||||||
@ -6213,7 +6213,7 @@ The default mode for
|
|||||||
\fI@rundir@\fR
|
\fI@rundir@\fR
|
||||||
is 0711.
|
is 0711.
|
||||||
.TP 3n
|
.TP 3n
|
||||||
unable to write to @rundir@/ts/username
|
unable to write to @rundir@/ts/user-ID
|
||||||
\fBsudoers\fR
|
\fBsudoers\fR
|
||||||
was unable to write to the user's time stamp file.
|
was unable to write to the user's time stamp file.
|
||||||
.TP 3n
|
.TP 3n
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
.nr BA @BAMAN@
|
.nr BA @BAMAN@
|
||||||
.nr LC @LCMAN@
|
.nr LC @LCMAN@
|
||||||
.nr PS @PSMAN@
|
.nr PS @PSMAN@
|
||||||
.Dd August 28, 2023
|
.Dd September 20, 2023
|
||||||
.Dt SUDOERS @mansectform@
|
.Dt SUDOERS @mansectform@
|
||||||
.Os Sudo @PACKAGE_VERSION@
|
.Os Sudo @PACKAGE_VERSION@
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -5797,7 +5797,7 @@ file) to the
|
|||||||
line in the
|
line in the
|
||||||
.Xr sudo.conf @mansectform@
|
.Xr sudo.conf @mansectform@
|
||||||
file.
|
file.
|
||||||
.It unable to open @rundir@/ts/username
|
.It unable to open @rundir@/ts/user-ID
|
||||||
.Nm
|
.Nm
|
||||||
was unable to read or create the user's time stamp file.
|
was unable to read or create the user's time stamp file.
|
||||||
This can happen when
|
This can happen when
|
||||||
@ -5810,7 +5810,7 @@ is not searchable by group or other.
|
|||||||
The default mode for
|
The default mode for
|
||||||
.Pa @rundir@
|
.Pa @rundir@
|
||||||
is 0711.
|
is 0711.
|
||||||
.It unable to write to @rundir@/ts/username
|
.It unable to write to @rundir@/ts/user-ID
|
||||||
.Nm
|
.Nm
|
||||||
was unable to write to the user's time stamp file.
|
was unable to write to the user's time stamp file.
|
||||||
.It @rundir@/ts is owned by uid X, should be Y
|
.It @rundir@/ts is owned by uid X, should be Y
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" SPDX-License-Identifier: ISC
|
.\" SPDX-License-Identifier: ISC
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2017-2020, 2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
.\" Copyright (c) 2017-2020, 2022-2023 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
.\"
|
.\"
|
||||||
.\" Permission to use, copy, modify, and distribute this software for any
|
.\" Permission to use, copy, modify, and distribute this software for any
|
||||||
.\" purpose with or without fee is hereby granted, provided that the above
|
.\" purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -16,7 +16,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.TH "SUDOERS_TIMESTAMP" "@mansectform@" "September 13, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
.TH "SUDOERS_TIMESTAMP" "@mansectform@" "September 20, 2023" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||||
.nh
|
.nh
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
@ -25,7 +25,7 @@
|
|||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
The
|
The
|
||||||
\fBsudoers\fR
|
\fBsudoers\fR
|
||||||
plugin uses per-user time stamp files for credential caching.
|
plugin uses per-user-ID time stamp files for credential caching.
|
||||||
Once a user has been authenticated, they may use
|
Once a user has been authenticated, they may use
|
||||||
\fBsudo\fR
|
\fBsudo\fR
|
||||||
without a password for a short period of time
|
without a password for a short period of time
|
||||||
@ -278,6 +278,12 @@ This prevents re-use of the time stamp file after logout in most cases.
|
|||||||
Support was added for the kernel-based tty time stamps available in
|
Support was added for the kernel-based tty time stamps available in
|
||||||
OpenBSD
|
OpenBSD
|
||||||
which do not use an on-disk time stamp file.
|
which do not use an on-disk time stamp file.
|
||||||
|
.TP 6n
|
||||||
|
1.9.15
|
||||||
|
Time stamp file path names are now based on the invoking user-ID
|
||||||
|
instead of the user name.
|
||||||
|
This avoids problems with user names that include a path separator
|
||||||
|
character.
|
||||||
.SH "AUTHORS"
|
.SH "AUTHORS"
|
||||||
Many people have worked on
|
Many people have worked on
|
||||||
\fBsudo\fR
|
\fBsudo\fR
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" SPDX-License-Identifier: ISC
|
.\" SPDX-License-Identifier: ISC
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2017-2020, 2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
.\" Copyright (c) 2017-2020, 2022-2023 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
.\"
|
.\"
|
||||||
.\" Permission to use, copy, modify, and distribute this software for any
|
.\" Permission to use, copy, modify, and distribute this software for any
|
||||||
.\" purpose with or without fee is hereby granted, provided that the above
|
.\" purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -15,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd September 13, 2022
|
.Dd September 20, 2023
|
||||||
.Dt SUDOERS_TIMESTAMP @mansectform@
|
.Dt SUDOERS_TIMESTAMP @mansectform@
|
||||||
.Os Sudo @PACKAGE_VERSION@
|
.Os Sudo @PACKAGE_VERSION@
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -24,7 +24,7 @@
|
|||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
.Nm sudoers
|
.Nm sudoers
|
||||||
plugin uses per-user time stamp files for credential caching.
|
plugin uses per-user-ID time stamp files for credential caching.
|
||||||
Once a user has been authenticated, they may use
|
Once a user has been authenticated, they may use
|
||||||
.Nm sudo
|
.Nm sudo
|
||||||
without a password for a short period of time
|
without a password for a short period of time
|
||||||
@ -256,6 +256,11 @@ This prevents re-use of the time stamp file after logout in most cases.
|
|||||||
Support was added for the kernel-based tty time stamps available in
|
Support was added for the kernel-based tty time stamps available in
|
||||||
.Ox
|
.Ox
|
||||||
which do not use an on-disk time stamp file.
|
which do not use an on-disk time stamp file.
|
||||||
|
.It 1.9.15
|
||||||
|
Time stamp file path names are now based on the invoking user-ID
|
||||||
|
instead of the user name.
|
||||||
|
This avoids problems with user names that include a path separator
|
||||||
|
character.
|
||||||
.El
|
.El
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
Many people have worked on
|
Many people have worked on
|
||||||
|
@ -201,7 +201,7 @@ check_user(struct sudoers_context *ctx, unsigned int validated,
|
|||||||
|
|
||||||
ret = verify_user(ctx, closure.auth_pw, prompt, validated, &callback);
|
ret = verify_user(ctx, closure.auth_pw, prompt, validated, &callback);
|
||||||
if (ret == AUTH_SUCCESS && closure.lectured)
|
if (ret == AUTH_SUCCESS && closure.lectured)
|
||||||
(void)set_lectured(ctx->user.name); /* lecture error not fatal */
|
(void)set_lectured(ctx); /* lecture error not fatal */
|
||||||
free(prompt);
|
free(prompt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -251,7 +251,7 @@ display_lecture(struct sudo_conv_callback *callback)
|
|||||||
debug_return;
|
debug_return;
|
||||||
|
|
||||||
if (def_lecture == never ||
|
if (def_lecture == never ||
|
||||||
(def_lecture == once && already_lectured(closure->ctx->user.name)))
|
(def_lecture == once && already_lectured(closure->ctx)))
|
||||||
debug_return;
|
debug_return;
|
||||||
|
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
|
@ -442,9 +442,10 @@ ts_init_key_nonglobal(const struct sudoers_context *ctx,
|
|||||||
void *
|
void *
|
||||||
timestamp_open(const struct sudoers_context *ctx)
|
timestamp_open(const struct sudoers_context *ctx)
|
||||||
{
|
{
|
||||||
|
int tries, len, dfd = -1, fd = -1;
|
||||||
|
char uidstr[STRLEN_MAX_UNSIGNED(uid_t) + 1];
|
||||||
struct ts_cookie *cookie;
|
struct ts_cookie *cookie;
|
||||||
char *fname = NULL;
|
char *fname = NULL;
|
||||||
int tries, dfd = -1, fd = -1;
|
|
||||||
debug_decl(timestamp_open, SUDOERS_DEBUG_AUTH);
|
debug_decl(timestamp_open, SUDOERS_DEBUG_AUTH);
|
||||||
|
|
||||||
/* Zero timeout means don't use the time stamp file. */
|
/* Zero timeout means don't use the time stamp file. */
|
||||||
@ -459,14 +460,19 @@ timestamp_open(const struct sudoers_context *ctx)
|
|||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
/* Open time stamp file. */
|
/* Open time stamp file. */
|
||||||
if (asprintf(&fname, "%s/%s", def_timestampdir, ctx->user.name) == -1) {
|
len = snprintf(uidstr, sizeof(uidstr), "%u", (unsigned int)ctx->user.uid);
|
||||||
|
if (len < 0 || len >= ssizeof(uidstr)) {
|
||||||
|
errno = EINVAL;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
if (asprintf(&fname, "%s/%s", def_timestampdir, uidstr) == -1) {
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
for (tries = 1; ; tries++) {
|
for (tries = 1; ; tries++) {
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
fd = ts_openat(dfd, ctx->user.name, O_RDWR|O_CREAT);
|
fd = ts_openat(dfd, uidstr, O_RDWR|O_CREAT);
|
||||||
switch (fd) {
|
switch (fd) {
|
||||||
case TIMESTAMP_OPEN_ERROR:
|
case TIMESTAMP_OPEN_ERROR:
|
||||||
log_warning(ctx, SLOG_SEND_MAIL, N_("unable to open %s"), fname);
|
log_warning(ctx, SLOG_SEND_MAIL, N_("unable to open %s"), fname);
|
||||||
@ -492,7 +498,7 @@ timestamp_open(const struct sudoers_context *ctx)
|
|||||||
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
||||||
"removing time stamp file that predates boot time");
|
"removing time stamp file that predates boot time");
|
||||||
close(fd);
|
close(fd);
|
||||||
unlinkat(dfd, ctx->user.name, 0);
|
unlinkat(dfd, uidstr, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1004,7 +1010,8 @@ int
|
|||||||
timestamp_remove(const struct sudoers_context *ctx, bool unlink_it)
|
timestamp_remove(const struct sudoers_context *ctx, bool unlink_it)
|
||||||
{
|
{
|
||||||
struct timestamp_entry key, entry;
|
struct timestamp_entry key, entry;
|
||||||
int dfd = -1, fd = -1, ret = true;
|
int len, dfd = -1, fd = -1, ret = true;
|
||||||
|
char uidstr[STRLEN_MAX_UNSIGNED(uid_t) + 1];
|
||||||
char *fname = NULL;
|
char *fname = NULL;
|
||||||
debug_decl(timestamp_remove, SUDOERS_DEBUG_AUTH);
|
debug_decl(timestamp_remove, SUDOERS_DEBUG_AUTH);
|
||||||
|
|
||||||
@ -1025,7 +1032,13 @@ timestamp_remove(const struct sudoers_context *ctx, bool unlink_it)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asprintf(&fname, "%s/%s", def_timestampdir, ctx->user.name) == -1) {
|
len = snprintf(uidstr, sizeof(uidstr), "%u", (unsigned int)ctx->user.uid);
|
||||||
|
if (len < 0 || len >= ssizeof(uidstr)) {
|
||||||
|
errno = EINVAL;
|
||||||
|
ret = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (asprintf(&fname, "%s/%s", def_timestampdir, uidstr) == -1) {
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto done;
|
goto done;
|
||||||
@ -1033,12 +1046,12 @@ timestamp_remove(const struct sudoers_context *ctx, bool unlink_it)
|
|||||||
|
|
||||||
/* For "sudo -K" simply unlink the time stamp file. */
|
/* For "sudo -K" simply unlink the time stamp file. */
|
||||||
if (unlink_it) {
|
if (unlink_it) {
|
||||||
ret = unlinkat(dfd, ctx->user.name, 0) ? -1 : true;
|
ret = unlinkat(dfd, uidstr, 0) ? -1 : true;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open time stamp file and lock it for exclusive access. */
|
/* Open time stamp file and lock it for exclusive access. */
|
||||||
fd = ts_openat(dfd, ctx->user.name, O_RDWR);
|
fd = ts_openat(dfd, uidstr, O_RDWR);
|
||||||
switch (fd) {
|
switch (fd) {
|
||||||
case TIMESTAMP_OPEN_ERROR:
|
case TIMESTAMP_OPEN_ERROR:
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
@ -1113,18 +1126,28 @@ cb_timestampowner(struct sudoers_context *ctx, const char *file,
|
|||||||
* Returns true if the user has already been lectured.
|
* Returns true if the user has already been lectured.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
already_lectured(const char *user)
|
already_lectured(const struct sudoers_context *ctx)
|
||||||
{
|
{
|
||||||
|
char uidstr[STRLEN_MAX_UNSIGNED(uid_t) + 1];
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
int dfd;
|
int dfd, len;
|
||||||
debug_decl(already_lectured, SUDOERS_DEBUG_AUTH);
|
debug_decl(already_lectured, SUDOERS_DEBUG_AUTH);
|
||||||
|
|
||||||
|
/* Check the existence and validity of timestamp dir. */
|
||||||
dfd = ts_secure_opendir(def_lecture_status_dir, false, true);
|
dfd = ts_secure_opendir(def_lecture_status_dir, false, true);
|
||||||
if (dfd != -1) {
|
if (dfd == -1)
|
||||||
ret = fstatat(dfd, user, &sb, AT_SYMLINK_NOFOLLOW) == 0;
|
goto done;
|
||||||
|
|
||||||
|
len = snprintf(uidstr, sizeof(uidstr), "%u", (unsigned int)ctx->user.uid);
|
||||||
|
if (len < 0 || len >= ssizeof(uidstr))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
ret = fstatat(dfd, uidstr, &sb, AT_SYMLINK_NOFOLLOW) == 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (dfd != -1)
|
||||||
close(dfd);
|
close(dfd);
|
||||||
}
|
|
||||||
debug_return_bool(ret);
|
debug_return_bool(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1133,9 +1156,10 @@ already_lectured(const char *user)
|
|||||||
* Returns true on success, false on failure or -1 on setuid failure.
|
* Returns true on success, false on failure or -1 on setuid failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
set_lectured(const char *user)
|
set_lectured(const struct sudoers_context *ctx)
|
||||||
{
|
{
|
||||||
int dfd, fd, ret = false;
|
char uidstr[STRLEN_MAX_UNSIGNED(uid_t) + 1];
|
||||||
|
int dfd, fd, len, ret = false;
|
||||||
debug_decl(set_lectured, SUDOERS_DEBUG_AUTH);
|
debug_decl(set_lectured, SUDOERS_DEBUG_AUTH);
|
||||||
|
|
||||||
/* Check the validity of timestamp dir and create if missing. */
|
/* Check the validity of timestamp dir and create if missing. */
|
||||||
@ -1143,8 +1167,12 @@ set_lectured(const char *user)
|
|||||||
if (dfd == -1)
|
if (dfd == -1)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
len = snprintf(uidstr, sizeof(uidstr), "%u", (unsigned int)ctx->user.uid);
|
||||||
|
if (len < 0 || len >= ssizeof(uidstr))
|
||||||
|
goto done;
|
||||||
|
|
||||||
/* Create lecture file. */
|
/* Create lecture file. */
|
||||||
fd = ts_openat(dfd, user, O_WRONLY|O_CREAT|O_EXCL);
|
fd = ts_openat(dfd, uidstr, O_WRONLY|O_CREAT|O_EXCL);
|
||||||
switch (fd) {
|
switch (fd) {
|
||||||
case TIMESTAMP_OPEN_ERROR:
|
case TIMESTAMP_OPEN_ERROR:
|
||||||
/* Failed to open, not a fatal error. */
|
/* Failed to open, not a fatal error. */
|
||||||
@ -1159,9 +1187,10 @@ set_lectured(const char *user)
|
|||||||
ret = true;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
close(dfd);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
if (dfd != -1)
|
||||||
|
close(dfd);
|
||||||
debug_return_int(ret);
|
debug_return_int(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,8 +96,8 @@ int timestamp_status(void *vcookie, struct passwd *pw);
|
|||||||
uid_t timestamp_get_uid(void);
|
uid_t timestamp_get_uid(void);
|
||||||
bool cb_timestampowner(struct sudoers_context *ctx, const char *file, int line, int column, const union sudo_defs_val *sd_un, int op);
|
bool cb_timestampowner(struct sudoers_context *ctx, const char *file, int line, int column, const union sudo_defs_val *sd_un, int op);
|
||||||
int get_starttime(pid_t pid, struct timespec *starttime);
|
int get_starttime(pid_t pid, struct timespec *starttime);
|
||||||
bool already_lectured(const char *user);
|
bool already_lectured(const struct sudoers_context *ctx);
|
||||||
int set_lectured(const char *user);
|
int set_lectured(const struct sudoers_context *ctx);
|
||||||
void display_lecture(struct sudo_conv_callback *callback);
|
void display_lecture(struct sudo_conv_callback *callback);
|
||||||
int create_admin_success_flag(const struct sudoers_context *ctx);
|
int create_admin_success_flag(const struct sudoers_context *ctx);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user