Commit 6b6f9a5c authored by Jaromil's avatar Jaromil

improvements to readibility and usage

Added use of getpwuid to resolve usernames found /etc/passwd
bumped version to 0.2 and improved -l, now also showing flags
error messages go to stderr, all others go to stdout.
parent 71575424
CC?=gcc
LDD?=ld
DESTDIR?=
PREFIX?=/usr
VERSION=0.1
PREFIX?=/usr/local
VERSION=0.2
USER=root
GROUP=root
CFLAGS?=-O2 -Wall
CFLAGS?=-fPIC -fPIE -Wall
LDFLAGS?=-fPIC -fPIE -pie
CFLAGS+=-Os -O2
all: config.h sup
......@@ -12,7 +17,7 @@ config.h:
cp config.def.h config.h
sup.o: config.h sup.c
${CC} ${CFLAGS} -c sup.c
${CC} ${CFLAGS} -c sup.c -DVERSION=${VERSION}
sup: sup.o
${CC} ${LDFLAGS} sup.o -o sup
......
......@@ -10,11 +10,13 @@
#define ENFORCE 1
static struct rule_t rules[] = {
{ USER, GROUP, "whoami", "/usr/bin/whoami" },
{ USER, GROUP, "ifconfig", "/sbin/ifconfig" },
{ USER, GROUP, "ls", "/bin/ls" },
{ USER, GROUP, "wifi", "/root/wifi.sh" },
{ USER, GROUP, "cp", "*"}, // allow to run this program in PATH
{ USER, GROUP, "*", "*"}, // allow to run any program in PATH
{ 0 },
// allow user to run these programs specifying full PATH
{ USER, GROUP, "whoami", "/usr/bin/whoami" },
{ USER, GROUP, "ifconfig", "/sbin/ifconfig" },
{ USER, GROUP, "ls", "/bin/ls" },
{ USER, GROUP, "wifi", "/root/wifi.sh" },
{ USER, GROUP, "id", "*" }, // allow to run this program when found in PATH */
/* { USER, GROUP, "*", "*"}, // allow to run any program found in PATH */
{ 0 },
};
......@@ -7,8 +7,12 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#define HELP "sup [-hlv] [cmd ..]"
#define VERSION "sup 0.1 pancake <nopcode.org> copyleft 2011"
#define MAXCMD 512
struct rule_t {
int uid;
......@@ -19,7 +23,7 @@ struct rule_t {
#include "config.h"
static int die(int ret, const char *org, const char *str) {
static int error(int ret, const char *org, const char *str) {
fprintf (stderr, "%s%s%s\n", org?org:"", org?": ":"", str);
return ret;
}
......@@ -42,31 +46,53 @@ static char *getpath(const char *str) {
return NULL;
}
#define MAXCMD 512
int main(int argc, char **argv) {
static char cmd[MAXCMD];
struct passwd *pw;
int i, uid, gid, ret;
if (argc < 2 || !strcmp (argv[1], "-h"))
return die (1, NULL, HELP);
if (argc < 2 || !strncmp (argv[1], "-h", 2)) {
fprintf(stdout, "%s\n", HELP);
return (0);
}
if (!strcmp (argv[1], "-v"))
return die (1, NULL, VERSION);
if (!strncmp (argv[1], "-v", 2)) {
fprintf(stdout, "sup %.1f - small and beautiful superuser tool\n", VERSION);
// "sup 0.1 pancake <nopcode.org> copyleft 2011"
return (0);
}
if (!strcmp (argv[1], "-l")) {
for (i = 0; rules[i].cmd != NULL; i++)
printf ("%d %d %10s %s\n", rules[i].uid, rules[i].gid,
fprintf(stdout,"List of compiled in authorizations:\n\n");
fprintf(stdout,"User\tUID\tGID\t%10s%25s\n",
"Command","Forced PATH");
for (i = 0; rules[i].cmd != NULL; i++) {
pw = getpwuid( rules[i].uid );
fprintf (stdout, "%s\t%d\t%d%16s%25s\n",
pw->pw_name, rules[i].uid,
rules[i].gid,
rules[i].cmd, rules[i].path);
}
fprintf(stdout,"\nFlags: %s %s %s\n",
ENFORCE?"ENFORCE":"",
strlen(CHROOT)?"CHROOT":"",
strlen(CHRDIR)?"CHRDIR":"");
return 0;
}
uid = getuid ();
gid = getgid ();
// get the username string from /etc/passwd
pw = getpwuid( uid );
// copy the execv argument locally
snprintf(cmd,MAXCMD,"%s",argv[1]);
// fprintf(stderr,"execv: %s\n",cmd);
fprintf(stderr,"sup %s called by %s(%d) gid(%d)\n",
cmd, pw->pw_name, uid, gid);
for (i = 0; rules[i].cmd != NULL; i++) {
if (*rules[i].cmd=='*' || !strcmp (argv[1], rules[i].cmd)) {
#if ENFORCE
......@@ -75,34 +101,34 @@ int main(int argc, char **argv) {
if (*argv[1]=='.' || *argv[1]=='/')
snprintf(cmd,MAXCMD,"%s",argv[1]);
else if (snprintf(cmd,MAXCMD,"%s",getpath(argv[1]))<0)
return die (1, "execv", "cannot find program");
return error (1, "execv", "cannot find program");
} else snprintf(cmd,MAXCMD,"%s",rules[i].path);
if (lstat (cmd, &st) == -1)
return die (1, "lstat", "cannot stat program");
/* if (st.st_mode & 0222) */
/* return die (1, "stat", "cannot run writable binaries."); */
return error (1, "lstat", "cannot stat program");
if (st.st_mode & 0022)
return error (1, "stat", "cannot run binaries others can write.");
#endif
if (uid != SETUID && rules[i].uid != -1 && rules[i].uid != uid)
return die (1, "urule", "user does not match");
return error (1, "urule", "user does not match");
if (gid != SETGID && rules[i].gid != -1 && rules[i].gid != gid)
return die (1, "grule", "group id does not match");
return error (1, "grule", "group id does not match");
if (setuid (SETUID) == -1 || setgid (SETGID) == -1 ||
seteuid (SETUID) == -1 || setegid (SETGID) == -1)
return die (1, "set[e][ug]id", strerror (errno));
return error (1, "set[e][ug]id", strerror (errno));
#ifdef CHROOT
if (*CHROOT)
if (chdir (CHROOT) == -1 || chroot (".") == -1)
return die (1, "chroot", strerror (errno));
return error (1, "chroot", strerror (errno));
if (*CHRDIR)
if (chdir (CHRDIR) == -1)
return die (1, "chdir", strerror (errno));
return error (1, "chdir", strerror (errno));
#endif
ret = execv (cmd, &argv[1]);
return die (ret, "execv", strerror (errno));
return error (ret, "execv", strerror (errno));
}
}
return die (1, NULL, "Sorry");
return error (1, NULL, "Sorry");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment