|
1 |
| -/* $OpenBSD: auth.c,v 1.122 2017/06/24 06:34:38 djm Exp $ */ |
| 1 | +/* $OpenBSD: auth.c,v 1.123 2017/08/18 05:36:45 djm Exp $ */ |
2 | 2 | /*
|
3 | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved.
|
4 | 4 | *
|
|
43 | 43 | #ifdef USE_SHADOW
|
44 | 44 | #include <shadow.h>
|
45 | 45 | #endif
|
46 |
| -#ifdef HAVE_LIBGEN_H |
47 |
| -#include <libgen.h> |
48 |
| -#endif |
49 | 46 | #include <stdarg.h>
|
50 | 47 | #include <stdio.h>
|
51 | 48 | #include <string.h>
|
@@ -508,98 +505,6 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
|
508 | 505 | return host_status;
|
509 | 506 | }
|
510 | 507 |
|
511 |
| -/* |
512 |
| - * Check a given path for security. This is defined as all components |
513 |
| - * of the path to the file must be owned by either the owner of |
514 |
| - * of the file or root and no directories must be group or world writable. |
515 |
| - * |
516 |
| - * XXX Should any specific check be done for sym links ? |
517 |
| - * |
518 |
| - * Takes a file name, its stat information (preferably from fstat() to |
519 |
| - * avoid races), the uid of the expected owner, their home directory and an |
520 |
| - * error buffer plus max size as arguments. |
521 |
| - * |
522 |
| - * Returns 0 on success and -1 on failure |
523 |
| - */ |
524 |
| -int |
525 |
| -auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, |
526 |
| - uid_t uid, char *err, size_t errlen) |
527 |
| -{ |
528 |
| - char buf[PATH_MAX], homedir[PATH_MAX]; |
529 |
| - char *cp; |
530 |
| - int comparehome = 0; |
531 |
| - struct stat st; |
532 |
| - |
533 |
| - if (realpath(name, buf) == NULL) { |
534 |
| - snprintf(err, errlen, "realpath %s failed: %s", name, |
535 |
| - strerror(errno)); |
536 |
| - return -1; |
537 |
| - } |
538 |
| - if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) |
539 |
| - comparehome = 1; |
540 |
| - |
541 |
| - if (!S_ISREG(stp->st_mode)) { |
542 |
| - snprintf(err, errlen, "%s is not a regular file", buf); |
543 |
| - return -1; |
544 |
| - } |
545 |
| - if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) || |
546 |
| - (stp->st_mode & 022) != 0) { |
547 |
| - snprintf(err, errlen, "bad ownership or modes for file %s", |
548 |
| - buf); |
549 |
| - return -1; |
550 |
| - } |
551 |
| - |
552 |
| - /* for each component of the canonical path, walking upwards */ |
553 |
| - for (;;) { |
554 |
| - if ((cp = dirname(buf)) == NULL) { |
555 |
| - snprintf(err, errlen, "dirname() failed"); |
556 |
| - return -1; |
557 |
| - } |
558 |
| - strlcpy(buf, cp, sizeof(buf)); |
559 |
| - |
560 |
| - if (stat(buf, &st) < 0 || |
561 |
| - (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) || |
562 |
| - (st.st_mode & 022) != 0) { |
563 |
| - snprintf(err, errlen, |
564 |
| - "bad ownership or modes for directory %s", buf); |
565 |
| - return -1; |
566 |
| - } |
567 |
| - |
568 |
| - /* If are past the homedir then we can stop */ |
569 |
| - if (comparehome && strcmp(homedir, buf) == 0) |
570 |
| - break; |
571 |
| - |
572 |
| - /* |
573 |
| - * dirname should always complete with a "/" path, |
574 |
| - * but we can be paranoid and check for "." too |
575 |
| - */ |
576 |
| - if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) |
577 |
| - break; |
578 |
| - } |
579 |
| - return 0; |
580 |
| -} |
581 |
| - |
582 |
| -/* |
583 |
| - * Version of secure_path() that accepts an open file descriptor to |
584 |
| - * avoid races. |
585 |
| - * |
586 |
| - * Returns 0 on success and -1 on failure |
587 |
| - */ |
588 |
| -static int |
589 |
| -secure_filename(FILE *f, const char *file, struct passwd *pw, |
590 |
| - char *err, size_t errlen) |
591 |
| -{ |
592 |
| - struct stat st; |
593 |
| - |
594 |
| - /* check the open file to avoid races */ |
595 |
| - if (fstat(fileno(f), &st) < 0) { |
596 |
| - snprintf(err, errlen, "cannot stat file %s: %s", |
597 |
| - file, strerror(errno)); |
598 |
| - return -1; |
599 |
| - } |
600 |
| - return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); |
601 |
| -} |
602 |
| - |
603 | 508 | static FILE *
|
604 | 509 | auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
605 | 510 | int log_missing, char *file_type)
|
@@ -646,7 +551,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
646 | 551 | return NULL;
|
647 | 552 | }
|
648 | 553 | if (strict_modes &&
|
649 |
| - secure_filename(f, file, pw, line, sizeof(line)) != 0) { |
| 554 | + safe_path_fd(fileno(f), file, pw, line, sizeof(line)) != 0) { |
650 | 555 | fclose(f);
|
651 | 556 | logit("Authentication refused: %s", line);
|
652 | 557 | auth_debug_add("Ignored %s: %s", file_type, line);
|
|
0 commit comments