diff options
author | Jesse Buhagiar <jesse.buhagiar@student.rmit.edu.au> | 2020-01-12 19:03:21 +1100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-02 10:58:45 +0100 |
commit | 5f78e2ff3ab6d5a55ca83a44f7e6f8fd1a1841f6 (patch) | |
tree | 195cefcbe096edd6749f93fa51e7584dd19215c9 | |
parent | dfaa5ecf81f0246e4f40b5044442ee596250ec13 (diff) | |
download | serenity-5f78e2ff3ab6d5a55ca83a44f7e6f8fd1a1841f6.zip |
LibC: Implement `putpwent()`
It was previously impossible to (correctly) put an entry into the
password file via libc. This patch implements the functionality
to do so.
-rw-r--r-- | Libraries/LibC/pwd.cpp | 25 | ||||
-rw-r--r-- | Libraries/LibC/pwd.h | 2 |
2 files changed, 27 insertions, 0 deletions
diff --git a/Libraries/LibC/pwd.cpp b/Libraries/LibC/pwd.cpp index f12c90ca5f..794438a51f 100644 --- a/Libraries/LibC/pwd.cpp +++ b/Libraries/LibC/pwd.cpp @@ -151,4 +151,29 @@ next_entry: strncpy(__pwdb_entry->shell_buffer, e_shell.characters(), PWDB_STR_MAX_LEN); return __pwdb_entry; } + +int putpwent(const struct passwd* p, FILE* stream) +{ + if (!p || !stream || !p->pw_name || !p->pw_dir || !p->pw_gecos || !p->pw_shell) { + errno = EINVAL; + return -1; + } + + auto is_valid_field = [](const char* str) { + return str && !strpbrk(str, ":\n"); + }; + + if (!is_valid_field(p->pw_name) || !is_valid_field(p->pw_dir) || !is_valid_field(p->pw_gecos) || !is_valid_field(p->pw_shell)) { + errno = EINVAL; + return -1; + } + + int nwritten = fprintf(stream, "%s:x:%u:%u:%s,,,:%s:%s\n", p->pw_name, p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell); + if (!nwritten || nwritten < 0) { + errno = ferror(stream); + return -1; + } + + return 0; +} } diff --git a/Libraries/LibC/pwd.h b/Libraries/LibC/pwd.h index 2e7653a356..334b04b05f 100644 --- a/Libraries/LibC/pwd.h +++ b/Libraries/LibC/pwd.h @@ -26,6 +26,7 @@ #pragma once +#include <bits/FILE.h> #include <sys/cdefs.h> #include <sys/types.h> @@ -46,5 +47,6 @@ void setpwent(); void endpwent(); struct passwd* getpwnam(const char* name); struct passwd* getpwuid(uid_t); +int putpwent(const struct passwd* p, FILE* stream); __END_DECLS |