login_auth.c (22993) | login_auth.c (25670) |
---|---|
1/*- 2 * Copyright (c) 1996 by 3 * Sean Eric Fagan <sef@kithrup.com> 4 * David Nugent <davidn@blaze.net.au> 5 * All rights reserved. 6 * | 1/*- 2 * Copyright (c) 1996 by 3 * Sean Eric Fagan <sef@kithrup.com> 4 * David Nugent <davidn@blaze.net.au> 5 * All rights reserved. 6 * |
7 * Portions copyright (c) 1995,1997 by 8 * Berkeley Software Design, Inc. 9 * All rights reserved. 10 * |
|
7 * Redistribution and use in source and binary forms, with or without 8 * modification, is permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice immediately at the beginning of the file, without modification, 12 * this list of conditions, and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. This work was done expressly for inclusion into FreeBSD. Other use 17 * is permitted provided this notation is included. 18 * 4. Absolutely no warranty of function or purpose is made by the authors. 19 * 5. Modifications may be freely made to this file providing the above 20 * conditions are met. 21 * 22 * Low-level routines relating to the user capabilities database 23 * | 11 * Redistribution and use in source and binary forms, with or without 12 * modification, is permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice immediately at the beginning of the file, without modification, 16 * this list of conditions, and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. This work was done expressly for inclusion into FreeBSD. Other use 21 * is permitted provided this notation is included. 22 * 4. Absolutely no warranty of function or purpose is made by the authors. 23 * 5. Modifications may be freely made to this file providing the above 24 * conditions are met. 25 * 26 * Low-level routines relating to the user capabilities database 27 * |
24 * $Id$ | 28 * $Id: login_auth.c,v 1.6 1997/02/22 15:08:18 peter Exp $ |
25 */ 26 27#include <sys/types.h> 28#include <sys/time.h> 29#include <sys/resource.h> 30#include <sys/stat.h> | 29 */ 30 31#include <sys/types.h> 32#include <sys/time.h> 33#include <sys/resource.h> 34#include <sys/stat.h> |
35#include <sys/param.h> |
|
31#include <errno.h> 32#include <fcntl.h> 33#include <limits.h> 34#include <stdio.h> | 36#include <errno.h> 37#include <fcntl.h> 38#include <limits.h> 39#include <stdio.h> |
40#include <ctype.h> |
|
35#include <pwd.h> 36#include <stdlib.h> 37#include <string.h> 38#include <syslog.h> 39#include <unistd.h> 40#include <login_cap.h> 41#include <stdarg.h> 42#include <paths.h> | 41#include <pwd.h> 42#include <stdlib.h> 43#include <string.h> 44#include <syslog.h> 45#include <unistd.h> 46#include <login_cap.h> 47#include <stdarg.h> 48#include <paths.h> |
49#include <sys/socket.h> |
|
43#include <sys/wait.h> | 50#include <sys/wait.h> |
51#include <err.h> 52#include <libutil.h> |
|
44 | 53 |
45#ifdef RLIM_LONG 46# define STRTOV strtol 47#else 48# define STRTOV strtoq 49#endif | 54#ifdef LOGIN_CAP_AUTH 55/* 56 * Comment from BSDI's authenticate.c module: 57 * NOTE: THIS MODULE IS TO BE DEPRECATED. FUTURE VERSIONS OF BSD/OS WILL 58 * HAVE AN UPDATED API, THOUGH THESE FUNCTIONS WILL CONTINUE TO BE AVAILABLE 59 * FOR BACKWARDS COMPATABILITY 60 */ |
50 | 61 |
51#define AUTHMAXLINES 1024 52#define AUTHMAXARGS 16 | |
53 | 62 |
54struct auth_info { 55 int reject; 56 int auths; 57 int env_count; 58 char **env; 59 int file_count; 60 char **files; | 63#define AUTHMAXSPOOL (8 * 1024) /* Max size of authentication data */ 64#define AUTHCOMM_FD 3 /* Handle used to read/write auth data */ 65 66struct rmfiles { 67 struct rmfiles *next; 68 char file[1]; |
61}; 62 | 69}; 70 |
63static struct auth_info auth_info; | 71struct authopts { 72 struct authopts *next; 73 char opt[1]; 74}; |
64 | 75 |
76static char *spoolbuf = NULL; 77static int spoolidx = 0; 78static struct rmfiles *rmfirst = NULL; 79static struct authopts *optfirst = NULL; 80 81 |
|
65/* | 82/* |
66 * free_auth_info() 67 * Go through the auth_info structure, and free() anything of interest. 68 * This includes the string arrays, and any individual element. 69 * All part of being environmentally conscious ;). | 83 * Setup a known environment for all authentication scripts. |
70 */ 71 | 84 */ 85 |
72static void 73free_auth_info(void) | 86static char *auth_environ[] = { 87 "PATH=" _PATH_DEFPATH, 88 "SHELL=" _PATH_BSHELL, 89 NULL, 90}; 91 92 93 94/* 95 * nextline() 96 * Get the next line from the data buffer collected from 97 * the authentication program. This function relies on the 98 * fact that lines are nul terminated. 99 */ 100 101static char * 102nextline(int *idx) |
74{ | 103{ |
75 int i; | 104 char *ptr = NULL; |
76 | 105 |
77 auth_info.reject = 0; 78 auth_info.auths = 0; 79 if (auth_info.env) { 80 for (i = 0; i < auth_info.env_count; i++) { 81 if (auth_info.env[i]) 82 free(auth_info.env[i]); | 106 if (spoolbuf != NULL && *idx < spoolidx) { 107 ptr = spoolbuf + *idx; 108 *idx += strlen(ptr) + 1; |
83 } | 109 } |
84 free(auth_info.env); 85 auth_info.env = NULL; 86 } 87 if (auth_info.files) { 88 for (i = 0; i < auth_info.file_count; i++) { 89 if (auth_info.files[i]) 90 free(auth_info.files[i]); 91 } 92 free(auth_info.files); 93 auth_info.files = NULL; 94 } | 110 return ptr; |
95} 96 97 98/* | 111} 112 113 114/* |
99 * collect_info() 100 * Read from <fd>, a list of authorization commands. 101 * These commands are: 102 * reject 103 * authorize [root|secure] 104 * setenv <name>[ <value>] 105 * remove <file> 106 * A single reject means the entire thing is bad; 107 * multiple authorize statements can be present (it would be 108 * silly, but that's what the spec says). 109 * The commands are collected, and are accted upon by: 110 * auth_scan() -- check for authorization or rejection 111 * auth_rmfiles() -- remove the specified files 112 * auth_env() -- set the specified environment variables 113 * We only get up to AUTHMAXLINES lines of input from the program. | 115 * spooldata() 116 * Read data returned on authentication backchannel and 117 * stuff it into our spool buffer. We also replace \n with nul 118 * to make parsing easier later. |
114 */ | 119 */ |
115#define STRSIZEOF(x) (sizeof(x)-1) 116static void 117collect_info(int fd) | 120 121static int 122spooldata(int fd) |
118{ | 123{ |
119 char *line; 120 FILE *fp; 121 char *ptr; 122 size_t len; 123 int line_count = 0; | |
124 | 124 |
125 fp = fdopen(fd, "r"); | 125 if (spoolbuf) 126 free(spoolbuf); 127 spoolidx = 0; |
126 | 128 |
127 while ((line = fgetln(fp, &len)) != NULL) { 128 if (++line_count > AUTHMAXLINES) 129 break; 130 if (len && line[len-1] == '\n') 131 --len; 132 line[len] = '\0'; /* Terminate */ 133 if (strncasecmp(line, BI_REJECT, STRSIZEOF(BI_REJECT)) == 0) { 134 auth_info.reject = 1; 135 } else if (strncasecmp(line, BI_AUTH, STRSIZEOF(BI_AUTH)) == 0) { 136 ptr = line + STRSIZEOF(BI_AUTH); 137 ptr += strspn(ptr, " \t"); 138 if (!*ptr) 139 auth_info.auths |= AUTH_OKAY; 140 else if (strncasecmp(ptr, BI_ROOTOKAY, STRSIZEOF(BI_ROOTOKAY)) == 0) 141 auth_info.auths |= AUTH_ROOTOKAY; 142 else if (strncasecmp(ptr, BI_SECURE, STRSIZEOF(BI_SECURE)) == 0) 143 auth_info.auths |= AUTH_SECURE; 144 } else if (strncasecmp(line, BI_SETENV, STRSIZEOF(BI_SETENV)) == 0) { 145 ptr = line + STRSIZEOF(BI_SETENV); 146 ptr += strspn(ptr, " \t"); 147 if (*ptr) { 148 char **tmp = realloc(auth_info.env, sizeof(char*) * (auth_info.env_count + 1)); 149 if (tmp != NULL) { 150 auth_info.env = tmp; 151 if ((auth_info.env[auth_info.env_count] = strdup(ptr)) != NULL) 152 auth_info.env_count++; | 129 if (spoolbuf == NULL && (spoolbuf = malloc(AUTHMAXSPOOL)) == NULL) 130 syslog(LOG_ERR, "authbuffer malloc: %m"); 131 132 else while (spoolidx < sizeof(spoolbuf) - 1) { 133 int r = read(fd, spoolbuf + spoolidx, sizeof(spoolbuf)-spoolidx); 134 char *b; 135 136 if (r <= 0) { 137 spoolbuf[spoolidx] = '\0'; 138 return 0; |
153 } | 139 } |
154 } 155 } else if (strncasecmp(line, BI_REMOVE, STRSIZEOF(BI_REMOVE)) == 0) { 156 ptr = line + STRSIZEOF(BI_REMOVE); 157 ptr += strspn(ptr, " \t"); 158 if (*ptr) { 159 char **tmp = realloc(auth_info.files, sizeof(char*) * (auth_info.file_count + 1)); 160 if (tmp != NULL) { 161 auth_info.files = tmp; 162 if ((auth_info.files[auth_info.file_count] = strdup(ptr)) != NULL) 163 auth_info.file_count++; 164 } 165 } | 140 /* 141 * Convert newlines into NULs to allow 142 * easier scanning of the file. 143 */ 144 while ((b = memchr(spoolbuf + spoolidx, '\n', r)) != NULL) 145 *b = '\0'; 146 spoolidx += r; |
166 } | 147 } |
167 } 168 fclose(fp); | 148 return -1; |
169} 170 | 149} 150 |
171 | 151 |
172/* | 152/* |
173 * authenticate() | 153 * auth_check() |
174 * Starts an auth_script() for the given <user>, with a class <class>, 175 * style <style>, and service <service>. <style> is necessary, 176 * as are <user> and <class>, but <service> is optional -- it defaults 177 * to "login". 178 * Since auth_script() expects an execl'able program name, authenticate() 179 * also concatenates <style> to _PATH_AUTHPROG. | 154 * Starts an auth_script() for the given <user>, with a class <class>, 155 * style <style>, and service <service>. <style> is necessary, 156 * as are <user> and <class>, but <service> is optional -- it defaults 157 * to "login". 158 * Since auth_script() expects an execl'able program name, authenticate() 159 * also concatenates <style> to _PATH_AUTHPROG. |
180 * Lastly, calls auth_scan(AUTH_NONE) to see if there are any "reject" statements, | 160 * Lastly, calls auth_scan(0) to see if there are any "reject" statements, |
181 * or lack of "auth" statements. 182 * Returns -1 on error, 0 on rejection, and >0 on success. 183 * (See AUTH_* for the return values.) 184 * 185 */ | 161 * or lack of "auth" statements. 162 * Returns -1 on error, 0 on rejection, and >0 on success. 163 * (See AUTH_* for the return values.) 164 * 165 */ |
166 |
|
186int | 167int |
187authenticate(const char * name, const char * class, const char * style, const char *service) | 168auth_check(const char *name, const char *clss, const char *style, 169 const char *service, int *status) |
188{ | 170{ |
189 int retval; | 171 int _status; |
190 | 172 |
191 if (style == NULL || *style == '\0') 192 retval = -1; 193 else { 194 char buf[sizeof(_PATH_AUTHPROG) + 64]; | 173 if (status == NULL) 174 status = &_status; 175 *status = 0; |
195 | 176 |
196 if (service == NULL || *service == '\0') 197 service = LOGIN_DEFSERVICE; | 177 if (style != NULL) { 178 char path[MAXPATHLEN]; |
198 | 179 |
199 free_auth_info(); | 180 if (service == NULL) 181 service = LOGIN_DEFSERVICE; |
200 | 182 |
201 if (snprintf(buf, sizeof buf, _PATH_AUTHPROG "%s", style) >= sizeof buf) 202 retval = -1; 203 else { 204 retval = auth_script(buf, style, "-s", service, name, class, NULL); 205 if (retval >= 0) 206 retval = auth_scan(AUTH_NONE); | 183 snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style); 184 if (auth_script(path, style, "-s", service, name, clss, 0)) 185 status = 0; 186 else 187 *status = auth_scan(0); 188 189 return *status & AUTH_ALLOW; |
207 } | 190 } |
208 } 209 return retval; | 191 return -1; |
210} 211 212 | 192} 193 194 |
195int 196auth_response(const char *name, const char *class, const char *style, 197 const char *service, int *status, 198 const char *challenge, const char *response) 199{ 200 int _status; 201 202 if (status == NULL) 203 status = &_status; 204 *status = 0; 205 206 if (style != NULL) { 207 int datalen; 208 char *data; 209 210 if (service == NULL) 211 service = LOGIN_DEFSERVICE; 212 213 datalen = strlen(challenge) + strlen(response) + 2; 214 215 if ((data = malloc(datalen)) == NULL) { 216 syslog(LOG_ERR, "auth_response: %m"); 217 warnx("internal resource failure"); 218 } else { 219 char path[MAXPATHLEN]; 220 221 snprintf(data, datalen, "%s%c%s", challenge, 0, response); 222 snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style); 223 if (auth_script_data(data, datalen, path, style, "-s", service, 224 name, class, 0)) 225 *status = 0; 226 else 227 *status = auth_scan(0); 228 free(data); 229 return (*status & AUTH_ALLOW); 230 } 231 } 232 return -1; 233} 234 235 236int 237auth_approve(login_cap_t *lc, const char *name, const char *service) 238{ 239 int r = -1; 240 char path[MAXPATHLEN]; 241 242 if (lc == NULL) { 243 if (strlen(name) > MAXPATHLEN) { 244 syslog(LOG_ERR, "%s: username too long", name); 245 warnx("username too long"); 246 } else { 247 struct passwd *pwd; 248 char *p; 249 250 pwd = getpwnam(name); 251 if (pwd == NULL && (p = strchr(name, '.')) != NULL) { 252 int i = p - name; 253 254 if (i >= MAXPATHLEN) 255 i = MAXPATHLEN - 1; 256 strncpy(path, name, i); 257 path[i] = '\0'; 258 pwd = getpwnam(path); /* Fixed bug in BSDI code... */ 259 } 260 if ((lc = login_getpwclass(pwd ? pwd->pw_class : NULL)) == NULL) 261 warnx("unable to classify user '%s'", name); 262 } 263 } 264 265 if (lc != NULL) { 266 char *approve; 267 char *s; 268 269 if (service != NULL) 270 service = LOGIN_DEFSERVICE; 271 272 snprintf(path, sizeof(path), "approve-%s", service); 273 274 if ((approve = login_getcapstr(lc, s = path, NULL, NULL)) == NULL && 275 (approve = login_getcapstr(lc, s = "approve", NULL, NULL)) == NULL) 276 r = AUTH_OKAY; 277 else { 278 279 if (approve[0] != '/') { 280 syslog(LOG_ERR, "Invalid %s script: %s", s, approve); 281 warnx("invalid path to approval script"); 282 } else { 283 char *s; 284 285 s = strrchr(approve, '/') + 1; 286 if (auth_script(approve, s, name, 287 lc->lc_class, service, 0) == 0 && 288 (r = auth_scan(AUTH_OKAY) & AUTH_ALLOW) != 0) 289 auth_env(); 290 } 291 } 292 } 293 return r; 294} 295 296 297void 298auth_env(void) 299{ 300 int idx = 0; 301 char *line; 302 303 while ((line = nextline(&idx)) != NULL) { 304 if (!strncasecmp(line, BI_SETENV, sizeof(BI_SETENV)-1)) { 305 line += sizeof(BI_SETENV) - 1; 306 if (*line && isspace(*line)) { 307 char *name; 308 char ch, *p; 309 310 while (*line && isspace(*line)) 311 ++line; 312 name = line; 313 while (*line && !isspace(*line)) 314 ++line; 315 ch = *(p = line); 316 if (*line) 317 ++line; 318 if (setenv(name, line, 1)) 319 warn("setenv(%s, %s)", name, line); 320 *p = ch; 321 } 322 } 323 } 324} 325 326 327char * 328auth_value(const char *what) 329{ 330 int idx = 0; 331 char *line; 332 333 while ((line = nextline(&idx)) != NULL) { 334 if (!strncasecmp(line, BI_VALUE, sizeof(BI_VALUE)-1)) { 335 char *name; 336 337 line += sizeof(BI_VALUE) - 1; 338 while (*line && isspace(*line)) 339 ++line; 340 name = line; 341 if (*line) { 342 int i; 343 char ch, *p; 344 345 ch = *(p = line); 346 *line++ = '\0'; 347 i = strcmp(name, what); 348 *p = ch; 349 if (i == 0) 350 return auth_mkvalue(line); 351 } 352 } 353 } 354 return NULL; 355} 356 357char * 358auth_mkvalue(const char *value) 359{ 360 char *big, *p; 361 362 big = malloc(strlen(value) * 4 + 1); 363 if (big != NULL) { 364 for (p = big; *value; ++value) { 365 switch (*value) { 366 case '\r': 367 *p++ = '\\'; 368 *p++ = 'r'; 369 break; 370 case '\n': 371 *p++ = '\\'; 372 *p++ = 'n'; 373 break; 374 case '\\': 375 *p++ = '\\'; 376 *p++ = *value; 377 break; 378 case '\t': 379 case ' ': 380 if (p == big) 381 *p++ = '\\'; 382 *p++ = *value; 383 break; 384 default: 385 if (!isprint(*value)) { 386 *p++ = '\\'; 387 *p++ = ((*value >> 6) & 0x3) + '0'; 388 *p++ = ((*value >> 3) & 0x7) + '0'; 389 *p++ = ((*value ) & 0x7) + '0'; 390 } else 391 *p++ = *value; 392 break; 393 } 394 } 395 *p = '\0'; 396 big = realloc(big, strlen(big) + 1); 397 } 398 return big; 399} 400 401 402#define NARGC 63 403static int 404_auth_script(const char *data, int nbytes, const char *path, va_list ap) 405{ 406 int r, argc, status; 407 int pfd[2]; 408 pid_t pid; 409 struct authopts *e; 410 char *argv[NARGC+1]; 411 412 r = -1; 413 argc = 0; 414 for (e = optfirst; argc < (NARGC - 1) && e != NULL; e = e->next) { 415 argv[argc++] = "-v"; 416 argv[argc++] = e->opt; 417 } 418 while (argc < NARGC && (argv[argc] = va_arg(ap, char *)) != NULL) 419 ++argc; 420 argv[argc] = NULL; 421 422 if (argc >= NARGC && va_arg(ap, char *)) 423 syslog(LOG_ERR, "too many arguments"); 424 else if (_secure_path(path, 0, 0) < 0) { 425 syslog(LOG_ERR, "%s: path not secure", path); 426 warnx("invalid script: %s", path); 427 } else if (socketpair(PF_LOCAL, SOCK_STREAM, 0, pfd) < 0) { 428 syslog(LOG_ERR, "unable to create backchannel %m"); 429 warnx("internal resource failure"); 430 } else switch (pid = fork()) { 431 case -1: /* fork() failure */ 432 close(pfd[0]); 433 close(pfd[1]); 434 syslog(LOG_ERR, "fork %s: %m", path); 435 warnx("internal resource failure"); 436 break; 437 case 0: /* child process */ 438 close(pfd[0]); 439 if (pfd[1] != AUTHCOMM_FD) { 440 if (dup2(pfd[1], AUTHCOMM_FD) < 0) 441 err(1, "dup backchannel"); 442 close(pfd[1]); 443 } 444 for (r = getdtablesize(); --r > AUTHCOMM_FD; ) 445 close(r); 446 execve(path, argv, auth_environ); 447 syslog(LOG_ERR, "exec %s: %m", path); 448 err(1, path); 449 default: /* parent */ 450 close(pfd[1]); 451 if (data && nbytes) 452 write(pfd[0], data, nbytes); 453 r = spooldata(pfd[0]); 454 close(pfd[0]); 455 if (waitpid(pid, &status, 0) < 0) { 456 syslog(LOG_ERR, "%s: waitpid: %m", path); 457 warnx("internal failure"); 458 r = -1; 459 } else { 460 if (r != 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) 461 r = -1; 462 } 463 /* kill the buffer if it is of no use */ 464 if (r != 0) { 465 free(spoolbuf); 466 spoolbuf = NULL; 467 spoolidx = 0; 468 } 469 break; 470 } 471 return r; 472} 473 474 475 |
|
213/* 214 * auth_script() 215 * Runs an authentication program with specified arguments. 216 * It sets up file descriptor 3 for the program to write to; 217 * it stashes the output somewhere. The output of the program 218 * consists of statements: | 476/* 477 * auth_script() 478 * Runs an authentication program with specified arguments. 479 * It sets up file descriptor 3 for the program to write to; 480 * it stashes the output somewhere. The output of the program 481 * consists of statements: |
219 * reject | 482 * reject [challenge|silent] |
220 * authorize [root|secure] 221 * setenv <name> [<value>] 222 * remove <file> 223 * | 483 * authorize [root|secure] 484 * setenv <name> [<value>] 485 * remove <file> 486 * |
224 * Terribly exciting, isn't it? There is no limit specified in 225 * BSDi's API for how much output can be present, but we should 226 * keep it fairly small, I think. 227 * No more than AUTHMAXLINES lines. | 487 * Terribly exciting, isn't it? 488 * Output cannot exceed AUTHMAXSPOOL characters. |
228 */ 229 230int | 489 */ 490 491int |
231auth_script(const char * path, ...) | 492auth_script(const char *path, ...) |
232{ | 493{ |
233 va_list ap; 234 int pid, status; 235 int argc = 0; 236 int p[2]; /* pipes */ 237 char *argv[AUTHMAXARGS+1]; | 494 int r; 495 va_list ap; |
238 | 496 |
239 va_start(ap, path); 240 while (argc < AUTHMAXARGS && (argv[argc++] = va_arg(ap, char*)) != NULL) 241 ; 242 argv[argc] = NULL; 243 va_end(ap); | 497 va_start(ap, path); 498 r = _auth_script(NULL, 0, path, ap); 499 va_end(ap); 500 return r; 501} |
244 | 502 |
245 fflush(NULL); | |
246 | 503 |
247 if (pipe(p) >= 0) { 248 if ((pid = fork()) == -1) { 249 close(p[0]); 250 close(p[1]); 251 } else if (pid == 0) { /* Child */ 252 close(p[0]); 253 dup2(p[1], 3); 254 if (setenv("PATH", _PATH_DEFPATH, 1)==0 && setenv("SHELL", _PATH_BSHELL, 1)==0) 255 execv(path, argv); 256 _exit(1); 257 } else { 258 close(p[1]); 259 collect_info(p[0]); 260 if (waitpid(pid, &status, 0) != -1 && WIFEXITED(status) && !WEXITSTATUS(status)) 261 return 0; 262 } 263 } 264 return -1; | 504int 505auth_script_data(const char *data, int nbytes, const char *path, ...) 506{ 507 int r; 508 va_list ap; 509 510 va_start(ap, path); 511 r = _auth_script(data, nbytes, path, ap); 512 va_end(ap); 513 return r; |
265} 266 267 | 514} 515 516 |
268/* 269 * auth_env() 270 * Processes the stored "setenv" lines from the stored authentication 271 * output. 272 */ | 517static void 518add_rmlist(const char *file) 519{ 520 struct rmfiles *rm; |
273 | 521 |
522 if ((rm = malloc(sizeof(struct rmfiles) + strlen(file) + 1)) == NULL) 523 syslog(LOG_ERR, "add_rmfile malloc: %m"); 524 else { 525 strcpy(rm->file, file); 526 rm->next = rmfirst; 527 rmfirst = rm; 528 } 529} 530 531 |
|
274int | 532int |
275auth_env(void) | 533auth_scan(int okay) |
276{ | 534{ |
277 int i; | 535 int idx = 0; 536 char *line; |
278 | 537 |
279 for (i = 0; i < auth_info.env_count; i++) { 280 char *nam = auth_info.env[i]; 281 char *ptr = nam + strcspn(nam, " \t="); 282 if (*ptr) { 283 *ptr++ = '\0'; 284 ptr += strspn(ptr, " \t"); | 538 while ((line = nextline(&idx)) != NULL) { 539 if (!strncasecmp(line, BI_REJECT, sizeof(BI_REJECT)-1)) { 540 line += sizeof(BI_REJECT) - 1; 541 while (*line && isspace(*line)) 542 ++line; 543 if (*line) { 544 if (!strcasecmp(line, "silent")) 545 return AUTH_SILENT; 546 if (!strcasecmp(line, "challenge")) 547 return AUTH_CHALLENGE; 548 } 549 return 0; 550 } else if (!strncasecmp(line, BI_AUTH, sizeof(BI_AUTH)-1)) { 551 line += sizeof(BI_AUTH) - 1; 552 while (*line && isspace(*line)) 553 ++line; 554 if (*line == '\0') 555 okay |= AUTH_OKAY; 556 else if (!strcasecmp(line, "root")) 557 okay |= AUTH_ROOTOKAY; 558 else if (!strcasecmp(line, "secure")) 559 okay |= AUTH_SECURE; 560 } 561 else if (!strncasecmp(line, BI_REMOVE, sizeof(BI_REMOVE)-1)) { 562 line += sizeof(BI_REMOVE) - 1; 563 while (*line && isspace(*line)) 564 ++line; 565 if (*line) 566 add_rmlist(line); 567 } |
285 } | 568 } |
286 setenv(nam, ptr, 1); 287 } 288 return 0; | 569 570 return okay; |
289} 290 291 | 571} 572 573 |
292/* 293 * auth_scan() 294 * Goes through the output of the auth_script/authenticate, and 295 * checks for a failure or authentication. 296 * <ok> is a default authentication value -- if there are no 297 * rejection or authentication statements, then it is returned 298 * unmodified. 299 * AUTH_NONE is returned if there were any reject statements 300 * from the authentication program (invoked by auth_script()), and 301 * AUTH, AUTH_ROOTOKAY, and/or AUTH_SECURE are returned if the 302 * appropriate directives were found. Note that AUTH* are 303 * *bitmasks*! 304 */ 305 | |
306int | 574int |
307auth_scan(int ok) | 575auth_setopt(const char *n, const char *v) |
308{ | 576{ |
309 if (auth_info.reject) 310 return 0; 311 return ok | auth_info.auths; | 577 int r; 578 struct authopts *e; 579 580 if ((e = malloc(sizeof(*e) + strlen(n) + strlen(v) + 1)) == NULL) 581 r = -1; 582 else { 583 sprintf(e->opt, "%s=%s", n, v); 584 e->next = optfirst; 585 optfirst = e; 586 r = 0; 587 } 588 return r; |
312} 313 314 | 589} 590 591 |
315/* 316 * auth_rmfiles() 317 * Removes any files that the authentication program said needed to be 318 * removed, said files having come from a previous execution of 319 * auth_script(). 320 */ | 592void 593auth_clropts(void) 594{ 595 struct authopts *e; |
321 | 596 |
322int | 597 while ((e = optfirst) != NULL) { 598 optfirst = e->next; 599 free(e); 600 } 601} 602 603 604void |
323auth_rmfiles(void) 324{ | 605auth_rmfiles(void) 606{ |
325 int i = auth_info.file_count; 326 while (i-- > 0) { 327 unlink(auth_info.files[i]); 328 free(auth_info.files[i]); 329 auth_info.files[i] = NULL; 330 } 331 return 0; | 607 struct rmfiles *rm; 608 609 while ((rm = rmfirst) != NULL) { 610 unlink(rm->file); 611 rmfirst = rm->next; 612 free(rm); 613 } |
332} 333 | 614} 615 |
616#endif |
|
334 | 617 |
618 |
|
335/* 336 * auth_checknologin() 337 * Checks for the existance of a nologin file in the login_cap 338 * capability <lc>. If there isn't one specified, then it checks 339 * to see if this class should just ignore nologin files. Lastly, 340 * it tries to print out the default nologin file, and, if such 341 * exists, it exits. 342 */ --- 22 unchanged lines hidden (view full) --- 365 366 367/* 368 * auth_cat() 369 * Checks for the readability of <file>; if it can be opened for 370 * reading, it prints it out to stdout, and then exits. Otherwise, 371 * it returns 0 (meaning no nologin file). 372 */ | 619/* 620 * auth_checknologin() 621 * Checks for the existance of a nologin file in the login_cap 622 * capability <lc>. If there isn't one specified, then it checks 623 * to see if this class should just ignore nologin files. Lastly, 624 * it tries to print out the default nologin file, and, if such 625 * exists, it exits. 626 */ --- 22 unchanged lines hidden (view full) --- 649 650 651/* 652 * auth_cat() 653 * Checks for the readability of <file>; if it can be opened for 654 * reading, it prints it out to stdout, and then exits. Otherwise, 655 * it returns 0 (meaning no nologin file). 656 */ |
657 |
|
373int 374auth_cat(const char *file) 375{ 376 int fd, count; 377 char buf[BUFSIZ]; 378 379 if ((fd = open(file, O_RDONLY)) < 0) 380 return 0; 381 while ((count = read(fd, buf, sizeof(buf))) > 0) | 658int 659auth_cat(const char *file) 660{ 661 int fd, count; 662 char buf[BUFSIZ]; 663 664 if ((fd = open(file, O_RDONLY)) < 0) 665 return 0; 666 while ((count = read(fd, buf, sizeof(buf))) > 0) |
382 write(fileno(stdout), buf, count); | 667 (void)write(fileno(stdout), buf, count); |
383 close(fd); 384 return 1; 385} | 668 close(fd); 669 return 1; 670} |