diff options
Diffstat (limited to 'nslcd/db_pam.c')
-rw-r--r-- | nslcd/db_pam.c | 283 |
1 files changed, 160 insertions, 123 deletions
diff --git a/nslcd/db_pam.c b/nslcd/db_pam.c index 085a733..cabafa3 100644 --- a/nslcd/db_pam.c +++ b/nslcd/db_pam.c @@ -42,6 +42,7 @@ struct authc { int authc_rc; + char *username; int authz_rc; char authz_msg[BUFLEN_MESSAGE]; }; @@ -71,198 +72,234 @@ static int check_password_age(struct session *session, const char *username, /* check authentication credentials of the user */ NSLCD_HANDLE_UID(PAM, AUTHC - ,/* decls */ - char username[BUFLEN_NAME]; - char service[BUFLEN_NAME]; - char ruser[BUFLEN_NAME]; - char rhost[HOST_NAME_MAX+1]; - char tty[64]; - char password[BUFLEN_PASSWORD]; - struct authc _entry; - ,/* int read(TFILE *fp) */ - 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_setrequest("authc=\"%s\"", username); + ,/* request data */ + struct { + char username[BUFLEN_NAME]; + char service[BUFLEN_NAME]; + char ruser[BUFLEN_NAME]; + char rhost[HOST_NAME_MAX+1]; + char tty[64]; + char password[BUFLEN_PASSWORD]; + } + ,/* search data */ + struct authc + ,/* entry type */ + struct authc + ,/* int read(TFILE *fp, *req) */ + READ_STRING(fp, req->username); + READ_STRING(fp, req->service); + READ_STRING(fp, req->ruser); + READ_STRING(fp, req->rhost); + READ_STRING(fp, req->tty); + READ_STRING(fp, req->password); + log_setrequest("authc=\"%s\"", req->username); log_log(LOG_DEBUG, "nslcd_pam_authc(\"%s\",\"%s\",\"%s\")", - username, service, *password ? "***" : ""); + req->username, req->service, req->password[0] ? "***" : ""); return 0; ,/* check */ - if (!isvalidname(username)) + if (!isvalidname(req->username)) { log_log(LOG_WARNING, "request denied by validnames option"); return -1; } - ,/* search(int *rcp, bool *more) */ - struct authc, + return 0; + ,/* search(*session, *req, *searchdat, **entry) */ + if (searchdat->username != NULL) { + *entry = NULL; + return 0; + } struct passwd *user = NULL; - struct authc *entry = &_entry; - *more = false; for (size_t i = 0; i < session->cnt; i++) { if (session->users[i].pw_uid != UID_INVALID && - STR_CMP(username, session->users[i].pw_name)==0) { - *rcp = 0; + STR_CMP(req->username, session->users[i].pw_name)==0) { user = &(session->users[i]); + break; } } - if (user == NULL) - return NULL; + if (user == NULL) { + *entry = NULL; + return 0; + } - entry->authz_msg[0] = '\0'; + *entry = searchdat; + (*entry)->authz_msg[0] = '\0'; /* try authentication */ - entry->authc_rc = check_password(password, NULL /* TODO */) + (*entry)->authc_rc = check_password(req->password, NULL /* TODO */) ? NSLCD_PAM_SUCCESS : NSLCD_PAM_AUTH_ERR; - entry->authz_rc = entry->authc_rc; + (*entry)->authz_rc = (*entry)->authc_rc; - if (entry->authz_rc == NSLCD_PAM_SUCCESS) { + if ((*entry)->authz_rc == NSLCD_PAM_SUCCESS) { + (*entry)->username = user->pw_name; /* perform shadow attribute checks */ - entry->authz_rc = check_password_age(session, username, - entry->authz_msg, sizeof(entry->authz_msg), + (*entry)->authz_rc = check_password_age(session, user->pw_name, + (*entry)->authz_msg, sizeof((*entry)->authz_msg), true, false); } - - return entry; - ,/* write(TFILE *fp, tentry *entry) */ - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); + return 0; + ,/* write(TFILE *fp, *entry) */ WRITE_INT32( fp, entry->authc_rc); - WRITE_STRING(fp, username); + WRITE_STRING(fp, entry->username); WRITE_INT32( fp, entry->authz_rc); WRITE_STRING(fp, entry->authz_msg); return 0; - ,/* cleanup */ - memset(password, 0, sizeof(password)); + ,/* cleanup(*req, *searchdat) */ + memset(req->password, 0, sizeof(req->password)); ) /* check authorisation of the user */ NSLCD_HANDLE(PAM, AUTHZ - ,/* decls */ - char username[BUFLEN_NAME]; - char service[BUFLEN_NAME]; - char ruser[BUFLEN_NAME]; - char rhost[HOST_NAME_MAX+1]; - char tty[64]; - struct authz _entry; - ,/* int read(TFILE *fp) */ - READ_STRING(fp, username); - READ_STRING(fp, service); - READ_STRING(fp, ruser); - READ_STRING(fp, rhost); - READ_STRING(fp, tty); - return 0; - /* log call */ - log_setrequest("authz=\"%s\"", username); + ,/* request data */ + struct { + char username[BUFLEN_NAME]; + char service[BUFLEN_NAME]; + char ruser[BUFLEN_NAME]; + char rhost[HOST_NAME_MAX+1]; + char tty[64]; + } + ,/* search data */ + struct { + int cnt; + struct authz entry; + } + ,/* entry type */ + struct authz + ,/* int read(TFILE *fp, *req) */ + READ_STRING(fp, req->username); + READ_STRING(fp, req->service); + READ_STRING(fp, req->ruser); + READ_STRING(fp, req->rhost); + READ_STRING(fp, req->tty); + log_setrequest("authz=\"%s\"", req->username); log_log(LOG_DEBUG, "nslcd_pam_authz(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")", - username, service, ruser, rhost, tty); + req->username, req->service, req->ruser, req->rhost, req->tty); + return 0; ,/* check */ - ,/* search(int *rcp, bool *more) */ - struct authz, + return 0; + ,/* search(*session, *req, *searchdat, *entry) */ + if (searchdat->cnt++ != 0) { + *entry = NULL; + return 0; + } struct passwd *user = NULL; - struct authz *entry = &_entry; - *more = false; for (size_t i = 0; i < session->cnt; i++) { if (session->users[i].pw_uid != UID_INVALID && - STR_CMP(username, session->users[i].pw_name)==0) { - *rcp = 0; + STR_CMP(req->username, session->users[i].pw_name)==0) { user = &(session->users[i]); + break; } } - if (user == NULL) - return NULL; + if (user == NULL) { + *entry = NULL; + return 0; + } + + *entry = &(searchdat->entry); /* Parabola doesn't have any weird reasons for authorization to suddenly fail */ if (0) { - entry->authz_rc = NSLCD_PAM_PERM_DENIED; - strcpy(entry->authz_msg, "hackers.git authorization check failed"); + (*entry)->authz_rc = NSLCD_PAM_PERM_DENIED; + strcpy((*entry)->authz_msg, "hackers.git authorization check failed"); } else { /* perform shadow attribute checks */ - entry->authz_rc = check_password_age(session, username, - entry->authz_msg, sizeof(entry->authz_msg), + (*entry)->authz_rc = check_password_age(session, req->username, + (*entry)->authz_msg, sizeof((*entry)->authz_msg), false, false); } - return entry; + return 0; ,/* write(TFILE *fp, tentry *entry) */ - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); WRITE_INT32( fp, entry->authz_rc); WRITE_STRING(fp, entry->authz_msg); return 0; ,/* cleanup */ ) +static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "01234567890"; + NSLCD_HANDLE(PAM, SESS_O - ,/* decls */ - char username[BUFLEN_NAME]; - char service[BUFLEN_NAME]; - char ruser[BUFLEN_NAME]; - char rhost[HOST_NAME_MAX+1]; - char tty[64]; - char sessionid[25]; - static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "01234567890"; - size_t i; - ,/* int read(TFILE *fp) */ - READ_STRING(fp, username); - READ_STRING(fp, service); - READ_STRING(fp, ruser); - READ_STRING(fp, rhost); - READ_STRING(fp, tty); + ,/* request data */ + struct { + char username[BUFLEN_NAME]; + char service[BUFLEN_NAME]; + char ruser[BUFLEN_NAME]; + char rhost[HOST_NAME_MAX+1]; + char tty[64]; + } + ,/* search data */ + struct { + char sessionid[25]; + } + ,/* entry type */ + char + ,/* int read(TFILE *fp, *req) */ + READ_STRING(fp, req->username); + READ_STRING(fp, req->service); + READ_STRING(fp, req->ruser); + READ_STRING(fp, req->rhost); + READ_STRING(fp, req->tty); + log_setrequest("sess_o=\"%s\"", req->username); + return 0; + ,/* check(*req) */ return 0; + ,/* search(*session, *req, *searchdat, **entry) */ /* generate pseudo-random session id */ - for (i = 0; i < (sizeof(sessionid) - 1); i++) - sessionid[i] = alphabet[rand() % (sizeof(alphabet) - 1)]; - sessionid[i] = '\0'; - /* log call */ - log_setrequest("sess_o=\"%s\"", username); + if (searchdat->sessionid[0] == '\0') { + size_t i; + for (i = 0; i < (sizeof(searchdat->sessionid) - 1); i++) + searchdat->sessionid[i] = alphabet[rand() % (sizeof(alphabet) - 1)]; + searchdat->sessionid[i] = '\0'; + *entry = searchdat->sessionid; + } else { + *entry = NULL; + } log_log(LOG_DEBUG, "nslcd_pam_sess_o(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"): %s", - username, service, tty, rhost, ruser, sessionid); - ,/* check */ - ,/* search(int *rcp, bool *more) */ - void, - *more = false; - return (void*)1; /* return non-NULL */ - ,/* write(TFILE *fp, tentry *entry) */ - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, sessionid); + req->username, req->service, req->tty, req->rhost, req->ruser, searchdat->sessionid); + return 0; + ,/* write(TFILE *fp, *entry) */ + WRITE_STRING(fp, entry); return 0; ,/* cleanup */ ) NSLCD_HANDLE(PAM, SESS_C - ,/* decls */ - char username[BUFLEN_NAME]; - char service[BUFLEN_NAME]; - char ruser[BUFLEN_NAME]; - char rhost[HOST_NAME_MAX+1]; - char tty[64]; - char sessionid[64]; - ,/* int read(TFILE *fp) */ - READ_STRING(fp, username); - READ_STRING(fp, service); - READ_STRING(fp, ruser); - READ_STRING(fp, rhost); - READ_STRING(fp, tty); - READ_STRING(fp, sessionid); - log_setrequest("sess_c=\"%s\"", username); + ,/* request data */ + struct { + char username[BUFLEN_NAME]; + char service[BUFLEN_NAME]; + char ruser[BUFLEN_NAME]; + char rhost[HOST_NAME_MAX+1]; + char tty[64]; + char sessionid[64]; + } + ,/* search data */ + struct { int cnt; } + ,/* entry type */ + void + ,/* int read(TFILE *fp, *req) */ + READ_STRING(fp, req->username); + READ_STRING(fp, req->service); + READ_STRING(fp, req->ruser); + READ_STRING(fp, req->rhost); + READ_STRING(fp, req->tty); + READ_STRING(fp, req->sessionid); + log_setrequest("sess_c=\"%s\"", req->username); log_log(LOG_DEBUG, "nslcd_pam_sess_c(\"%s\",\"%s\",%s)", - username, service, sessionid); + req->username, req->service, req->sessionid); + return 0; + ,/* check(*req) */ + return 0; + ,/* search(*session, *req, *searchdat, **entry) */ + *entry = (searchdat->cnt++ == 0) ? (void*)1 : NULL; return 0; - ,/* check */ - ,/* tentry *search(struct session *session, int *rcp, bool *more) */ - void, - *more = false; - return (void*)1; /* return non-NULL */ ,/* int write(TFILE *fp, tentry *entry) */ - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); return 0; ,/* cleanup */ ) |