mirror of
https://github.com/linux-pam/linux-pam.git
synced 2024-11-23 09:43:36 +08:00
55a20554f9
libpam/pam_modutil_check_user.c: explicitly convert the character read from /etc/passwd to type "char" to get the same signedness as the one compared with. Otherwise the functionality will depend on the (implementation defined) signedness of "char" on the platform built for.
78 lines
1.6 KiB
C
78 lines
1.6 KiB
C
#include "pam_modutil_private.h"
|
|
#include <security/pam_ext.h>
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <syslog.h>
|
|
|
|
int
|
|
pam_modutil_check_user_in_passwd(pam_handle_t *pamh,
|
|
const char *user_name,
|
|
const char *file_name)
|
|
{
|
|
int rc, c = EOF;
|
|
FILE *fp;
|
|
|
|
/* Validate the user name. */
|
|
if (user_name[0] == '\0') {
|
|
pam_syslog(pamh, LOG_NOTICE, "user name is not valid");
|
|
return PAM_SERVICE_ERR;
|
|
}
|
|
|
|
if (strchr(user_name, ':') != NULL) {
|
|
/*
|
|
* "root:x" is not a local user name even if the passwd file
|
|
* contains a line starting with "root:x:".
|
|
*/
|
|
return PAM_PERM_DENIED;
|
|
}
|
|
|
|
/* Open the passwd file. */
|
|
if (file_name == NULL) {
|
|
file_name = "/etc/passwd";
|
|
}
|
|
if ((fp = fopen(file_name, "r")) == NULL) {
|
|
pam_syslog(pamh, LOG_ERR, "error opening %s: %m", file_name);
|
|
return PAM_SERVICE_ERR;
|
|
}
|
|
|
|
/*
|
|
* Scan the file using fgetc() instead of fgetpwent_r() because
|
|
* the latter is not flexible enough in handling long lines
|
|
* in passwd files.
|
|
*/
|
|
rc = PAM_PERM_DENIED;
|
|
do {
|
|
const char *p;
|
|
|
|
/*
|
|
* Does this line start with the user name
|
|
* followed by a colon?
|
|
*/
|
|
for (p = user_name; *p != '\0'; p++) {
|
|
c = fgetc(fp);
|
|
if (c == EOF || c == '\n' || (char)c != *p)
|
|
break;
|
|
}
|
|
|
|
if (c != EOF && c != '\n')
|
|
c = fgetc(fp);
|
|
|
|
if (*p == '\0' && c == ':') {
|
|
rc = PAM_SUCCESS;
|
|
/*
|
|
* Continue reading the file to avoid timing attacks.
|
|
*/
|
|
}
|
|
|
|
/* Read till the end of this line. */
|
|
while (c != EOF && c != '\n')
|
|
c = fgetc(fp);
|
|
|
|
/* Continue with the next line. */
|
|
} while (c != EOF);
|
|
|
|
fclose(fp);
|
|
return rc;
|
|
}
|