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

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.3 ! misho     126:     id_t id;
        !           127:     char *cp, *colon;
        !           128:     const char *errstr;
1.1       misho     129: 
1.1.1.2   misho     130: next_entry:
1.1       misho     131:     if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
                    132:        return NULL;
                    133: 
1.1.1.3 ! misho     134:     memset(&pw, 0, sizeof(pw));
1.1       misho     135:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2   misho     136:        goto next_entry;
1.1       misho     137:     *colon++ = '\0';
                    138:     pw.pw_name = cp;
                    139:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2   misho     140:        goto next_entry;
1.1       misho     141:     *colon++ = '\0';
                    142:     pw.pw_passwd = cp;
                    143:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2   misho     144:        goto next_entry;
1.1       misho     145:     *colon++ = '\0';
1.1.1.3 ! misho     146:     id = atoid(cp, NULL, NULL, &errstr);
        !           147:     if (errstr != NULL)
1.1.1.2   misho     148:        goto next_entry;
                    149:     pw.pw_uid = (uid_t)id;
1.1       misho     150:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2   misho     151:        goto next_entry;
1.1       misho     152:     *colon++ = '\0';
1.1.1.3 ! misho     153:     id = atoid(cp, NULL, NULL, &errstr);
        !           154:     if (errstr != NULL)
1.1.1.2   misho     155:        goto next_entry;
                    156:     pw.pw_gid = (gid_t)id;
1.1       misho     157:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2   misho     158:        goto next_entry;
1.1       misho     159:     *colon++ = '\0';
                    160:     pw.pw_gecos = cp;
                    161:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2   misho     162:        goto next_entry;
1.1       misho     163:     *colon++ = '\0';
                    164:     pw.pw_dir = cp;
                    165:     pw.pw_shell = colon;
                    166:     len = strlen(colon);
                    167:     if (len > 0 && colon[len - 1] == '\n')
                    168:        colon[len - 1] = '\0';
                    169:     return &pw;
                    170: }
                    171: 
                    172: struct passwd *
                    173: getpwnam(const char *name)
                    174: {
                    175:     struct passwd *pw;
                    176: 
                    177:     if (pwf == NULL) {
                    178:        if ((pwf = fopen(pwfile, "r")) == NULL)
                    179:            return NULL;
                    180:        fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
                    181:     } else {
                    182:        rewind(pwf);
                    183:     }
                    184:     while ((pw = getpwent()) != NULL) {
                    185:        if (strcmp(pw->pw_name, name) == 0)
                    186:            break;
                    187:     }
                    188:     if (!pw_stayopen) {
                    189:        fclose(pwf);
                    190:        pwf = NULL;
                    191:     }
                    192:     return pw;
                    193: }
                    194: 
                    195: struct passwd *
                    196: getpwuid(uid_t uid)
                    197: {
                    198:     struct passwd *pw;
                    199: 
                    200:     if (pwf == NULL) {
                    201:        if ((pwf = fopen(pwfile, "r")) == NULL)
                    202:            return NULL;
                    203:        fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
                    204:     } else {
                    205:        rewind(pwf);
                    206:     }
                    207:     while ((pw = getpwent()) != NULL) {
                    208:        if (pw->pw_uid == uid)
                    209:            break;
                    210:     }
                    211:     if (!pw_stayopen) {
                    212:        fclose(pwf);
                    213:        pwf = NULL;
                    214:     }
                    215:     return pw;
                    216: }
                    217: 
                    218: void
                    219: setgrfile(const char *file)
                    220: {
                    221:     grfile = file;
                    222:     if (grf != NULL)
                    223:        endgrent();
                    224: }
                    225: 
                    226: void
                    227: setgrent(void)
                    228: {
                    229:     if (grf == NULL) {
                    230:        grf = fopen(grfile, "r");
                    231:        if (grf != NULL)
                    232:            fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
                    233:     } else {
                    234:        rewind(grf);
                    235:     }
                    236:     gr_stayopen = 1;
                    237: }
                    238: 
                    239: void
                    240: endgrent(void)
                    241: {
                    242:     if (grf != NULL) {
                    243:        fclose(grf);
                    244:        grf = NULL;
                    245:     }
                    246:     gr_stayopen = 0;
                    247: }
                    248: 
                    249: struct group *
                    250: getgrent(void)
                    251: {
                    252:     static struct group gr;
                    253:     static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
                    254:     size_t len;
1.1.1.3 ! misho     255:     id_t id;
        !           256:     char *cp, *colon;
        !           257:     const char *errstr;
1.1       misho     258:     int n;
                    259: 
1.1.1.2   misho     260: next_entry:
1.1       misho     261:     if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
                    262:        return NULL;
                    263: 
1.1.1.3 ! misho     264:     memset(&gr, 0, sizeof(gr));
1.1       misho     265:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2   misho     266:        goto next_entry;
1.1       misho     267:     *colon++ = '\0';
                    268:     gr.gr_name = cp;
                    269:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2   misho     270:        goto next_entry;
1.1       misho     271:     *colon++ = '\0';
                    272:     gr.gr_passwd = cp;
                    273:     if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2   misho     274:        goto next_entry;
1.1       misho     275:     *colon++ = '\0';
1.1.1.3 ! misho     276:     id = atoid(cp, NULL, NULL, &errstr);
        !           277:     if (errstr != NULL)
1.1.1.2   misho     278:        goto next_entry;
                    279:     gr.gr_gid = (gid_t)id;
1.1       misho     280:     len = strlen(colon);
                    281:     if (len > 0 && colon[len - 1] == '\n')
                    282:        colon[len - 1] = '\0';
                    283:     if (*colon != '\0') {
                    284:        gr.gr_mem = gr_mem;
                    285:        cp = strtok(colon, ",");
                    286:        for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
                    287:            gr.gr_mem[n] = cp;
                    288:            cp = strtok(NULL, ",");
                    289:        }
                    290:        gr.gr_mem[n++] = NULL;
                    291:     } else
                    292:        gr.gr_mem = NULL;
                    293:     return &gr;
                    294: }
                    295: 
                    296: struct group *
                    297: getgrnam(const char *name)
                    298: {
                    299:     struct group *gr;
                    300: 
                    301:     if (grf == NULL) {
                    302:        if ((grf = fopen(grfile, "r")) == NULL)
                    303:            return NULL;
                    304:        fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
                    305:     } else {
                    306:        rewind(grf);
                    307:     }
                    308:     while ((gr = getgrent()) != NULL) {
                    309:        if (strcmp(gr->gr_name, name) == 0)
                    310:            break;
                    311:     }
                    312:     if (!gr_stayopen) {
                    313:        fclose(grf);
                    314:        grf = NULL;
                    315:     }
                    316:     return gr;
                    317: }
                    318: 
                    319: struct group *
                    320: getgrgid(gid_t gid)
                    321: {
                    322:     struct group *gr;
                    323: 
                    324:     if (grf == NULL) {
                    325:        if ((grf = fopen(grfile, "r")) == NULL)
                    326:            return NULL;
                    327:        fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
                    328:     } else {
                    329:        rewind(grf);
                    330:     }
                    331:     while ((gr = getgrent()) != NULL) {
                    332:        if (gr->gr_gid == gid)
                    333:            break;
                    334:     }
                    335:     if (!gr_stayopen) {
                    336:        fclose(grf);
                    337:        grf = NULL;
                    338:     }
                    339:     return gr;
                    340: }

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