Compare commits

..

No commits in common. "5aba1c5f1539cd4b4ed3f97ad855b46722586746" and "b8296eb92d0e970be64f945061e722befce3ad63" have entirely different histories.

9 changed files with 8 additions and 291 deletions

View File

@ -17,7 +17,6 @@ build: $(REAL_APPS)
install: $(REAL_APPS) install: $(REAL_APPS)
@mkdir -p $(LUNA_ROOT)/initrd/bin @mkdir -p $(LUNA_ROOT)/initrd/bin
cp $(REAL_APPS) $(LUNA_ROOT)/initrd/bin cp $(REAL_APPS) $(LUNA_ROOT)/initrd/bin
@chmod a+s $(LUNA_ROOT)/initrd/bin/su
clean: clean:
rm -f $(APPS_BIN)/* rm -f $(APPS_BIN)/*

View File

@ -1,6 +1,5 @@
#include <errno.h> #include <errno.h>
#include <luna/pstat.h> #include <luna/pstat.h>
#include <pwd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
@ -18,9 +17,7 @@ pid_t get_current_max_threads()
void display_process(struct pstat* pstatbuf) void display_process(struct pstat* pstatbuf)
{ {
struct passwd* pwd = getpwuid(pstatbuf->pt_uid); printf("%d %d %ld %ld %s %s (%ld ms)\n", pstatbuf->pt_uid, pstatbuf->pt_gid, pstatbuf->pt_pid, pstatbuf->pt_ppid,
if (!pwd && errno) perror("getpwuid");
printf("%s %ld %ld %s %s (%ld ms)\n", pwd ? pwd->pw_name : "???", pstatbuf->pt_pid, pstatbuf->pt_ppid,
pstatbuf->pt_name, pstatname(pstatbuf), pstatbuf->pt_time); pstatbuf->pt_name, pstatname(pstatbuf), pstatbuf->pt_time);
} }
@ -44,5 +41,4 @@ int main()
{ {
if (try_pstat(pid, &pst)) { display_process(&pst); } if (try_pstat(pid, &pst)) { display_process(&pst); }
} }
endpwent();
} }

View File

@ -1,10 +1,9 @@
#include <errno.h>
#include <pwd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
char* default_argv[] = {"/bin/sh", NULL};
void run_program(char** argv) void run_program(char** argv)
{ {
execv(argv[0], argv); execv(argv[0], argv);
@ -13,64 +12,26 @@ void run_program(char** argv)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
void strip_newline(char* str)
{
size_t len = strlen(str);
if (str[len - 1] == '\n') str[len - 1] = 0;
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
if (argc == 1) if (argc == 1)
{ {
fprintf(stderr, "Usage: %s [username] [command | login shell]\n", argv[0]); fprintf(stderr, "Usage: %s [uid] [command | sh]\n", argv[0]);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (getuid() != 0) if (setuid(atoi(argv[1])) < 0)
{
fprintf(stderr, "%s must be setuid root", argv[0]);
return EXIT_FAILURE;
}
struct passwd* user = getpwnam(argv[1]);
if (!user)
{
if (errno) perror("getpwnam");
else
fprintf(stderr, "Unknown user %s\n", argv[1]);
return EXIT_FAILURE;
}
if (getuid() != geteuid()) // we were started from a non-root user
{
printf("Password: ");
char buf[BUFSIZ];
fgets(buf, BUFSIZ, stdin);
strip_newline(buf);
putchar('\n');
if (strcmp(buf, user->pw_passwd) != 0)
{
fprintf(stderr, "Invalid password\n");
return EXIT_FAILURE;
}
}
if (setuid(user->pw_uid) < 0)
{ {
perror("setuid"); perror("setuid");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (setgid(user->pw_gid) < 0) if (setgid(atoi(argv[1])) < 0)
{ {
perror("setgid"); perror("setgid");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
char* default_argv[] = {user->pw_shell, NULL};
if (argc == 2) run_program(default_argv); if (argc == 2) run_program(default_argv);
else else
run_program(argv + 2); run_program(argv + 2);

View File

@ -1,2 +0,0 @@
root:secure:0:0:Administrator:/:/bin/sh
selene:moon:1:1:Default User:/:/bin/sh

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <sys/types.h>
#define TAR_MAGIC "ustar" #define TAR_MAGIC "ustar"
#define TAR_BLOCKSIZE 512 #define TAR_BLOCKSIZE 512
@ -34,7 +33,6 @@ namespace InitRD
uint64_t size; uint64_t size;
uint64_t size_in_blocks; uint64_t size_in_blocks;
void* addr; void* addr;
mode_t mode;
}; };
uint64_t get_total_blocks(); uint64_t get_total_blocks();

View File

@ -62,13 +62,6 @@ InitRD::File InitRD::get_file(TarHeader* header)
} }
result.addr = (void*)((uint64_t)header + TAR_BLOCKSIZE); result.addr = (void*)((uint64_t)header + TAR_BLOCKSIZE);
result.size_in_blocks = Utilities::get_blocks_from_size(TAR_BLOCKSIZE, result.size); result.size_in_blocks = Utilities::get_blocks_from_size(TAR_BLOCKSIZE, result.size);
result.mode = 0;
multiplier = 1;
for (int i = 6; i >= 0; i--)
{
result.mode += (mode_t)(multiplier * (header->mode[i] - 48));
multiplier *= 8;
}
return result; return result;
} }
@ -352,7 +345,7 @@ static bool initrd_register_file(InitRD::File& f, uint64_t inode)
node.read_func = initrd_read; node.read_func = initrd_read;
node.length = f.size; node.length = f.size;
node.type = VFS_FILE; node.type = VFS_FILE;
node.mode = f.mode & 07555; // don't allow writing node.mode = 0555;
node.uid = node.gid = 0; node.uid = node.gid = 0;
strncpy(node.name, buffer, sizeof(node.name)); strncpy(node.name, buffer, sizeof(node.name));
strncpy(f.name, buffer, sizeof(f.name)); strncpy(f.name, buffer, sizeof(f.name));

View File

@ -311,7 +311,7 @@ void sys_close(Context* context, int fd)
{ {
int err; int err;
Descriptor* file = Scheduler::current_task()->descriptor_from_fd(fd, err); Descriptor* file = Scheduler::current_task()->descriptor_from_fd(fd, err);
if (!file) if (!err)
{ {
context->rax = -err; context->rax = -err;
return; return;

View File

@ -1,42 +0,0 @@
#ifndef _PWD_H
#define _PWD_H
#include <sys/types.h>
/* Structure representing a password file entry. */
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
/* Returns the next password file entry. */
struct passwd* getpwent(void);
/* Returns the first password file entry with a login name matching name, or NULL if there are none. */
struct passwd* getpwnam(const char* name);
/* Returns the first password file entry with a user ID matching uid, or NULL if there are none. */
struct passwd* getpwuid(uid_t uid);
/* Rewinds to the first password file entry. */
void setpwent(void);
/* Ends password file processing. */
void endpwent(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,186 +0,0 @@
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static FILE* pwd_file = nullptr;
static int initialize_pwd(FILE** stream)
{
int pwfd = open("/etc/passwd", O_RDONLY | O_CLOEXEC);
if (pwfd < 0) return 0;
FILE* file = fdopen(pwfd, "r");
if (!file) return 0;
*stream = file;
return 1;
}
static int pwd_unbuffered_fgetc(FILE* stream)
{
char c;
fread(&c, 1, 1, stream);
if (ferror(stream) || feof(stream)) return EOF;
return (int)c;
}
static char* pwd_unbuffered_fgets(char* buf, size_t size, FILE* stream)
{
char* s = buf;
memset(buf, 0, size);
while (size)
{
int c = pwd_unbuffered_fgetc(stream);
if (c == EOF)
{
if (ferror(stream)) return NULL;
if (feof(stream))
{
if (s != buf) return s;
else
return NULL;
};
}
size--;
*buf = (char)c;
buf++;
*buf = 0;
if ((char)c == '\n') return s;
}
return s;
}
static char* pwd_strchrtok(char* s, char delim)
{
static char* saved = nullptr;
if (s) saved = s;
else
s = saved;
if (!saved) return nullptr;
char* loc = strchr(saved, delim);
if (loc)
{
saved = loc + 1;
if (*saved == 0) saved = nullptr;
*loc = 0;
}
else { saved = nullptr; }
return s;
}
static void pwd_strip_newline(char* buf)
{
size_t len = strlen(buf);
if (buf[len - 1] == '\n') buf[len - 1] = 0;
}
static struct passwd* internal_getpwent(FILE* stream)
{
#define PWENT_INVALID \
do { \
errno = EINVAL; \
return NULL; \
} while (0)
static struct passwd result;
static char buf[BUFSIZ];
if (!pwd_unbuffered_fgets(buf, BUFSIZ, stream)) return NULL;
pwd_strip_newline(buf);
result.pw_name = pwd_strchrtok(buf, ':');
if (!result.pw_name) PWENT_INVALID;
result.pw_passwd = pwd_strchrtok(NULL, ':');
if (!result.pw_passwd) PWENT_INVALID;
char* uid_string = pwd_strchrtok(NULL, ':');
if (!uid_string) PWENT_INVALID;
result.pw_uid = atoi(uid_string);
char* gid_string = pwd_strchrtok(NULL, ':');
if (!gid_string) PWENT_INVALID;
result.pw_gid = atoi(gid_string);
result.pw_gecos = pwd_strchrtok(NULL, ':');
if (!result.pw_gecos) PWENT_INVALID;
result.pw_dir = pwd_strchrtok(NULL, ':');
if (!result.pw_dir) PWENT_INVALID;
result.pw_shell = pwd_strchrtok(NULL, ':');
if (!result.pw_shell) PWENT_INVALID;
return &result;
}
extern "C"
{
struct passwd* getpwent()
{
if (!pwd_file)
{
if (!initialize_pwd(&pwd_file)) return NULL;
}
if (feof(pwd_file))
{
endpwent();
return NULL;
}
return internal_getpwent(pwd_file);
}
struct passwd* getpwnam(const char* name)
{
static FILE* pwnam_file = nullptr;
if (!pwnam_file)
{
if (!initialize_pwd(&pwnam_file)) return NULL;
}
else
rewind(pwnam_file);
struct passwd* pwd = internal_getpwent(pwnam_file);
while (pwd)
{
if (strcmp(pwd->pw_name, name) == 0) break;
if (feof(pwnam_file))
{
pwd = nullptr;
break;
}
pwd = internal_getpwent(pwnam_file);
}
return pwd; // if we matched one, pwd contains a pointer to it. else it is NULL
}
struct passwd* getpwuid(uid_t uid)
{
static FILE* pwuid_file = nullptr;
if (!pwuid_file)
{
if (!initialize_pwd(&pwuid_file)) return NULL;
}
else
rewind(pwuid_file);
struct passwd* pwd = internal_getpwent(pwuid_file);
while (pwd)
{
if (pwd->pw_uid == uid) break;
if (feof(pwuid_file))
{
pwd = nullptr;
break;
}
pwd = internal_getpwent(pwuid_file);
}
return pwd; // if we matched one, pwd contains a pointer to it. else it is NULL
}
void setpwent()
{
if (pwd_file) rewind(pwd_file);
}
void endpwent()
{
if (pwd_file)
{
fclose(pwd_file);
pwd_file = nullptr;
}
}
}