Ignore:
Timestamp:
Apr 29, 2011, 9:22:38 PM (12 years ago)
Author:
andersk
Message:
Update nss_nonlocal to 2.0

- Fix errno saving and restoring.
- Document nss-nonlocal-users and nss-local-users groups in README.
- Allow local whitelisting of nonlocal user and group memberships,
  using the magic local ‘nss-nonlocal-users’ user and group.
File:
1 edited

Legend:

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

    r1553 r1825  
    3434#include <syslog.h>
    3535#include <errno.h>
     36#include <pwd.h>
    3637#include <grp.h>
    3738#include <nss.h>
     
    3940#include "nonlocal.h"
    4041
     42/*
     43 * If the MAGIC_NONLOCAL_GROUPNAME local group exists, then nonlocal
     44 * users will be automatically added to it.  Furthermore, if a local
     45 * user is added to this group, then that user will inherit any
     46 * nonlocal gids from a nonlocal user of the same name, as
     47 * supplementary gids.
     48 */
    4149#define MAGIC_NONLOCAL_GROUPNAME "nss-nonlocal-users"
     50
     51/*
     52 * If the MAGIC_LOCAL_GROUPNAME local group exists, then local users
     53 * will be automatically added to it.
     54 */
    4255#define MAGIC_LOCAL_GROUPNAME "nss-local-users"
     56
     57/*
     58 * If the MAGIC_NONLOCAL_USERNAME local user is added to a local
     59 * group, then the local group will inherit the nonlocal membership of
     60 * a group of the same gid.
     61 */
     62#define MAGIC_NONLOCAL_USERNAME "nss-nonlocal-users"
    4363
    4464
     
    5272
    5373
    54 static service_user *
    55 nss_group_nonlocal_database(void)
    56 {
    57     static service_user *nip = NULL;
    58     if (nip == NULL)
    59         __nss_database_lookup("group_nonlocal", NULL, "", &nip);
    60 
    61     return nip;
    62 }
    63 
    64 
    65 enum nss_status
    66 check_nonlocal_gid(const char *user, gid_t gid, int *errnop)
    67 {
    68     static const char *fct_name = "getgrgid_r";
    69     static service_user *startp = NULL;
    70     static void *fct_start = NULL;
    71     enum nss_status status;
    72     service_user *nip;
    73     union {
    74         enum nss_status (*l)(gid_t gid, struct group *grp,
    75                              char *buffer, size_t buflen, int *errnop);
    76         void *ptr;
    77     } fct;
     74static service_user *__nss_group_nonlocal_database;
     75
     76static int
     77internal_function
     78__nss_group_nonlocal_lookup(service_user **ni, const char *fct_name,
     79                            void **fctp)
     80{
     81    if (__nss_group_nonlocal_database == NULL
     82        && __nss_database_lookup("group_nonlocal", NULL, NULL,
     83                                 &__nss_group_nonlocal_database) < 0)
     84        return -1;
     85
     86    *ni = __nss_group_nonlocal_database;
     87
     88    *fctp = __nss_lookup_function(*ni, fct_name);
     89    return 0;
     90}
     91
     92
     93enum nss_status
     94check_nonlocal_gid(const char *user, const char *group, gid_t gid, int *errnop)
     95{
     96    enum nss_status status;
    7897    struct group gbuf;
    79     int old_errno = errno;
    80 
     98    char *buf;
    8199    size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
    82     char *buf = malloc(buflen);
    83     if (buf == NULL) {
    84         *errnop = ENOMEM;
    85         errno = old_errno;
    86         return NSS_STATUS_TRYAGAIN;
    87     }
    88 
    89     if (fct_start == NULL &&
    90         __nss_group_lookup(&startp, fct_name, &fct_start) != 0) {
    91         free(buf);
    92         return NSS_STATUS_UNAVAIL;
    93     }
    94     nip = startp;
    95     fct.ptr = fct_start;
    96     do {
    97     morebuf:
    98         if (fct.l == _nss_nonlocal_getgrgid_r)
    99             status = NSS_STATUS_NOTFOUND;
    100         else
    101             status = DL_CALL_FCT(fct.l, (gid, &gbuf, buf, buflen, errnop));
    102         if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) {
    103             free(buf);
    104             buflen *= 2;
    105             buf = malloc(buflen);
    106             if (buf == NULL) {
    107                 *errnop = ENOMEM;
    108                 errno = old_errno;
    109                 return NSS_STATUS_TRYAGAIN;
     100    const struct walk_nss w = {
     101        .lookup = &__nss_group_lookup, .fct_name = "getgrgid_r",
     102        .status = &status, .errnop = errnop, .buf = &buf, .buflen = &buflen
     103    };
     104    const __typeof__(&_nss_nonlocal_getgrgid_r) self = &_nss_nonlocal_getgrgid_r;
     105#define args (gid, &gbuf, buf, buflen, errnop)
     106#include "walk_nss.h"
     107#undef args
     108
     109    if (status == NSS_STATUS_TRYAGAIN)
     110        return status;
     111    else if (status != NSS_STATUS_SUCCESS)
     112        return NSS_STATUS_SUCCESS;
     113
     114    if (group == NULL || strcmp(gbuf.gr_name, group) == 0) {
     115        char *const *mem;
     116        for (mem = gbuf.gr_mem; *mem != NULL; mem++)
     117            if (strcmp(*mem, MAGIC_NONLOCAL_USERNAME) == 0) {
     118                status = check_nonlocal_user(*mem, errnop);
     119                if (status == NSS_STATUS_TRYAGAIN) {
     120                    free(buf);
     121                    return status;
     122                } else if (status == NSS_STATUS_NOTFOUND) {
     123                    free(buf);
     124                    return NSS_STATUS_SUCCESS;
     125                }
     126                break;
    110127            }
    111             goto morebuf;
    112         }
    113     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
    114 
    115     if (status == NSS_STATUS_SUCCESS) {
    116         syslog(LOG_DEBUG, "nss_nonlocal: removing local group %u (%s) from non-local user %s\n", gbuf.gr_gid, gbuf.gr_name, user);
    117         status = NSS_STATUS_NOTFOUND;
    118     } else if (status != NSS_STATUS_TRYAGAIN) {
    119         status = NSS_STATUS_SUCCESS;
    120     }
    121 
     128    }
     129
     130    syslog(LOG_DEBUG, "nss_nonlocal: removing local group %u (%s) from non-local user %s\n", gbuf.gr_gid, gbuf.gr_name, user);
    122131    free(buf);
    123     return status;
     132    return NSS_STATUS_NOTFOUND;
    124133}
    125134
     
    134143    errno = 0;
    135144    gid = strtoul(grp->gr_name, &end, 10);
    136     if (errno == 0 && *end == '\0' && (gid_t)gid == gid)
    137         status = check_nonlocal_gid(user, gid, errnop);
    138     errno = old_errno;
     145    if (errno == 0 && *end == '\0' && (gid_t)gid == gid) {
     146        errno = old_errno;
     147        status = check_nonlocal_gid(user, grp->gr_name, gid, errnop);
     148    } else
     149        errno = old_errno;
    139150    if (status != NSS_STATUS_SUCCESS)
    140151        return status;
    141152
    142     return check_nonlocal_gid(user, grp->gr_gid, errnop);
     153    return check_nonlocal_gid(user, grp->gr_name, grp->gr_gid, errnop);
    143154}
    144155
     
    146157get_local_group(const char *name, struct group *grp, char **buffer, int *errnop)
    147158{
    148     static const char *fct_name = "getgrnam_r";
    149     static service_user *startp = NULL;
    150     static void *fct_start = NULL;
    151     enum nss_status status;
    152     service_user *nip;
    153     union {
    154         enum nss_status (*l)(const char *name, struct group *grp,
    155                              char *buffer, size_t buflen, int *errnop);
    156         void *ptr;
    157     } fct;
    158     size_t buflen;
    159     int old_errno = errno;
    160 
    161     buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
    162     *buffer = malloc(buflen);
    163     if (*buffer == NULL) {
    164         *errnop = ENOMEM;
    165         errno = old_errno;
    166         return NSS_STATUS_TRYAGAIN;
    167     }
    168 
    169     if (fct_start == NULL &&
    170         __nss_group_lookup(&startp, fct_name, &fct_start) != 0) {
    171         free(*buffer);
    172         *buffer = NULL;
    173         return NSS_STATUS_UNAVAIL;
    174     }
    175     nip = startp;
    176     fct.ptr = fct_start;
    177     do {
    178     morebuf:
    179         if (fct.l == _nss_nonlocal_getgrnam_r)
    180             status = NSS_STATUS_NOTFOUND;
    181         else
    182             status = DL_CALL_FCT(fct.l, (name, grp, *buffer, buflen, errnop));
    183         if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) {
    184             free(*buffer);
    185             buflen *= 2;
    186             *buffer = malloc(buflen);
    187             if (*buffer == NULL) {
    188                 *errnop = ENOMEM;
    189                 errno = old_errno;
    190                 return NSS_STATUS_TRYAGAIN;
    191             }
    192             goto morebuf;
    193         }
    194     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
    195 
    196     if (status != NSS_STATUS_SUCCESS) {
    197         free(*buffer);
    198         *buffer = NULL;
    199     }
    200 
     159    enum nss_status status;
     160    size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
     161    const struct walk_nss w = {
     162        .lookup = &__nss_group_lookup, .fct_name = "getgrnam_r",
     163        .status = &status, .errnop = errnop, .buf = buffer, .buflen = &buflen
     164    };
     165    const __typeof__(&_nss_nonlocal_getgrnam_r) self = &_nss_nonlocal_getgrnam_r;
     166#define args (name, grp, *buffer, buflen, errnop)
     167#include "walk_nss.h"
     168#undef args
    201169    return status;
    202170}
    203171
    204 static service_user *grent_nip = NULL;
     172static service_user *grent_startp, *grent_nip;
    205173static void *grent_fct_start;
    206174static union {
     
    214182_nss_nonlocal_setgrent(int stayopen)
    215183{
    216     static const char *fct_name = "setgrent";
    217     static void *fct_start = NULL;
    218     enum nss_status status;
    219     service_user *nip;
    220     union {
    221         enum nss_status (*l)(int stayopen);
    222         void *ptr;
    223     } fct;
    224 
    225     nip = nss_group_nonlocal_database();
    226     if (nip == NULL)
    227         return NSS_STATUS_UNAVAIL;
    228     if (fct_start == NULL)
    229         fct_start = __nss_lookup_function(nip, fct_name);
    230     fct.ptr = fct_start;
    231     do {
    232         if (fct.ptr == NULL)
    233             status = NSS_STATUS_UNAVAIL;
    234         else
    235             status = DL_CALL_FCT(fct.l, (stayopen));
    236     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     184    enum nss_status status;
     185    const struct walk_nss w = {
     186        .lookup = &__nss_group_nonlocal_lookup, .fct_name = "setgrent",
     187        .status = &status
     188    };
     189    const __typeof__(&_nss_nonlocal_setgrent) self = NULL;
     190#define args (stayopen)
     191#include "walk_nss.h"
     192#undef args
    237193    if (status != NSS_STATUS_SUCCESS)
    238194        return status;
    239195
    240     grent_nip = nip;
    241196    if (grent_fct_start == NULL)
    242         grent_fct_start = __nss_lookup_function(nip, grent_fct_name);
     197        __nss_group_nonlocal_lookup(&grent_startp, grent_fct_name,
     198                                    &grent_fct_start);
     199    grent_nip = grent_startp;
    243200    grent_fct.ptr = grent_fct_start;
    244201    return NSS_STATUS_SUCCESS;
     
    248205_nss_nonlocal_endgrent(void)
    249206{
    250     static const char *fct_name = "endgrent";
    251     static void *fct_start = NULL;
    252     enum nss_status status;
    253     service_user *nip;
    254     union {
    255         enum nss_status (*l)(void);
    256         void *ptr;
    257     } fct;
     207    enum nss_status status;
     208    const struct walk_nss w = {
     209        .lookup = &__nss_group_nonlocal_lookup, .fct_name = "endgrent",
     210        .status = &status
     211    };
     212    const __typeof__(&_nss_nonlocal_endgrent) self = NULL;
    258213
    259214    grent_nip = NULL;
    260215
    261     nip = nss_group_nonlocal_database();
    262     if (nip == NULL)
    263         return NSS_STATUS_UNAVAIL;
    264     if (fct_start == NULL)
    265         fct_start = __nss_lookup_function(nip, fct_name);
    266     fct.ptr = fct_start;
    267     do {
    268         if (fct.ptr == NULL)
    269             status = NSS_STATUS_UNAVAIL;
    270         else
    271             status = DL_CALL_FCT(fct.l, ());
    272     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     216#define args ()
     217#include "walk_nss.h"
     218#undef args
    273219    return status;
    274220}
     
    315261                         char *buffer, size_t buflen, int *errnop)
    316262{
    317     static const char *fct_name = "getgrnam_r";
    318     static void *fct_start = NULL;
    319     enum nss_status status;
    320     service_user *nip;
    321     union {
    322         enum nss_status (*l)(const char *name, struct group *grp,
    323                              char *buffer, size_t buflen, int *errnop);
    324         void *ptr;
    325     } fct;
     263    enum nss_status status;
     264    const struct walk_nss w = {
     265        .lookup = &__nss_group_nonlocal_lookup, .fct_name = "getgrnam_r",
     266        .status = &status, .errnop = errnop
     267    };
     268    const __typeof__(&_nss_nonlocal_getgrnam_r) self = NULL;
    326269
    327270    char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV);
     
    329272        return NSS_STATUS_UNAVAIL;
    330273
    331     nip = nss_group_nonlocal_database();
    332     if (nip == NULL)
    333         return NSS_STATUS_UNAVAIL;
    334     if (fct_start == NULL)
    335         fct_start = __nss_lookup_function(nip, fct_name);
    336     fct.ptr = fct_start;
    337     do {
    338         if (fct.ptr == NULL)
    339             status = NSS_STATUS_UNAVAIL;
    340         else
    341             status = DL_CALL_FCT(fct.l, (name, grp, buffer, buflen, errnop));
    342         if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
    343             break;
    344     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     274#define args (name, grp, buffer, buflen, errnop)
     275#include "walk_nss.h"
     276#undef args
    345277    if (status != NSS_STATUS_SUCCESS)
    346278        return status;
     
    358290                         char *buffer, size_t buflen, int *errnop)
    359291{
    360     static const char *fct_name = "getgrgid_r";
    361     static void *fct_start = NULL;
    362     enum nss_status status;
    363     service_user *nip;
    364     union {
    365         enum nss_status (*l)(gid_t gid, struct group *grp,
    366                              char *buffer, size_t buflen, int *errnop);
    367         void *ptr;
    368     } fct;
     292    enum nss_status status;
     293    const struct walk_nss w = {
     294        .lookup = &__nss_group_nonlocal_lookup, .fct_name = "getgrgid_r",
     295        .status = &status, .errnop = errnop
     296    };
     297    const __typeof__(&_nss_nonlocal_getgrgid_r) self = NULL;
    369298
    370299    char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV);
     
    372301        return NSS_STATUS_UNAVAIL;
    373302
    374     nip = nss_group_nonlocal_database();
    375     if (nip == NULL)
    376         return NSS_STATUS_UNAVAIL;
    377     if (fct_start == NULL)
    378         fct_start = __nss_lookup_function(nip, fct_name);
    379     fct.ptr = fct_start;
    380     do {
    381         if (fct.ptr == NULL)
    382             status = NSS_STATUS_UNAVAIL;
    383         else
    384             status = DL_CALL_FCT(fct.l, (gid, grp, buffer, buflen, errnop));
    385         if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
    386             break;
    387     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     303#define args (gid, grp, buffer, buflen, errnop)
     304#include "walk_nss.h"
     305#undef args
    388306    if (status != NSS_STATUS_SUCCESS)
    389307        return status;
     
    397315}
    398316
     317static bool
     318add_group(gid_t group, long int *start, long int *size, gid_t **groupsp,
     319          long int limit, int *errnop, enum nss_status *status)
     320{
     321    int i, old_errno = errno;
     322    for (i = 0; i < *start; ++i)
     323        if ((*groupsp)[i] == group)
     324            return true;
     325    if (*start + 1 > *size) {
     326        gid_t *newgroups;
     327        long int newsize = 2 * *size;
     328        if (limit > 0) {
     329            if (*size >= limit) {
     330                *status = NSS_STATUS_SUCCESS;
     331                return false;
     332            }
     333            if (newsize > limit)
     334                newsize = limit;
     335        }
     336        newgroups = realloc(*groupsp, newsize * sizeof((*groupsp)[0]));
     337        errno = old_errno;
     338        if (newgroups == NULL) {
     339            *errnop = ENOMEM;
     340            *status = NSS_STATUS_TRYAGAIN;
     341            return false;
     342        }
     343        *groupsp = newgroups;
     344        *size = newsize;
     345    }
     346    (*groupsp)[(*start)++] = group;
     347    return true;
     348}
     349
    399350enum nss_status
    400351_nss_nonlocal_initgroups_dyn(const char *user, gid_t group, long int *start,
     
    402353                             int *errnop)
    403354{
    404     static const char *fct_name = "initgroups_dyn";
    405     static void *fct_start = NULL;
    406     enum nss_status status;
    407     service_user *nip;
    408     union {
    409         enum nss_status (*l)(const char *user, gid_t group, long int *start,
    410                              long int *size, gid_t **groupsp, long int limit,
    411                              int *errnop);
    412         void *ptr;
    413     } fct;
     355    enum nss_status status;
     356    const struct walk_nss w = {
     357        .lookup = &__nss_group_nonlocal_lookup, .fct_name = "initgroups_dyn",
     358        .status = &status, .errnop = errnop
     359    };
     360    const __typeof__(&_nss_nonlocal_initgroups_dyn) self = NULL;
    414361
    415362    struct group local_users_group, nonlocal_users_group;
    416     gid_t local_users_gid, gid;
    417     int is_local = 0;
     363    bool is_nonlocal = true;
    418364    char *buffer;
    419     int old_errno;
    420365    int in, out, i;
    421366
    422     /* Check that the user is a nonlocal user before adding any groups. */
     367    /* Check that the user is a nonlocal user, or a member of the
     368     * MAGIC_NONLOCAL_GROUPNAME group, before adding any groups. */
    423369    status = check_nonlocal_user(user, errnop);
    424     if (status == NSS_STATUS_TRYAGAIN)
    425         return status;
    426     else if (status != NSS_STATUS_SUCCESS)
    427         is_local = 1;
    428 
    429     old_errno = errno;
    430 
    431     status = get_local_group(MAGIC_LOCAL_GROUPNAME,
    432                              &local_users_group, &buffer, errnop);
    433     if (status == NSS_STATUS_SUCCESS) {
    434         local_users_gid = local_users_group.gr_gid;
    435         free(buffer);
    436     } else if (status == NSS_STATUS_TRYAGAIN) {
    437         return status;
    438     } else {
    439         syslog(LOG_WARNING, "nss_nonlocal: Group %s does not exist locally!",
    440                MAGIC_LOCAL_GROUPNAME);
    441         local_users_gid = -1;
    442     }
    443 
    444     if (is_local) {
    445         gid = local_users_gid;
    446     } else {
    447         status = get_local_group(MAGIC_NONLOCAL_GROUPNAME,
    448                                  &nonlocal_users_group, &buffer, errnop);
     370    if (status == NSS_STATUS_TRYAGAIN) {
     371        return status;
     372    } else if (status != NSS_STATUS_SUCCESS) {
     373        is_nonlocal = false;
     374
     375        status = get_local_group(MAGIC_LOCAL_GROUPNAME,
     376                                 &local_users_group, &buffer, errnop);
    449377        if (status == NSS_STATUS_SUCCESS) {
    450             gid = nonlocal_users_group.gr_gid;
    451378            free(buffer);
     379            if (!add_group(local_users_group.gr_gid, start, size, groupsp,
     380                           limit, errnop, &status))
     381                return status;
    452382        } else if (status == NSS_STATUS_TRYAGAIN) {
    453383            return status;
    454384        } else {
    455             syslog(LOG_WARNING, "nss_nonlocal: Group %s does not exist locally!",
    456                    MAGIC_NONLOCAL_GROUPNAME);
    457             gid = -1;
    458         }
    459     }
    460 
    461     if (gid != -1) {
    462         int i;
    463         for (i = 0; i < *start; ++i)
    464             if ((*groupsp)[i] == gid)
    465                 break;
    466         if (i >= *start) {
    467             if (*start + 1 > *size) {
    468                 gid_t *newgroups;
    469                 long int newsize = 2 * *size;
    470                 if (limit > 0) {
    471                     if (*size >= limit)
    472                         return NSS_STATUS_SUCCESS;
    473                     if (newsize > limit)
    474                         newsize = limit;
     385            syslog(LOG_WARNING,
     386                   "nss_nonlocal: Group %s does not exist locally!",
     387                   MAGIC_LOCAL_GROUPNAME);
     388        }
     389    }
     390
     391    status = get_local_group(MAGIC_NONLOCAL_GROUPNAME,
     392                             &nonlocal_users_group, &buffer, errnop);
     393    if (status == NSS_STATUS_SUCCESS) {
     394        free(buffer);
     395        if (is_nonlocal) {
     396            if (!add_group(nonlocal_users_group.gr_gid, start, size, groupsp,
     397                           limit, errnop, &status))
     398                return status;
     399        } else {
     400            int i;
     401            for (i = 0; i < *start; ++i) {
     402                if ((*groupsp)[i] == nonlocal_users_group.gr_gid) {
     403                    is_nonlocal = true;
     404                    break;
    475405                }
    476                 newgroups = realloc(*groupsp, newsize * sizeof((*groupsp)[0]));
    477                 if (newgroups == NULL) {
    478                     *errnop = ENOMEM;
    479                     errno = old_errno;
    480                     return NSS_STATUS_TRYAGAIN;
     406            }
     407
     408            if (is_nonlocal) {
     409                struct passwd pwbuf;
     410                char *buf;
     411                int nonlocal_errno = *errnop;
     412                status = get_nonlocal_passwd(user, &pwbuf, &buf, errnop);
     413
     414                if (status == NSS_STATUS_SUCCESS) {
     415                    nonlocal_errno = *errnop;
     416                    status = check_nonlocal_gid(user, NULL, pwbuf.pw_gid,
     417                                                &nonlocal_errno);
     418                    free(buf);
    481419                }
    482                 *groupsp = newgroups;
    483                 *size = newsize;
     420
     421                if (status == NSS_STATUS_SUCCESS) {
     422                    if (!add_group(pwbuf.pw_gid, start, size, groupsp, limit,
     423                                   errnop, &status))
     424                        return status;
     425                } else if (status == NSS_STATUS_TRYAGAIN) {
     426                    *errnop = nonlocal_errno;
     427                    return status;
     428                }
    484429            }
    485             (*groupsp)[(*start)++] = gid;
    486         }
    487     }
    488 
    489     if (is_local)
     430        }
     431    } else if (status == NSS_STATUS_TRYAGAIN) {
     432        if (is_nonlocal)
     433            return status;
     434    } else {
     435        syslog(LOG_WARNING, "nss_nonlocal: Group %s does not exist locally!",
     436               MAGIC_NONLOCAL_GROUPNAME);
     437    }
     438
     439    if (!is_nonlocal)
    490440        return NSS_STATUS_SUCCESS;
    491441
    492442    in = out = *start;
    493443
    494     nip = nss_group_nonlocal_database();
    495     if (nip == NULL)
    496         return NSS_STATUS_UNAVAIL;
    497     if (fct_start == NULL)
    498         fct_start = __nss_lookup_function(nip, fct_name);
    499     fct.ptr = fct_start;
    500 
    501     do {
    502         if (fct.ptr == NULL)
    503             status = NSS_STATUS_UNAVAIL;
    504         else
    505             status = DL_CALL_FCT(fct.l, (user, group, start, size, groupsp, limit, errnop));
    506         if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
    507             break;
    508     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     444#define args (user, group, start, size, groupsp, limit, errnop)
     445#include "walk_nss.h"
     446#undef args
    509447    if (status != NSS_STATUS_SUCCESS)
    510448        return status;
     
    519457            continue;
    520458
    521         /* Don't let users get into MAGIC_LOCAL_GROUPNAME from nonlocal reasons. */
    522         if (local_users_gid == (*groupsp)[in]) {
    523             syslog(LOG_WARNING, "nss_nonlocal: Nonlocal user %s removed from special local users group %s",
    524                    user, MAGIC_LOCAL_GROUPNAME);
    525             continue;
    526         }
    527 
    528         status = check_nonlocal_gid(user, (*groupsp)[in], &nonlocal_errno);
     459        status = check_nonlocal_gid(user, NULL, (*groupsp)[in],
     460                                    &nonlocal_errno);
    529461        if (status == NSS_STATUS_SUCCESS) {
    530462            (*groupsp)[out++] = (*groupsp)[in];
Note: See TracChangeset for help on using the changeset viewer.