File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers / tsgetgrpw.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 10:46:12 2013 UTC (11 years, 1 month ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_7p0, v1_8_7, HEAD
1.8.7

    1: /*
    2:  * Copyright (c) 2005, 2008, 2010-2013
    3:  *	Todd C. Miller <Todd.Miller@courtesan.com>
    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 */
   45: #include <errno.h>
   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: 
   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: 
   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;
  126:     unsigned long id;
  127:     char *cp, *colon, *ep;
  128: 
  129: next_entry:
  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)
  135: 	goto next_entry;
  136:     *colon++ = '\0';
  137:     pw.pw_name = cp;
  138:     if ((colon = strchr(cp = colon, ':')) == NULL)
  139: 	goto next_entry;
  140:     *colon++ = '\0';
  141:     pw.pw_passwd = cp;
  142:     if ((colon = strchr(cp = colon, ':')) == NULL)
  143: 	goto next_entry;
  144:     *colon++ = '\0';
  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;
  151:     if ((colon = strchr(cp = colon, ':')) == NULL)
  152: 	goto next_entry;
  153:     *colon++ = '\0';
  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;
  160:     if ((colon = strchr(cp = colon, ':')) == NULL)
  161: 	goto next_entry;
  162:     *colon++ = '\0';
  163:     pw.pw_gecos = cp;
  164:     if ((colon = strchr(cp = colon, ':')) == NULL)
  165: 	goto next_entry;
  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;
  258:     unsigned long id;
  259:     char *cp, *colon, *ep;
  260:     int n;
  261: 
  262: next_entry:
  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)
  268: 	goto next_entry;
  269:     *colon++ = '\0';
  270:     gr.gr_name = cp;
  271:     if ((colon = strchr(cp = colon, ':')) == NULL)
  272: 	goto next_entry;
  273:     *colon++ = '\0';
  274:     gr.gr_passwd = cp;
  275:     if ((colon = strchr(cp = colon, ':')) == NULL)
  276: 	goto next_entry;
  277:     *colon++ = '\0';
  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;
  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>