Ignore:
Timestamp:
Jul 29, 2008, 7:18:13 AM (14 years ago)
Author:
andersk
Message:
Update to nss_nonlocal 1.7, which fixes the nscd bug.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • server/common/oursrc/nss_nonlocal/nonlocal-passwd.c

    r750 r782  
    4444#include "nonlocal.h"
    4545
    46 #define MAGIC_LOCAL_PW_BUFLEN (sysconf(_SC_GETPW_R_SIZE_MAX) + 7)
     46
     47enum nss_status
     48_nss_nonlocal_getpwuid_r(uid_t uid, struct passwd *pwd,
     49                         char *buffer, size_t buflen, int *errnop);
     50enum nss_status
     51_nss_nonlocal_getpwnam_r(const char *name, struct passwd *pwd,
     52                         char *buffer, size_t buflen, int *errnop);
    4753
    4854
     
    6167check_nonlocal_uid(const char *user, uid_t uid, int *errnop)
    6268{
    63     enum nss_status status = NSS_STATUS_SUCCESS;
     69    static const char *fct_name = "getpwuid_r";
     70    static service_user *startp = NULL;
     71    static void *fct_start = NULL;
     72    enum nss_status status;
     73    service_user *nip;
     74    union {
     75        enum nss_status (*l)(uid_t uid, struct passwd *pwd,
     76                             char *buffer, size_t buflen, int *errnop);
     77        void *ptr;
     78    } fct;
    6479    struct passwd pwbuf;
    65     struct passwd *pwbufp = &pwbuf;
    66     int ret;
    6780    int old_errno = errno;
    68     int buflen = MAGIC_LOCAL_PW_BUFLEN;
     81
     82    int buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
    6983    char *buf = malloc(buflen);
    7084    if (buf == NULL) {
     
    7387        return NSS_STATUS_TRYAGAIN;
    7488    }
    75     errno = 0;
    76     ret = getpwuid_r(uid, pwbufp, buf, buflen, &pwbufp);
    77     if (ret != 0) {
    78         *errnop = errno;
    79         status = NSS_STATUS_TRYAGAIN;
    80     } else if (pwbufp != NULL) {
     89
     90    if (fct_start == NULL &&
     91        __nss_passwd_lookup(&startp, fct_name, &fct_start) != 0) {
     92        free(buf);
     93        return NSS_STATUS_UNAVAIL;
     94    }
     95    nip = startp;
     96    fct.ptr = fct_start;
     97    do {
     98        if (fct.l == _nss_nonlocal_getpwuid_r)
     99            status = NSS_STATUS_NOTFOUND;
     100        else
     101            status = DL_CALL_FCT(fct.l, (uid, &pwbuf, buf, buflen, errnop));
     102        if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
     103            break;
     104    } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     105
     106    if (status == NSS_STATUS_SUCCESS) {
    81107        syslog(LOG_ERR, "nss_nonlocal: possible spoofing attack: non-local user %s has same UID as local user %s!\n", user, pwbuf.pw_name);
    82108        status = NSS_STATUS_NOTFOUND;
    83     }
     109    } else if (status != NSS_STATUS_TRYAGAIN) {
     110        status = NSS_STATUS_SUCCESS;
     111    }
     112
    84113    free(buf);
    85     errno = old_errno;
    86114    return status;
    87115}
     
    90118check_nonlocal_user(const char *user, int *errnop)
    91119{
    92     enum nss_status status = NSS_STATUS_SUCCESS;
     120    static const char *fct_name = "getpwnam_r";
     121    static service_user *startp = NULL;
     122    static void *fct_start = NULL;
     123    enum nss_status status;
     124    service_user *nip;
     125    union {
     126        enum nss_status (*l)(const char *name, struct passwd *pwd,
     127                             char *buffer, size_t buflen, int *errnop);
     128        void *ptr;
     129    } fct;
    93130    struct passwd pwbuf;
    94     struct passwd *pwbufp = &pwbuf;
    95     int ret;
    96131    int old_errno = errno;
    97     int buflen = MAGIC_LOCAL_PW_BUFLEN;
     132
     133    int buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
    98134    char *buf = malloc(buflen);
    99135    if (buf == NULL) {
     
    102138        return NSS_STATUS_TRYAGAIN;
    103139    }
    104     errno = 0;
    105     ret = getpwnam_r(user, pwbufp, buf, buflen, &pwbufp);
    106     if (ret != 0) {
    107         *errnop = errno;
    108         status = NSS_STATUS_TRYAGAIN;
    109     } else if (pwbufp != NULL) {
     140
     141    if (fct_start == NULL &&
     142        __nss_passwd_lookup(&startp, fct_name, &fct_start) != 0) {
     143        free(buf);
     144        return NSS_STATUS_UNAVAIL;
     145    }
     146    nip = startp;
     147    fct.ptr = fct_start;
     148    do {
     149        if (fct.l == _nss_nonlocal_getpwnam_r)
     150            status = NSS_STATUS_NOTFOUND;
     151        else
     152            status = DL_CALL_FCT(fct.l, (user, &pwbuf, buf, buflen, errnop));
     153        if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
     154            break;
     155    } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     156
     157    if (status == NSS_STATUS_SUCCESS)
    110158        status = NSS_STATUS_NOTFOUND;
    111     }
     159    else if (status != NSS_STATUS_TRYAGAIN)
     160        status = NSS_STATUS_SUCCESS;
     161
    112162    free(buf);
    113     errno = old_errno;
    114163    return status;
    115164}
     
    195244
    196245    char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV);
    197     if (buflen == MAGIC_LOCAL_PW_BUFLEN ||
    198         (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0'))
     246    if (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0')
    199247        return NSS_STATUS_UNAVAIL;
    200248
     
    242290
    243291    char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV);
    244     if (buflen == MAGIC_LOCAL_PW_BUFLEN ||
    245         (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0'))
     292    if (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0')
    246293        return NSS_STATUS_UNAVAIL;
    247294
     
    289336
    290337    char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV);
    291     if (buflen == MAGIC_LOCAL_PW_BUFLEN ||
    292         (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0'))
     338    if (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0')
    293339        return NSS_STATUS_UNAVAIL;
    294340
Note: See TracChangeset for help on using the changeset viewer.