diff options
author | sheldonh <sheldonh@FreeBSD.org> | 1999-08-13 16:51:40 +0000 |
---|---|---|
committer | sheldonh <sheldonh@FreeBSD.org> | 1999-08-13 16:51:40 +0000 |
commit | a9521339a7bd807b0dae35b4b70a0150df0bcd24 (patch) | |
tree | 52c5ac63021af58b637d51c1adb05ce87efc8614 /lib/libutil/login_auth.c | |
parent | 2de9577491dbec6d8e645d0097f31430db51e027 (diff) | |
download | FreeBSD-src-a9521339a7bd807b0dae35b4b70a0150df0bcd24.zip FreeBSD-src-a9521339a7bd807b0dae35b4b70a0150df0bcd24.tar.gz |
Axe LOGIN_CAP_AUTH.
PR: 10115
Reported by: Gene Skonicki <gene@cif.rochester.edu>
Requested by: jdp
Diffstat (limited to 'lib/libutil/login_auth.c')
-rw-r--r-- | lib/libutil/login_auth.c | 566 |
1 files changed, 1 insertions, 565 deletions
diff --git a/lib/libutil/login_auth.c b/lib/libutil/login_auth.c index b0c617c3..15f5892 100644 --- a/lib/libutil/login_auth.c +++ b/lib/libutil/login_auth.c @@ -25,7 +25,7 @@ * * Low-level routines relating to the user capabilities database * - * $Id: login_auth.c,v 1.8 1997/07/19 04:47:05 davidn Exp $ + * $Id: login_auth.c,v 1.9 1998/09/16 04:17:47 imp Exp $ */ #include <sys/types.h> @@ -51,570 +51,6 @@ #include <err.h> #include <libutil.h> -#ifdef LOGIN_CAP_AUTH -/* - * Comment from BSDI's authenticate.c module: - * NOTE: THIS MODULE IS TO BE DEPRECATED. FUTURE VERSIONS OF BSD/OS WILL - * HAVE AN UPDATED API, THOUGH THESE FUNCTIONS WILL CONTINUE TO BE AVAILABLE - * FOR BACKWARDS COMPATABILITY - */ - - -#define AUTHMAXSPOOL (8 * 1024) /* Max size of authentication data */ -#define AUTHCOMM_FD 3 /* Handle used to read/write auth data */ - -struct rmfiles { - struct rmfiles *next; - char file[1]; -}; - -struct authopts { - struct authopts *next; - char opt[1]; -}; - -static char *spoolbuf = NULL; -static int spoolidx = 0; -static struct rmfiles *rmfirst = NULL; -static struct authopts *optfirst = NULL; - - -/* - * Setup a known environment for all authentication scripts. - */ - -static char *auth_environ[] = { - "PATH=" _PATH_DEFPATH, - "SHELL=" _PATH_BSHELL, - NULL, -}; - - - -/* - * nextline() - * Get the next line from the data buffer collected from - * the authentication program. This function relies on the - * fact that lines are nul terminated. - */ - -static char * -nextline(int *idx) -{ - char *ptr = NULL; - - if (spoolbuf != NULL && *idx < spoolidx) { - ptr = spoolbuf + *idx; - *idx += strlen(ptr) + 1; - } - return ptr; -} - - -/* - * spooldata() - * Read data returned on authentication backchannel and - * stuff it into our spool buffer. We also replace \n with nul - * to make parsing easier later. - */ - -static int -spooldata(int fd) -{ - - if (spoolbuf) - free(spoolbuf); - spoolidx = 0; - - if (spoolbuf == NULL && (spoolbuf = malloc(AUTHMAXSPOOL)) == NULL) - syslog(LOG_ERR, "authbuffer malloc: %m"); - - else while (spoolidx < sizeof(spoolbuf) - 1) { - int r = read(fd, spoolbuf + spoolidx, sizeof(spoolbuf)-spoolidx); - char *b; - - if (r <= 0) { - spoolbuf[spoolidx] = '\0'; - return 0; - } - /* - * Convert newlines into NULs to allow - * easier scanning of the file. - */ - while ((b = memchr(spoolbuf + spoolidx, '\n', r)) != NULL) - *b = '\0'; - spoolidx += r; - } - return -1; -} - - -/* - * auth_check() - * Starts an auth_script() for the given <user>, with a class <class>, - * style <style>, and service <service>. <style> is necessary, - * as are <user> and <class>, but <service> is optional -- it defaults - * to "login". - * Since auth_script() expects an execl'able program name, authenticate() - * also concatenates <style> to _PATH_AUTHPROG. - * Lastly, calls auth_scan(0) to see if there are any "reject" statements, - * or lack of "auth" statements. - * Returns -1 on error, 0 on rejection, and >0 on success. - * (See AUTH_* for the return values.) - * - */ - -int -auth_check(const char *name, const char *clss, const char *style, - const char *service, int *status) -{ - int _status; - - if (status == NULL) - status = &_status; - *status = 0; - - if (style != NULL) { - char path[MAXPATHLEN]; - - if (service == NULL) - service = LOGIN_DEFSERVICE; - - snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style); - if (auth_script(path, style, "-s", service, name, clss, 0)) - status = 0; - else - *status = auth_scan(0); - - return *status & AUTH_ALLOW; - } - return -1; -} - - -int -auth_response(const char *name, const char *class, const char *style, - const char *service, int *status, - const char *challenge, const char *response) -{ - int _status; - - if (status == NULL) - status = &_status; - *status = 0; - - if (style != NULL) { - int datalen; - char *data; - - if (service == NULL) - service = LOGIN_DEFSERVICE; - - datalen = strlen(challenge) + strlen(response) + 2; - - if ((data = malloc(datalen)) == NULL) { - syslog(LOG_ERR, "auth_response: %m"); - warnx("internal resource failure"); - } else { - char path[MAXPATHLEN]; - - snprintf(data, datalen, "%s%c%s", challenge, 0, response); - snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style); - if (auth_script_data(data, datalen, path, style, "-s", service, - name, class, 0)) - *status = 0; - else - *status = auth_scan(0); - free(data); - return (*status & AUTH_ALLOW); - } - } - return -1; -} - - -int -auth_approve(login_cap_t *lc, const char *name, const char *service) -{ - int r = -1; - char path[MAXPATHLEN]; - - if (lc == NULL) { - if (strlen(name) > MAXPATHLEN) { - syslog(LOG_ERR, "%s: username too long", name); - warnx("username too long"); - } else { - struct passwd *pwd; - char *p; - - pwd = getpwnam(name); - if (pwd == NULL && (p = strchr(name, '.')) != NULL) { - int i = p - name; - - if (i >= MAXPATHLEN) - i = MAXPATHLEN - 1; - strncpy(path, name, i); - path[i] = '\0'; - pwd = getpwnam(path); /* Fixed bug in BSDI code... */ - } - if ((lc = login_getpwclass(pwd ? pwd->pw_class : NULL)) == NULL) - warnx("unable to classify user '%s'", name); - } - } - - if (lc != NULL) { - char *approve; - char *s; - - if (service != NULL) - service = LOGIN_DEFSERVICE; - - snprintf(path, sizeof(path), "approve-%s", service); - - if ((approve = login_getcapstr(lc, s = path, NULL, NULL)) == NULL && - (approve = login_getcapstr(lc, s = "approve", NULL, NULL)) == NULL) - r = AUTH_OKAY; - else { - - if (approve[0] != '/') { - syslog(LOG_ERR, "Invalid %s script: %s", s, approve); - warnx("invalid path to approval script"); - } else { - char *s; - - s = strrchr(approve, '/') + 1; - if (auth_script(approve, s, name, - lc->lc_class, service, 0) == 0 && - (r = auth_scan(AUTH_OKAY) & AUTH_ALLOW) != 0) - auth_env(); - } - } - } - return r; -} - - -void -auth_env(void) -{ - int idx = 0; - char *line; - - while ((line = nextline(&idx)) != NULL) { - if (!strncasecmp(line, BI_SETENV, sizeof(BI_SETENV)-1)) { - line += sizeof(BI_SETENV) - 1; - if (*line && isspace(*line)) { - char *name; - char ch, *p; - - while (*line && isspace(*line)) - ++line; - name = line; - while (*line && !isspace(*line)) - ++line; - ch = *(p = line); - if (*line) - ++line; - if (setenv(name, line, 1)) - warn("setenv(%s, %s)", name, line); - *p = ch; - } - } - } -} - - -char * -auth_value(const char *what) -{ - int idx = 0; - char *line; - - while ((line = nextline(&idx)) != NULL) { - if (!strncasecmp(line, BI_VALUE, sizeof(BI_VALUE)-1)) { - char *name; - - line += sizeof(BI_VALUE) - 1; - while (*line && isspace(*line)) - ++line; - name = line; - if (*line) { - int i; - char ch, *p; - - ch = *(p = line); - *line++ = '\0'; - i = strcmp(name, what); - *p = ch; - if (i == 0) - return auth_mkvalue(line); - } - } - } - return NULL; -} - -char * -auth_mkvalue(const char *value) -{ - char *big, *p; - - big = malloc(strlen(value) * 4 + 1); - if (big != NULL) { - for (p = big; *value; ++value) { - switch (*value) { - case '\r': - *p++ = '\\'; - *p++ = 'r'; - break; - case '\n': - *p++ = '\\'; - *p++ = 'n'; - break; - case '\\': - *p++ = '\\'; - *p++ = *value; - break; - case '\t': - case ' ': - if (p == big) - *p++ = '\\'; - *p++ = *value; - break; - default: - if (!isprint(*value)) { - *p++ = '\\'; - *p++ = ((*value >> 6) & 0x3) + '0'; - *p++ = ((*value >> 3) & 0x7) + '0'; - *p++ = ((*value ) & 0x7) + '0'; - } else - *p++ = *value; - break; - } - } - *p = '\0'; - big = reallocf(big, strlen(big) + 1); - } - return big; -} - - -#define NARGC 63 -static int -_auth_script(const char *data, int nbytes, const char *path, va_list ap) -{ - int r, argc, status; - int pfd[2]; - pid_t pid; - struct authopts *e; - char *argv[NARGC+1]; - - r = -1; - argc = 0; - for (e = optfirst; argc < (NARGC - 1) && e != NULL; e = e->next) { - argv[argc++] = "-v"; - argv[argc++] = e->opt; - } - while (argc < NARGC && (argv[argc] = va_arg(ap, char *)) != NULL) - ++argc; - argv[argc] = NULL; - - if (argc >= NARGC && va_arg(ap, char *)) - syslog(LOG_ERR, "too many arguments"); - else if (_secure_path(path, 0, 0) < 0) { - syslog(LOG_ERR, "%s: path not secure", path); - warnx("invalid script: %s", path); - } else if (socketpair(PF_LOCAL, SOCK_STREAM, 0, pfd) < 0) { - syslog(LOG_ERR, "unable to create backchannel %m"); - warnx("internal resource failure"); - } else switch (pid = fork()) { - case -1: /* fork() failure */ - close(pfd[0]); - close(pfd[1]); - syslog(LOG_ERR, "fork %s: %m", path); - warnx("internal resource failure"); - break; - case 0: /* child process */ - close(pfd[0]); - if (pfd[1] != AUTHCOMM_FD) { - if (dup2(pfd[1], AUTHCOMM_FD) < 0) - err(1, "dup backchannel"); - close(pfd[1]); - } - for (r = getdtablesize(); --r > AUTHCOMM_FD; ) - close(r); - execve(path, argv, auth_environ); - syslog(LOG_ERR, "exec %s: %m", path); - err(1, path); - default: /* parent */ - close(pfd[1]); - if (data && nbytes) - write(pfd[0], data, nbytes); - r = spooldata(pfd[0]); - close(pfd[0]); - if (waitpid(pid, &status, 0) < 0) { - syslog(LOG_ERR, "%s: waitpid: %m", path); - warnx("internal failure"); - r = -1; - } else { - if (r != 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) - r = -1; - } - /* kill the buffer if it is of no use */ - if (r != 0) { - free(spoolbuf); - spoolbuf = NULL; - spoolidx = 0; - } - break; - } - return r; -} - - - -/* - * auth_script() - * Runs an authentication program with specified arguments. - * It sets up file descriptor 3 for the program to write to; - * it stashes the output somewhere. The output of the program - * consists of statements: - * reject [challenge|silent] - * authorize [root|secure] - * setenv <name> [<value>] - * remove <file> - * - * Terribly exciting, isn't it? - * Output cannot exceed AUTHMAXSPOOL characters. - */ - -int -auth_script(const char *path, ...) -{ - int r; - va_list ap; - - va_start(ap, path); - r = _auth_script(NULL, 0, path, ap); - va_end(ap); - return r; -} - - -int -auth_script_data(const char *data, int nbytes, const char *path, ...) -{ - int r; - va_list ap; - - va_start(ap, path); - r = _auth_script(data, nbytes, path, ap); - va_end(ap); - return r; -} - - -static void -add_rmlist(const char *file) -{ - struct rmfiles *rm; - - if ((rm = malloc(sizeof(struct rmfiles) + strlen(file) + 1)) == NULL) - syslog(LOG_ERR, "add_rmfile malloc: %m"); - else { - strcpy(rm->file, file); - rm->next = rmfirst; - rmfirst = rm; - } -} - - -int -auth_scan(int okay) -{ - int idx = 0; - char *line; - - while ((line = nextline(&idx)) != NULL) { - if (!strncasecmp(line, BI_REJECT, sizeof(BI_REJECT)-1)) { - line += sizeof(BI_REJECT) - 1; - while (*line && isspace(*line)) - ++line; - if (*line) { - if (!strcasecmp(line, "silent")) - return AUTH_SILENT; - if (!strcasecmp(line, "challenge")) - return AUTH_CHALLENGE; - } - return 0; - } else if (!strncasecmp(line, BI_AUTH, sizeof(BI_AUTH)-1)) { - line += sizeof(BI_AUTH) - 1; - while (*line && isspace(*line)) - ++line; - if (*line == '\0') - okay |= AUTH_OKAY; - else if (!strcasecmp(line, "root")) - okay |= AUTH_ROOTOKAY; - else if (!strcasecmp(line, "secure")) - okay |= AUTH_SECURE; - } - else if (!strncasecmp(line, BI_REMOVE, sizeof(BI_REMOVE)-1)) { - line += sizeof(BI_REMOVE) - 1; - while (*line && isspace(*line)) - ++line; - if (*line) - add_rmlist(line); - } - } - - return okay; -} - - -int -auth_setopt(const char *n, const char *v) -{ - int r; - struct authopts *e; - - if ((e = malloc(sizeof(*e) + strlen(n) + strlen(v) + 1)) == NULL) - r = -1; - else { - sprintf(e->opt, "%s=%s", n, v); - e->next = optfirst; - optfirst = e; - r = 0; - } - return r; -} - - -void -auth_clropts(void) -{ - struct authopts *e; - - while ((e = optfirst) != NULL) { - optfirst = e->next; - free(e); - } -} - - -void -auth_rmfiles(void) -{ - struct rmfiles *rm; - - while ((rm = rmfirst) != NULL) { - unlink(rm->file); - rmfirst = rm->next; - free(rm); - } -} - -#endif - /* * auth_checknologin() |