TransWikia.com

add status of sudo session to PS1 without extending session

Unix & Linux Asked by Nathaniel M. Beaver on November 16, 2021

I can add the status of a sudo session to the bash prompt like this:

function sudo_active() {
    if sudo -n /bin/true 2> /dev/null
    then
        printf '(sudo) '
    fi
}

PS1="$PS1"'$(sudo_active)'

This way I can run a series of sudo commands
and afterward I’ll know if the sudo session is still active or not.
I can end the session early with sudo -k,
close the shell,
or just remember to be careful.

One issue with this approach
is that every time a new prompt runs without sudo privileges
it adds a message like this to the system log:

sudo[25653]: myusername : a password is required ; TTY=pts/13 ; PWD=/home/myusername/ ; USER=root ; COMMAND=/bin/true

The other problem is that because this runs a sudo command
in the prompt every time,
it will re-extend the timeout every time I run a command
(depending on the value of passwd_timeout),
even if I don’t run a command that requires sudo.

Is there a way I can test if the sudo session is still active
and show this in the bash prompt
without continually re-extending the session as a side effect?

One Answer

You can use the timestamp file that sudo creates per-user to find how long ago a sudo command was used by that user; if it is further than the configured timestamp_timeout (default 5 minutes), then a new sudo will need a password.

The per-user file is created under /var/run/sudo/ts/ (on my system). Its format is partially described in man sudoers and you can see from the sources timestamp.c and check.h that it consists of several records described by the struct struct timestamp_entry_v1 or the newer struct timestamp_entry.

The git version is newer than the sources corresponding to my old-ish system so I'm using the older struct, version 1. You may need need the newer version 2 with an extra field.

Here's a minimal C program to dump the records for a hard-wired user:

/* https://unix.stackexchange.com/a/595473/119298
 * struct from 
 * https://github.com/sudo-project/sudo/blob/master/plugins/sudoers/check.h
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define TS_VERSION      1
/* Time stamp entry types */
#define TS_GLOBAL       0x01
#define TS_TTY          0x02
#define TS_PPID         0x03
#define TS_LOCKEXCL     0x04
/* Time stamp flags */
#define TS_DISABLED     0x01    /* entry disabled */
#define TS_ANYUID       0x02    /* ignore uid, only valid in the key */

struct timestamp_entry {
    unsigned short version;     /* version number */
    unsigned short size;        /* entry size */
    unsigned short type;        /* TS_GLOBAL, TS_TTY, TS_PPID */
    unsigned short flags;       /* TS_DISABLED, TS_ANYUID */
    uid_t auth_uid;             /* uid to authenticate as */
    pid_t sid;                  /* session ID associated with tty/ppid */
    struct timespec ts;         /* timestamp (CLOCK_MONOTONIC) */
    union {
        dev_t ttydev;         /* tty device number */
        pid_t ppid;           /* parent pid */
    } u;
};

void main(int argc, char **argv){
    struct timestamp_entry entry;
    struct timespec now;
    int fd = open("/var/run/sudo/ts/meuh",O_RDONLY);

    if(fd<0)exit(1);
    clock_gettime(CLOCK_MONOTONIC, &now);
    while(read(fd,&entry,sizeof(entry))==sizeof(entry)){
        printf("type=%d flags=%d uid=%d sid=%d elapsedtime=%dn",
               entry.type, entry.flags, entry.auth_uid, entry.sid,
               entry.ts.tv_sec-now.tv_sec);
    }
    exit(0);
}

Compiling and running this setuid root on my system gave me lines like

type=4 flags=0 uid=0 sid=0 elapsedtime=-4763540
type=2 flags=1 uid=1000 sid=7003 elapsedtime=-4763540
type=2 flags=0 uid=1000 sid=4378 elapsedtime=-12

The first entry of type 4 is used to lock the records. The other lines can be per-tty and so on. flags of 1 are for a disabled entry (for example due to sudo -k). The last line was for my uid 1000 having done a sudo command 12 seconds ago from process 4378. Since this is less than 5*60 seconds, further sudo's do not yet need a password.

Answered by meuh on November 16, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP