Compare commits
4 Commits
e5a3bbcbbc
...
66c2896652
Author | SHA1 | Date | |
---|---|---|---|
66c2896652 | |||
3e5957f9fc | |||
fee33e7a14 | |||
76eb8cd129 |
63
apps/su.cpp
63
apps/su.cpp
@ -1,16 +1,63 @@
|
|||||||
|
#include <bits/termios.h>
|
||||||
#include <os/ArgumentParser.h>
|
#include <os/ArgumentParser.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static struct termios orig;
|
||||||
|
|
||||||
|
void restore_terminal()
|
||||||
|
{
|
||||||
|
ioctl(fileno(stdin), TCSETS, &orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getpass()
|
||||||
|
{
|
||||||
|
fputs("Password: ", stdout);
|
||||||
|
|
||||||
|
if (ioctl(fileno(stdin), TCGETS, &orig) < 0)
|
||||||
|
{
|
||||||
|
perror("ioctl(TCGETS)");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
atexit(restore_terminal);
|
||||||
|
|
||||||
|
struct termios tc = orig;
|
||||||
|
tc.c_lflag &= ~ECHO;
|
||||||
|
if (ioctl(fileno(stdin), TCSETS, &tc) < 0)
|
||||||
|
{
|
||||||
|
perror("ioctl(TCSETS)");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char buf[1024];
|
||||||
|
char* rc = fgets(buf, sizeof(buf), stdin);
|
||||||
|
|
||||||
|
restore_terminal();
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
perror("fgets");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* newline = strrchr(rc, '\n');
|
||||||
|
if (newline) *newline = 0;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView name;
|
StringView name;
|
||||||
|
|
||||||
if (geteuid() != 0)
|
if (geteuid() != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "su must be run as root!\n");
|
fprintf(stderr, "su must be setuid root!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,10 +72,18 @@ int main(int argc, char** argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getuid() != geteuid())
|
if (getuid() != geteuid() && *entry->pw_passwd)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "FIXME: you have to enter %s's password first!\n", name.chars());
|
char* pass = getpass();
|
||||||
return 1;
|
if (!pass) return 1;
|
||||||
|
|
||||||
|
if (strcmp(pass, entry->pw_passwd))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Wrong password!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(pass, 0, strlen(pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
setgid(entry->pw_gid);
|
setgid(entry->pw_gid);
|
||||||
|
@ -27,6 +27,11 @@ namespace VFS
|
|||||||
class Inode
|
class Inode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual Result<u64> ioctl(int, void*)
|
||||||
|
{
|
||||||
|
return err(ENOTTY);
|
||||||
|
}
|
||||||
|
|
||||||
// Directory-specific methods
|
// Directory-specific methods
|
||||||
virtual Result<SharedPtr<Inode>> find(const char* name) const = 0;
|
virtual Result<SharedPtr<Inode>> find(const char* name) const = 0;
|
||||||
|
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
#include "fs/devices/ConsoleDevice.h"
|
#include "fs/devices/ConsoleDevice.h"
|
||||||
#include "arch/Keyboard.h"
|
#include "arch/Keyboard.h"
|
||||||
|
#include "memory/MemoryManager.h"
|
||||||
#include "video/TextConsole.h"
|
#include "video/TextConsole.h"
|
||||||
|
#include <bits/termios.h>
|
||||||
#include <luna/Buffer.h>
|
#include <luna/Buffer.h>
|
||||||
#include <luna/CString.h>
|
#include <luna/CString.h>
|
||||||
#include <luna/Vector.h>
|
#include <luna/Vector.h>
|
||||||
|
|
||||||
static Buffer g_console_input;
|
static Buffer g_console_input;
|
||||||
static bool g_eof { false };
|
static bool g_eof { false };
|
||||||
|
static bool g_echo { true };
|
||||||
|
|
||||||
Result<SharedPtr<Device>> ConsoleDevice::create()
|
Result<SharedPtr<Device>> ConsoleDevice::create()
|
||||||
{
|
{
|
||||||
@ -45,7 +48,10 @@ void ConsoleDevice::did_press_key(char key)
|
|||||||
{
|
{
|
||||||
if (key == '\b')
|
if (key == '\b')
|
||||||
{
|
{
|
||||||
if (g_temp_input.try_pop().has_value()) TextConsole::putwchar(L'\b');
|
if (g_temp_input.try_pop().has_value())
|
||||||
|
{
|
||||||
|
if (g_echo) TextConsole::putwchar(L'\b');
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -65,5 +71,32 @@ void ConsoleDevice::did_press_key(char key)
|
|||||||
g_temp_input.clear();
|
g_temp_input.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!g_echo) return;
|
||||||
TextConsole::putchar(key);
|
TextConsole::putchar(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<u64> ConsoleDevice::ioctl(int request, void* arg)
|
||||||
|
{
|
||||||
|
switch (request)
|
||||||
|
{
|
||||||
|
case TCGETS: {
|
||||||
|
struct termios tc
|
||||||
|
{
|
||||||
|
.c_lflag = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
if (g_echo) tc.c_lflag |= ECHO;
|
||||||
|
return MemoryManager::copy_to_user_typed((struct termios*)arg, &tc) ? 0 : err(EFAULT);
|
||||||
|
}
|
||||||
|
case TCSETS: {
|
||||||
|
struct termios tc;
|
||||||
|
if (!MemoryManager::copy_from_user_typed((const struct termios*)arg, &tc)) return err(EFAULT);
|
||||||
|
if (tc.c_lflag & ECHO) g_echo = true;
|
||||||
|
else
|
||||||
|
g_echo = false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
default: return err(EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -15,5 +15,7 @@ class ConsoleDevice : public Device
|
|||||||
|
|
||||||
bool blocking() const override;
|
bool blocking() const override;
|
||||||
|
|
||||||
|
Result<u64> ioctl(int request, void* arg) override;
|
||||||
|
|
||||||
virtual ~ConsoleDevice() = default;
|
virtual ~ConsoleDevice() = default;
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,11 @@ class Device
|
|||||||
|
|
||||||
virtual Result<usize> write(const u8* buf, usize offset, usize length) = 0;
|
virtual Result<usize> write(const u8* buf, usize offset, usize length) = 0;
|
||||||
|
|
||||||
|
virtual Result<u64> ioctl(int, void*)
|
||||||
|
{
|
||||||
|
return err(ENOTTY);
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool blocking() const = 0;
|
virtual bool blocking() const = 0;
|
||||||
|
|
||||||
virtual ~Device() = default;
|
virtual ~Device() = default;
|
||||||
|
@ -153,6 +153,11 @@ namespace TmpFS
|
|||||||
return err(EINVAL);
|
return err(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<u64> ioctl(int request, void* arg) override
|
||||||
|
{
|
||||||
|
return m_device->ioctl(request, arg);
|
||||||
|
}
|
||||||
|
|
||||||
bool blocking() const override
|
bool blocking() const override
|
||||||
{
|
{
|
||||||
return m_device->blocking();
|
return m_device->blocking();
|
||||||
|
@ -135,3 +135,15 @@ Result<u64> sys_fcntl(Registers*, SyscallArgs args)
|
|||||||
default: return err(EINVAL);
|
default: return err(EINVAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<u64> sys_ioctl(Registers*, SyscallArgs args)
|
||||||
|
{
|
||||||
|
int fd = (int)args[0];
|
||||||
|
int request = (int)args[1];
|
||||||
|
void* arg = (void*)args[2];
|
||||||
|
|
||||||
|
Thread* current = Scheduler::current();
|
||||||
|
auto& descriptor = *TRY(current->resolve_fd(fd));
|
||||||
|
|
||||||
|
return descriptor.inode->ioctl(request, arg);
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ set(SOURCES
|
|||||||
src/sys/stat.cpp
|
src/sys/stat.cpp
|
||||||
src/sys/mman.cpp
|
src/sys/mman.cpp
|
||||||
src/sys/wait.cpp
|
src/sys/wait.cpp
|
||||||
|
src/sys/ioctl.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(${LUNA_ARCH} STREQUAL "x86_64")
|
if(${LUNA_ARCH} STREQUAL "x86_64")
|
||||||
|
21
libc/include/bits/termios.h
Normal file
21
libc/include/bits/termios.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* bits/termios.h: Terminal control definitions. */
|
||||||
|
|
||||||
|
#ifndef _BITS_TERMIOS_H
|
||||||
|
#define _BITS_TERMIOS_H
|
||||||
|
|
||||||
|
typedef long tcflag_t;
|
||||||
|
|
||||||
|
// VERY incomplete termios structure.
|
||||||
|
struct termios
|
||||||
|
{
|
||||||
|
tcflag_t c_lflag;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Values for c_lflag.
|
||||||
|
#define ECHO 1
|
||||||
|
|
||||||
|
// termios ioctl() requests.
|
||||||
|
#define TCGETS 0
|
||||||
|
#define TCSETS 1
|
||||||
|
|
||||||
|
#endif
|
18
libc/include/sys/ioctl.h
Normal file
18
libc/include/sys/ioctl.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/* sys/ioctl.h: IO device control. */
|
||||||
|
|
||||||
|
#ifndef _SYS_IOCTL_H
|
||||||
|
#define _SYS_IOCTL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Perform an IO control operation on a device. */
|
||||||
|
int ioctl(int fd, int request, ...);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
22
libc/src/sys/ioctl.cpp
Normal file
22
libc/src/sys/ioctl.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <bits/errno-return.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
int ioctl(int fd, int request, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, request);
|
||||||
|
|
||||||
|
void* arg = va_arg(ap, void*);
|
||||||
|
|
||||||
|
long rc = syscall(SYS_ioctl, fd, request, arg);
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
__errno_return(rc, int);
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,8 @@
|
|||||||
#define enumerate_syscalls(_e) \
|
#define enumerate_syscalls(_e) \
|
||||||
_e(exit) _e(clock_gettime) _e(mmap) _e(munmap) _e(usleep) _e(open) _e(close) _e(read) _e(getpid) _e(write) \
|
_e(exit) _e(clock_gettime) _e(mmap) _e(munmap) _e(usleep) _e(open) _e(close) _e(read) _e(getpid) _e(write) \
|
||||||
_e(lseek) _e(mkdir) _e(execve) _e(mknod) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) \
|
_e(lseek) _e(mkdir) _e(execve) _e(mknod) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) \
|
||||||
_e(geteuid) _e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(chmod) _e(chown)
|
_e(geteuid) _e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(chmod) _e(chown) \
|
||||||
|
_e(ioctl)
|
||||||
|
|
||||||
enum Syscalls
|
enum Syscalls
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user