Annotation of src/usr.bin/sudo/tsgetgrpw.c, Revision 1.1
1.1 ! millert 1: /*
! 2: * Copyright (c) 2005,2008 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 get{gr,pw}{uid,nam}() routines
! 19: * for use by testsudoers in the sudo test harness.
! 20: * We need our own since many platforms don't provide set{pw,gr}file().
! 21: */
! 22:
! 23: #include <config.h>
! 24:
! 25: #include <sys/types.h>
! 26: #include <sys/param.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: #else
! 42: # ifdef HAVE_STRINGS_H
! 43: # include <strings.h>
! 44: # endif
! 45: #endif /* HAVE_STRING_H */
! 46: #include <limits.h>
! 47: #include <pwd.h>
! 48: #include <grp.h>
! 49:
! 50: #include "sudo.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: static FILE *pwf;
! 60: static const char *pwfile = "/etc/passwd";
! 61: static int pw_stayopen;
! 62:
! 63: static FILE *grf;
! 64: static const char *grfile = "/etc/group";
! 65: static int gr_stayopen;
! 66:
! 67: void ts_setgrfile __P((const char *));
! 68: void ts_setgrent __P((void));
! 69: void ts_endgrent __P((void));
! 70: struct group *ts_getgrent __P((void));
! 71: struct group *ts_getgrnam __P((const char *));
! 72: struct group *ts_getgrgid __P((gid_t));
! 73:
! 74: void ts_setpwfile __P((const char *));
! 75: void ts_setpwent __P((void));
! 76: void ts_endpwent __P((void));
! 77: struct passwd *ts_getpwent __P((void));
! 78: struct passwd *ts_getpwnam __P((const char *));
! 79: struct passwd *ts_getpwuid __P((uid_t));
! 80:
! 81: void
! 82: ts_setpwfile(file)
! 83: const char *file;
! 84: {
! 85: pwfile = file;
! 86: if (pwf != NULL)
! 87: ts_endpwent();
! 88: }
! 89:
! 90: void
! 91: ts_setpwent()
! 92: {
! 93: if (pwf == NULL)
! 94: pwf = fopen(pwfile, "r");
! 95: else
! 96: rewind(pwf);
! 97: pw_stayopen = 1;
! 98: }
! 99:
! 100: void
! 101: ts_endpwent()
! 102: {
! 103: if (pwf != NULL) {
! 104: fclose(pwf);
! 105: pwf = NULL;
! 106: }
! 107: pw_stayopen = 0;
! 108: }
! 109:
! 110: struct passwd *
! 111: ts_getpwent()
! 112: {
! 113: static struct passwd pw;
! 114: static char pwbuf[LINE_MAX];
! 115: size_t len;
! 116: char *cp, *colon;
! 117:
! 118: if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
! 119: return(NULL);
! 120:
! 121: zero_bytes(&pw, sizeof(pw));
! 122: if ((colon = strchr(cp = colon, ':')) == NULL)
! 123: return(NULL);
! 124: *colon++ = '\0';
! 125: pw.pw_name = cp;
! 126: if ((colon = strchr(cp = colon, ':')) == NULL)
! 127: return(NULL);
! 128: *colon++ = '\0';
! 129: pw.pw_passwd = cp;
! 130: if ((colon = strchr(cp = colon, ':')) == NULL)
! 131: return(NULL);
! 132: *colon++ = '\0';
! 133: pw.pw_uid = atoi(cp);
! 134: if ((colon = strchr(cp = colon, ':')) == NULL)
! 135: return(NULL);
! 136: *colon++ = '\0';
! 137: pw.pw_gid = atoi(cp);
! 138: if ((colon = strchr(cp = colon, ':')) == NULL)
! 139: return(NULL);
! 140: *colon++ = '\0';
! 141: pw.pw_gecos = cp;
! 142: if ((colon = strchr(cp = colon, ':')) == NULL)
! 143: return(NULL);
! 144: *colon++ = '\0';
! 145: pw.pw_dir = cp;
! 146: pw.pw_shell = colon;
! 147: len = strlen(colon);
! 148: if (len > 0 && colon[len - 1] == '\n')
! 149: colon[len - 1] = '\0';
! 150: return(&pw);
! 151: }
! 152:
! 153: struct passwd *
! 154: ts_getpwnam(name)
! 155: const char *name;
! 156: {
! 157: struct passwd *pw;
! 158:
! 159: if (pwf != NULL)
! 160: rewind(pwf);
! 161: else if ((pwf = fopen(pwfile, "r")) == NULL)
! 162: return(NULL);
! 163: while ((pw = ts_getpwent()) != NULL) {
! 164: if (strcmp(pw->pw_name, name) == 0)
! 165: break;
! 166: }
! 167: if (!pw_stayopen) {
! 168: fclose(pwf);
! 169: pwf = NULL;
! 170: }
! 171: return(pw);
! 172: }
! 173:
! 174: struct passwd *
! 175: ts_getpwuid(uid)
! 176: uid_t uid;
! 177: {
! 178: struct passwd *pw;
! 179:
! 180: if (pwf != NULL)
! 181: rewind(pwf);
! 182: else if ((pwf = fopen(pwfile, "r")) == NULL)
! 183: return(NULL);
! 184: while ((pw = ts_getpwent()) != NULL) {
! 185: if (pw->pw_uid == uid)
! 186: break;
! 187: }
! 188: if (!pw_stayopen) {
! 189: fclose(pwf);
! 190: pwf = NULL;
! 191: }
! 192: return(pw);
! 193: }
! 194:
! 195: void
! 196: ts_setgrfile(file)
! 197: const char *file;
! 198: {
! 199: grfile = file;
! 200: if (grf != NULL)
! 201: ts_endgrent();
! 202: }
! 203:
! 204: void
! 205: ts_setgrent()
! 206: {
! 207: if (grf == NULL)
! 208: grf = fopen(grfile, "r");
! 209: else
! 210: rewind(grf);
! 211: gr_stayopen = 1;
! 212: }
! 213:
! 214: void
! 215: ts_endgrent()
! 216: {
! 217: if (grf != NULL) {
! 218: fclose(grf);
! 219: grf = NULL;
! 220: }
! 221: gr_stayopen = 0;
! 222: }
! 223:
! 224: struct group *
! 225: ts_getgrent()
! 226: {
! 227: static struct group gr;
! 228: static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
! 229: size_t len;
! 230: char *cp, *colon;
! 231: int n;
! 232:
! 233: if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
! 234: return(NULL);
! 235:
! 236: zero_bytes(&gr, sizeof(gr));
! 237: if ((colon = strchr(cp = colon, ':')) == NULL)
! 238: return(NULL);
! 239: *colon++ = '\0';
! 240: gr.gr_name = cp;
! 241: if ((colon = strchr(cp = colon, ':')) == NULL)
! 242: return(NULL);
! 243: *colon++ = '\0';
! 244: gr.gr_passwd = cp;
! 245: if ((colon = strchr(cp = colon, ':')) == NULL)
! 246: return(NULL);
! 247: *colon++ = '\0';
! 248: gr.gr_gid = atoi(cp);
! 249: len = strlen(colon);
! 250: if (len > 0 && colon[len - 1] == '\n')
! 251: colon[len - 1] = '\0';
! 252: if (*colon != '\0') {
! 253: gr.gr_mem = gr_mem;
! 254: cp = strtok(colon, ",");
! 255: for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
! 256: gr.gr_mem[n] = cp;
! 257: cp = strtok(NULL, ",");
! 258: }
! 259: gr.gr_mem[n++] = NULL;
! 260: } else
! 261: gr.gr_mem = NULL;
! 262: return(&gr);
! 263: }
! 264:
! 265: struct group *
! 266: ts_getgrnam(name)
! 267: const char *name;
! 268: {
! 269: struct group *gr;
! 270:
! 271: if (grf != NULL)
! 272: rewind(grf);
! 273: else if ((grf = fopen(grfile, "r")) == NULL)
! 274: return(NULL);
! 275: while ((gr = ts_getgrent()) != NULL) {
! 276: if (strcmp(gr->gr_name, name) == 0)
! 277: break;
! 278: }
! 279: if (!gr_stayopen) {
! 280: fclose(grf);
! 281: grf = NULL;
! 282: }
! 283: return(gr);
! 284: }
! 285:
! 286: struct group *
! 287: ts_getgrgid(gid)
! 288: gid_t gid;
! 289: {
! 290: struct group *gr;
! 291:
! 292: if (grf != NULL)
! 293: rewind(grf);
! 294: else if ((grf = fopen(grfile, "r")) == NULL)
! 295: return(NULL);
! 296: while ((gr = ts_getgrent()) != NULL) {
! 297: if (gr->gr_gid == gid)
! 298: break;
! 299: }
! 300: if (!gr_stayopen) {
! 301: fclose(grf);
! 302: grf = NULL;
! 303: }
! 304: return(gr);
! 305: }