Factor out platform-specific locked account check.

Also fixes an incorrect free on platforms with both libiaf and shadow
passwords (probably only Unixware).  Prompted by github PR#284,
originally from @c3h2_ctf and stoeckmann@.
This commit is contained in:
Darren Tucker 2022-03-26 12:49:50 +11:00
parent d23efe4b12
commit 2923d026e5
3 changed files with 55 additions and 47 deletions

46
auth.c
View File

@ -104,60 +104,16 @@ allowed_user(struct ssh *ssh, struct passwd * pw)
const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
u_int i;
int r;
#ifdef USE_SHADOW
struct spwd *spw = NULL;
#endif
/* Shouldn't be called if pw is NULL, but better safe than sorry... */
if (!pw || !pw->pw_name)
return 0;
#ifdef USE_SHADOW
if (!options.use_pam)
spw = getspnam(pw->pw_name);
#ifdef HAS_SHADOW_EXPIRE
if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw))
return 0;
#endif /* HAS_SHADOW_EXPIRE */
#endif /* USE_SHADOW */
/* grab passwd field for locked account check */
passwd = pw->pw_passwd;
#ifdef USE_SHADOW
if (spw != NULL)
#ifdef USE_LIBIAF
passwd = get_iaf_password(pw);
#else
passwd = spw->sp_pwdp;
#endif /* USE_LIBIAF */
#endif
/* check for locked account */
if (!options.use_pam && passwd && *passwd) {
int locked = 0;
#ifdef LOCKED_PASSWD_STRING
if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0)
locked = 1;
#endif
#ifdef LOCKED_PASSWD_PREFIX
if (strncmp(passwd, LOCKED_PASSWD_PREFIX,
strlen(LOCKED_PASSWD_PREFIX)) == 0)
locked = 1;
#endif
#ifdef LOCKED_PASSWD_SUBSTR
if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
locked = 1;
#endif
#ifdef USE_LIBIAF
free((void *) passwd);
#endif /* USE_LIBIAF */
if (locked) {
if (!options.use_pam && platform_locked_account(pw)) {
logit("User %.100s not allowed because account is locked",
pw->pw_name);
return 0;
}
}
/*
* Deny if shell does not exist or is not executable unless we

View File

@ -18,6 +18,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "log.h"
@ -197,3 +198,53 @@ platform_krb5_get_principal_name(const char *pw_name)
return NULL;
#endif
}
/* returns 1 if account is locked */
int
platform_locked_account(struct passwd *pw)
{
int locked = 0;
char *passwd = pw->pw_passwd;
#ifdef USE_SHADOW
struct spwd *spw = NULL;
#ifdef USE_LIBIAF
char *iaf_passwd = NULL;
#endif
spw = getspnam(pw->pw_name);
#ifdef HAS_SHADOW_EXPIRE
if (spw != NULL && auth_shadow_acctexpired(spw))
return 1;
#endif /* HAS_SHADOW_EXPIRE */
if (spw != NULL)
#ifdef USE_LIBIAF
iaf_passwd = passwd = get_iaf_password(pw);
#else
passwd = spw->sp_pwdp;
#endif /* USE_LIBIAF */
#endif
/* check for locked account */
if (passwd && *passwd) {
#ifdef LOCKED_PASSWD_STRING
if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0)
locked = 1;
#endif
#ifdef LOCKED_PASSWD_PREFIX
if (strncmp(passwd, LOCKED_PASSWD_PREFIX,
strlen(LOCKED_PASSWD_PREFIX)) == 0)
locked = 1;
#endif
#ifdef LOCKED_PASSWD_SUBSTR
if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
locked = 1;
#endif
}
#ifdef USE_LIBIAF
if (iaf_passwd != NULL)
freezero(iaf_passwd, strlen(iaf_passwd));
#endif /* USE_LIBIAF */
return locked;
}

View File

@ -28,6 +28,7 @@ void platform_setusercontext(struct passwd *);
void platform_setusercontext_post_groups(struct passwd *);
char *platform_get_krb5_client(const char *);
char *platform_krb5_get_principal_name(const char *);
int platform_locked_account(struct passwd *)
int platform_sys_dir_uid(uid_t);
void platform_disable_tracing(int);