File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers / tsgetgrpw.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 07:56:35 2013 UTC (10 years, 10 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, v1_8_10p3_0, v1_8_10p3, HEAD
v 1.8.8

    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:     id_t id;
  127:     char *cp, *colon;
  128:     const char *errstr;
  129: 
  130: next_entry:
  131:     if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
  132: 	return NULL;
  133: 
  134:     memset(&pw, 0, sizeof(pw));
  135:     if ((colon = strchr(cp = colon, ':')) == NULL)
  136: 	goto next_entry;
  137:     *colon++ = '\0';
  138:     pw.pw_name = cp;
  139:     if ((colon = strchr(cp = colon, ':')) == NULL)
  140: 	goto next_entry;
  141:     *colon++ = '\0';
  142:     pw.pw_passwd = cp;
  143:     if ((colon = strchr(cp = colon, ':')) == NULL)
  144: 	goto next_entry;
  145:     *colon++ = '\0';
  146:     id = atoid(cp, NULL, NULL, &errstr);
  147:     if (errstr != NULL)
  148: 	goto next_entry;
  149:     pw.pw_uid = (uid_t)id;
  150:     if ((colon = strchr(cp = colon, ':')) == NULL)
  151: 	goto next_entry;
  152:     *colon++ = '\0';
  153:     id = atoid(cp, NULL, NULL, &errstr);
  154:     if (errstr != NULL)
  155: 	goto next_entry;
  156:     pw.pw_gid = (gid_t)id;
  157:     if ((colon = strchr(cp = colon, ':')) == NULL)
  158: 	goto next_entry;
  159:     *colon++ = '\0';
  160:     pw.pw_gecos = cp;
  161:     if ((colon = strchr(cp = colon, ':')) == NULL)
  162: 	goto next_entry;
  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;
  255:     id_t id;
  256:     char *cp, *colon;
  257:     const char *errstr;
  258:     int n;
  259: 
  260: next_entry:
  261:     if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
  262: 	return NULL;
  263: 
  264:     memset(&gr, 0, sizeof(gr));
  265:     if ((colon = strchr(cp = colon, ':')) == NULL)
  266: 	goto next_entry;
  267:     *colon++ = '\0';
  268:     gr.gr_name = cp;
  269:     if ((colon = strchr(cp = colon, ':')) == NULL)
  270: 	goto next_entry;
  271:     *colon++ = '\0';
  272:     gr.gr_passwd = cp;
  273:     if ((colon = strchr(cp = colon, ':')) == NULL)
  274: 	goto next_entry;
  275:     *colon++ = '\0';
  276:     id = atoid(cp, NULL, NULL, &errstr);
  277:     if (errstr != NULL)
  278: 	goto next_entry;
  279:     gr.gr_gid = (gid_t)id;
  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>