File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sample_group / getgrent.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 16:23:02 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: /*
    2:  * Copyright (c) 2005,2008,2010-2011 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 <sys/param.h>
   25: #include <stdio.h>
   26: #ifdef STDC_HEADERS
   27: # include <stdlib.h>
   28: # include <stddef.h>
   29: #else
   30: # ifdef HAVE_STDLIB_H
   31: #  include <stdlib.h>
   32: # endif
   33: #endif /* STDC_HEADERS */
   34: #ifdef HAVE_STRING_H
   35: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
   36: #  include <memory.h>
   37: # endif
   38: # include <string.h>
   39: #endif /* HAVE_STRING_H */
   40: #ifdef HAVE_STRINGS_H
   41: # include <strings.h>
   42: #endif /* HAVE_STRINGS_H */
   43: #include <fcntl.h>
   44: #include <limits.h>
   45: #include <pwd.h>
   46: #include <grp.h>
   47: 
   48: #include "missing.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:     char *cp, *colon;
  106:     int n;
  107: 
  108:     if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
  109: 	return NULL;
  110: 
  111:     memset(&gr, 0, sizeof(gr));
  112:     if ((colon = strchr(cp = colon, ':')) == NULL)
  113: 	return NULL;
  114:     *colon++ = '\0';
  115:     gr.gr_name = cp;
  116:     if ((colon = strchr(cp = colon, ':')) == NULL)
  117: 	return NULL;
  118:     *colon++ = '\0';
  119:     gr.gr_passwd = cp;
  120:     if ((colon = strchr(cp = colon, ':')) == NULL)
  121: 	return NULL;
  122:     *colon++ = '\0';
  123:     gr.gr_gid = atoi(cp);
  124:     len = strlen(colon);
  125:     if (len > 0 && colon[len - 1] == '\n')
  126: 	colon[len - 1] = '\0';
  127:     if (*colon != '\0') {
  128: 	gr.gr_mem = gr_mem;
  129: 	cp = strtok(colon, ",");
  130: 	for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
  131: 	    gr.gr_mem[n] = cp;
  132: 	    cp = strtok(NULL, ",");
  133: 	}
  134: 	gr.gr_mem[n++] = NULL;
  135:     } else
  136: 	gr.gr_mem = NULL;
  137:     return &gr;
  138: }
  139: 
  140: struct group *
  141: mygetgrnam(const char *name)
  142: {
  143:     struct group *gr;
  144: 
  145:     if (grf == NULL) {
  146: 	if ((grf = fopen(grfile, "r")) == NULL)
  147: 	    return NULL;
  148: 	fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
  149:     } else {
  150: 	rewind(grf);
  151:     }
  152:     while ((gr = mygetgrent()) != NULL) {
  153: 	if (strcmp(gr->gr_name, name) == 0)
  154: 	    break;
  155:     }
  156:     if (!gr_stayopen) {
  157: 	fclose(grf);
  158: 	grf = NULL;
  159:     }
  160:     return gr;
  161: }
  162: 
  163: struct group *
  164: mygetgrgid(gid_t gid)
  165: {
  166:     struct group *gr;
  167: 
  168:     if (grf == NULL) {
  169: 	if ((grf = fopen(grfile, "r")) == NULL)
  170: 	    return NULL;
  171: 	fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
  172:     } else {
  173: 	rewind(grf);
  174:     }
  175:     while ((gr = mygetgrent()) != NULL) {
  176: 	if (gr->gr_gid == gid)
  177: 	    break;
  178:     }
  179:     if (!gr_stayopen) {
  180: 	fclose(grf);
  181: 	grf = NULL;
  182:     }
  183:     return gr;
  184: }

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