SHADOW(3)

🌸 SHADOW 🌸

bestie we're doing Library Calls today, and this one is literally the encrypted password file routines page πŸ’– aka shadow and getspnam β€” yes those ones. the ones that touch the sacred text (/etc/shadow) πŸ‘‘


✨ NAME ✨

shadow, getspnam β€” encrypted password file routines πŸ”


πŸŽ€ SYNTAX πŸŽ€

okay so first you gotta pull in the header, standard behavior:

#include <shadow.h>

struct spwd *getspent();

struct spwd *getspnam(char *name);

void setspent();

void endspent();

struct spwd *fgetspent(FILE *fp);

struct spwd *sgetspent(char *cp);

int putspent(struct spwd *p, FILE *fp);

int lckpwdf();

int ulckpwdf();

πŸ’… DESCRIPTION πŸ’…

so shadow is the little gremlin that manipulates the contents of the shadow password file, /etc/shadow. and the struct in the #include file? it's giving:

struct spwd {
      char      *sp_namp; /* user login name */
      char      *sp_pwdp; /* encrypted password */
      long int       sp_lstchg; /* last password change */
      long int       sp_min; /* days until change allowed. */
      long int       sp_max; /* days before change required */
      long int       sp_warn; /* days warning for expiration */
      long int       sp_inact; /* days before account inactive */
      long int       sp_expire; /* date when account expires */
      unsigned long int   sp_flag; /* reserved for future use */
}

and the meanings of each field, one by one, no skips:

  • sp_namp - pointer to null-terminated user name
  • sp_pwdp - pointer to null-terminated password
  • sp_lstchg - days since Jan 1, 1970 password was last changed
  • sp_min - days before which password may not be changed
  • sp_max - days after which password must be changed
  • sp_warn - days before password is to expire that user is warned of pending password expiration
  • sp_inact - days after password expires that account is considered inactive and disabled
  • sp_expire - days since Jan 1, 1970 when account will be disabled
  • sp_flag - reserved for future use

🌈 DESCRIPTION (part two, the functions) 🌈

not me writing two DESCRIPTION sections, but that's literally what the page does so we're doing it πŸ’€

getspent, getspname, fgetspent, and sgetspent each return a pointer to a struct spwd. breaking it down:

  • getspent returns the next entry from the file πŸ“„
  • fgetspent returns the next entry from the given stream, which is assumed to be a file of the proper format
  • sgetspent returns a pointer to a struct spwd using the provided string as input
  • getspnam searches from the current position in the file for an entry matching name πŸ”

setspent and endspent may be used to begin and end, respectively, access to the shadow password file. open and close, the way that duo is supposed to work 🫢

the lckpwdf and ulckpwdf routines should be used to insure exclusive access to the /etc/shadow file. lckpwdf attempts to acquire a lock using pw_lock for up to 15 seconds. it continues by attempting to acquire a second lock using spw_lock for the remainder of the initial 15 seconds. should either attempt fail after a total of 15 seconds, lckpwdf returns -1. when both locks are acquired 0 is returned ✨

lowkey dramatic but the lock window is real: 15 seconds total, -1 if either attempt fails, 0 when both locks are yours πŸ‘‘

🩺 DIAGNOSTICS 🩺

routines return NULL if no more entries are available or if an error occurs during processing. routines which have int as the return value return 0 for success and -1 for failure. that's it, that's the whole vibe check πŸ“‹


⚠️ CAVEATS ⚠️

these routines may only be used by the superuser as access to the shadow password file is restricted. so if you're not root, bestie, you're not getting in πŸ’€ no cap.


πŸ“ FILES πŸ“

  • /etc/shadow β€” secure user account information. πŸ’–

πŸ‘€ SEE ALSO πŸ‘€

getpwent(3), shadow(5).


and that's the whole page, periodt πŸ’… go forth and read your shadow entries responsibly. this was shadow-utils 4.20.0, dated 07/30/2026 β€” mwah, bye bestie πŸŽ€πŸ¦‹βœ¨

πŸ“¦ where this page comes from