Annotation of embedaddon/sudo/plugins/sudoers/tsgetgrpw.c, revision 1.1.1.2

1.1       misho       1: /*
1.1.1.2 ! misho       2:  * Copyright (c) 2005, 2008, 2010-2013
        !             3:  *     Todd C. Miller <Todd.Miller@courtesan.com>
1.1       misho       4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17: 
                     18: /*
                     19:  * Trivial replacements for the libc get{gr,pw}{uid,nam}() routines
                     20:  * for use by testsudoers in the sudo test harness.
                     21:  * We need our own since many platforms don't provide set{pw,gr}file().
                     22:  */
                     23: 
                     24: #include <config.h>
                     25: 
                     26: #include <sys/types.h>
                     27: #include <stdio.h>
                     28: #ifdef STDC_HEADERS
                     29: # include <stdlib.h>
                     30: # include <stddef.h>
                     31: #else
                     32: # ifdef HAVE_STDLIB_H
                     33: #  include <stdlib.h>
                     34: # endif
                     35: #endif /* STDC_HEADERS */
                     36: #ifdef HAVE_STRING_H
                     37: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
                     38: #  include <memory.h>
                     39: # endif
                     40: # include <string.h>
                     41: #endif /* HAVE_STRING_H */
                     42: #ifdef HAVE_STRINGS_H
                     43: # include <strings.h>
                     44: #endif /* HAVE_STRINGS_H */
1.1.1.2 ! misho      45: #include <errno.h>
1.1       misho      46: #include <fcntl.h>
                     47: #include <limits.h>
                     48: 
                     49: #include "tsgetgrpw.h"
                     50: #include "sudoers.h"
                     51: 
                     52: #ifndef LINE_MAX
                     53: # define LINE_MAX 2048
                     54: #endif
                     55: 
                     56: #undef GRMEM_MAX
                     57: #define GRMEM_MAX 200
                     58: 
1.1.1.2 ! misho      59: #ifndef UID_MAX
        !            60: # define UID_MAX 0xffffffffU
        !            61: #endif
        !            62: 
        !            63: #ifndef GID_MAX
        !            64: # define GID_MAX UID_MAX
        !            65: #endif
        !            66: 
