Ignore:
Timestamp:
Jun 7, 2011, 12:58:14 PM (13 years ago)
Author:
achernya
Message:
Merge r1803-1877 from trunk to branches/fc15-dev
Location:
branches/fc15-dev
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/fc15-dev

  • branches/fc15-dev/server/common/oursrc/nss_nonlocal/nonlocal-passwd.c

    r1553 r1878  
    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 */;
Note: See TracChangeset for help on using the changeset viewer.