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 LC @LCMAN@
|
||||
.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
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -6199,7 +6199,7 @@ line in the
|
||||
sudo.conf(@mansectform@)
|
||||
file.
|
||||
.TP 3n
|
||||
unable to open @rundir@/ts/username
|
||||
unable to open @rundir@/ts/user-ID
|
||||
\fBsudoers\fR
|
||||
was unable to read or create the user's time stamp file.
|
||||
This can happen when
|
||||
@ -6213,7 +6213,7 @@ The default mode for
|
||||
\fI@rundir@\fR
|
||||
is 0711.
|
||||
.TP 3n
|
||||
unable to write to @rundir@/ts/username
|
||||
unable to write to @rundir@/ts/user-ID
|
||||
\fBsudoers\fR
|
||||
was unable to write to the user's time stamp file.
|
||||
.TP 3n
|
||||
|
@ -25,7 +25,7 @@
|
||||
.nr BA @BAMAN@
|
||||
.nr LC @LCMAN@
|
||||
.nr PS @PSMAN@
|
||||
.Dd August 28, 2023
|
||||
.Dd September 20, 2023
|
||||
.Dt SUDOERS @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -5797,7 +5797,7 @@ file) to the
|
||||
line in the
|
||||
.Xr sudo.conf @mansectform@
|
||||
file.
|
||||
.It unable to open @rundir@/ts/username
|
||||
.It unable to open @rundir@/ts/user-ID
|
||||
.Nm
|
||||
was unable to read or create the user's time stamp file.
|
||||
This can happen when
|
||||
@ -5810,7 +5810,7 @@ is not searchable by group or other.
|
||||
The default mode for
|
||||
.Pa @rundir@
|
||||
is 0711.
|
||||
.It unable to write to @rundir@/ts/username
|
||||
.It unable to write to @rundir@/ts/user-ID
|
||||
.Nm
|
||||
was unable to write to the user's time stamp file.
|
||||
.It @rundir@/ts is owned by uid X, should be Y
|
||||
|
@ -2,7 +2,7 @@
|
||||
.\"
|
||||
.\" 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
|
||||
.\" 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
|
||||
.\" 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
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -25,7 +25,7 @@
|
||||
.SH "DESCRIPTION"
|
||||
The
|
||||
\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
|
||||
\fBsudo\fR
|
||||
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
|
||||
OpenBSD
|
||||
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"
|
||||
Many people have worked on
|
||||
\fBsudo\fR
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\"
|
||||
.\" 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
|
||||
.\" 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
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd September 13, 2022
|
||||
.Dd September 20, 2023
|
||||
.Dt SUDOERS_TIMESTAMP @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -24,7 +24,7 @@
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.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
|
||||
.Nm sudo
|
||||
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
|
||||
.Ox
|
||||
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
|
||||
.Sh AUTHORS
|
||||
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);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
@ -251,7 +251,7 @@ display_lecture(struct sudo_conv_callback *callback)
|
||||
debug_return;
|
||||
|
||||
if (def_lecture == never ||
|
||||
(def_lecture == once && already_lectured(closure->ctx->user.name)))
|
||||
(def_lecture == once && already_lectured(closure->ctx)))
|
||||
debug_return;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
@ -442,9 +442,10 @@ ts_init_key_nonglobal(const struct sudoers_context *ctx,
|
||||
void *
|
||||
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;
|
||||
char *fname = NULL;
|
||||
int tries, dfd = -1, fd = -1;
|
||||
debug_decl(timestamp_open, SUDOERS_DEBUG_AUTH);
|
||||
|
||||
/* Zero timeout means don't use the time stamp file. */
|
||||
@ -459,14 +460,19 @@ timestamp_open(const struct sudoers_context *ctx)
|
||||
goto bad;
|
||||
|
||||
/* 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"));
|
||||
goto bad;
|
||||
}
|
||||
for (tries = 1; ; tries++) {
|
||||
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) {
|
||||
case TIMESTAMP_OPEN_ERROR:
|
||||
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,
|
||||
"removing time stamp file that predates boot time");
|
||||
close(fd);
|
||||
unlinkat(dfd, ctx->user.name, 0);
|
||||
unlinkat(dfd, uidstr, 0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -1004,7 +1010,8 @@ int
|
||||
timestamp_remove(const struct sudoers_context *ctx, bool unlink_it)
|
||||
{
|
||||
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;
|
||||
debug_decl(timestamp_remove, SUDOERS_DEBUG_AUTH);
|
||||
|
||||
@ -1025,7 +1032,13 @@ timestamp_remove(const struct sudoers_context *ctx, bool unlink_it)
|
||||
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"));
|
||||
ret = -1;
|
||||
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. */
|
||||
if (unlink_it) {
|
||||
ret = unlinkat(dfd, ctx->user.name, 0) ? -1 : true;
|
||||
ret = unlinkat(dfd, uidstr, 0) ? -1 : true;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
case TIMESTAMP_OPEN_ERROR:
|
||||
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.
|
||||
*/
|
||||
bool
|
||||
already_lectured(const char *user)
|
||||
already_lectured(const struct sudoers_context *ctx)
|
||||
{
|
||||
char uidstr[STRLEN_MAX_UNSIGNED(uid_t) + 1];
|
||||
bool ret = false;
|
||||
struct stat sb;
|
||||
int dfd;
|
||||
int dfd, len;
|
||||
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);
|
||||
if (dfd != -1) {
|
||||
ret = fstatat(dfd, user, &sb, AT_SYMLINK_NOFOLLOW) == 0;
|
||||
if (dfd == -1)
|
||||
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);
|
||||
}
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
|
||||
/* Check the validity of timestamp dir and create if missing. */
|
||||
@ -1143,8 +1167,12 @@ set_lectured(const char *user)
|
||||
if (dfd == -1)
|
||||
goto done;
|
||||
|
||||
len = snprintf(uidstr, sizeof(uidstr), "%u", (unsigned int)ctx->user.uid);
|
||||
if (len < 0 || len >= ssizeof(uidstr))
|
||||
goto done;
|
||||
|
||||
/* 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) {
|
||||
case TIMESTAMP_OPEN_ERROR:
|
||||
/* Failed to open, not a fatal error. */
|
||||
@ -1159,9 +1187,10 @@ set_lectured(const char *user)
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
close(dfd);
|
||||
|
||||
done:
|
||||
if (dfd != -1)
|
||||
close(dfd);
|
||||
debug_return_int(ret);
|
||||
}
|
||||
|
||||
|
@ -96,8 +96,8 @@ int timestamp_status(void *vcookie, struct passwd *pw);
|
||||
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);
|
||||
int get_starttime(pid_t pid, struct timespec *starttime);
|
||||
bool already_lectured(const char *user);
|
||||
int set_lectured(const char *user);
|
||||
bool already_lectured(const struct sudoers_context *ctx);
|
||||
int set_lectured(const struct sudoers_context *ctx);
|
||||
void display_lecture(struct sudo_conv_callback *callback);
|
||||
int create_admin_success_flag(const struct sudoers_context *ctx);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user