Changeset 782 for server/common


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.
Location:
server/common/oursrc/nss_nonlocal
Files:
2 added
2 deleted
4 edited

Legend:

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

    r750 r782  
    4242#include "nonlocal.h"
    4343
    44 #define MAGIC_LOCAL_GR_BUFLEN (sysconf(_SC_GETGR_R_SIZE_MAX) + 7)
    4544#define MAGIC_NONLOCAL_GROUPNAME "nss-nonlocal-users"
    4645#define MAGIC_LOCAL_GROUPNAME "nss-local-users"
     46
     47
     48enum nss_status
     49_nss_nonlocal_getgrnam_r(const char *name, struct group *grp,
     50                         char *buffer, size_t buflen, int *errnop);
     51
     52enum nss_status
     53_nss_nonlocal_getgrgid_r(gid_t gid, struct group *grp,
     54                         char *buffer, size_t buflen, int *errnop);
    4755
    4856
     
    6169check_nonlocal_gid(const char *user, gid_t gid, int *errnop)
    6270{
    63     enum nss_status status = NSS_STATUS_SUCCESS;
     71    static const char *fct_name = "getgrgid_r";
     72    static service_user *startp = NULL;
     73    static void *fct_start = NULL;
     74    enum nss_status status;
     75    service_user *nip;
     76    union {
     77        enum nss_status (*l)(gid_t gid, struct group *grp,
     78                             char *buffer, size_t buflen, int *errnop);
     79        void *ptr;
     80    } fct;
    6481    struct group gbuf;
    65     struct group *gbufp = &gbuf;
    66     int ret;
    6782    int old_errno = errno;
    68     int buflen = MAGIC_LOCAL_GR_BUFLEN;
     83
     84    int buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
    6985    char *buf = malloc(buflen);
    7086    if (buf == NULL) {
     
    7389        return NSS_STATUS_TRYAGAIN;
    7490    }
    75     errno = 0;
    76     ret = getgrgid_r(gid, gbufp, buf, buflen, &gbufp);
    77     if (ret != 0) {
    78         *errnop = old_errno;
    79         status = NSS_STATUS_TRYAGAIN;
    80     } else if (gbufp != NULL) {
     91
     92    if (fct_start == NULL &&
     93        __nss_group_lookup(&startp, fct_name, &fct_start) != 0) {
     94        free(buf);
     95        return NSS_STATUS_UNAVAIL;
     96    }
     97    nip = startp;
     98    fct.ptr = fct_start;
     99    do {
     100        if (fct.l == _nss_nonlocal_getgrgid_r)
     101            status = NSS_STATUS_NOTFOUND;
     102        else
     103            status = DL_CALL_FCT(fct.l, (gid, &gbuf, buf, buflen, errnop));
     104        if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
     105            break;
     106    } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     107
     108    if (status == NSS_STATUS_SUCCESS) {
    81109        syslog(LOG_WARNING, "nss_nonlocal: removing local group %u (%s) from non-local user %s\n", gbuf.gr_gid, gbuf.gr_name, user);
    82110        status = NSS_STATUS_NOTFOUND;
    83     }
     111    } else if (status != NSS_STATUS_TRYAGAIN) {
     112        status = NSS_STATUS_SUCCESS;
     113    }
     114
    84115    free(buf);
    85     errno = old_errno;
    86116    return status;
    87117}
     
    90120get_local_group(const char *name, struct group *grp, char *buffer, size_t buflen, int *errnop)
    91121{
    92     enum nss_status status = NSS_STATUS_NOTFOUND;
     122    static const char *fct_name = "getgrnam_r";
     123    static service_user *startp = NULL;
     124    static void *fct_start = NULL;
     125    enum nss_status status;
     126    service_user *nip;
     127    union {
     128        enum nss_status (*l)(const char *name, struct group *grp,
     129                             char *buffer, size_t buflen, int *errnop);
     130        void *ptr;
     131    } fct;
    93132    struct group gbuf;
    94     struct group *gbufp = &gbuf;
    95     int ret, n;
     133    int n;
    96134    int old_errno = errno;
    97     int len = MAGIC_LOCAL_GR_BUFLEN;
     135
     136    int len = sysconf(_SC_GETGR_R_SIZE_MAX);
    98137    char *buf = malloc(len);
    99138    if (buf == NULL) {
     
    102141        return NSS_STATUS_TRYAGAIN;
    103142    }
    104     errno = 0;
    105     ret = getgrnam_r(name, gbufp, buf, len, &gbufp);
    106     if (ret != 0) {
    107         *errnop = old_errno;
     143
     144    if (fct_start == NULL &&
     145        __nss_group_lookup(&startp, fct_name, &fct_start) != 0) {
     146        free(buf);
     147        return NSS_STATUS_UNAVAIL;
     148    }
     149    nip = startp;
     150    fct.ptr = fct_start;
     151    do {
     152        if (fct.l == _nss_nonlocal_getgrnam_r)
     153            status = NSS_STATUS_NOTFOUND;
     154        else
     155            status = DL_CALL_FCT(fct.l, (name, &gbuf, buf, buflen, errnop));
     156        if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
     157            break;
     158    } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     159
     160    if (status != NSS_STATUS_SUCCESS)
     161        goto get_local_group_done;
     162
     163    n = snprintf(buffer, buflen, "%s", gbuf.gr_name);
     164    if (n < 0 || n >= buflen) {
     165        *errnop = ERANGE;
    108166        status = NSS_STATUS_TRYAGAIN;
    109     } else if (gbufp != NULL) {
    110         status = NSS_STATUS_SUCCESS;
    111 
    112         n = snprintf(buffer, buflen, "%s", gbufp->gr_name);
    113         if (n < 0 || n >= buflen) {
    114             *errnop = ERANGE;
    115             status = NSS_STATUS_TRYAGAIN;
    116             goto get_local_group_done;
    117         }
    118         grp->gr_name = buffer;
    119         buffer += n;
    120         buflen -= n;
    121 
    122         n = snprintf(buffer, buflen, "%s", gbufp->gr_passwd);
    123         if (n < 0 || n >= buflen) {
    124             *errnop = ERANGE;
    125             status = NSS_STATUS_TRYAGAIN;
    126             goto get_local_group_done;
    127         }
    128         grp->gr_passwd = buffer;
    129         buffer += n;
    130         buflen -= n;
    131 
    132         grp->gr_gid = gbufp->gr_gid;
    133 
    134         if (buflen < sizeof(void *)) {
    135             *errnop = ERANGE;
    136             status = NSS_STATUS_TRYAGAIN;
    137             goto get_local_group_done;
    138         }
    139         *(void **)buffer = NULL;
    140         buffer += sizeof(void *);
    141         buflen -= sizeof(void *);
    142     }
     167        goto get_local_group_done;
     168    }
     169    grp->gr_name = buffer;
     170    buffer += n;
     171    buflen -= n;
     172
     173    n = snprintf(buffer, buflen, "%s", gbuf.gr_passwd);
     174    if (n < 0 || n >= buflen) {
     175        *errnop = ERANGE;
     176        status = NSS_STATUS_TRYAGAIN;
     177        goto get_local_group_done;
     178    }
     179    grp->gr_passwd = buffer;
     180    buffer += n;
     181    buflen -= n;
     182
     183    grp->gr_gid = gbuf.gr_gid;
     184
     185    if (buflen < sizeof(void *)) {
     186        *errnop = ERANGE;
     187        status = NSS_STATUS_TRYAGAIN;
     188        goto get_local_group_done;
     189    }
     190    *(void **)buffer = NULL;
     191    buffer += sizeof(void *);
     192    buflen -= sizeof(void *);
     193
    143194 get_local_group_done:
    144195    free(buf);
    145     errno = old_errno;
    146196    return status;
    147197}
     
    226276
    227277    char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV);
    228     if (buflen == MAGIC_LOCAL_GR_BUFLEN ||
    229         (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0'))
     278    if (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0')
    230279        return NSS_STATUS_UNAVAIL;
    231280
     
    272321
    273322    char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV);
    274     if (buflen == MAGIC_LOCAL_GR_BUFLEN ||
    275         (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0'))
     323    if (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0')
    276324        return NSS_STATUS_UNAVAIL;
    277325
     
    311359
    312360    char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV);
    313     if (buflen == MAGIC_LOCAL_GR_BUFLEN ||
    314         (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0'))
     361    if (nonlocal_ignore != NULL && nonlocal_ignore[0] != '\0')
    315362        return NSS_STATUS_UNAVAIL;
    316363
     
    359406    /* Check that the user is a nonlocal user before adding any groups. */
    360407    status = check_nonlocal_user(user, errnop);
    361     if (status == NSS_STATUS_NOTFOUND)
     408    if (status == NSS_STATUS_TRYAGAIN)
     409        return status;
     410    else if (status != NSS_STATUS_SUCCESS)
    362411        is_local = 1;
    363     else if (status != NSS_STATUS_SUCCESS)
    364         return status;
    365412
    366413    int old_errno = errno;
     
    375422    status = get_local_group(MAGIC_LOCAL_GROUPNAME,
    376423                             &local_users_group, buffer, buflen, errnop);
    377     if (status == NSS_STATUS_NOTFOUND) {
     424    if (status == NSS_STATUS_SUCCESS) {
     425        local_users_gid = local_users_group.gr_gid;
     426    } else if (status == NSS_STATUS_TRYAGAIN) {
     427        free(buffer);
     428        return status;
     429    } else {
    378430        syslog(LOG_WARNING, "nss_nonlocal: Group %s does not exist locally!",
    379431               MAGIC_LOCAL_GROUPNAME);
    380432        local_users_gid = -1;
    381     } else if (status != NSS_STATUS_SUCCESS) {
    382         return status;
    383     } else
    384         local_users_gid = local_users_group.gr_gid;
     433    }
    385434    free(buffer);
    386435
     
    397446        status = get_local_group(MAGIC_NONLOCAL_GROUPNAME,
    398447                                 &nonlocal_users_group, buffer, buflen, errnop);
    399         if (status == NSS_STATUS_NOTFOUND) {
     448        if (status == NSS_STATUS_SUCCESS) {
     449            gid = nonlocal_users_group.gr_gid;
     450        } else if (status == NSS_STATUS_TRYAGAIN) {
     451            free(buffer);
     452            return status;
     453        } else {
    400454            syslog(LOG_WARNING, "nss_nonlocal: Group %s does not exist locally!",
    401455                   MAGIC_NONLOCAL_GROUPNAME);
    402456            gid = -1;
    403         } else if (status != NSS_STATUS_SUCCESS) {
    404             errno = old_errno;
    405             return status;
    406         } else
    407             gid = nonlocal_users_group.gr_gid;
     457        }
    408458        free(buffer);
    409459    }
     
    437487    }
    438488
    439     errno = old_errno;
    440 
    441489    if (is_local)
    442490        return NSS_STATUS_SUCCESS;
     
    481529        if (status == NSS_STATUS_SUCCESS) {
    482530            (*groupsp)[out++] = (*groupsp)[in];
    483         } else if (status != NSS_STATUS_NOTFOUND) {
     531        } else if (status == NSS_STATUS_TRYAGAIN) {
    484532            *start = out;
    485533            *errnop = nonlocal_errno;
  • 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
  • server/common/oursrc/nss_nonlocal/nonlocal.h

    r750 r782  
    11#ifndef NONLOCAL_H
    22#define NONLOCAL_H
     3
     4#include "config.h"
     5
    36enum nss_status check_nonlocal_uid(const char *user, uid_t uid, int *errnop);
    47enum nss_status check_nonlocal_gid(const char *user, gid_t gid, int *errnop);
    58enum nss_status check_nonlocal_user(const char *user, int *errnop);
     9
    610#define NONLOCAL_IGNORE_ENV "NSS_NONLOCAL_IGNORE"
     11
    712#endif /* NON_LOCAL_H */
  • server/common/oursrc/nss_nonlocal/nsswitch-internal.h

    r750 r782  
    77#define NSSWITCH_INTERNAL_H
    88
     9#include "config.h"
     10
     11/* glibc/config.h.in */
     12#if defined USE_REGPARMS && !defined PROF && !defined __BOUNDED_POINTERS__
     13# define internal_function __attribute__ ((regparm (3), stdcall))
     14#else
     15# define internal_function
     16#endif
     17
     18/* glibc/nss/nsswitch.h */
    919typedef struct service_user service_user;
    1020
    11 extern int
    12 __nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
    13             int all_values);
     21extern int __nss_next (service_user **ni, const char *fct_name, void **fctp,
     22                       int status, int all_values);
     23extern int __nss_database_lookup (const char *database,
     24                                  const char *alternative_name,
     25                                  const char *defconfig, service_user **ni);
     26extern void *__nss_lookup_function (service_user *ni, const char *fct_name);
    1427
    15 extern int
    16 __nss_database_lookup (const char *database,
    17                        const char *alternative_name,
    18                        const char *defconfig, service_user **ni);
    19 
    20 extern int
    21 __nss_configure_lookup (const char *dbname, const char *service_line);
    22 
    23 extern void
    24 *__nss_lookup_function (service_user *ni, const char *fct_name);
     28/* glibc/nss/XXX-lookup.c */
     29extern int __nss_passwd_lookup (service_user **ni, const char *fct_name,
     30                                void **fctp) internal_function;
     31extern int __nss_group_lookup (service_user **ni, const char *fct_name,
     32                                void **fctp) internal_function;
    2533
    2634#endif /* NSSWITCH_INTERNAL_H */
Note: See TracChangeset for help on using the changeset viewer.