From a7e1207e0fd8977e82e4f38e7942b55c570f4495 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Tue, 1 Oct 2013 20:21:50 +0200 Subject: [PATCH] Implement the API properly. --- Makefile | 1 + libc/Makefile | 12 ++- libc/include/pwd.h | 30 +++++--- libc/pwd/endpwent.cpp | 34 +++++++++ libc/pwd/fgetpwent.cpp | 57 ++++++++++++++ libc/pwd/fgetpwent_r.cpp | 156 +++++++++++++++++++++++++++++++++++++++ libc/pwd/getpwent.cpp | 35 +++++++++ libc/pwd/getpwent_r.cpp | 39 ++++++++++ libc/pwd/getpwnam.cpp | 58 +++++++++++++++ libc/pwd/getpwnam_r.cpp | 55 ++++++++++++++ libc/pwd/getpwuid.cpp | 58 +++++++++++++++ libc/pwd/getpwuid_r.cpp | 54 ++++++++++++++ libc/pwd/openpw.cpp | 31 ++++++++ libc/pwd/pwent.cpp | 117 ----------------------------- libc/pwd/setpwent.cpp | 34 +++++++++ 15 files changed, 644 insertions(+), 127 deletions(-) create mode 100644 libc/pwd/endpwent.cpp create mode 100644 libc/pwd/fgetpwent.cpp create mode 100644 libc/pwd/fgetpwent_r.cpp create mode 100644 libc/pwd/getpwent.cpp create mode 100644 libc/pwd/getpwent_r.cpp create mode 100644 libc/pwd/getpwnam.cpp create mode 100644 libc/pwd/getpwnam_r.cpp create mode 100644 libc/pwd/getpwuid.cpp create mode 100644 libc/pwd/getpwuid_r.cpp create mode 100644 libc/pwd/openpw.cpp delete mode 100644 libc/pwd/pwent.cpp create mode 100644 libc/pwd/setpwent.cpp diff --git a/Makefile b/Makefile index 4e8a32da..b81e6fae 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,7 @@ sysroot-fsh: mkdir -p "$(SYSROOT)/share" mkdir -p "$(SYSROOT)/src" mkdir -p "$(SYSROOT)/tmp" + echo "root::0:0:root:/root:sh" > "$(SYSROOT)/etc/passwd" .PHONY: sysroot-base-headers sysroot-base-headers: sysroot-fsh diff --git a/libc/Makefile b/libc/Makefile index 544a668f..30cf5e9e 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -273,7 +273,17 @@ netdb/setprotoent.o \ netdb/setservent.o \ poll/poll.o \ poll/ppoll.o \ -pwd/pwent.o \ +pwd/endpwent.o \ +pwd/fgetpwent.o \ +pwd/fgetpwent_r.o \ +pwd/getpwent.o \ +pwd/getpwent_r.o \ +pwd/getpwnam.o \ +pwd/getpwnam_r.o \ +pwd/getpwuid.o \ +pwd/getpwuid_r.o \ +pwd/openpw.o \ +pwd/setpwent.o \ signal/kill.o \ signal/killpg.o \ signal/psignal.o \ diff --git a/libc/include/pwd.h b/libc/include/pwd.h index 30fa8176..78f5455f 100644 --- a/libc/include/pwd.h +++ b/libc/include/pwd.h @@ -31,28 +31,40 @@ __BEGIN_DECLS +@include(FILE.h) @include(gid_t.h) -@include(uid_t.h) @include(size_t.h) - -#define _PASSWD_BUFFER_SIZE 64 +@include(uid_t.h) struct passwd { - char pw_name[_PASSWD_BUFFER_SIZE]; - char pw_dir[_PASSWD_BUFFER_SIZE]; - char pw_shell[_PASSWD_BUFFER_SIZE]; - char pw_gecos[_PASSWD_BUFFER_SIZE]; uid_t pw_uid; gid_t pw_gid; + char* pw_dir; + char* pw_gecos; + char* pw_name; + char* pw_passwd; + char* pw_shell; }; +#if __is_sortix_libc +extern FILE* __pwd_file; +#endif + void endpwent(void); +struct passwd* fgetpwent(FILE*); +int fgetpwent_r(FILE* __restrict, struct passwd* __restrict, char* __restrict, + size_t, struct passwd** __restrict); struct passwd* getpwent(void); +int getpwent_r(struct passwd* __restrict, char* __restrict, size_t, + struct passwd** __restrict); struct passwd* getpwnam(const char*); -int getpwnam_r(const char*, struct passwd*, char*, size_t, struct passwd**); +int getpwnam_r(const char* __restrict, struct passwd* __restrict, + char* __restrict, size_t, struct passwd** __restrict); struct passwd* getpwuid(uid_t); -int getpwuid_r(uid_t, struct passwd *, char*, size_t, struct passwd**); +int getpwuid_r(uid_t, struct passwd* __restrict, char* __restrict, size_t, + struct passwd** __restrict); +FILE* openpw(void); void setpwent(void); __END_DECLS diff --git a/libc/pwd/endpwent.cpp b/libc/pwd/endpwent.cpp new file mode 100644 index 00000000..d6adb1d5 --- /dev/null +++ b/libc/pwd/endpwent.cpp @@ -0,0 +1,34 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/endpwent.cpp + Closes the passwd database. + +*******************************************************************************/ + +#include +#include + +extern "C" void endpwent(void) +{ + if ( !__pwd_file ) + return; + fclose(__pwd_file); + __pwd_file = NULL; +} diff --git a/libc/pwd/fgetpwent.cpp b/libc/pwd/fgetpwent.cpp new file mode 100644 index 00000000..16f46877 --- /dev/null +++ b/libc/pwd/fgetpwent.cpp @@ -0,0 +1,57 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/fgetpwent.cpp + Reads a passwd entry from a FILE in a thread-insecure manner. + +*******************************************************************************/ + +#include +#include +#include + +extern "C" struct passwd* fgetpwent(FILE* fp) +{ + static struct passwd result_object; + static char* buf = NULL; + static size_t buflen = 0; + if ( !buf ) + { + size_t new_buflen = 64; + if ( !(buf = (char*) malloc(new_buflen)) ) + return NULL; + buflen = new_buflen; + } + struct passwd* result; +retry: + int errnum = fgetpwent_r(fp, &result_object, buf, buflen, &result); + if ( errnum == ERANGE ) + { + size_t new_buflen = 2 * buflen; + char* new_buf = (char*) realloc(buf, new_buflen); + if ( !new_buf ) + return NULL; + buf = new_buf; + buflen = new_buflen; + goto retry; + } + if ( errnum < 0 ) + return errno = errnum, (struct passwd*) NULL; + return result; +} diff --git a/libc/pwd/fgetpwent_r.cpp b/libc/pwd/fgetpwent_r.cpp new file mode 100644 index 00000000..626f108c --- /dev/null +++ b/libc/pwd/fgetpwent_r.cpp @@ -0,0 +1,156 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/fgetpwent_r.cpp + Reads a passwd entry from a FILE. + +*******************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +static char* next_field(char** current) +{ + char* result = *current; + if ( result ) + { + char* next = result; + while ( *next && *next != ':' ) + next++; + if ( !*next ) + next = NULL; + else + *next++ = '\0'; + *current = next; + } + return result; +} + +static id_t next_field_id(char** current) +{ + char* id_str = next_field(current); + if ( !id_str ) + return -1; + char* id_endptr; + intmax_t id_imax = strtoimax(id_str, &id_endptr, 10); + if ( id_imax < 0 || *id_endptr ) + return -1; + id_t id = (id_t) id_imax; + if ( id != id_imax ) + return -1; + return id; +} + +extern "C" +int fgetpwent_r(FILE* restrict fp, + struct passwd* restrict result, + char* restrict buf, + size_t buf_len, + struct passwd** restrict result_pointer) +{ + if ( !result_pointer ) + return errno = EINVAL; + + if ( !fp || !result || !buf ) + return *result_pointer = NULL, errno = EINVAL; + + int original_errno = errno; + + flockfile(fp); + + off_t original_offset = ftello(fp); + if ( original_offset < 0 ) + { + funlockfile(fp); + return *result_pointer = NULL, errno; + } + + size_t buf_used = 0; + int ic; + while ( (ic = fgetc(fp)) != EOF ) + { + if ( ic == '\n' ) + break; + + if ( buf_used == buf_len ) + { + fseeko(fp, original_offset, SEEK_SET); + funlockfile(fp); + return *result_pointer = NULL, errno = ERANGE; + } + + buf[buf_used++] = (char) ic; + } + + if ( ferror(fp) ) + { + int original_error = errno; + fseeko(fp, original_offset, SEEK_SET); + funlockfile(fp); + return *result_pointer = NULL, original_error; + } + + if ( !buf_used && feof(fp) ) + { + funlockfile(fp); + return *result_pointer = NULL, errno = original_errno, NULL; + } + + if ( buf_used == buf_len ) + { + fseeko(fp, original_offset, SEEK_SET); + funlockfile(fp); + return *result_pointer = NULL, errno = ERANGE; + } + buf[buf_used] = '\0'; + + char* parse_str = buf; + if ( !(result->pw_name = next_field(&parse_str)) ) + goto parse_failure; + if ( !(result->pw_passwd = next_field(&parse_str)) ) + goto parse_failure; + if ( (result->pw_uid = next_field_id(&parse_str)) < 0 ) + goto parse_failure; + if ( !(result->pw_gid = next_field_id(&parse_str)) < 0 ) + goto parse_failure; + if ( !(result->pw_gecos = next_field(&parse_str)) ) + goto parse_failure; + if ( !(result->pw_dir = next_field(&parse_str)) ) + goto parse_failure; + if ( !(result->pw_shell = next_field(&parse_str)) ) + goto parse_failure; + if ( parse_str ) + goto parse_failure; + + funlockfile(fp); + + return *result_pointer = result, 0; + +parse_failure: + fseeko(fp, original_offset, SEEK_SET); + funlockfile(fp); + return errno = EINVAL; +} diff --git a/libc/pwd/getpwent.cpp b/libc/pwd/getpwent.cpp new file mode 100644 index 00000000..a07630ee --- /dev/null +++ b/libc/pwd/getpwent.cpp @@ -0,0 +1,35 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/getpwent.cpp + Reads a passwd entry in a thread-insecure manner. + +*******************************************************************************/ + +#include +#include + +extern "C" { FILE* __pwd_file = NULL; } + +extern "C" struct passwd* getpwent(void) +{ + if ( !__pwd_file && !(__pwd_file = openpw()) ) + return NULL; + return fgetpwent(__pwd_file); +} diff --git a/libc/pwd/getpwent_r.cpp b/libc/pwd/getpwent_r.cpp new file mode 100644 index 00000000..28e34236 --- /dev/null +++ b/libc/pwd/getpwent_r.cpp @@ -0,0 +1,39 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/getpwent_r.cpp + Reads a passwd entry (but not fully thread-securely). + +*******************************************************************************/ + +#include +#include + +extern "C" +int getpwent_r(struct passwd* restrict result, + char* restrict buf, + size_t buflen, + struct passwd** restrict result_pointer) +{ + if ( !result_pointer ) + return errno = EINVAL; + if ( !__pwd_file && !(__pwd_file = openpw()) ) + return errno; + return fgetpwent_r(__pwd_file, result, buf, buflen, result_pointer); +} diff --git a/libc/pwd/getpwnam.cpp b/libc/pwd/getpwnam.cpp new file mode 100644 index 00000000..c740df4f --- /dev/null +++ b/libc/pwd/getpwnam.cpp @@ -0,0 +1,58 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/getpwnam.cpp + Searchs the passwd database for a user with the given username in a + thread-insecure manner. + +*******************************************************************************/ + +#include +#include +#include + +extern "C" struct passwd* getpwnam(const char* username) +{ + static struct passwd result_object; + static char* buf = NULL; + static size_t buflen = 0; + if ( !buf ) + { + size_t new_buflen = 64; + if ( !(buf = (char*) malloc(new_buflen)) ) + return NULL; + buflen = new_buflen; + } + struct passwd* result; +retry: + int errnum = getpwnam_r(username, &result_object, buf, buflen, &result); + if ( errnum == ERANGE ) + { + size_t new_buflen = 2 * buflen; + char* new_buf = (char*) realloc(buf, new_buflen); + if ( !new_buf ) + return NULL; + buf = new_buf; + buflen = new_buflen; + goto retry; + } + if ( errnum < 0 ) + return errno = errnum, (struct passwd*) NULL; + return result; +} diff --git a/libc/pwd/getpwnam_r.cpp b/libc/pwd/getpwnam_r.cpp new file mode 100644 index 00000000..5b1cbf9e --- /dev/null +++ b/libc/pwd/getpwnam_r.cpp @@ -0,0 +1,55 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/getpwnam_r.cpp + Searchs the passwd database for a user with the given username. + +*******************************************************************************/ + +#include +#include +#include +#include + +extern "C" +int getpwnam_r(const char* restrict username, + struct passwd* restrict ret, + char* restrict buf, + size_t buflen, + struct passwd** restrict ret_ptr) +{ + if ( !ret_ptr ) + return errno = EINVAL; + if ( !username || !ret || !buf ) + return *ret_ptr = NULL, errno = EINVAL; + FILE* fpasswd = openpw(); + if ( !fpasswd ) + return *ret_ptr = NULL, errno; + int errnum; + while ( (errnum = fgetpwent_r(fpasswd, ret, buf, buflen, ret_ptr)) == 0 && + *ret_ptr ) + { + if ( strcmp((*ret_ptr)->pw_name, username) != 0 ) + continue; + fclose(fpasswd); + return *ret_ptr = *ret_ptr, 0; + } + fclose(fpasswd); + return *ret_ptr = NULL, errnum ? errnum : errno = ENOUSER; +} diff --git a/libc/pwd/getpwuid.cpp b/libc/pwd/getpwuid.cpp new file mode 100644 index 00000000..fc647095 --- /dev/null +++ b/libc/pwd/getpwuid.cpp @@ -0,0 +1,58 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/getpwuid.cpp + Searchs the passwd database for a user with the given numeric user id in a + thread-insecure manner. + +*******************************************************************************/ + +#include +#include +#include + +extern "C" struct passwd* getpwuid(uid_t uid) +{ + static struct passwd result_object; + static char* buf = NULL; + static size_t buflen = 0; + if ( !buf ) + { + size_t new_buflen = 64; + if ( !(buf = (char*) malloc(new_buflen)) ) + return NULL; + buflen = new_buflen; + } + struct passwd* result; +retry: + int errnum = getpwuid_r(uid, &result_object, buf, buflen, &result); + if ( errnum == ERANGE ) + { + size_t new_buflen = 2 * buflen; + char* new_buf = (char*) realloc(buf, new_buflen); + if ( !new_buf ) + return NULL; + buf = new_buf; + buflen = new_buflen; + goto retry; + } + if ( errnum < 0 ) + return errno = errnum, (struct passwd*) NULL; + return result; +} diff --git a/libc/pwd/getpwuid_r.cpp b/libc/pwd/getpwuid_r.cpp new file mode 100644 index 00000000..3d176041 --- /dev/null +++ b/libc/pwd/getpwuid_r.cpp @@ -0,0 +1,54 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/getpwuid_r.cpp + Searchs the passwd database for a user with the given numeric user id. + +*******************************************************************************/ + +#include +#include +#include + +extern "C" +int getpwuid_r(uid_t uid, + struct passwd* restrict ret, + char* restrict buf, + size_t buflen, + struct passwd** restrict ret_ptr) +{ + if ( !ret_ptr ) + return errno = EINVAL; + if ( !ret || !buf ) + return *ret_ptr = NULL, errno = EINVAL; + FILE* fpasswd = openpw(); + if ( !fpasswd ) + return *ret_ptr = NULL, errno; + int errnum; + while ( (errnum = fgetpwent_r(fpasswd, ret, buf, buflen, ret_ptr)) == 0 && + *ret_ptr ) + { + if ( (*ret_ptr)->pw_uid != uid ) + continue; + fclose(fpasswd); + return *ret_ptr = *ret_ptr, 0; + } + fclose(fpasswd); + return *ret_ptr = NULL, errnum ? errnum : errno = ENOUSER; +} diff --git a/libc/pwd/openpw.cpp b/libc/pwd/openpw.cpp new file mode 100644 index 00000000..98f2f30d --- /dev/null +++ b/libc/pwd/openpw.cpp @@ -0,0 +1,31 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/openpw.cpp + Opens the passwd database and returns a FILE to it. + +*******************************************************************************/ + +#include +#include + +extern "C" FILE* openpw(void) +{ + return fopen("/etc/passwd", "r"); +} diff --git a/libc/pwd/pwent.cpp b/libc/pwd/pwent.cpp deleted file mode 100644 index 6273471b..00000000 --- a/libc/pwd/pwent.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2013. - - This file is part of the Sortix C Library. - - The Sortix C Library is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or (at your - option) any later version. - - The Sortix C Library is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with the Sortix C Library. If not, see . - - pwd/pwent.cpp - User database. - -*******************************************************************************/ - -#include - -#include -#include -#include -#include - -// TODO: This implementation of pwent is very hacky and insecure. - -const char* const ROOT_UID = "0"; -const char* const ROOT_GID = "0"; -const char* const ROOT_NAME = "root"; -const char* const ROOT_HOME = "/root"; -const char* const ROOT_SHELL = "sh"; -const char* const ROOT_FULLNAME = "root"; - -static struct passwd global_passwd; - -static size_t global_user_offset = 0; - -extern "C" void setpwent(void) -{ - global_user_offset = 0; -} - -extern "C" void endpwent(void) -{ -} - -static const char* getenv_def(const char* key, const char* def) -{ - const char* value = getenv(key); - return value ? value : def; -} - -static struct passwd* fill_passwd(struct passwd* pw) -{ - // TODO: Potential buffer overflow. - strcpy(pw->pw_name, getenv_def("USERNAME", ROOT_NAME)); - strcpy(pw->pw_dir, getenv_def("HOME", ROOT_HOME)); - strcpy(pw->pw_shell, getenv_def("SHELL", ROOT_SHELL)); - strcpy(pw->pw_gecos, getenv_def("USERFULLNAME", ROOT_FULLNAME)); - pw->pw_uid = atoi(getenv_def("USERID", ROOT_UID)); - pw->pw_gid = atoi(getenv_def("GROUPID", ROOT_GID)); - return pw; -} - -static uid_t lookup_username(const char* name) -{ - const char* my_username = getenv("USERNAME") ? getenv("USERNAME") : "root"; - if ( !strcmp(my_username, name) ) - if ( getenv("USERID") ) - return atoi(getenv("USERID")); - return atoi(ROOT_UID); -} - -extern "C" struct passwd* getpwent(void) -{ - if ( global_user_offset == 1 ) - return NULL; - global_user_offset++; - return fill_passwd(&global_passwd); -} - -extern "C" struct passwd* getpwnam(const char* name) -{ - return getpwuid(lookup_username(name)); -} - -extern "C" int getpwnam_r(const char* name, struct passwd* pw, char* buf, - size_t buflen, struct passwd** ret) -{ - return getpwuid_r(lookup_username(name), pw, buf, buflen, ret); -} - -extern "C" struct passwd* getpwuid(uid_t uid) -{ - struct passwd* ret; - if ( getpwuid_r(uid, &global_passwd, NULL, 0, &ret) ) - return NULL; - return ret; -} - -extern "C" int getpwuid_r(uid_t uid, struct passwd* pw, char* buf, - size_t buflen, struct passwd** ret) -{ - (void) buf; - (void) buflen; - fill_passwd(pw); - pw->pw_uid = uid; - *ret = pw; - return 0; -} diff --git a/libc/pwd/setpwent.cpp b/libc/pwd/setpwent.cpp new file mode 100644 index 00000000..c52266f3 --- /dev/null +++ b/libc/pwd/setpwent.cpp @@ -0,0 +1,34 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + pwd/setpwent.cpp + Rewinds the passwd database. + +*******************************************************************************/ + +#include +#include + +extern "C" void setpwent(void) +{ + if ( __pwd_file ) + fseeko(__pwd_file, 0, SEEK_SET); + else + __pwd_file = openpw(); +}