From 0ac1ff73698b57d06657758519eb9443fec852f9 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 17 Dec 2014 17:10:41 -0500 Subject: Re-jigger to not use closures --- nslcd/common.h | 100 ++++++++++-------- nslcd/db_pam.c | 283 ++++++++++++++++++++++++++++---------------------- nslcd/db_passwd.c | 125 ++++++++++++---------- nslcd/db_shadow.c | 125 ++++++++++++---------- nslcd/hackers.c | 2 +- nslcd/hackers_parse.c | 2 +- 6 files changed, 354 insertions(+), 283 deletions(-) diff --git a/nslcd/common.h b/nslcd/common.h index 6477284..ca543fb 100644 --- a/nslcd/common.h +++ b/nslcd/common.h @@ -101,56 +101,64 @@ void invalidator_do(enum nss_map_selector map); #include "dispatch.h" /* macros for generating service handling code */ -#define NSLCD_HANDLE(db, fn, fndecls, fnread, fncheck, tentry, fnsearch, fnwrite, fnclean) \ - int nslcd_##db##_##fn(TFILE *_handle_fp, struct session *_handle_session) \ - NSLCD_HANDLE_BODY(db, fn, fndecls, fnread, fncheck, tentry, fnsearch, fnwrite, fnclean) -#define NSLCD_HANDLE_UID(db, fn, fndecls, fnread, fncheck, tentry, fnsearch, fnwrite, fnclean) \ - int nslcd_##db##_##fn(TFILE *_handle_fp, struct session *_handle_session, uid_t calleruid) \ - NSLCD_HANDLE_BODY(db, fn, fndecls, fnread, fncheck, tentry, fnsearch, fnwrite, fnclean) -#define NSLCD_HANDLE_BODY(db, fn, fndecls, fnread, fncheck, tentry, fnsearch, fnwrite, fnclean) \ - { \ - /* define common variables */ \ - tentry *_handle_entry = NULL; \ - int _handle_rc = 1; \ - bool _handle_more = true; \ - fndecls \ - __extension__ int read(TFILE *fp) { fnread } \ - __extension__ tentry *search(struct session *session, \ - int *rcp, bool *more) { fnsearch } \ - __extension__ int write(TFILE *fp, tentry *entry) { fnwrite } \ - __extension__ void clean() { fnclean } \ - /* read request parameters */ \ - if ((_handle_rc = read(_handle_fp)) != 0) \ - return _handle_rc; \ - _handle_rc = 1; \ - /* validate request parameters */ \ - fncheck \ - /* write the response header */ \ - WRITE_INT32(_handle_fp, NSLCD_VERSION); \ - WRITE_INT32(_handle_fp, NSLCD_ACTION_##db##_##fn); \ - /* go over results */ \ - while ((_handle_entry = search(_handle_session, &_handle_rc, &_handle_more)) != NULL)\ - { \ - if ( write(_handle_fp, _handle_entry) ) { \ - clean(); \ - return -1; \ - } \ - if (! _handle_more) \ - break; \ - } \ - /* write the final result code */ \ - if (_handle_rc == 0) \ - { \ - WRITE_INT32(_handle_fp, NSLCD_RESULT_END); \ - } \ - clean(); \ - return 0; \ +#define NSLCD_HANDLE( db, fn, type_request, type_searchdat, type_entry, fnread, fncheck, fnsearch, fnwrite, fnclean) \ + int nslcd_##db##_##fn(TFILE *_fp, struct session *_session) \ + NSLCD_HANDLE_BODY(db, fn, type_request, type_searchdat, type_entry, fnread, fncheck, fnsearch, fnwrite, fnclean) +#define NSLCD_HANDLE_UID(db, fn, type_request, type_searchdat, type_entry, fnread, fncheck, fnsearch, fnwrite, fnclean) \ + int nslcd_##db##_##fn(TFILE *_fp, struct session *_session, uid_t calleruid) \ + NSLCD_HANDLE_BODY(db, fn, type_request, type_searchdat, type_entry, fnread, fncheck, fnsearch, fnwrite, fnclean) +#define NSLCD_HANDLE_BODY(_db, _fn, _type_request, _type_searchdat, _type_entry, _fnread, _fncheck, _fnsearch, _fnwrite, _fnclean) \ + { \ + /* define common variables */ \ + int _rc = 1; \ + _type_request _request; memset(&_request, 0, sizeof(_request)); \ + _type_searchdat _searchdat; memset(&_searchdat, 0, sizeof(_searchdat)); \ + _type_entry *_entry = NULL; \ + __extension__ int _read(TFILE *fp, __typeof__(_request) *req) \ + { _fnread } \ + __extension__ int _check(__typeof__(_request) *req) \ + { _fncheck } \ + __extension__ int _search(struct session *session, \ + __typeof__(_request) *req, \ + __typeof__(_searchdat) *searchdat, \ + __typeof__(_entry) *entry) \ + { _fnsearch } \ + __extension__ int _write(TFILE *fp, __typeof__(_entry) entry) \ + { _fnwrite } \ + __extension__ void _clean(__typeof__(_request) *req, \ + __typeof__(_searchdat) *searchdat) \ + { _fnclean } \ + /* read request parameters */ \ + if ((_rc = _read(_fp, &_request)) != 0) \ + return _rc; \ + /* validate request parameters */ \ + if ((_rc = _check(&_request)) != 0) \ + return _rc; \ + /* write the response header */ \ + WRITE_INT32(_fp, NSLCD_VERSION); \ + WRITE_INT32(_fp, NSLCD_ACTION_##_db##_##_fn); \ + /* go over results */ \ + do { \ + _rc = _search(_session, &_request, &_searchdat, &_entry); \ + if (_entry != NULL) { \ + /* write the response */ \ + WRITE_INT32(_fp, NSLCD_RESULT_BEGIN); \ + if ( _write(_fp, _entry) != 0 ) { \ + _clean(&_request, &_searchdat); \ + return -1; \ + } \ + } \ + } while (_rc == 0 && _entry != NULL ); \ + if (_rc == 0) \ + WRITE_INT32(_fp, NSLCD_RESULT_END); \ + _clean(&_request, &_searchdat); \ + return 0; \ } /* macro to compare strings which uses the ignorecase config option to determine whether or not to do a case-sensitive match */ -#define STR_CMP(str1, str2) \ - (nslcd_cfg->ignorecase == 1 ? \ +#define STR_CMP(str1, str2) \ + (nslcd_cfg->ignorecase == 1 ? \ strcasecmp(str1, str2) : strcmp(str1, str2)) #endif /* not NSLCD__COMMON_H */ 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 */ ) diff --git a/nslcd/db_passwd.c b/nslcd/db_passwd.c index ed57098..5696aaf 100644 --- a/nslcd/db_passwd.c +++ b/nslcd/db_passwd.c @@ -67,104 +67,115 @@ static int write_passwd(TFILE *fp, struct passwd *entry, uid_t calleruid) if ((passwd == NULL) || (calleruid != 0)) passwd = "!"; } - if (entry->pw_uid >= nslcd_cfg->nss_min_uid) - { - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, entry->pw_name ); - WRITE_STRING(fp, passwd ); - WRITE_INT32( fp, entry->pw_uid ); - WRITE_INT32( fp, entry->pw_gid ); - WRITE_STRING(fp, entry->pw_gecos); - WRITE_STRING(fp, entry->pw_dir ); - WRITE_STRING(fp, entry->pw_shell); - } + WRITE_STRING(fp, entry->pw_name ); + WRITE_STRING(fp, passwd ); + WRITE_INT32( fp, entry->pw_uid ); + WRITE_INT32( fp, entry->pw_gid ); + WRITE_STRING(fp, entry->pw_gecos); + WRITE_STRING(fp, entry->pw_dir ); + WRITE_STRING(fp, entry->pw_shell); return 0; } NSLCD_HANDLE_UID(PASSWD, BYNAME - ,/* decls */ - char name[BUFLEN_NAME]; - ,/* int read(TFILE *fp) */ - READ_STRING(fp, name); - log_setrequest("passwd=\"%s\"", name); + ,/* request data */ + struct { + char name[BUFLEN_NAME]; + } + ,/* search data */ + struct { int cnt; } + ,/* entry type */ + struct passwd + ,/* int read(TFILE *fp, *req) */ + READ_STRING(fp, req->name); + log_setrequest("passwd=\"%s\"", req->name); return 0; - ,/* check */ - if (!isvalidname(name)) + ,/* check(*req) */ + if (!isvalidname(req->name)) { log_log(LOG_WARNING, "request denied by validnames option"); return -1; } nsswitch_check_reload(); - ,/* tentry *search(struct session *session, int *rcp, bool *more) */ - struct passwd, - *more = false; + return 0; + ,/* search(*session, *req, *searchdat, *entry) */ + *entry = NULL; + if (searchdat->cnt++ != 0) + return 0; for (size_t i = 0; i < session->cnt; i++) { if (session->users[i].pw_uid != UID_INVALID && - STR_CMP(name, session->users[i].pw_name)==0) { - *rcp = 0; - return &(session->users[i]); + STR_CMP(req->name, session->users[i].pw_name)==0) { + *entry = &(session->users[i]); + if ((*entry)->pw_uid < nslcd_cfg->nss_min_uid) { + *entry = NULL; + return -1; + } + break; } } - return NULL; + return 0; ,/* int write(TFILE *fp, tentry *entry) */ return write_passwd(fp, entry, calleruid); ,/* cleanup */ ) NSLCD_HANDLE_UID(PASSWD, BYUID - ,/* decls */ - uid_t uid; + ,/* request data */ + struct { uid_t uid; } + ,/* search data */ + struct { int cnt; } + ,/* entry type */ + struct passwd ,/* int read(TFILe *fp) */ - READ_INT32(fp, uid); - log_setrequest("passwd=%lu", (unsigned long int)uid); + READ_INT32(fp, req->uid); + log_setrequest("passwd=%lu", (unsigned long int)(req->uid)); return 0; ,/* check */ - if (uid < nslcd_cfg->nss_min_uid) - { - /* return an empty result */ - WRITE_INT32(_handle_fp, NSLCD_VERSION); - WRITE_INT32(_handle_fp, NSLCD_ACTION_PASSWD_BYUID); - WRITE_INT32(_handle_fp, NSLCD_RESULT_END); - return 0; - } nsswitch_check_reload(); - ,/* tentry *search(struct session *session, int *rcp, bool *more) */ - struct passwd, - *more = false; + return 0; + ,/* search(*session, *req, *searchdat, *entry) */ + *entry = NULL; + if (req->uid < nslcd_cfg->nss_min_uid || searchdat->cnt++ != 0) + return 0; for (size_t i = 0; i < session->cnt; i++) { - if (uid == session->users[i].pw_uid) { - *rcp = 0; - return &(session->users[i]); + if (req->uid == session->users[i].pw_uid) { + *entry = &(session->users[i]); + break; } } - return NULL; - ,/* int write(TFILe *fp, tentry *entry */ + return 0; + ,/* int write(TFILe *fp, *entry) */ return write_passwd(fp, entry, calleruid); ,/* cleanup */ ) NSLCD_HANDLE_UID(PASSWD, ALL - ,/* decls */ - ,/* int read(TFILE *fp) */ + ,/* request data */ + int + ,/* search data */ + struct { size_t i; } + ,/* entry type */ + struct passwd + ,/* int read(TFILE *fp, *req) */ log_setrequest("passwd(all)"); return 0; ,/* check */ nsswitch_check_reload(); - ,/* tentry *search(struct session *session, int *rcp, bool *more) */ - struct passwd, - static __thread size_t i = 0; - *more = true; - for (; i < session->cnt; i++) + return 0; + ,/* search(*session, *req, *searchdat, *entry) */ + *entry = NULL; + for (; searchdat->i < session->cnt; searchdat->i++) { - if (session->users[i].pw_uid != UID_INVALID) { - *rcp = 0; - return &(session->users[i]); + if (session->users[searchdat->i].pw_uid != UID_INVALID && + session->users[searchdat->i].pw_uid >= nslcd_cfg->nss_min_uid) { + *entry = &(session->users[searchdat->i]); + searchdat->i++; + return 0; } } - i = 0; - return NULL; + return 0; ,/* int write(TFILE *fp, tentry *entry) */ return write_passwd(fp, entry, calleruid); ,/* cleanup */ diff --git a/nslcd/db_shadow.c b/nslcd/db_shadow.c index 4011c7e..cd791a9 100644 --- a/nslcd/db_shadow.c +++ b/nslcd/db_shadow.c @@ -29,16 +29,16 @@ #include "log.h" struct shadow { - /* for the integers: a value < 0 means empty */ - char *name; /* the account name */ - char *hash; /* a crypt(3) formatted password hash */ - int32_t lastchange_date; /* days since Jan 1, 1970 */ - int32_t min_days; /* minimum number of days between changes */ - int32_t max_days; /* maximum number of days between changes */ - int32_t warn_days; /* how long before max_days is up to warn the user */ - int32_t inact_days; /* how long after max_days to accept the pw */ - int32_t expire_date; /* days since Jarn 1, 1970 */ - int32_t flag; /* unused on Linux/Glibc */ + /* for the integers: a value < 0 means empty */ + char *name; /* the account name */ + char *hash; /* a crypt(3) formatted password hash */ + int32_t lastchange_date; /* days since Jan 1, 1970 */ + int32_t min_days; /* minimum number of days between changes */ + int32_t max_days; /* maximum number of days between changes */ + int32_t warn_days; /* how long before max_days is up to warn the user */ + int32_t inact_days; /* how long after max_days to accept the pw */ + int32_t expire_date; /* days since Jarn 1, 1970 */ + int32_t flag; /* unused on Linux/Glibc */ }; static void passwd2shadow(struct passwd *p, struct shadow *s) @@ -54,79 +54,94 @@ static void passwd2shadow(struct passwd *p, struct shadow *s) s->flag = -1; } -static int write_shadow(TFILE *fp, struct shadow *entry, uid_t calleruid) +static int write_shadow(TFILE *fp, struct shadow *entry) { - if (calleruid == 0) - { - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, entry->name); - WRITE_STRING(fp, entry->hash ? entry->hash : "!"); - WRITE_INT32( fp, entry->lastchange_date); - WRITE_INT32( fp, entry->min_days); - WRITE_INT32( fp, entry->max_days); - WRITE_INT32( fp, entry->warn_days); - WRITE_INT32( fp, entry->inact_days); - WRITE_INT32( fp, entry->expire_date); - WRITE_INT32( fp, entry->flag); - } + WRITE_STRING(fp, entry->name); + WRITE_STRING(fp, entry->hash ? entry->hash : "!"); + WRITE_INT32( fp, entry->lastchange_date); + WRITE_INT32( fp, entry->min_days); + WRITE_INT32( fp, entry->max_days); + WRITE_INT32( fp, entry->warn_days); + WRITE_INT32( fp, entry->inact_days); + WRITE_INT32( fp, entry->expire_date); + WRITE_INT32( fp, entry->flag); return 0; } NSLCD_HANDLE_UID(SHADOW, BYNAME - ,/* decls */ - char name[BUFLEN_NAME]; - struct shadow ret; - ,/* int read(TFILE *fp) */ - READ_STRING(fp, name); - log_setrequest("shadow=\"%s\"", name); + ,/* request data */ + struct { + char name[BUFLEN_NAME]; + } + ,/* search data */ + struct { + int cnt; + struct shadow ret; + } + ,/* entry type */ + struct shadow + ,/* int read(TFILE *fp, *req) */ + READ_STRING(fp, req->name); + log_setrequest("shadow=\"%s\"", req->name); return 0; ,/* check */ - if (!isvalidname(name)) + if (!isvalidname(req->name)) { log_log(LOG_WARNING, "request denied by validnames option"); return -1; } - ,/* tentry *search(struct session *session, int *rcp, bool *more) */ - struct shadow, - *more = false; + return 0; + ,/* search(*session, *req, *searchdat, *entry) */ + *entry = NULL; + if (calleruid != 0 || searchdat->cnt++ != 0) + return 0; for (size_t i = 0; i < session->cnt; i++) { if (session->users[i].pw_uid != UID_INVALID && - STR_CMP(name, session->users[i].pw_name)==0) + STR_CMP(req->name, session->users[i].pw_name)==0) { - *rcp = 0; - passwd2shadow(&(session->users[i]), &ret); - return &ret; + if (session->users[i].pw_uid < nslcd_cfg->nss_min_uid) + return -1; + passwd2shadow(&(session->users[i]), &(searchdat->ret)); + *entry = &(searchdat->ret); + break; } } - return NULL; + return 0; ,/* int write(TFILE *fp, tentry *entry) */ - return write_shadow(fp, entry, calleruid); + return write_shadow(fp, entry); ,/* cleanup */ ) NSLCD_HANDLE_UID(SHADOW, ALL - ,/* decls */ - struct shadow ret; - ,/* int read(TFILE *fp) */ + ,/* request data */ + int + ,/* search data */ + struct { + size_t i; + struct shadow ret; + } + ,/* entry type */ + struct shadow + ,/* int read(TFILE *fp, *req) */ log_setrequest("shadow(all)"); return 0; ,/* check */ - ,/* tentry *search(struct session *session, int *rcp, bool *more) */ - struct shadow, - static __thread size_t i = 0; - *more = true; - for (; i < session->cnt; i++) + return 0; + ,/* search(*session, *req, *searchdat, *entry) */ + *entry = NULL; + for (; searchdat->i < session->cnt; searchdat->i++) { - if (session->users[i].pw_uid != UID_INVALID) { - *rcp = 0; - passwd2shadow(&(session->users[i]), &ret); - return &ret; + if (session->users[searchdat->i].pw_uid != UID_INVALID && + session->users[searchdat->i].pw_uid >= nslcd_cfg->nss_min_uid) { + passwd2shadow(&(session->users[searchdat->i]), &(searchdat->ret)); + *entry = &(searchdat->ret); + searchdat->i++; + break; } } - i = 0; - return NULL; + return 0; ,/* write */ - return write_shadow(fp, entry, calleruid); + return write_shadow(fp, entry); ,/* cleanup */ ) diff --git a/nslcd/hackers.c b/nslcd/hackers.c index 8f3e6f4..fe0e614 100644 --- a/nslcd/hackers.c +++ b/nslcd/hackers.c @@ -58,4 +58,4 @@ session_messup(struct session *sess) { void session_cleanup(struct session *sess) { pthread_rwlock_unlock(&(sess->lock)); -} +} diff --git a/nslcd/hackers_parse.c b/nslcd/hackers_parse.c index 1cb1681..0c9b6f8 100644 --- a/nslcd/hackers_parse.c +++ b/nslcd/hackers_parse.c @@ -64,7 +64,7 @@ #define PW_ALL ((1 << 7) - 1) /* Returns GID_INVALID on error */ -static +static gid_t name2gid(const char *name) { gid_t gid = GID_INVALID; -- cgit v1.2.3