Compare commits

..

No commits in common. "33ed6e5c17e332e498813bff180eb98d6e595758" and "32e09d34178fe212053612c69f689e4b6745df00" have entirely different histories.

4 changed files with 20 additions and 49 deletions

View File

@ -53,6 +53,8 @@ int main()
show_motd(); show_motd();
msleep(200);
pid_t child = fork(); pid_t child = fork();
if (child < 0) if (child < 0)
{ {

View File

@ -39,24 +39,6 @@ static void strip_newline(char* str)
if (str[len - 1] == '\n') str[len - 1] = 0; if (str[len - 1] == '\n') str[len - 1] = 0;
} }
static char* collect_password()
{
static char buf[BUFSIZ];
printf("Password: ");
fgets(buf, BUFSIZ, stdin);
strip_newline(buf);
putchar('\n');
char* copy = strdup(
buf); // The password only stays in a caller-controlled heap-allocated buffer, where it can be freed at will.
memset(buf, 0, BUFSIZ);
return copy;
}
static void login_as(struct passwd* user) static void login_as(struct passwd* user)
{ {
pid_t child = fork(); pid_t child = fork();
@ -92,19 +74,18 @@ static int login()
printf("Unknown user %s\n", username); printf("Unknown user %s\n", username);
return 0; return 0;
} }
char* password = collect_password(); printf("Password: ");
putchar('\n'); char password[BUFSIZ];
fgets(password, BUFSIZ, stdin);
strip_newline(password);
puts("\n");
if (strcmp(user->pw_passwd, password) == 0) if (strcmp(user->pw_passwd, password) == 0)
{ {
free(password);
login_as(user); login_as(user);
puts("logout\n"); puts("logout\n");
} }
else else
{
free(password);
puts("Invalid password.\n"); puts("Invalid password.\n");
}
return 0; return 0;
} }

View File

@ -87,7 +87,6 @@ void show_prompt()
username = "??"; username = "??";
} }
else { username = user->pw_name; } else { username = user->pw_name; }
atexit(endpwent);
} }
if (WEXITSTATUS(status)) { printf("%d [%s]> ", WEXITSTATUS(status), username); } if (WEXITSTATUS(status)) { printf("%d [%s]> ", WEXITSTATUS(status), username); }
else else

View File

@ -19,26 +19,13 @@ void strip_newline(char* str)
if (str[len - 1] == '\n') str[len - 1] = 0; if (str[len - 1] == '\n') str[len - 1] = 0;
} }
static const char* collect_password()
{
static char buf[BUFSIZ];
printf("Password: ");
fgets(buf, BUFSIZ, stdin);
strip_newline(buf);
putchar('\n');
return buf;
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
const char* username; if (argc == 1)
{
if (argc == 1) username = "root"; fprintf(stderr, "Usage: %s [username] [command | login shell]\n", argv[0]);
else return EXIT_FAILURE;
username = argv[1]; }
if (getuid() != 0) if (getuid() != 0)
{ {
@ -46,22 +33,24 @@ int main(int argc, char** argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
struct passwd* user = getpwnam(username); struct passwd* user = getpwnam(argv[1]);
endpwent();
if (!user) if (!user)
{ {
if (errno) perror("getpwnam"); if (errno) perror("getpwnam");
else else
fprintf(stderr, "Unknown user %s\n", username); fprintf(stderr, "Unknown user %s\n", argv[1]);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (getuid() != geteuid()) // we were started from a non-root user if (getuid() != geteuid()) // we were started from a non-root user
{ {
const char* pw = collect_password(); printf("Password: ");
if (strcmp(pw, user->pw_passwd) != 0) char buf[BUFSIZ];
fgets(buf, BUFSIZ, stdin);
strip_newline(buf);
putchar('\n');
if (strcmp(buf, user->pw_passwd) != 0)
{ {
fprintf(stderr, "Invalid password\n"); fprintf(stderr, "Invalid password\n");
return EXIT_FAILURE; return EXIT_FAILURE;