Isolate pw lock/unlock into a separate function
This commit is contained in:
parent
4f1905177a
commit
04c25b678f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=285405
@ -191,6 +191,78 @@ pw_usershow(char *name, long id, struct passwd *fakeuser)
|
|||||||
return (print_user(pwd));
|
return (print_user(pwd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
perform_chgpwent(const char *name, struct passwd *pwd)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = chgpwent(name, pwd);
|
||||||
|
if (rc == -1)
|
||||||
|
errx(EX_IOERR, "user '%s' does not exist (NIS?)", pwd->pw_name);
|
||||||
|
else if (rc != 0)
|
||||||
|
err(EX_IOERR, "passwd file update");
|
||||||
|
|
||||||
|
if (conf.userconf->nispasswd && *conf.userconf->nispasswd == '/') {
|
||||||
|
rc = chgnispwent(conf.userconf->nispasswd, name, pwd);
|
||||||
|
if (rc == -1)
|
||||||
|
warn("User '%s' not found in NIS passwd", pwd->pw_name);
|
||||||
|
else
|
||||||
|
warn("NIS passwd update");
|
||||||
|
/* NOTE: NIS-only update errors are not fatal */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
pw_userlock(char *name, long id, int mode)
|
||||||
|
{
|
||||||
|
struct passwd *pwd = NULL;
|
||||||
|
char *passtmp = NULL;
|
||||||
|
bool locked = false;
|
||||||
|
|
||||||
|
if (id < 0 && name == NULL)
|
||||||
|
errx(EX_DATAERR, "username or id required");
|
||||||
|
|
||||||
|
pwd = (name != NULL) ? GETPWNAM(pw_checkname(name, 0)) : GETPWUID(id);
|
||||||
|
if (pwd == NULL) {
|
||||||
|
if (name == NULL)
|
||||||
|
errx(EX_NOUSER, "no such uid `%ld'", id);
|
||||||
|
errx(EX_NOUSER, "no such user `%s'", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == NULL)
|
||||||
|
name = pwd->pw_name;
|
||||||
|
|
||||||
|
if (strncmp(pwd->pw_passwd, locked_str, sizeof(locked_str) -1) == 0)
|
||||||
|
locked = true;
|
||||||
|
if (mode == M_LOCK && locked)
|
||||||
|
errx(EX_DATAERR, "user '%s' is already locked", pwd->pw_name);
|
||||||
|
if (mode == M_UNLOCK && !locked)
|
||||||
|
errx(EX_DATAERR, "user '%s' is not locked", pwd->pw_name);
|
||||||
|
|
||||||
|
if (mode == M_LOCK) {
|
||||||
|
asprintf(&passtmp, "%s%s", locked_str, pwd->pw_passwd);
|
||||||
|
if (passtmp == NULL) /* disaster */
|
||||||
|
errx(EX_UNAVAILABLE, "out of memory");
|
||||||
|
pwd->pw_passwd = passtmp;
|
||||||
|
} else {
|
||||||
|
pwd->pw_passwd += sizeof(locked_str)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
perform_chgpwent(name, pwd);
|
||||||
|
free(passtmp);
|
||||||
|
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* -C config configuration file
|
* -C config configuration file
|
||||||
* -q quiet operation
|
* -q quiet operation
|
||||||
@ -228,7 +300,6 @@ pw_user(int mode, char *name, long id, struct cargs * args)
|
|||||||
{
|
{
|
||||||
int rc, edited = 0;
|
int rc, edited = 0;
|
||||||
char *p = NULL;
|
char *p = NULL;
|
||||||
char *passtmp;
|
|
||||||
struct carg *arg;
|
struct carg *arg;
|
||||||
struct passwd *pwd = NULL;
|
struct passwd *pwd = NULL;
|
||||||
struct group *grp;
|
struct group *grp;
|
||||||
@ -268,6 +339,9 @@ pw_user(int mode, char *name, long id, struct cargs * args)
|
|||||||
if (mode == M_DELETE)
|
if (mode == M_DELETE)
|
||||||
return (pw_userdel(name, id));
|
return (pw_userdel(name, id));
|
||||||
|
|
||||||
|
if (mode == M_LOCK || mode == M_UNLOCK)
|
||||||
|
return (pw_userlock(name, id, mode));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can do all of the common legwork here
|
* We can do all of the common legwork here
|
||||||
*/
|
*/
|
||||||
@ -421,7 +495,7 @@ pw_user(int mode, char *name, long id, struct cargs * args)
|
|||||||
/*
|
/*
|
||||||
* Update require that the user exists
|
* Update require that the user exists
|
||||||
*/
|
*/
|
||||||
if (mode == M_UPDATE || mode == M_LOCK || mode == M_UNLOCK) {
|
if (mode == M_UPDATE) {
|
||||||
|
|
||||||
if (name == NULL && pwd == NULL) /* Try harder */
|
if (name == NULL && pwd == NULL) /* Try harder */
|
||||||
pwd = GETPWUID(id);
|
pwd = GETPWUID(id);
|
||||||
@ -435,31 +509,6 @@ pw_user(int mode, char *name, long id, struct cargs * args)
|
|||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
name = pwd->pw_name;
|
name = 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);
|
|
||||||
asprintf(&passtmp, "%s%s", locked_str, pwd->pw_passwd);
|
|
||||||
if (passtmp == NULL) /* disaster */
|
|
||||||
errx(EX_UNAVAILABLE, "out of memory");
|
|
||||||
pwd->pw_passwd = passtmp;
|
|
||||||
edited = 1;
|
|
||||||
} 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;
|
|
||||||
edited = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The rest is edit code
|
* The rest is edit code
|
||||||
*/
|
*/
|
||||||
@ -635,23 +684,8 @@ pw_user(int mode, char *name, long id, struct cargs * args)
|
|||||||
warn("NIS passwd update");
|
warn("NIS passwd update");
|
||||||
/* NOTE: we treat NIS-only update errors as non-fatal */
|
/* NOTE: we treat NIS-only update errors as non-fatal */
|
||||||
}
|
}
|
||||||
} else if (mode == M_UPDATE || mode == M_LOCK || mode == M_UNLOCK) {
|
} else if (mode == M_UPDATE && edited) /* Only updated this if required */
|
||||||
if (edited) { /* Only updated this if required */
|
perform_chgpwent(name, pwd);
|
||||||
rc = chgpwent(name, pwd);
|
|
||||||
if (rc == -1)
|
|
||||||
errx(EX_IOERR, "user '%s' does not exist (NIS?)", pwd->pw_name);
|
|
||||||
else if (rc != 0)
|
|
||||||
err(EX_IOERR, "passwd file update");
|
|
||||||
if ( cnf->nispasswd && *cnf->nispasswd=='/') {
|
|
||||||
rc = chgnispwent(cnf->nispasswd, name, pwd);
|
|
||||||
if (rc == -1)
|
|
||||||
warn("User '%s' not found in NIS passwd", pwd->pw_name);
|
|
||||||
else
|
|
||||||
warn("NIS passwd update");
|
|
||||||
/* NOTE: NIS-only update errors are not fatal */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ok, user is created or changed - now edit group file
|
* Ok, user is created or changed - now edit group file
|
||||||
|
Loading…
Reference in New Issue
Block a user