Changeset 1825


Ignore:
Timestamp:
Apr 29, 2011, 9:22:38 PM (13 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.
Location:
trunk/server
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/server/common/oursrc/nss_nonlocal/Makefile.am

    r782 r1825  
    55libnss_nonlocal_la_LDFLAGS = \
    66    -version-info 2:0:0 \
    7     -export-symbols-regex '^_nss_nonlocal_'
    8 
    9 noinst_PROGRAMS = .linktest
    10 _linktest_SOURCES =
    11 _linktest_LDADD = libnss_nonlocal.la
    12 _linktest_LDFLAGS = -nostdlib -entry=0
     7    -export-symbols-regex '^_nss_nonlocal_' \
     8    -no-undefined -Wl,-z,defs
    139
    1410install-exec-hook:
  • trunk/server/common/oursrc/nss_nonlocal/README

    r1553 r1825  
    99group:          compat nonlocal
    1010group_nonlocal: hesiod
     11
     12The module also assigns special properties to two local groups and one
     13local user, if they exist:
     14
     15• If the local group ‘nss-nonlocal-users’ exists, then nonlocal users
     16  will be automatically added to it.  Furthermore, if a local user is
     17  added to this group, then that user will inherit any nonlocal gids
     18  from a nonlocal user of the same name, as supplementary gids.
     19
     20• If the local group ‘nss-local-users’ exists, then local users will
     21  be automatically added to it.
     22
     23• If the local user ‘nss-nonlocal-users’ is added to a local group,
     24  then the local group will inherit the nonlocal membership of a group
     25  of the same gid.
    1126
    1227Copyright © 2007–2010 Anders Kaseorg <andersk@mit.edu> and Tim Abbott
  • trunk/server/common/oursrc/nss_nonlocal/configure.ac

    r1553 r1825  
    1 AC_INIT([nss_nonlocal], [1.11], [andersk@mit.edu])
     1AC_INIT([nss_nonlocal], [2.0], [andersk@mit.edu])
    22AC_CANONICAL_TARGET
    33AM_INIT_AUTOMAKE([-Wall -Werror foreign])
     
    99AC_PROG_INSTALL
    1010AC_PROG_LIBTOOL
     11
     12AC_HEADER_STDBOOL
    1113
    1214case "$target_cpu" in
  • 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];
  • trunk/server/common/oursrc/nss_nonlocal/nonlocal-passwd.c

    r1553 r1825  
    5050
    5151
    52 static service_user *
    53 nss_passwd_nonlocal_database(void)
    54 {
    55     static service_user *nip = NULL;
    56     if (nip == NULL)
    57         __nss_database_lookup("passwd_nonlocal", NULL, "", &nip);
    58 
    59     return nip;
     52static service_user *__nss_passwd_nonlocal_database;
     53
     54static int
     55internal_function
     56__nss_passwd_nonlocal_lookup(service_user **ni, const char *fct_name,
     57                             void **fctp)
     58{
     59    if (__nss_passwd_nonlocal_database == NULL
     60        && __nss_database_lookup("passwd_nonlocal", NULL, NULL,
     61                                 &__nss_passwd_nonlocal_database) < 0)
     62        return -1;
     63
     64    *ni = __nss_passwd_nonlocal_database;
     65
     66    *fctp = __nss_lookup_function(*ni, fct_name);
     67    return 0;
    6068}
    6169
     
    6472check_nonlocal_uid(const char *user, uid_t uid, int *errnop)
    6573{
    66     static const char *fct_name = "getpwuid_r";
    67     static service_user *startp = NULL;
    68     static void *fct_start = NULL;
    69     enum nss_status status;
    70     service_user *nip;
    71     union {
    72         enum nss_status (*l)(uid_t uid, struct passwd *pwd,
    73                              char *buffer, size_t buflen, int *errnop);
    74         void *ptr;
    75     } fct;
     74    enum nss_status status;
    7675    struct passwd pwbuf;
    77     int old_errno = errno;
    78 
     76    char *buf;
    7977    size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
    80     char *buf = malloc(buflen);
    81     if (buf == NULL) {
    82         *errnop = ENOMEM;
    83         errno = old_errno;
    84         return NSS_STATUS_TRYAGAIN;
    85     }
    86 
    87     if (fct_start == NULL &&
    88         __nss_passwd_lookup(&startp, fct_name, &fct_start) != 0) {
    89         free(buf);
    90         return NSS_STATUS_UNAVAIL;
    91     }
    92     nip = startp;
    93     fct.ptr = fct_start;
    94     do {
    95     morebuf:
    96         if (fct.l == _nss_nonlocal_getpwuid_r)
    97             status = NSS_STATUS_NOTFOUND;
    98         else
    99             status = DL_CALL_FCT(fct.l, (uid, &pwbuf, buf, buflen, errnop));
    100         if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) {
    101             free(buf);
    102             buflen *= 2;
    103             buf = malloc(buflen);
    104             if (buf == NULL) {
    105                 *errnop = ENOMEM;
    106                 errno = old_errno;
    107                 return NSS_STATUS_TRYAGAIN;
    108             }
    109             goto morebuf;
    110         }
    111     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     78    const struct walk_nss w = {
     79        .lookup = &__nss_passwd_lookup, .fct_name = "getpwuid_r",
     80        .status = &status, .errnop = errnop, .buf = &buf, .buflen = &buflen
     81    };
     82    const __typeof__(&_nss_nonlocal_getpwuid_r) self = &_nss_nonlocal_getpwuid_r;
     83#define args (uid, &pwbuf, buf, buflen, errnop)
     84#include "walk_nss.h"
     85#undef args
    11286
    11387    if (status == NSS_STATUS_SUCCESS) {
    11488        syslog(LOG_ERR, "nss_nonlocal: possible spoofing attack: non-local user %s has same UID as local user %s!\n", user, pwbuf.pw_name);
     89        free(buf);
    11590        status = NSS_STATUS_NOTFOUND;
    11691    } else if (status != NSS_STATUS_TRYAGAIN) {
     
    11893    }
    11994
    120     free(buf);
    12195    return status;
    12296}
     
    132106    errno = 0;
    133107    uid = strtoul(pwd->pw_name, &end, 10);
    134     if (errno == 0 && *end == '\0' && (uid_t)uid == uid)
     108    if (errno == 0 && *end == '\0' && (uid_t)uid == uid) {
     109        errno = old_errno;
    135110        status = check_nonlocal_uid(user, uid, errnop);
    136     errno = old_errno;
     111    } else {
     112        errno = old_errno;
     113    }
    137114    if (status != NSS_STATUS_SUCCESS)
    138115        return status;
     
    144121check_nonlocal_user(const char *user, int *errnop)
    145122{
    146     static const char *fct_name = "getpwnam_r";
    147     static service_user *startp = NULL;
    148     static void *fct_start = NULL;
    149     enum nss_status status;
    150     service_user *nip;
    151     union {
    152         enum nss_status (*l)(const char *name, struct passwd *pwd,
    153                              char *buffer, size_t buflen, int *errnop);
    154         void *ptr;
    155     } fct;
     123    enum nss_status status;
    156124    struct passwd pwbuf;
    157     int old_errno = errno;
    158 
     125    char *buf;
    159126    size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
    160     char *buf = malloc(buflen);
    161     if (buf == NULL) {
    162         *errnop = ENOMEM;
    163         errno = old_errno;
    164         return NSS_STATUS_TRYAGAIN;
    165     }
    166 
    167     if (fct_start == NULL &&
    168         __nss_passwd_lookup(&startp, fct_name, &fct_start) != 0) {
     127    const struct walk_nss w = {
     128        .lookup = __nss_passwd_lookup, .fct_name = "getpwnam_r",
     129        .status = &status, .errnop = errnop, .buf = &buf, .buflen = &buflen
     130    };
     131    const __typeof__(&_nss_nonlocal_getpwnam_r) self = &_nss_nonlocal_getpwnam_r;
     132#define args (user, &pwbuf, buf, buflen, errnop)
     133#include "walk_nss.h"
     134#undef args
     135
     136    if (status == NSS_STATUS_SUCCESS) {
    169137        free(buf);
    170         return NSS_STATUS_UNAVAIL;
    171     }
    172     nip = startp;
    173     fct.ptr = fct_start;
    174     do {
    175     morebuf:
    176         if (fct.l == _nss_nonlocal_getpwnam_r)
    177             status = NSS_STATUS_NOTFOUND;
    178         else
    179             status = DL_CALL_FCT(fct.l, (user, &pwbuf, buf, buflen, errnop));
    180         if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) {
    181             free(buf);
    182             buflen *= 2;
    183             buf = malloc(buflen);
    184             if (buf == NULL) {
    185                 *errnop = ENOMEM;
    186                 errno = old_errno;
    187                 return NSS_STATUS_TRYAGAIN;
    188             }
    189             goto morebuf;
    190         }
    191     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
    192 
    193     if (status == NSS_STATUS_SUCCESS)
    194138        status = NSS_STATUS_NOTFOUND;
    195     else if (status != NSS_STATUS_TRYAGAIN)
     139    } else if (status != NSS_STATUS_TRYAGAIN) {
    196140        status = NSS_STATUS_SUCCESS;
    197 
    198     free(buf);
     141    }
     142
    199143    return status;
    200144}
    201145
    202 
    203 static service_user *pwent_nip = NULL;
     146enum nss_status
     147get_nonlocal_passwd(const char *name, struct passwd *pwd, char **buffer,
     148                    int *errnop)
     149{
     150    enum nss_status status;
     151    size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
     152    const struct walk_nss w = {
     153        .lookup = __nss_passwd_nonlocal_lookup, .fct_name = "getpwnam_r",
     154        .status = &status, .errnop = errnop, .buf = buffer, .buflen = &buflen
     155    };
     156    const __typeof__(&_nss_nonlocal_getpwnam_r) self = NULL;
     157#define args (name, pwd, *buffer, buflen, errnop)
     158#include "walk_nss.h"
     159#undef args
     160    return status;
     161}
     162
     163
     164static service_user *pwent_startp, *pwent_nip;
    204165static void *pwent_fct_start;
    205166static union {
     
    213174_nss_nonlocal_setpwent(int stayopen)
    214175{
    215     static const char *fct_name = "setpwent";
    216     static void *fct_start = NULL;
    217     enum nss_status status;
    218     service_user *nip;
    219     union {
    220         enum nss_status (*l)(int stayopen);
    221         void *ptr;
    222     } fct;
    223 
    224     nip = nss_passwd_nonlocal_database();
    225     if (nip == NULL)
    226         return NSS_STATUS_UNAVAIL;
    227     if (fct_start == NULL)
    228         fct_start = __nss_lookup_function(nip, fct_name);
    229     fct.ptr = fct_start;
    230     do {
    231         if (fct.ptr == NULL)
    232             status = NSS_STATUS_UNAVAIL;
    233         else
    234             status = DL_CALL_FCT(fct.l, (stayopen));
    235     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
    236     if (status != NSS_STATUS_SUCCESS)
    237         return status;
    238 
    239     pwent_nip = nip;
     176    enum nss_status status;
     177    const struct walk_nss w = {
     178        .lookup = &__nss_passwd_nonlocal_lookup, .fct_name = "setpwent",
     179        .status = &status
     180    };
     181    const __typeof__(&_nss_nonlocal_setpwent) self = NULL;
     182#define args (stayopen)
     183#include "walk_nss.h"
     184#undef args
     185    if (status != NSS_STATUS_SUCCESS)
     186        return status;
     187
    240188    if (pwent_fct_start == NULL)
    241         pwent_fct_start = __nss_lookup_function(nip, pwent_fct_name);
     189        __nss_passwd_nonlocal_lookup(&pwent_startp, pwent_fct_name,
     190                                     &pwent_fct_start);
     191    pwent_nip = pwent_startp;
    242192    pwent_fct.ptr = pwent_fct_start;
    243193    return NSS_STATUS_SUCCESS;
     
    247197_nss_nonlocal_endpwent(void)
    248198{
    249     static const char *fct_name = "endpwent";
    250     static void *fct_start = NULL;
    251     enum nss_status status;
    252     service_user *nip;
    253     union {
    254         enum nss_status (*l)(void);
    255         void *ptr;
    256     } fct;
     199    enum nss_status status;
     200    const struct walk_nss w = {
     201        .lookup = &__nss_passwd_nonlocal_lookup, .fct_name = "endpwent",
     202        .status = &status
     203    };
     204    const __typeof__(&_nss_nonlocal_endpwent) self = NULL;
    257205
    258206    pwent_nip = NULL;
    259207
    260     nip = nss_passwd_nonlocal_database();
    261     if (nip == NULL)
    262         return NSS_STATUS_UNAVAIL;
    263     if (fct_start == NULL)
    264         fct_start = __nss_lookup_function(nip, fct_name);
    265     fct.ptr = fct_start;
    266     do {
    267         if (fct.ptr == NULL)
    268             status = NSS_STATUS_UNAVAIL;
    269         else
    270             status = DL_CALL_FCT(fct.l, ());
    271     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     208#define args ()
     209#include "walk_nss.h"
     210#undef args
    272211    return status;
    273212}
     
    314253                         char *buffer, size_t buflen, int *errnop)
    315254{
    316     static const char *fct_name = "getpwnam_r";
    317     static void *fct_start = NULL;
    318     enum nss_status status;
    319     service_user *nip;
    320     union {
    321         enum nss_status (*l)(const char *name, struct passwd *pwd,
    322                              char *buffer, size_t buflen, int *errnop);
    323         void *ptr;
    324     } fct;
     255    enum nss_status status;
    325256    int group_errno;
     257    const struct walk_nss w = {
     258        .lookup = __nss_passwd_nonlocal_lookup, .fct_name = "getpwnam_r",
     259        .status = &status, .errnop = errnop
     260    };
     261    const __typeof__(&_nss_nonlocal_getpwnam_r) self = NULL;
    326262
    327263    char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV);
     
    329265        return NSS_STATUS_UNAVAIL;
    330266
    331     nip = nss_passwd_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, pwd, 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);
     267#define args (name, pwd, buffer, buflen, errnop)
     268#include "walk_nss.h"
     269#undef args
    345270    if (status != NSS_STATUS_SUCCESS)
    346271        return status;
     
    355280        return status;
    356281
    357     if (check_nonlocal_gid(name, pwd->pw_gid, &group_errno) !=
     282    if (check_nonlocal_gid(name, NULL, pwd->pw_gid, &group_errno) !=
    358283        NSS_STATUS_SUCCESS)
    359284        pwd->pw_gid = 65534 /* nogroup */;
     
    365290                         char *buffer, size_t buflen, int *errnop)
    366291{
    367     static const char *fct_name = "getpwuid_r";
    368     static void *fct_start = NULL;
    369     enum nss_status status;
    370     service_user *nip;
    371     union {
    372         enum nss_status (*l)(uid_t uid, struct passwd *pwd,
    373                              char *buffer, size_t buflen, int *errnop);
    374         void *ptr;
    375     } fct;
     292    enum nss_status status;
    376293    int group_errno;
     294    const struct walk_nss w = {
     295        .lookup = &__nss_passwd_nonlocal_lookup, .fct_name = "getpwuid_r",
     296        .status = &status, .errnop = errnop
     297    };
     298    const __typeof__(&_nss_nonlocal_getpwuid_r) self = NULL;
    377299
    378300    char *nonlocal_ignore = getenv(NONLOCAL_IGNORE_ENV);
     
    380302        return NSS_STATUS_UNAVAIL;
    381303
    382     nip = nss_passwd_nonlocal_database();
    383     if (nip == NULL)
    384         return NSS_STATUS_UNAVAIL;
    385     if (fct_start == NULL)
    386         fct_start = __nss_lookup_function(nip, fct_name);
    387     fct.ptr = fct_start;
    388     do {
    389         if (fct.ptr == NULL)
    390             status = NSS_STATUS_UNAVAIL;
    391         else
    392             status = DL_CALL_FCT(fct.l, (uid, pwd, buffer, buflen, errnop));
    393         if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
    394             break;
    395     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     304#define args (uid, pwd, buffer, buflen, errnop)
     305#include "walk_nss.h"
     306#undef args
    396307    if (status != NSS_STATUS_SUCCESS)
    397308        return status;
     
    406317        return status;
    407318
    408     if (check_nonlocal_gid(pwd->pw_name, pwd->pw_gid, &group_errno) !=
     319    if (check_nonlocal_gid(pwd->pw_name, NULL, pwd->pw_gid, &group_errno) !=
    409320        NSS_STATUS_SUCCESS)
    410321        pwd->pw_gid = 65534 /* nogroup */;
  • trunk/server/common/oursrc/nss_nonlocal/nonlocal-shadow.c

    r1553 r1825  
    4040
    4141
    42 static service_user *
    43 nss_shadow_nonlocal_database(void)
     42static service_user *__nss_shadow_nonlocal_database;
     43
     44static int
     45internal_function
     46__nss_shadow_nonlocal_lookup(service_user **ni, const char *fct_name,
     47                            void **fctp)
    4448{
    45     static service_user *nip = NULL;
    46     if (nip == NULL)
    47         __nss_database_lookup("shadow_nonlocal", NULL, "", &nip);
     49    if (__nss_shadow_nonlocal_database == NULL
     50        && __nss_database_lookup("shadow_nonlocal", NULL, NULL,
     51                                 &__nss_shadow_nonlocal_database) < 0)
     52        return -1;
    4853
    49     return nip;
     54    *ni = __nss_shadow_nonlocal_database;
     55
     56    *fctp = __nss_lookup_function(*ni, fct_name);
     57    return 0;
    5058}
    5159
    5260
    53 static service_user *spent_nip = NULL;
     61static service_user *spent_startp, *spent_nip;
    5462static void *spent_fct_start;
    5563static union {
     
    6371_nss_nonlocal_setspent(int stayopen)
    6472{
    65     static const char *fct_name = "setspent";
    66     static void *fct_start = NULL;
    6773    enum nss_status status;
    68     service_user *nip;
    69     union {
    70         enum nss_status (*l)(int stayopen);
    71         void *ptr;
    72     } fct;
    73 
    74     nip = nss_shadow_nonlocal_database();
    75     if (nip == NULL)
    76         return NSS_STATUS_UNAVAIL;
    77     if (fct_start == NULL)
    78         fct_start = __nss_lookup_function(nip, fct_name);
    79     fct.ptr = fct_start;
    80     do {
    81         if (fct.ptr == NULL)
    82             status = NSS_STATUS_UNAVAIL;
    83         else
    84             status = DL_CALL_FCT(fct.l, (stayopen));
    85     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     74    const struct walk_nss w = {
     75        .lookup = &__nss_shadow_nonlocal_lookup, .fct_name = "setspent",
     76        .status = &status
     77    };
     78    const __typeof__(&_nss_nonlocal_setspent) self = NULL;
     79#define args (stayopen)
     80#include "walk_nss.h"
     81#undef args
    8682    if (status != NSS_STATUS_SUCCESS)
    8783        return status;
    8884
    89     spent_nip = nip;
    9085    if (spent_fct_start == NULL)
    91         spent_fct_start = __nss_lookup_function(nip, spent_fct_name);
     86        __nss_shadow_nonlocal_lookup(&spent_startp, spent_fct_name,
     87                                     &spent_fct_start);
     88    spent_nip = spent_startp;
    9289    spent_fct.ptr = spent_fct_start;
    9390    return NSS_STATUS_SUCCESS;
     
    9794_nss_nonlocal_endspent(void)
    9895{
    99     static const char *fct_name = "endspent";
    100     static void *fct_start = NULL;
    10196    enum nss_status status;
    102     service_user *nip;
    103     union {
    104         enum nss_status (*l)(void);
    105         void *ptr;
    106     } fct;
     97    const struct walk_nss w = {
     98        .lookup = &__nss_shadow_nonlocal_lookup, .fct_name = "endspent",
     99        .status = &status
     100    };
     101    const __typeof__(&_nss_nonlocal_endspent) self = NULL;
    107102
    108103    spent_nip = NULL;
    109104
    110     nip = nss_shadow_nonlocal_database();
    111     if (nip == NULL)
    112         return NSS_STATUS_UNAVAIL;
    113     if (fct_start == NULL)
    114         fct_start = __nss_lookup_function(nip, fct_name);
    115     fct.ptr = fct_start;
    116     do {
    117         if (fct.ptr == NULL)
    118             status = NSS_STATUS_UNAVAIL;
    119         else
    120             status = DL_CALL_FCT(fct.l, ());
    121     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     105#define args ()
     106#include "walk_nss.h"
     107#undef args
    122108    return status;
    123109}
     
    154140                         char *buffer, size_t buflen, int *errnop)
    155141{
    156     static const char *fct_name = "getspnam_r";
    157     static void *fct_start = NULL;
    158142    enum nss_status status;
    159     service_user *nip;
    160     union {
    161         enum nss_status (*l)(const char *name, struct spwd *pwd,
    162                              char *buffer, size_t buflen, int *errnop);
    163         void *ptr;
    164     } fct;
    165 
    166     nip = nss_shadow_nonlocal_database();
    167     if (nip == NULL)
    168         return NSS_STATUS_UNAVAIL;
    169     if (fct_start == NULL)
    170         fct_start = __nss_lookup_function(nip, fct_name);
    171     fct.ptr = fct_start;
    172     do {
    173         if (fct.ptr == NULL)
    174             status = NSS_STATUS_UNAVAIL;
    175         else
    176             status = DL_CALL_FCT(fct.l, (name, pwd, buffer, buflen, errnop));
    177         if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
    178             break;
    179     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
     143    const struct walk_nss w = {
     144        .lookup = __nss_shadow_nonlocal_lookup, .fct_name = "getspnam_r",
     145        .status = &status, .errnop = errnop
     146    };
     147    const __typeof__(&_nss_nonlocal_getspnam_r) self = NULL;
     148#define args (name, pwd, buffer, buflen, errnop)
     149#include "walk_nss.h"
     150#undef args
    180151    if (status != NSS_STATUS_SUCCESS)
    181152        return status;
  • trunk/server/common/oursrc/nss_nonlocal/nonlocal.h

    r782 r1825  
     1/*
     2 * nonlocal.h
     3 * common definitions for nss_nonlocal proxy
     4 *
     5 * Copyright © 2007–2010 Anders Kaseorg <andersk@mit.edu> and Tim
     6 * Abbott <tabbott@mit.edu>
     7 *
     8 * This file is part of nss_nonlocal.
     9 *
     10 * nss_nonlocal is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU Lesser General Public License
     12 * as published by the Free Software Foundation; either version 2.1 of
     13 * the License, or (at your option) any later version.
     14 *
     15 * nss_nonlocal is distributed in the hope that it will be useful, but
     16 * WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     18 * Lesser General Public License for more details.
     19 *
     20 * You should have received a copy of the GNU Lesser General Public
     21 * License along with nss_nonlocal; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     23 * 02110-1301  USA
     24 */
     25
    126#ifndef NONLOCAL_H
    227#define NONLOCAL_H
     
    429#include "config.h"
    530
     31#ifdef HAVE_STDBOOL_H
     32# include <stdbool.h>
     33#else
     34# ifndef HAVE__BOOL
     35#  ifdef __cplusplus
     36typedef bool _Bool;
     37#  else
     38#   define _Bool signed char
     39#  endif
     40# endif
     41# define bool _Bool
     42# define false 0
     43# define true 1
     44# define __bool_true_false_are_defined 1
     45#endif
     46
     47#include "nsswitch-internal.h"
     48#include <pwd.h>
     49
     50struct walk_nss {
     51    enum nss_status *status;
     52    int (*lookup)(service_user **ni, const char *fct_name,
     53                  void **fctp) internal_function;
     54    const char *fct_name;
     55    int *errnop;
     56    char **buf;
     57    size_t *buflen;
     58};
     59
    660enum nss_status check_nonlocal_uid(const char *user, uid_t uid, int *errnop);
    7 enum nss_status check_nonlocal_gid(const char *user, gid_t gid, int *errnop);
     61enum nss_status check_nonlocal_gid(const char *user, const char *group,
     62                                   gid_t gid, int *errnop);
    863enum nss_status check_nonlocal_user(const char *user, int *errnop);
     64enum nss_status get_nonlocal_passwd(const char *name, struct passwd *pwd,
     65                                    char **buffer, int *errnop);
    966
    1067#define NONLOCAL_IGNORE_ENV "NSS_NONLOCAL_IGNORE"
  • trunk/server/fedora/specs/nss_nonlocal.spec

    r1554 r1825  
    22Group: System Environment/Libraries
    33Name: nss_nonlocal
    4 Version: 1.11
     4Version: 2.0
    55Release: 1
    66URL: http://debathena.mit.edu/nss_nonlocal/
     
    1111Source: %{name}.tar.gz
    1212BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
     13Requires(pre): shadow-utils
    1314
    1415%description
     
    4748
    4849%pre
    49 groupadd -r nss-local-users || :
    50 groupadd -r nss-nonlocal-users || :
     50getent passwd nss-nonlocal-users >/dev/null || \
     51    useradd -r -g nobody -d / -s /sbin/nologin \
     52    -c 'Magic user for local group whitelist' nss-nonlocal-users
     53getent group nss-local-users || groupadd -r nss-local-users
     54getent group nss-nonlocal-users || groupadd -r nss-nonlocal-users
     55exit 0
    5156
    5257%post
     
    5762
    5863%changelog
     64
     65* Tue Mar 29 2011 Anders Kaseorg <andersk@mit.edu> 2.0-1
     66- New upstream version.
    5967
    6068* Sun May  2 2010 Anders Kaseorg <andersk@mit.edu> 1.11-1
Note: See TracChangeset for help on using the changeset viewer.