/*- * Copyright (c) 1996 by * Sean Eric Fagan * David Nugent * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice immediately at the beginning of the file, without modification, * this list of conditions, and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. This work was done expressly for inclusion into FreeBSD. Other use * is permitted provided this notation is included. * 4. Absolutely no warranty of function or purpose is made by the authors. * 5. Modifications may be freely made to this file providing the above * conditions are met. * * Low-level routines relating to the user capabilities database * * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef RLIM_LONG # define STRTOV strtol #else # define STRTOV strtoq #endif #define AUTHMAXLINES 1024 #define AUTHMAXARGS 16 struct auth_info { int reject; int auths; int env_count; char **env; int file_count; char **files; }; static struct auth_info auth_info; /* * free_auth_info() * Go through the auth_info structure, and free() anything of interest. * This includes the string arrays, and any individual element. * All part of being environmentally conscious ;). */ static void free_auth_info(void) { int i; auth_info.reject = 0; auth_info.auths = 0; if (auth_info.env) { for (i = 0; i < auth_info.env_count; i++) { if (auth_info.env[i]) free(auth_info.env[i]); } free(auth_info.env); auth_info.env = NULL; } if (auth_info.files) { for (i = 0; i < auth_info.file_count; i++) { if (auth_info.files[i]) free(auth_info.files[i]); } free(auth_info.files); auth_info.files = NULL; } } /* * collect_info() * Read from , a list of authorization commands. * These commands are: * reject * authorize [root|secure] * setenv [ ] * remove * A single reject means the entire thing is bad; * multiple authorize statements can be present (it would be * silly, but that's what the spec says). * The commands are collected, and are accted upon by: * auth_scan() -- check for authorization or rejection * auth_rmfiles() -- remove the specified files * auth_env() -- set the specified environment variables * We only get up to AUTHMAXLINES lines of input from the program. */ #define STRSIZEOF(x) (sizeof(x)-1) static void collect_info(int fd) { char *line; FILE *fp; char *ptr; size_t len; int line_count = 0; fp = fdopen(fd, "r"); while ((line = fgetln(fp, &len)) != NULL) { if (++line_count > AUTHMAXLINES) break; if (len && line[len-1] == '\n') --len; line[len] = '\0'; /* Terminate */ if (strncasecmp(line, BI_REJECT, STRSIZEOF(BI_REJECT)) == 0) { auth_info.reject = 1; } else if (strncasecmp(line, BI_AUTH, STRSIZEOF(BI_AUTH)) == 0) { ptr = line + STRSIZEOF(BI_AUTH); ptr += strspn(ptr, " \t"); if (!*ptr) auth_info.auths |= AUTH_OKAY; else if (strncasecmp(ptr, BI_ROOTOKAY, STRSIZEOF(BI_ROOTOKAY)) == 0) auth_info.auths |= AUTH_ROOTOKAY; else if (strncasecmp(ptr, BI_SECURE, STRSIZEOF(BI_SECURE)) == 0) auth_info.auths |= AUTH_SECURE; } else if (strncasecmp(line, BI_SETENV, STRSIZEOF(BI_SETENV)) == 0) { ptr = line + STRSIZEOF(BI_SETENV); ptr += strspn(ptr, " \t"); if (*ptr) { char **tmp = realloc(auth_info.env, sizeof(char*) * (auth_info.env_count + 1)); if (tmp != NULL) { auth_info.env = tmp; if ((auth_info.env[auth_info.env_count] = strdup(ptr)) != NULL) auth_info.env_count++; } } } else if (strncasecmp(line, BI_REMOVE, STRSIZEOF(BI_REMOVE)) == 0) { ptr = line + STRSIZEOF(BI_REMOVE); ptr += strspn(ptr, " \t"); if (*ptr) { char **tmp = realloc(auth_info.files, sizeof(char*) * (auth_info.file_count + 1)); if (tmp != NULL) { auth_info.files = tmp; if ((auth_info.files[auth_info.file_count] = strdup(ptr)) != NULL) auth_info.file_count++; } } } } fclose(fp); } /* * authenticate() * Starts an auth_script() for the given , with a class , * style