File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / group_file / getgrent.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:12:54 2014 UTC (10 years, 3 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_10p3_0, v1_8_10p3, HEAD
sudo v 1.8.10p3

    1: /*
    2:  * Copyright (c) 2005,2008,2010-2013 Todd C. Miller <Todd.Miller@courtesan.com>
    3:  *
    4:  * Permission to use, copy, modify, and distribute this software for any
    5:  * purpose with or without fee is hereby granted, provided that the above
    6:  * copyright notice and this permission notice appear in all copies.
    7:  *
    8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   15:  */
   16: 
   17: /*
   18:  * Trivial replacements for the libc getgr{uid,nam}() routines.
   19:  */
   20: 
   21: #include <config.h>
   22: 
   23: #include <sys/types.h>
   24: #include <stdio.h>
   25: #ifdef STDC_HEADERS
   26: # include <stdlib.h>
   27: # include <stddef.h>
   28: #else
   29: # ifdef HAVE_STDLIB_H
   30: #  include <stdlib.h>
   31: # endif
   32: #endif /* STDC_HEADERS */
   33: #ifdef HAVE_STRING_H
   34: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
   35: #  include <memory.h>
   36: # endif
   37: # include <string.h>
   38: #endif /* HAVE_STRING_H */
   39: #ifdef HAVE_STRINGS_H
   40: # include <strings.h>
   41: #endif /* HAVE_STRINGS_H */
   42: #include <fcntl.h>
   43: #include <limits.h>
   44: #include <pwd.h>
   45: #include <grp.h>
   46: 
   47: #include "missing.h"
   48: #include "sudo_util.h"
   49: 
   50: #ifndef LINE_MAX
   51: # define LINE_MAX 2048
   52: #endif
   53: 
   54: #undef GRMEM_MAX
   55: #define GRMEM_MAX 200
   56: 
   57: static FILE *grf;
   58: static const char *grfile = "/etc/group";
   59: static int gr_stayopen;
   60: 
   61: void mysetgrfile(const char *);
   62: void mysetgrent(void);
   63: void myendgrent(void);
   64: struct group *mygetgrent(void);
   65: struct group *mygetgrnam(const char *);
   66: struct group *mygetgrgid(gid_t);
   67: 
   68: void
   69: mysetgrfile(const char *file)
   70: {
   71:     grfile = file;
   72:     if (grf != NULL)
   73: 	myendgrent();
   74: }
   75: 
   76: void
   77: mysetgrent(void)
   78: {
   79:     if (grf == NULL) {
   80: 	grf = fopen(grfile, "r");
   81: 	if (grf != NULL)
   82: 	    fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
   83:     } else {
   84: 	rewind(grf);
   85:     }
   86:     gr_stayopen = 1;
   87: }
   88: 
   89: void
   90: myendgrent(void)
   91: {
   92:     if (grf != NULL) {
   93: 	fclose(grf);
   94: 	grf = NULL;
   95:     }
   96:     gr_stayopen = 0;
   97: }
   98: 
   99: struct group *
  100: mygetgrent(void)
  101: {
  102:     static struct group gr;
  103:     static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
  104:     size_t len;
  105:     id_t id;
  106:     char *cp, *colon;
  107:     const char *errstr;
  108:     int n;
  109: 
  110: next_entry:
  111:     if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
  112: 	return NULL;
  113: 
  114:     memset(&gr, 0, sizeof(gr));
  115:     if ((colon = strchr(cp = colon, ':')) == NULL)
  116: 	goto next_entry;
  117:     *colon++ = '\0';
  118:     gr.gr_name = cp;
  119:     if ((colon = strchr(cp = colon, ':')) == NULL)
  120: 	goto next_entry;
  121:     *colon++ = '\0';
  122:     gr.gr_passwd = cp;
  123:     if ((colon = strchr(cp = colon, ':')) == NULL)
  124: 	goto next_entry;
  125:     *colon++ = '\0';
  126:     id = atoid(cp, NULL, NULL, &errstr);
  127:     if (errstr != NULL)
  128: 	goto next_entry;
  129:     gr.gr_gid = (gid_t)id;
  130:     len = strlen(colon);
  131:     if (len > 0 && colon[len - 1] == '\n')
  132: 	colon[len - 1] = '\0';
  133:     if (*colon != '\0') {
  134: 	gr.gr_mem = gr_mem;
  135: 	cp = strtok(colon, ",");
  136: 	for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
  137: 	    gr.gr_mem[n] = cp;
  138: 	    cp = strtok(NULL, ",");
  139: 	}
  140: 	gr.gr_mem[n++] = NULL;
  141:     } else
  142: 	gr.gr_mem = NULL;
  143:     return &gr;
  144: }
  145: 
  146: struct group *
  147: mygetgrnam(const char *name)
  148: {
  149:     struct group *gr;
  150: 
  151:     if (grf == NULL) {
  152: 	if ((grf = fopen(grfile, "r")) == NULL)
  153: 	    return NULL;
  154: 	fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
  155:     } else {
  156: 	rewind(grf);
  157:     }
  158:     while ((gr = mygetgrent()) != NULL) {
  159: 	if (strcmp(gr->gr_name, name) == 0)
  160: 	    break;
  161:     }
  162:     if (!gr_stayopen) {
  163: 	fclose(grf);
  164: 	grf = NULL;
  165:     }
  166:     return gr;
  167: }
  168: 
  169: struct group *
  170: mygetgrgid(gid_t gid)
  171: {
  172:     struct group *gr;
  173: 
  174:     if (grf == NULL) {
  175: 	if ((grf = fopen(grfile, "r")) == NULL)
  176: 	    return NULL;
  177: 	fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
  178:     } else {
  179: 	rewind(grf);
  180:     }
  181:     while ((gr = mygetgrent()) != NULL) {
  182: 	if (gr->gr_gid == gid)
  183: 	    break;
  184:     }
  185:     if (!gr_stayopen) {
  186: 	fclose(grf);
  187: 	grf = NULL;
  188:     }
  189:     return gr;
  190: }

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