1.1       misho      67: static FILE *pwf;
                     68: static const char *pwfile = "/etc/passwd";
                     69: static int pw_stayopen;
                     70: 
                     71: static FILE *grf;
                     72: static const char *grfile = "/etc/group";
                     73: static int gr_stayopen;
                     74: 
                     75: void setgrfile(const char *);
                     76: void setgrent(void);
                     77: void endgrent(void);
                     78: struct group *getgrent(void);
                     79: struct group *getgrnam(const char *);
                     80: struct group *getgrgid(gid_t);
                     81: 
                     82: void setpwfile(const char *);
                     83: void setpwent(void);
                     84: void endpwent(void);
                     85: struct passwd *getpwent(void);
                     86: struct passwd *getpwnam(const char *);
                     87: struct passwd *getpwuid(uid_t);
                     88: 
                     89: void
                     90: setpwfile(const char *file)
                     91: {
                     92:     pwfile = file;
                     93:     if (pwf != NULL)
                     94:        endpwent();
                     95: }
                     96: 
                     97: void
                     98: setpwent(void)
                     99: {
                    100:     if (pwf == NULL) {
                    101:        pwf = fopen(pwfile, "r");
                    102:        if (pwf != NULL)
                    103:            fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
                    104:     } else {
                    105:        rewind(pwf);
                    106:     }
                    107:     pw_stayopen = 1;
                    108: }
                    109: 
                    110: void
                    111: endpwent(void)
                    112: {
                    113:     if (pwf != NULL) {
                    114:        fclose(pwf);
                    115:        pwf = NULL;
                    116:     }
                    117:     pw_stayopen = 0;
                    118: }
                    119: 
                    120: struct passwd *
                    121: getpwent(void)
                    122: {
                    123:     static struct passwd pw;
                    124:     static char pwbuf[LINE_MAX];
                    125:     size_t len;
1.1.1.2 ! misho     126:     unsigned long id;
        !           127:     char *cp, *colon, *ep;
1.1       misho     128: 
1.1.1.2 ! misho     129: next_entry:
1.1       misho     130:     if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
                    131:        return NULL;
                    132: 
                    133:     zero_bytes(&pw, sizeof(pw));
                    134:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho     135:        goto next_entry;
1.1       misho     136:     *colon++ = '\0';
                    137:     pw.pw_name = cp;
                    138:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho     139:        goto next_entry;
1.1       misho     140:     *colon++ = '\0';
                    141:     pw.pw_passwd = cp;
                    142:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho     143:        goto next_entry;
1.1       misho     144:     *colon++ = '\0';
1.1.1.2 ! misho     145:     id = strtoul(cp, &ep, 10);
        !           146:     if (*cp == '\0' || *ep != '\0')
        !           147:        goto next_entry;
        !           148:     if (id > UID_MAX || (id == ULONG_MAX && errno == ERANGE))
        !           149:        goto next_entry;
        !           150:     pw.pw_uid = (uid_t)id;
1.1       misho     151:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho     152:        goto next_entry;
1.1       misho     153:     *colon++ = '\0';
1.1.1.2 ! misho     154:     id = strtoul(cp, &ep, 10);
        !           155:     if (*cp == '\0' || *ep != '\0')
        !           156:        goto next_entry;
        !           157:     if (id > GID_MAX || (id == ULONG_MAX && errno == ERANGE))
        !           158:        goto next_entry;
        !           159:     pw.pw_gid = (gid_t)id;
1.1       misho     160:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho     161:        goto next_entry;
1.1       misho     162:     *colon++ = '\0';
                    163:     pw.pw_gecos = cp;
                    164:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho     165:        goto next_entry;
1.1       misho     166:     *colon++ = '\0';
                    167:     pw.pw_dir = cp;
                    168:     pw.pw_shell = colon;
                    169:     len = strlen(colon);
                    170:     if (len > 0 && colon[len - 1] == '\n')
                    171:        colon[len - 1] = '\0';
                    172:     return &pw;
                    173: }
                    174: 
                    175: struct passwd *
                    176: getpwnam(const char *name)
                    177: {
                    178:     struct passwd *pw;
                    179: 
                    180:     if (pwf == NULL) {
                    181:        if ((pwf = fopen(pwfile, "r")) == NULL)
                    182:            return NULL;
                    183:        fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
                    184:     } else {
                    185:        rewind(pwf);
                    186:     }
                    187:     while ((pw = getpwent()) != NULL) {
                    188:        if (strcmp(pw->pw_name, name) == 0)
                    189:            break;
                    190:     }
                    191:     if (!pw_stayopen) {
                    192:        fclose(pwf);
                    193:        pwf = NULL;
                    194:     }
                    195:     return pw;
                    196: }
                    197: 
                    198: struct passwd *
                    199: getpwuid(uid_t uid)
                    200: {
                    201:     struct passwd *pw;
                    202: 
                    203:     if (pwf == NULL) {
                    204:        if ((pwf = fopen(pwfile, "r")) == NULL)
                    205:            return NULL;
                    206:        fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
                    207:     } else {
                    208:        rewind(pwf);
                    209:     }
                    210:     while ((pw = getpwent()) != NULL) {
                    211:        if (pw->pw_uid == uid)
                    212:            break;
                    213:     }
                    214:     if (!pw_stayopen) {
                    215:        fclose(pwf);
                    216:        pwf = NULL;
                    217:     }
                    218:     return pw;
                    219: }
                    220: 
                    221: void
                    222: setgrfile(const char *file)
                    223: {
                    224:     grfile = file;
                    225:     if (grf != NULL)
                    226:        endgrent();
                    227: }
                    228: 
                    229: void
                    230: setgrent(void)
                    231: {
                    232:     if (grf == NULL) {
                    233:        grf = fopen(grfile, "r");
                    234:        if (grf != NULL)
                    235:            fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
                    236:     } else {
                    237:        rewind(grf);
                    238:     }
                    239:     gr_stayopen = 1;
                    240: }
                    241: 
                    242: void
                    243: endgrent(void)
                    244: {
                    245:     if (grf != NULL) {
                    246:        fclose(grf);
                    247:        grf = NULL;
                    248:     }
                    249:     gr_stayopen = 0;
                    250: }
                    251: 
                    252: struct group *
                    253: getgrent(void)
                    254: {
                    255:     static struct group gr;
                    256:     static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
                    257:     size_t len;
1.1.1.2 ! misho     258:     unsigned long id;
        !           259:     char *cp, *colon, *ep;
1.1       misho     260:     int n;
                    261: 
1.1.1.2 ! misho     262: next_entry:
1.1       misho     263:     if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
                    264:        return NULL;
                    265: 
                    266:     zero_bytes(&gr, sizeof(gr));
                    267:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho     268:        goto next_entry;
1.1       misho     269:     *colon++ = '\0';
                    270:     gr.gr_name = cp;
                    271:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho     272:        goto next_entry;
1.1       misho     273:     *colon++ = '\0';
                    274:     gr.gr_passwd = cp;
                    275:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho     276:        goto next_entry;
1.1       misho     277:     *colon++ = '\0';
1.1.1.2 ! misho     278:     id = strtoul(cp, &ep, 10);
        !           279:     if (*cp == '\0' || *ep != '\0')
        !           280:        goto next_entry;
        !           281:     if (id > GID_MAX || (id == ULONG_MAX && errno == ERANGE))
        !           282:        goto next_entry;
        !           283:     gr.gr_gid = (gid_t)id;
1.1       misho     284:     len = strlen(colon);
                    285:     if (len > 0 && colon[len - 1] == '\n')
                    286:        colon[len - 1] = '\0';
                    287:     if (*colon != '\0') {
                    288:        gr.gr_mem = gr_mem;
                    289:        cp = strtok(colon, ",");
                    290:        for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
                    291:            gr.gr_mem[n] = cp;
                    292:            cp = strtok(NULL, ",");
                    293:        }
                    294:        gr.gr_mem[n++] = NULL;
                    295:     } else
                    296:        gr.gr_mem = NULL;
                    297:     return &gr;
                    298: }
                    299: 
                    300: struct group *
                    301: getgrnam(const char *name)
                    302: {
                    303:     struct group *gr;
                    304: 
                    305:     if (grf == NULL) {
                    306:        if ((grf = fopen(grfile, "r")) == NULL)
                    307:            return NULL;
                    308:        fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
                    309:     } else {
                    310:        rewind(grf);
                    311:     }
                    312:     while ((gr = getgrent()) != NULL) {
                    313:        if (strcmp(gr->gr_name, name) == 0)
                    314:            break;
                    315:     }
                    316:     if (!gr_stayopen) {
                    317:        fclose(grf);
                    318:        grf = NULL;
                    319:     }
                    320:     return gr;
                    321: }
                    322: 
                    323: struct group *
                    324: getgrgid(gid_t gid)
                    325: {
                    326:     struct group *gr;
                    327: 
                    328:     if (grf == NULL) {
                    329:        if ((grf = fopen(grfile, "r")) == NULL)
                    330:            return NULL;
                    331:        fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
                    332:     } else {
                    333:        rewind(grf);
                    334:     }
                    335:     while ((gr = getgrent()) != NULL) {
                    336:        if (gr->gr_gid == gid)
                    337:            break;
                    338:     }
                    339:     if (!gr_stayopen) {
                    340:        fclose(grf);
                    341:        grf = NULL;
                    342:     }
                    343:     return gr;
                    344: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>