summaryrefslogtreecommitdiff
path: root/nslcd/db_pam.c
diff options
context:
space:
mode:
Diffstat (limited to 'nslcd/db_pam.c')
-rw-r--r--nslcd/db_pam.c258
1 files changed, 124 insertions, 134 deletions
diff --git a/nslcd/db_pam.c b/nslcd/db_pam.c
index 0eff71b..f47b331 100644
--- a/nslcd/db_pam.c
+++ b/nslcd/db_pam.c
@@ -39,6 +39,17 @@
#include "common/dict.h"
#include "common/expr.h"
+struct authc {
+ int authc_rc;
+ int authz_rc;
+ char authz_msg[BUFLEN_MESSAGE];
+};
+
+struct authz {
+ int authz_rc;
+ char authz_msg[BUFLEN_MESSAGE];
+};
+
/* set up a connection and try to bind with the specified DN and password,
returns an LDAP result code */
static int try_bind(const char *userdn, const char *password,
@@ -94,32 +105,6 @@ static int try_bind(const char *userdn, const char *password,
return rc;
}
-/* ensure that both userdn and username are filled in from the entry,
- returns an LDAP result code */
-static MYLDAP_ENTRY *validate_user(MYLDAP_SESSION *session,
- char *username, int *rcp)
-{
- int rc;
- MYLDAP_ENTRY *entry = NULL;
- /* check username for validity */
- if (!isvalidname(username))
- {
- log_log(LOG_WARNING, "request denied by validnames option");
- *rcp = LDAP_NO_SUCH_OBJECT;
- return NULL;
- }
- /* get the user entry based on the username */
- entry = uid2entry(session, username, &rc);
- if (entry == NULL)
- {
- if (rc == LDAP_SUCCESS)
- rc = LDAP_NO_SUCH_OBJECT;
- log_log(LOG_DEBUG, "\"%s\": user not found: %s", username, ldap_err2string(rc));
- *rcp = rc;
- }
- return entry;
-}
-
/* update the username value from the entry if needed */
static void update_username(MYLDAP_ENTRY *entry, char *username,
size_t username_len)
@@ -156,6 +141,16 @@ static void update_username(MYLDAP_ENTRY *entry, char *username,
}
}
+static int check_password(const char *password, const char *hash)
+{
+ int ret;
+ struct crypt_data data;
+ data.initialized = 0;
+ ret = (strcmp(crypt_r(password, hash, &data), hash) == 0);
+ memset(&data, 0, sizeof(data));
+ return ret;
+}
+
static int check_shadow(MYLDAP_SESSION *session, const char *username,
char *authzmsg, size_t authzmsgsz,
int check_maxdays, int check_mindays)
@@ -260,95 +255,73 @@ static int check_shadow(MYLDAP_SESSION *session, const char *username,
}
/* check authentication credentials of the user */
-int nslcd_pam_authc(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid)
-{
- int32_t tmpint32;
- int rc;
- char username[BUFLEN_NAME], service[BUFLEN_NAME], ruser[BUFLEN_NAME], rhost[BUFLEN_HOSTNAME], tty[64];
- char password[BUFLEN_PASSWORD];
- const char *userdn;
- MYLDAP_ENTRY *entry;
- int authzrc = NSLCD_PAM_SUCCESS;
- char authzmsg[BUFLEN_MESSAGE];
- authzmsg[0] = '\0';
- /* read request parameters */
+NSLCD_HANDLE_UID(
+ pam, authc, NSLCD_ACTION_PAM_AUTHC
+ ,/* decls */
+ char username[BUFLEN_NAME],
+ service[BUFLEN_NAME],
+ ruser[BUFLEN_NAME],
+ rhost[BUFLEN_HOSTNAME],
+ tty[64],
+ password[BUFLEN_PASSWORD];
+ struct authc _entry;
+ ,/* read */
READ_STRING(fp, username);
READ_STRING(fp, service);
READ_STRING(fp, ruser);
READ_STRING(fp, rhost);
READ_STRING(fp, tty);
READ_STRING(fp, password);
- /* log call */
log_setrequest("authc=\"%s\"", username);
log_log(LOG_DEBUG, "nslcd_pam_authc(\"%s\",\"%s\",\"%s\")",
username, service, *password ? "***" : "");
- /* write the response header */
- WRITE_INT32(fp, NSLCD_VERSION);
- WRITE_INT32(fp, NSLCD_ACTION_PAM_AUTHC);
- /* if the username is blank and rootpwmoddn is configured, try to
- authenticate as administrator, otherwise validate request as usual */
- if (*username == '\0')
+ ,/* check */
+ if (!isvalidname(username))
{
- if (nslcd_cfg->rootpwmoddn == NULL)
- {
- log_log(LOG_NOTICE, "rootpwmoddn not configured");
- /* we break the protocol */
- memset(password, 0, sizeof(password));
- return -1;
- }
- userdn = nslcd_cfg->rootpwmoddn;
- /* if the caller is root we will allow the use of the rootpwmodpw option */
- if ((*password == '\0') && (calleruid == 0) && (nslcd_cfg->rootpwmodpw != NULL))
- {
- if (strlen(nslcd_cfg->rootpwmodpw) >= sizeof(password))
- {
- log_log(LOG_ERR, "nslcd_pam_authc(): rootpwmodpw will not fit in password");
- memset(password, 0, sizeof(password));
- return -1;
- }
- strcpy(password, nslcd_cfg->rootpwmodpw);
- }
+ log_log(LOG_WARNING, "request denied by validnames option");
+ return -1;
}
- else
+ ,/* search(int *rcp) */
+ struct authc,
+ static size_t i = 0;
+ struct passwd *user = NULL;
+ struct authc *entry = &_entry;
+
+ *rcp = 0;
+
+ for (; i < session->cnt; i++)
{
- /* try normal authentication, lookup the user entry */
- entry = validate_user(session, username, &rc);
- if (entry == NULL)
- {
- /* for user not found we just say no result */
- if (rc == LDAP_NO_SUCH_OBJECT)
- {
- WRITE_INT32(fp, NSLCD_RESULT_END);
- }
- memset(password, 0, sizeof(password));
- return -1;
+ if (strcmp(username, session->users[i].pw_name)==0) {
+ *rcp = 0;
+ i = session->cnt;
+ user = &(session->users[i]);
}
- userdn = myldap_get_dn(entry);
- update_username(entry, username, sizeof(username));
}
+ if (user == NULL)
+ return NULL;
+
+ entry->authz_msg[0] = '\0';
+
/* try authentication */
- rc = try_bind(userdn, password, &authzrc, authzmsg, sizeof(authzmsg));
- if (rc == LDAP_SUCCESS)
- log_log(LOG_DEBUG, "bind successful");
- /* map result code */
- switch (rc)
- {
- case LDAP_SUCCESS: rc = NSLCD_PAM_SUCCESS; break;
- case LDAP_INVALID_CREDENTIALS: rc = NSLCD_PAM_AUTH_ERR; break;
- default: rc = NSLCD_PAM_AUTH_ERR;
- }
+ entry->authc_rc = check_password(password, hash)
+ ? NSLCD_PAM_SUCCESS
+ : NSLCD_PAM_AUTH_ERR;
+ entry->authz_rc = entry->authc_rc;
+ myldap_get_policy_response(session, &(entry->authz_rc), &(entry->authz_msg))
+
/* perform shadow attribute checks */
- if ((*username != '\0') && (authzrc == NSLCD_PAM_SUCCESS))
- authzrc = check_shadow(session, username, authzmsg, sizeof(authzmsg), 1, 0);
- /* write response */
+ if (entry->authz_rc == NSLCD_PAM_SUCCESS)
+ entry->authz_rc = check_shadow(session, username, entry->authz_msg, sizeof(entry->authz_msg), 1, 0);
+
+ return entry;
+ ,/* write */
WRITE_INT32(fp, NSLCD_RESULT_BEGIN);
- WRITE_INT32(fp, rc);
+ WRITE_INT32( fp, entry->authc_rc);
WRITE_STRING(fp, username);
- WRITE_INT32(fp, authzrc);
- WRITE_STRING(fp, authzmsg);
- WRITE_INT32(fp, NSLCD_RESULT_END);
+ WRITE_INT32( fp, entry->authz_rc);
+ WRITE_STRING(fp, entry->authz_msg);
+ ,/* cleanup */
memset(password, 0, sizeof(password));
- return 0;
}
static void autzsearch_var_add(DICT *dict, const char *name,
@@ -501,15 +474,16 @@ static int try_autzsearch(MYLDAP_SESSION *session, const char *dn,
}
/* check authorisation of the user */
-int nslcd_pam_authz(TFILE *fp, MYLDAP_SESSION *session)
-{
- int32_t tmpint32;
- int rc;
- char username[BUFLEN_NAME], service[BUFLEN_NAME], ruser[BUFLEN_NAME], rhost[BUFLEN_HOSTNAME], tty[64];
- MYLDAP_ENTRY *entry;
- char authzmsg[BUFLEN_MESSAGE];
- authzmsg[0] = '\0';
- /* read request parameters */
+NSLCD_HANDLE(
+ pam, authz, NSLCD_ACTION_PAM_AUTHZ
+ ,/* decls */
+ char username[BUFLEN_NAME],
+ service[BUFLEN_NAME],
+ ruser[BUFLEN_NAME],
+ rhost[BUFLEN_HOSTNAME],
+ tty[64];
+ struct authz _entry;
+ ,/* read */
READ_STRING(fp, username);
READ_STRING(fp, service);
READ_STRING(fp, ruser);
@@ -519,46 +493,54 @@ int nslcd_pam_authz(TFILE *fp, MYLDAP_SESSION *session)
log_setrequest("authz=\"%s\"", username);
log_log(LOG_DEBUG, "nslcd_pam_authz(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")",
username, service, ruser, rhost, tty);
- /* write the response header */
- WRITE_INT32(fp, NSLCD_VERSION);
- WRITE_INT32(fp, NSLCD_ACTION_PAM_AUTHZ);
- /* validate request */
- entry = validate_user(session, username, &rc);
- if (entry == NULL)
+ ,/* search(int *rcp) */
+ struct authz,
+ static size_t i = 0;
+ struct passwd *user = NULL;
+ struct authz *entry = &_entry;
+
+ *rcp = 0;
+
+ for (; i < session->cnt; i++)
{
- /* for user not found we just say no result */
- if (rc == LDAP_NO_SUCH_OBJECT)
- {
- WRITE_INT32(fp, NSLCD_RESULT_END);
+ if (strcmp(username, session->users[i].pw_name)==0) {
+ *rcp = 0;
+ i = session->cnt;
+ user = &(session->users[i]);
}
- return -1;
}
+ if (user == NULL)
+ return NULL;
+
/* check authorisation search */
- rc = try_autzsearch(session, myldap_get_dn(entry), username, service, ruser,
- rhost, tty);
+ int rc = try_autzsearch(session, myldap_get_dn(entry),
+ username, service, ruser, rhost, tty);
if (rc != LDAP_SUCCESS)
{
- WRITE_INT32(fp, NSLCD_RESULT_BEGIN);
- WRITE_INT32(fp, NSLCD_PAM_PERM_DENIED);
- WRITE_STRING(fp, "LDAP authorisation check failed");
- WRITE_INT32(fp, NSLCD_RESULT_END);
- return 0;
+ entry->authz_rc = NSLCD_PAM_PERM_DENIED);
+ strcpy(entry->authz_msg, "LDAP authorisation check failed");
+ return entry;
}
+
/* perform shadow attribute checks */
- rc = check_shadow(session, username, authzmsg, sizeof(authzmsg), 0, 0);
- /* write response */
+ entry->authz_rc = check_shadow(session, username, entry->authz_msg, sizeof(entry->authz_msg), 0, 0);
+
+ ,/* write response */
WRITE_INT32(fp, NSLCD_RESULT_BEGIN);
- WRITE_INT32(fp, rc);
- WRITE_STRING(fp, authzmsg);
- WRITE_INT32(fp, NSLCD_RESULT_END);
- return 0;
+ WRITE_INT32( fp, entry->authz_rc);
+ WRITE_STRING(fp, entry->authz_msg);
+ ,/* cleanup */
}
int nslcd_pam_sess_o(TFILE *fp, MYLDAP_SESSION UNUSED(*session))
{
int32_t tmpint32;
- char username[BUFLEN_NAME], service[BUFLEN_NAME], ruser[BUFLEN_NAME], rhost[BUFLEN_HOSTNAME], tty[64];
- char sessionid[25];
+ char username[BUFLEN_NAME],
+ service[BUFLEN_NAME],
+ ruser[BUFLEN_NAME],
+ rhost[BUFLEN_HOSTNAME],
+ tty[64],
+ sessionid[25];
static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"01234567890";
@@ -590,8 +572,12 @@ int nslcd_pam_sess_o(TFILE *fp, MYLDAP_SESSION UNUSED(*session))
int nslcd_pam_sess_c(TFILE *fp, MYLDAP_SESSION UNUSED(*session))
{
int32_t tmpint32;
- char username[BUFLEN_NAME], service[BUFLEN_NAME], ruser[BUFLEN_NAME], rhost[BUFLEN_HOSTNAME], tty[64];
- char sessionid[64];
+ char username[BUFLEN_NAME],
+ service[BUFLEN_NAME],
+ ruser[BUFLEN_NAME],
+ rhost[BUFLEN_HOSTNAME],
+ tty[64],
+ sessionid[64];
/* read request parameters */
READ_STRING(fp, username);
READ_STRING(fp, service);
@@ -735,7 +721,11 @@ int nslcd_pam_pwmod(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid)
{
int32_t tmpint32;
int rc;
- char username[BUFLEN_NAME], service[BUFLEN_NAME], ruser[BUFLEN_NAME], rhost[BUFLEN_HOSTNAME], tty[64];
+ char username[BUFLEN_NAME],
+ service[BUFLEN_NAME],
+ ruser[BUFLEN_NAME],
+ rhost[BUFLEN_HOSTNAME],
+ tty[64];
int asroot;
char oldpassword[BUFLEN_PASSWORD];
char newpassword[BUFLEN_PASSWORD];