#include <string.h>
#include <pwd.h>
#include <crypt.h>
+#ifdef HAS_SHADOW
#include <shadow.h>
+#endif
#include <time.h>
#include <utmp.h>
#include <fcntl.h>
bool try_session = 0;
#else /* #ifdef USE_PAM */
struct passwd *pw;
+ char *cbuf;
#ifdef HAS_SHADOW
struct spwd *spwd;
struct spwd *getspnam();
#else /* #ifdef USE_PAM */
/*
- * Use the non-PAM methods directly
+ * Use the non-PAM methods directly. 'pw' will remain NULL if the user
+ * has not been authenticated using local UNIX system services.
*/
+ pw = NULL;
if ((SESS_AUTH & flags)) {
pw = getpwnam(user);
/*
* If no passwd, don't let them login if we're authenticating.
*/
- if (pw->pw_passwd == NULL || strlen(pw->pw_passwd) < 2
- || strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd) != 0)
+ if (pw->pw_passwd == NULL || strlen(pw->pw_passwd) < 2)
+ return SESSION_FAILED;
+ cbuf = crypt(passwd, pw->pw_passwd);
+ if (!cbuf || strcmp(cbuf, pw->pw_passwd) != 0)
return SESSION_FAILED;
}
logged_in = 1;
#if defined(_PATH_LASTLOG) && !defined(USE_PAM)
- {
+ /*
+ * Enter the user in lastlog only if he has been authenticated using
+ * local system services. If he has not, then we don't know what his
+ * UID might be, and lastlog is indexed by UID.
+ */
+ if (pw != NULL) {
struct lastlog ll;
int fd;
+ time_t tnow;
if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
(void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET);
memset((void *)&ll, 0, sizeof(ll));
- (void)time(&ll.ll_time);
+ (void)time(&tnow);
+ ll.ll_time = tnow;
(void)strncpy(ll.ll_line, ttyName, sizeof(ll.ll_line));
(void)strncpy(ll.ll_host, ifname, sizeof(ll.ll_host));
(void)write(fd, (char *)&ll, sizeof(ll));