Compare commits
3 Commits
3867a29a10
...
3887b98a7d
Author | SHA1 | Date | |
---|---|---|---|
3887b98a7d | |||
8b45766aaa | |||
7667f49d62 |
24
apps/su.cpp
24
apps/su.cpp
@ -1,11 +1,12 @@
|
|||||||
#include <os/ArgumentParser.h>
|
#include <os/ArgumentParser.h>
|
||||||
|
#include <pwd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView id;
|
StringView name;
|
||||||
|
|
||||||
if (geteuid() != 0)
|
if (geteuid() != 0)
|
||||||
{
|
{
|
||||||
@ -14,19 +15,24 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
os::ArgumentParser parser;
|
os::ArgumentParser parser;
|
||||||
parser.add_positional_argument(id, "id"_sv, true);
|
parser.add_positional_argument(name, "name"_sv, true);
|
||||||
parser.parse(argc, argv);
|
parser.parse(argc, argv);
|
||||||
|
|
||||||
int uid = atoi(id.chars());
|
struct passwd* entry = getpwnam(name.chars());
|
||||||
|
if (!entry)
|
||||||
if (uid == 0)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Already root!\n");
|
fprintf(stderr, "su: user %s not found!\n", name.chars());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
setgid(uid);
|
if (getuid() != geteuid())
|
||||||
setuid(uid);
|
{
|
||||||
|
fprintf(stderr, "FIXME: you have to enter %s's password first!\n", name.chars());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
execl("/bin/sh", "sh", NULL);
|
setgid(entry->pw_gid);
|
||||||
|
setuid(entry->pw_uid);
|
||||||
|
|
||||||
|
execl(entry->pw_shell, entry->pw_shell, NULL);
|
||||||
}
|
}
|
||||||
|
2
initrd/etc/passwd
Normal file
2
initrd/etc/passwd
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
root:toor:0:0:Administrator:/:/bin/sh
|
||||||
|
selene:moon:1000:1000:User:/home/selene:/bin/sh
|
@ -86,4 +86,14 @@ namespace VFS
|
|||||||
|
|
||||||
return inode->mode() & S_IROTH;
|
return inode->mode() & S_IROTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_setuid(SharedPtr<Inode> inode)
|
||||||
|
{
|
||||||
|
return inode->mode() & S_ISUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_setgid(SharedPtr<Inode> inode)
|
||||||
|
{
|
||||||
|
return inode->mode() & S_ISGID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,6 +178,8 @@ namespace VFS
|
|||||||
bool can_execute(SharedPtr<Inode> inode, Credentials auth);
|
bool can_execute(SharedPtr<Inode> inode, Credentials auth);
|
||||||
bool can_read(SharedPtr<Inode> inode, Credentials auth);
|
bool can_read(SharedPtr<Inode> inode, Credentials auth);
|
||||||
bool can_write(SharedPtr<Inode> inode, Credentials auth);
|
bool can_write(SharedPtr<Inode> inode, Credentials auth);
|
||||||
|
bool is_setuid(SharedPtr<Inode> inode);
|
||||||
|
bool is_setgid(SharedPtr<Inode> inode);
|
||||||
|
|
||||||
Inode& root_inode();
|
Inode& root_inode();
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,9 @@ Result<u64> sys_execve(Registers* regs, SyscallArgs args)
|
|||||||
|
|
||||||
MMU::delete_userspace_page_directory(current->directory);
|
MMU::delete_userspace_page_directory(current->directory);
|
||||||
|
|
||||||
|
if (VFS::is_setuid(inode)) current->auth.euid = current->auth.suid = inode->uid();
|
||||||
|
if (VFS::is_setgid(inode)) current->auth.egid = current->auth.sgid = inode->gid();
|
||||||
|
|
||||||
current->name = path.chars();
|
current->name = path.chars();
|
||||||
|
|
||||||
image->apply(current);
|
image->apply(current);
|
||||||
|
@ -16,6 +16,7 @@ set(SOURCES
|
|||||||
src/dirent.cpp
|
src/dirent.cpp
|
||||||
src/setjmp.cpp
|
src/setjmp.cpp
|
||||||
src/env.cpp
|
src/env.cpp
|
||||||
|
src/pwd.cpp
|
||||||
src/sys/stat.cpp
|
src/sys/stat.cpp
|
||||||
src/sys/mman.cpp
|
src/sys/mman.cpp
|
||||||
src/sys/wait.cpp
|
src/sys/wait.cpp
|
||||||
|
43
libc/include/pwd.h
Normal file
43
libc/include/pwd.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/* pwd.h: Password file parsing. */
|
||||||
|
|
||||||
|
#ifndef _PWD_H
|
||||||
|
#define _PWD_H
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
struct passwd
|
||||||
|
{
|
||||||
|
char* pw_name;
|
||||||
|
char* pw_passwd;
|
||||||
|
uid_t pw_uid;
|
||||||
|
gid_t pw_gid;
|
||||||
|
char* pw_gecos;
|
||||||
|
char* pw_dir;
|
||||||
|
char* pw_shell;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Read the next entry from the password file. */
|
||||||
|
struct passwd* getpwent(void);
|
||||||
|
|
||||||
|
/* Find the entry with a matching username in the password file. */
|
||||||
|
struct passwd* getpwnam(const char* name);
|
||||||
|
|
||||||
|
/* Find the entry with a matching user ID in the password file. */
|
||||||
|
struct passwd* getpwuid(uid_t uid);
|
||||||
|
|
||||||
|
/* Rewind the password file. */
|
||||||
|
void setpwent(void);
|
||||||
|
|
||||||
|
/* End password file parsing. */
|
||||||
|
void endpwent(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
109
libc/src/pwd.cpp
Normal file
109
libc/src/pwd.cpp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#include <pwd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static struct passwd pwd;
|
||||||
|
static FILE* f { nullptr };
|
||||||
|
static char buf[4096];
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
struct passwd* getpwent()
|
||||||
|
{
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
f = fopen("/etc/passwd", "r");
|
||||||
|
if (!f) return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
char* rc = fgets(buf, sizeof(buf), f);
|
||||||
|
if (!rc) return nullptr;
|
||||||
|
|
||||||
|
char* name = strtok(rc, ":\n");
|
||||||
|
if (!name) continue;
|
||||||
|
|
||||||
|
char* passwd = strtok(nullptr, ":\n");
|
||||||
|
if (!passwd) continue;
|
||||||
|
|
||||||
|
char* uid = strtok(nullptr, ":\n");
|
||||||
|
if (!uid) continue;
|
||||||
|
|
||||||
|
char* gid = strtok(nullptr, ":\n");
|
||||||
|
if (!gid) continue;
|
||||||
|
|
||||||
|
char* gecos = strtok(nullptr, ":\n");
|
||||||
|
if (!gecos) continue;
|
||||||
|
|
||||||
|
char* dir = strtok(nullptr, ":\n");
|
||||||
|
if (!dir) continue;
|
||||||
|
|
||||||
|
char* shell = strtok(nullptr, ":\n");
|
||||||
|
if (!shell) continue;
|
||||||
|
|
||||||
|
pwd.pw_name = name;
|
||||||
|
pwd.pw_passwd = passwd;
|
||||||
|
pwd.pw_uid = (uid_t)strtoul(uid, NULL, 10);
|
||||||
|
pwd.pw_gid = (gid_t)strtoul(gid, NULL, 10);
|
||||||
|
pwd.pw_gecos = gecos;
|
||||||
|
pwd.pw_dir = dir;
|
||||||
|
pwd.pw_shell = shell;
|
||||||
|
|
||||||
|
return &pwd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct passwd* getpwnam(const char* name)
|
||||||
|
{
|
||||||
|
setpwent();
|
||||||
|
|
||||||
|
struct passwd* entry;
|
||||||
|
|
||||||
|
while ((entry = getpwent()))
|
||||||
|
{
|
||||||
|
if (!strcmp(entry->pw_name, name))
|
||||||
|
{
|
||||||
|
endpwent();
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endpwent();
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct passwd* getpwuid(uid_t uid)
|
||||||
|
{
|
||||||
|
setpwent();
|
||||||
|
|
||||||
|
struct passwd* entry;
|
||||||
|
|
||||||
|
while ((entry = getpwent()))
|
||||||
|
{
|
||||||
|
if (entry->pw_uid == uid)
|
||||||
|
{
|
||||||
|
endpwent();
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endpwent();
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setpwent()
|
||||||
|
{
|
||||||
|
if (f) rewind(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void endpwent()
|
||||||
|
{
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
fclose(f);
|
||||||
|
f = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user