Ignore:
Timestamp:
Jul 29, 2008, 7:18:13 AM (16 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-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;
Note: See TracChangeset for help on using the changeset viewer.