FreeBSD/usr.sbin/pw/pw_user.c
/*
 * 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.
 */
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.
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 *arg1, int mode)
{
	struct passwd *pwd = NULL;
	char *passtmp = NULL;
	char *name;
	bool locked = false;
	uid_t id = (uid_t)-1;
	if (geteuid() != 0)
		errx(EX_NOPERM, "you must be root");
	if (arg1 == NULL)
		errx(EX_DATAERR, "username or id required");
	name = arg1;
	if (arg1[strspn(name, "0123456789")] == '\0')
		id = pw_checkid(name, UID_MAX);
	pwd = GETPWNAM(pw_checkname(name, 0));
	if (pwd == NULL && id != (uid_t)-1) {
		pwd = GETPWUID(id);
		if (pwd != NULL)
			name = pwd->pw_name;
	}
	if (pwd == NULL) {
		if (id == (uid_t)-1)
			errx(EX_NOUSER, "no such name or uid `%ju'", (uintmax_t) 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)	
			errx(EX_UNAVAILABLE, "out of memory");
		pwd->pw_passwd = passtmp;
	} else {
		pwd->pw_passwd += sizeof(locked_str)-1;
	}
	perform_chgpwent(name, pwd, NULL);
	free(passtmp);
	return (EXIT_SUCCESS);
}
static int pw_userlock ( char * arg1 , int mode ) { struct passwd * pwd = NULL ; char * passtmp = NULL ; char * name ; bool locked = false ; uid_t id = ( uid_t ) - 1 ; if ( geteuid ( ) != 0 ) errx ( EX_NOPERM , " " ) ; if ( arg1 == NULL ) errx ( EX_DATAERR , " " ) ; name = arg1 ; if ( arg1 [ strspn ( name , " " ) ] == ' \0 ' ) id = pw_checkid ( name , UID_MAX ) ; pwd = GETPWNAM ( pw_checkname ( name , 0 ) ) ; if ( pwd == NULL && id != ( uid_t ) - 1 ) { pwd = GETPWUID ( id ) ; if ( pwd != NULL ) name = pwd -> pw_name ; } if ( pwd == NULL ) { if ( id == ( uid_t ) - 1 ) errx ( EX_NOUSER , " " , ( uintmax_t ) id ) ; errx ( EX_NOUSER , " " , 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 , " " , pwd -> pw_name ) ; if ( mode == M_UNLOCK && ! locked ) errx ( EX_DATAERR , " " , pwd -> pw_name ) ; if ( mode == M_LOCK ) { asprintf ( & passtmp , " " , locked_str , pwd -> pw_passwd ) ; if ( passtmp == NULL ) errx ( EX_UNAVAILABLE , " " ) ; pwd -> pw_passwd = passtmp ; } else { pwd -> pw_passwd += sizeof ( locked_str ) - 1 ; } perform_chgpwent ( name , pwd , NULL ) ; free ( passtmp ) ; return ( EXIT_SUCCESS ) ; }
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.
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 .
/* disaster */