PW_UTIL(3)
π PW_UTIL β passwd file handling, but make it a group chat π
okay so bestie, welcome to PW_UTIL(3) β that's section 3 of the manual, the library-functions one, mwah. This whole page lives in the System Utilities Library (libutil, and you link it with -lutil, no cap). It's all about the passwd file: reading it, writing it, duping it, editing it, locking it, the works. Buckle up. π¦
β¨ SYNOPSIS β¨
Like, here's the exact vibe of what you're getting into, character for character:
#include <pwd.h>
#include <libutil.h>
int
pw_copy(int ffd, int tfd, const struct passwd *pw,
struct passwd *oldpw);
struct passwd *
pw_dup(const struct passwd *pw);
int
pw_edit(int nosetuid);
int
pw_equal(const struct passwd *pw1, const struct passwd *pw2);
void
pw_fini(void);
int
pw_init(const char *dir, const char *master);
void
pw_initpwd(struct passwd *pw);
char *
pw_make(const struct passwd *pw);
char *
pw_make_v7(const struct passwd *pw);
int
pw_mkdb(const char *user);
int
pw_lock(void);
struct passwd *
pw_scan(const char *line, int flags);
const char *
pw_tempname(void);
int
pw_tmp(int mfd);
π DESCRIPTION π
π«Ά pw_copy()
The pw_copy() function reads a password file from ffd and writes it back out to tfd, possibly with modifications. It's giving "copy but with opinions". Here's the tea:
- If
pwisNULLandoldpwis notNULL, then the record represented byoldpwwill not be copied (corresponding to user deletion). - If
pwandoldpware notNULLthen the record corresponding topwwill be replaced by the record corresponding tooldpw. - If
pwis set andoldpwisNULLthen the record corresponding topwwill be appended (corresponding to user addition).
pw_copy() returns -1 in case of failure, otherwise 0. Classic.
π¦ pw_dup()
The pw_dup() function duplicates the struct passwd pointed to by pw and returns a pointer to the copy, or NULL in case of failure. The new struct passwd is allocated with malloc(3), and it is the caller's responsibility to free it with free(3). ma'am, that's your job now, don't forget it π
πΈ pw_edit()
The pw_edit() function invokes the command specified by the EDITOR environment variable (or /usr/bin/vi if EDITOR is not defined) on a temporary copy of the master password file created by pw_tmp(). If the file was modified, pw_edit() installs it and regenerates the password database. So it's basically "let the user cook, then commit the recipe".
Return values, listen up:
-1in case of failure0if the file was not modified- a non-zero positive number if the file was modified and successfully installed
β pw_equal()
The pw_equal() function compares two struct passwd and returns 0 if they are equal. yes bestie, returning 0 for "yes" is the chaotic Unix way, we don't make the rules (we do, but like, historically).
π§ pw_fini()
The pw_fini() function destroys the temporary file created by pw_tmp() if any, kills any running instance of EDITOR executed by pw_edit() if any, and closes the lock created by pw_lock() if any. It's the cleanup crew, the friend who takes the trash out at the end of the party. π«Ά
π pw_init()
The pw_init() initializes the static variable representing the path to a password file.
diris the directory where the password file is located. If set toNULL, it will default to/etc.masteris the name of the password file. If set toNULL?it will default tomaster.passwd.
(yes the manpage literally has that NULL? with the question mark β we keep it, it's iconic π
)
π pw_initpwd()
The pw_initpwd() function initializes the passwd struct to canonical values. The entire structure is zeroed, then pw_uid and pw_gid are set to -1, and all string pointers are set to point at an internally-defined zero-length string. A blank slate, a clean girl, a fresh start β¨
π pw_make()
The pw_make() function creates a properly formatted BSD passwd(5) line from a struct passwd, and returns a pointer to the resulting string. The string is allocated with malloc(3), and it is the caller's responsibility to free it with free(3).
π pw_make_v7()
The pw_make_v7() function creates a properly formatted Unix V7 passwd(5) line from a struct passwd, and returns a pointer to the resulting string. The string is allocated with malloc(3), and it is the caller's responsibility to free it with free(3). Same energy, vintage flavour.
π₯ pw_mkdb()
The pw_mkdb() function regenerates the password database by running pwd_mkdb(8). If user is given, only the record corresponding to that user will be updated. Returns 0 in case of success and -1 in case of failure. Tiny targeted update, we love a surgical queen.
π pw_lock()
The pw_lock() function locks the master password file. It returns a file descriptor to the master password file on success and -1 on failure. Claim your territory. π©
π pw_scan()
The pw_scan() function is a wrapper around the internal libc function __pw_scan(). It scans the master password file for a line corresponding to the line provided and returns a struct passwd if it matched an existing record.
- In case of failure, it returns
NULL. - Otherwise, it returns a pointer to a
struct passwdcontaining the matching record.
The struct passwd is allocated with malloc(3), and it is the caller's responsibility to free it with free(3). (yes, again. we know. free your memory, bestie, it's self care π)
π pw_tempname()
The pw_tempname() function returns the temporary name of the masterfile created via pw_tmp().
π
pw_tmp()
The pw_tmp() creates and opens a presumably safe temporary password file. ("presumably", the manpage said it, not me β keep your eye on it π)
- If
mfdis a file descriptor to an open password file, it will be read and written back to the temporary password file. - Otherwise it should be set to
-1.
pw_tmp() returns an open file descriptor to the temporary password file or -1 in case of failure.
π°οΈ HISTORY π°οΈ
The functions for passwd file handling first appeared in 4.4BSD. vintage. antique. still slaying.
πΈ AUTHORS πΈ
Portions of this software were developed for the FreeBSD Project by ThinkSec AS and Network Associates Laboratories, the Security Research Division of Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 (βCBOSSβ), as part of the DARPA CHATS research program.
This manual page was written by Baptiste Daroussin <bapt@FreeBSD.org>. thank you baptiste, icon behaviour π«Ά
π that's the whole page bestie, every flag, every return value, every malloc(3) reminder. go free your pointers. π
sign-off: this lil page is from Debian, dated May 10, 2020 β yea that's the footer, we folded it in all cute instead of copy-pasting it. mwah π
π¦ where this page comes from
- freebsd 14.5: base 14.5
- freebsd 15.1: base 15.1
- Copyright (c) 2012 Baptiste Daroussin <bapt@FreeBSD.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms