forked from Bananymous/banan-os
Init: Use the new pwd.h api for user parsing
This commit is contained in:
parent
bba09a3cd0
commit
e341a36287
|
@ -4,82 +4,11 @@
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <pwd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct User
|
|
||||||
{
|
|
||||||
BAN::String name;
|
|
||||||
uid_t uid;
|
|
||||||
gid_t gid;
|
|
||||||
BAN::String home;
|
|
||||||
BAN::String shell;
|
|
||||||
};
|
|
||||||
|
|
||||||
BAN::Optional<id_t> parse_id(BAN::StringView value)
|
|
||||||
{
|
|
||||||
// NOTE: we only allow 10^9 uids
|
|
||||||
if (value.size() < 1 || value.size() > 9)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
id_t id { 0 };
|
|
||||||
for (char c : value)
|
|
||||||
{
|
|
||||||
if (!isdigit(c))
|
|
||||||
return {};
|
|
||||||
id = (id * 10) + (c - '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::Optional<User> parse_user(BAN::StringView line)
|
|
||||||
{
|
|
||||||
auto parts = MUST(line.split(':', true));
|
|
||||||
if (parts.size() != 7)
|
|
||||||
return {};
|
|
||||||
User user;
|
|
||||||
user.name = parts[0];
|
|
||||||
user.uid = ({ auto id = parse_id(parts[2]); if (!id.has_value()) return {}; id.value(); });
|
|
||||||
user.gid = ({ auto id = parse_id(parts[3]); if (!id.has_value()) return {}; id.value(); });
|
|
||||||
user.home = parts[5];
|
|
||||||
user.shell = parts[6];
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::Vector<User> parse_users()
|
|
||||||
{
|
|
||||||
FILE* fp = fopen("/etc/passwd", "r");
|
|
||||||
if (fp == nullptr)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "could not open /etc/passwd\n");
|
|
||||||
perror("fopen");
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::Vector<User> users;
|
|
||||||
|
|
||||||
char buffer[1024];
|
|
||||||
while (fgets(buffer, sizeof(buffer), fp))
|
|
||||||
{
|
|
||||||
*strchrnul(buffer, '\n') = '\0';
|
|
||||||
auto user = parse_user(buffer);
|
|
||||||
if (user.has_value())
|
|
||||||
MUST(users.push_back(user.release_value()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ferror(fp))
|
|
||||||
{
|
|
||||||
perror("fread");
|
|
||||||
fclose(fp);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
void initialize_stdio()
|
void initialize_stdio()
|
||||||
{
|
{
|
||||||
char tty[L_ctermid];
|
char tty[L_ctermid];
|
||||||
|
@ -97,18 +26,9 @@ int main()
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
auto users = parse_users();
|
|
||||||
|
|
||||||
char name_buffer[128];
|
char name_buffer[128];
|
||||||
BAN::StringView name;
|
|
||||||
|
|
||||||
if (first)
|
while (!first)
|
||||||
{
|
|
||||||
name = "user"sv;
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (name.empty())
|
|
||||||
{
|
{
|
||||||
printf("username: ");
|
printf("username: ");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -123,47 +43,51 @@ int main()
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (nread == 1)
|
if (nread <= 1 || name_buffer[nread - 1] != '\n')
|
||||||
continue;
|
continue;
|
||||||
|
name_buffer[nread - 1] = '\0';
|
||||||
name = BAN::StringView(name_buffer, nread - 1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const User& user : users)
|
if (first)
|
||||||
{
|
{
|
||||||
if (user.name == name)
|
strcpy(name_buffer, "user");
|
||||||
{
|
first = false;
|
||||||
pid_t pid = fork();
|
|
||||||
if (pid == 0)
|
|
||||||
{
|
|
||||||
printf("Welcome back %s!\n", user.name.data());
|
|
||||||
|
|
||||||
if (setgid(user.gid) == -1)
|
|
||||||
perror("setgid");
|
|
||||||
if (setuid(user.uid) == -1)
|
|
||||||
perror("setuid");
|
|
||||||
|
|
||||||
setenv("HOME", user.home.data(), 1);
|
|
||||||
chdir(user.home.data());
|
|
||||||
|
|
||||||
execl(user.shell.data(), user.shell.data(), nullptr);
|
|
||||||
perror("execl");
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid == -1)
|
|
||||||
{
|
|
||||||
perror("fork");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int status;
|
|
||||||
waitpid(pid, &status, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto* pwd = getpwnam(name_buffer);
|
||||||
|
if (pwd == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
printf("Welcome back %s!\n", pwd->pw_name);
|
||||||
|
|
||||||
|
if (setgid(pwd->pw_gid) == -1)
|
||||||
|
perror("setgid");
|
||||||
|
if (setuid(pwd->pw_uid) == -1)
|
||||||
|
perror("setuid");
|
||||||
|
|
||||||
|
setenv("HOME", pwd->pw_dir, 1);
|
||||||
|
chdir(pwd->pw_dir);
|
||||||
|
|
||||||
|
execl(pwd->pw_shell, pwd->pw_shell, nullptr);
|
||||||
|
perror("execl");
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
endpwent();
|
||||||
|
|
||||||
|
if (pid == -1)
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int status;
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue