implemented config persist
This commit is contained in:
parent
391353cea6
commit
f489885e3e
76
us.c
76
us.c
@ -39,6 +39,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if !defined(_XOPEN_CRYPT) || _XOPEN_CRYPT == -1
|
||||
#include <crypt.h>
|
||||
@ -55,6 +57,8 @@
|
||||
#define FLAG_PERSIST 0x1
|
||||
#define FLAG_NOPASS 0x2
|
||||
#define FLAG_NOLOG 0x4
|
||||
#define SESSION_FILE_DIR "/var/run"
|
||||
#define SESSION_TIMEOUT (60*5)
|
||||
|
||||
struct env_elem {
|
||||
char *name;
|
||||
@ -84,7 +88,7 @@ void *erealloc(void *, size_t);
|
||||
static void usage(void);
|
||||
static void die(const char *, ...);
|
||||
static int perm_set(struct passwd *, struct group *);
|
||||
static int authenticate(uid_t, char);
|
||||
static int authenticate(uid_t, int, int);
|
||||
static struct passwd* user_to_passwd(const char *, struct user_info *);
|
||||
static struct group* group_to_grp(const char *, struct user_info *);
|
||||
static int get_config(struct config **, int *);
|
||||
@ -159,6 +163,8 @@ int main(int argc, char *argv[])
|
||||
/* From now on most actions require root */
|
||||
if (setuid(0) == -1)
|
||||
die("setuid:");
|
||||
if (setgid(0) == -1)
|
||||
die("setgid:");
|
||||
|
||||
/* get info from the config file and check if the action we want to
|
||||
* do is permitted */
|
||||
@ -236,7 +242,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* Authenticate, we will be root from now on */
|
||||
if (!(conf_flags & FLAG_NOPASS))
|
||||
if (authenticate(my_pw->pw_uid, askpass))
|
||||
if (authenticate(my_pw->pw_uid, askpass, conf_flags & FLAG_PERSIST))
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
/* Get target user's shell */
|
||||
@ -394,9 +400,57 @@ static int perm_set(struct passwd *pw, struct group *gr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int authenticate(uid_t uid, char ask)
|
||||
static int authenticate(uid_t uid, int ask, int persist)
|
||||
{
|
||||
// TODO: implement u2f compat
|
||||
// TODO: check root access, maybe
|
||||
/* try to check if a valid saved session exists */
|
||||
char tmp_file[512] = {0};
|
||||
if (persist) {
|
||||
pid_t sid = getsid(0);
|
||||
if (sid == (pid_t)-1)
|
||||
die("getsid:");
|
||||
if (snprintf(tmp_file, 512, SESSION_FILE_DIR "/us.%d", sid) >= 512)
|
||||
die("snprintf: output truncated");
|
||||
int session_file = open(tmp_file, O_RDONLY | O_CLOEXEC);
|
||||
int valid_session = 1;
|
||||
struct timespec now_t[2] = {0}, old_t[2] = {0};
|
||||
if (session_file != -1) {
|
||||
struct stat st;
|
||||
if (fstat(session_file, &st) == -1) {
|
||||
valid_session = 0;
|
||||
} else if (st.st_uid != 0 || st.st_gid != 0) {
|
||||
valid_session = 0;
|
||||
} else if (!S_ISREG(st.st_mode)) {
|
||||
valid_session = 0;
|
||||
} else if (st.st_mode & S_IRWXO ||
|
||||
st.st_mode & S_IROTH ||
|
||||
st.st_mode & S_IWOTH || st.st_mode & S_IXOTH) {
|
||||
valid_session = 0;
|
||||
} else {
|
||||
int r = read(session_file, old_t, sizeof(struct timespec)*2);
|
||||
if (r != sizeof(struct timespec)*2)
|
||||
valid_session = 0;
|
||||
close(session_file);
|
||||
}
|
||||
} else {
|
||||
valid_session = 0;
|
||||
}
|
||||
|
||||
if (valid_session && session_file != -1) {
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &(now_t[0])) == -1)
|
||||
die("clock_gettime:");
|
||||
if (clock_gettime(CLOCK_REALTIME, &(now_t[1])) == -1)
|
||||
die("clock_gettime:");
|
||||
if (now_t[0].tv_sec <= old_t[0].tv_sec ||
|
||||
old_t[0].tv_sec < now_t[0].tv_sec - SESSION_TIMEOUT ||
|
||||
now_t[1].tv_sec <= old_t[1].tv_sec ||
|
||||
old_t[1].tv_sec < now_t[1].tv_sec - SESSION_TIMEOUT)
|
||||
valid_session = 0;
|
||||
}
|
||||
if (valid_session)
|
||||
return 0;
|
||||
}
|
||||
/* get the encrypted password */
|
||||
struct passwd *pw = getpwuid(uid);
|
||||
char *hash_p, hash[MAX_HASH];
|
||||
@ -511,6 +565,22 @@ static int authenticate(uid_t uid, char ask)
|
||||
return -1;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if (persist) {
|
||||
if (!tmp_file[0])
|
||||
return 0;
|
||||
int session_file = creat(tmp_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
if (session_file == -1)
|
||||
return 0;
|
||||
chown(tmp_file, 0, 0);
|
||||
struct timespec t[2] = {0};
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &(t[0])) == -1)
|
||||
die("clock_gettime:");
|
||||
if (clock_gettime(CLOCK_REALTIME, &(t[1])) == -1)
|
||||
die("clock_gettime:");
|
||||
write(session_file, t, sizeof(struct timespec)*2);
|
||||
close(session_file);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user