added su
This commit is contained in:
parent
94a0c8c60c
commit
021447a556
|
@ -8,6 +8,10 @@
|
|||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef ARG_MAX
|
||||
#define ARG_MAX 10000
|
||||
#endif
|
||||
|
||||
int args;
|
||||
char *cmd[ARG_MAX + 1];
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC -lcrypt
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC -lcrypt
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC -lcrypt
|
|
@ -0,0 +1,146 @@
|
|||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
#include "pw_check.h"
|
||||
#include "unused.h"
|
||||
|
||||
#define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL)
|
||||
|
||||
char *c_flag = NULL;
|
||||
char *s_flag = NULL;
|
||||
char p_flag;
|
||||
|
||||
int hide_input(int fd, int flag) {
|
||||
struct termios term;
|
||||
if (tcgetattr(fd, &term) < 0)
|
||||
return 1;
|
||||
|
||||
if (flag)
|
||||
term.c_lflag &= ~ECHOFLAGS;
|
||||
|
||||
else
|
||||
term.c_lflag |= ECHOFLAGS;
|
||||
|
||||
if (tcsetattr(fd, TCSAFLUSH, &term) < 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void su(const struct passwd *pw) {
|
||||
char *shell = s_flag;
|
||||
if (s_flag == NULL)
|
||||
shell = (pw->pw_shell[0] == '\0') ? "/bin/sh" : pw->pw_shell;
|
||||
|
||||
if (!p_flag) {
|
||||
setenv("HOME", pw->pw_dir, 1);
|
||||
setenv("SHELL", shell, 1);
|
||||
setenv("USER", pw->pw_name, 1);
|
||||
setenv("LOGNAME", pw->pw_name, 1);
|
||||
setenv("PATH", "/bin", 1);
|
||||
}
|
||||
|
||||
if (c_flag)
|
||||
execlp(shell, shell, "-c", c_flag, NULL);
|
||||
|
||||
else
|
||||
execlp(shell, shell, "-l", NULL);
|
||||
}
|
||||
|
||||
int password(const struct passwd *pw) {
|
||||
static char psswd[512];
|
||||
|
||||
printf("Password: ");
|
||||
fflush(stdout);
|
||||
|
||||
if (hide_input(STDIN_FILENO, 1)) {
|
||||
fprintf(stderr, "su: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
off_t ret = 0;
|
||||
if ((ret = read(STDIN_FILENO, psswd, sizeof(psswd))) <= 0) {
|
||||
fprintf(stderr, "su: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
psswd[ret - 1] = '\0';
|
||||
if (pw_check("su", pw, psswd)) {
|
||||
memset(psswd, '\0', sizeof(psswd));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
memset(psswd, '\0', sizeof(psswd));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void endwin(int sig) {
|
||||
UNUSED(sig);
|
||||
|
||||
hide_input(STDIN_FILENO, 0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "c:s:p")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
c_flag = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
s_flag = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
p_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("su [cps] [user Default: root]\n\t-c CMD Command to pass to \'sh -c\'\n\t-s SHELL Shell to use instead of user's default\n\t-p Do not set new env\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
char *user = "root";
|
||||
if (argv[0])
|
||||
user = argv[0];
|
||||
|
||||
struct passwd *pw = getpwnam(user);
|
||||
if (!pw) {
|
||||
fprintf(stderr, "su: Incorrent username\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
signal(SIGINT, endwin);
|
||||
|
||||
int ret = password(pw);
|
||||
hide_input(STDIN_FILENO, 0);
|
||||
if (ret)
|
||||
return 1;
|
||||
|
||||
/* Start */
|
||||
if (setgid(pw->pw_gid) < 0) {
|
||||
fprintf(stderr, "su: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (setuid(pw->pw_uid) < 0) {
|
||||
fprintf(stderr, "su: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
su(pw);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue