summaryrefslogtreecommitdiffstats
path: root/lib/pwio.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pwio.c')
-rw-r--r--lib/pwio.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/lib/pwio.c b/lib/pwio.c
new file mode 100644
index 0000000..e59b473
--- /dev/null
+++ b/lib/pwio.c
@@ -0,0 +1,207 @@
+/*
+ * SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
+ * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
+ * SPDX-FileCopyrightText: 2001 , Michał Moskal
+ * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
+ * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <config.h>
+
+#ident "$Id$"
+
+#include "prototypes.h"
+#include "defines.h"
+#include <pwd.h>
+#include <stdio.h>
+#include "commonio.h"
+#include "pwio.h"
+
+static /*@null@*/ /*@only@*/void *passwd_dup (const void *ent)
+{
+ const struct passwd *pw = ent;
+
+ return __pw_dup (pw);
+}
+
+static void passwd_free (/*@out@*/ /*@only@*/void *ent)
+{
+ struct passwd *pw = ent;
+
+ pw_free (pw);
+}
+
+static const char *passwd_getname (const void *ent)
+{
+ const struct passwd *pw = ent;
+
+ return pw->pw_name;
+}
+
+static void *passwd_parse (const char *line)
+{
+ return (void *) sgetpwent (line);
+}
+
+static int passwd_put (const void *ent, FILE * file)
+{
+ const struct passwd *pw = ent;
+
+ if ( (NULL == pw)
+ || (valid_field (pw->pw_name, ":\n") == -1)
+ || (valid_field (pw->pw_passwd, ":\n") == -1)
+ || (pw->pw_uid == (uid_t)-1)
+ || (pw->pw_gid == (gid_t)-1)
+ || (valid_field (pw->pw_gecos, ":\n") == -1)
+ || (valid_field (pw->pw_dir, ":\n") == -1)
+ || (valid_field (pw->pw_shell, ":\n") == -1)
+ || (strlen (pw->pw_name) + strlen (pw->pw_passwd) +
+ strlen (pw->pw_gecos) + strlen (pw->pw_dir) +
+ strlen (pw->pw_shell) + 100 > PASSWD_ENTRY_MAX_LENGTH)) {
+ return -1;
+ }
+
+ return (putpwent (pw, file) == -1) ? -1 : 0;
+}
+
+static struct commonio_ops passwd_ops = {
+ passwd_dup,
+ passwd_free,
+ passwd_getname,
+ passwd_parse,
+ passwd_put,
+ fgets,
+ fputs,
+ NULL, /* open_hook */
+ NULL /* close_hook */
+};
+
+static struct commonio_db passwd_db = {
+ PASSWD_FILE, /* filename */
+ &passwd_ops, /* ops */
+ NULL, /* fp */
+#ifdef WITH_SELINUX
+ NULL, /* scontext */
+#endif
+ 0644, /* st_mode */
+ 0, /* st_uid */
+ 0, /* st_gid */
+ NULL, /* head */
+ NULL, /* tail */
+ NULL, /* cursor */
+ false, /* changed */
+ false, /* isopen */
+ false, /* locked */
+ false, /* readonly */
+ false /* setname */
+};
+
+int pw_setdbname (const char *filename)
+{
+ return commonio_setname (&passwd_db, filename);
+}
+
+/*@observer@*/const char *pw_dbname (void)
+{
+ return passwd_db.filename;
+}
+
+int pw_lock (void)
+{
+ return commonio_lock (&passwd_db);
+}
+
+int pw_open (int mode)
+{
+ return commonio_open (&passwd_db, mode);
+}
+
+/*@observer@*/ /*@null@*/const struct passwd *pw_locate (const char *name)
+{
+ return commonio_locate (&passwd_db, name);
+}
+
+/*@observer@*/ /*@null@*/const struct passwd *pw_locate_uid (uid_t uid)
+{
+ const struct passwd *pwd;
+
+ pw_rewind ();
+ while ( ((pwd = pw_next ()) != NULL)
+ && (pwd->pw_uid != uid)) {
+ }
+
+ return pwd;
+}
+
+int pw_update (const struct passwd *pw)
+{
+ return commonio_update (&passwd_db, (const void *) pw);
+}
+
+int pw_remove (const char *name)
+{
+ return commonio_remove (&passwd_db, name);
+}
+
+int pw_rewind (void)
+{
+ return commonio_rewind (&passwd_db);
+}
+
+/*@observer@*/ /*@null@*/const struct passwd *pw_next (void)
+{
+ return commonio_next (&passwd_db);
+}
+
+int pw_close (void)
+{
+ return commonio_close (&passwd_db);
+}
+
+int pw_unlock (void)
+{
+ return commonio_unlock (&passwd_db);
+}
+
+/*@null@*/struct commonio_entry *__pw_get_head (void)
+{
+ return passwd_db.head;
+}
+
+void __pw_del_entry (const struct commonio_entry *ent)
+{
+ commonio_del_entry (&passwd_db, ent);
+}
+
+struct commonio_db *__pw_get_db (void)
+{
+ return &passwd_db;
+}
+
+static int pw_cmp (const void *p1, const void *p2)
+{
+ uid_t u1, u2;
+
+ if ((*(struct commonio_entry **) p1)->eptr == NULL)
+ return 1;
+ if ((*(struct commonio_entry **) p2)->eptr == NULL)
+ return -1;
+
+ u1 = ((struct passwd *) (*(struct commonio_entry **) p1)->eptr)->pw_uid;
+ u2 = ((struct passwd *) (*(struct commonio_entry **) p2)->eptr)->pw_uid;
+
+ if (u1 < u2)
+ return -1;
+ else if (u1 > u2)
+ return 1;
+ else
+ return 0;
+}
+
+/* Sort entries by UID */
+int pw_sort ()
+{
+ return commonio_sort (&passwd_db, pw_cmp);
+}