From 091d63007009782645e83fda77ebeff7eb52f243 Mon Sep 17 00:00:00 2001 From: davidn Date: Tue, 26 Oct 1999 08:34:09 +0000 Subject: Add new functionality "lock" and "unlock" to provide a simple password locking mechanism for users. This works by prepending the string "*LOCKED*" to the password field in master.passwd to prevent successful decoding. --- usr.sbin/pw/pw_user.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index da6c83b..c9d2b40 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -55,6 +55,7 @@ static const char rcsid[] = #endif static int randinit; +static char locked_str[] = "*LOCKED*"; static int print_user(struct passwd * pwd, int pretty, int v7); static uid_t pw_uidpolicy(struct userconf * cnf, struct cargs * args); @@ -104,6 +105,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) { int rc; char *p = NULL; + char *passtmp; struct carg *a_name; struct carg *a_uid; struct carg *arg; @@ -127,6 +129,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) 0 }; + /* * With M_NEXT, we only need to return the * next uid to stdout @@ -303,7 +306,8 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) /* * Update, delete & print require that the user exists */ - if (mode == M_UPDATE || mode == M_DELETE || mode == M_PRINT) { + if (mode == M_UPDATE || mode == M_DELETE || + mode == M_PRINT || mode == M_LOCK || mode == M_UNLOCK) { if (a_name == NULL && pwd == NULL) /* Try harder */ pwd = GETPWUID(atoi(a_uid->val)); @@ -323,6 +327,31 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) a_name = addarg(args, 'n', newstr(pwd->pw_name)); /* + * The M_LOCK and M_UNLOCK functions simply add or remove + * a "*LOCKED*" prefix from in front of the password to + * prevent it decoding correctly, and therefore prevents + * access. Of course, this only prevents access via + * password authentication (not ssh, kerberos or any + * other method that does not use the UNIX password) but + * that is a known limitation. + */ + + if (mode == M_LOCK) { + if (strncmp(pwd->pw_passwd, locked_str, sizeof(locked_str)-1) == 0) + errx(EX_DATAERR, "user '%s' is already locked", pwd->pw_name); + passtmp = malloc(strlen(pwd->pw_passwd) + sizeof(locked_str)); + if (passtmp == NULL) /* disaster */ + errx(EX_UNAVAILABLE, "out of memory"); + strcpy(passtmp, locked_str); + strcat(passtmp, pwd->pw_passwd); + pwd->pw_passwd = passtmp; + } else if (mode == M_UNLOCK) { + if (strncmp(pwd->pw_passwd, locked_str, sizeof(locked_str)-1) != 0) + errx(EX_DATAERR, "user '%s' is not locked", pwd->pw_name); + pwd->pw_passwd += sizeof(locked_str)-1; + } + + /* * Handle deletions now */ if (mode == M_DELETE) { @@ -563,7 +592,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) warnc(rc, "NIS passwd update"); /* NOTE: we treat NIS-only update errors as non-fatal */ } - } else if (mode == M_UPDATE) { + } else if (mode == M_UPDATE || mode == M_LOCK || mode == M_UNLOCK) { rc = chgpwent(a_name->val, pwd); if (rc == -1) { warnx("user '%s' does not exist (NIS?)", pwd->pw_name); -- cgit v1.1