summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/misc.c b/misc.c
index a7a23dcc6..ddff00e52 100644
--- a/misc.c
+++ b/misc.c
@@ -48,8 +48,9 @@
48#include <netdb.h> 48#include <netdb.h>
49#ifdef HAVE_PATHS_H 49#ifdef HAVE_PATHS_H
50# include <paths.h> 50# include <paths.h>
51#include <pwd.h>
52#endif 51#endif
52#include <pwd.h>
53#include <grp.h>
53#ifdef SSH_TUN_OPENBSD 54#ifdef SSH_TUN_OPENBSD
54#include <net/if.h> 55#include <net/if.h>
55#endif 56#endif
@@ -642,6 +643,55 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
642} 643}
643 644
644int 645int
646secure_permissions(struct stat *st, uid_t uid)
647{
648 if (st->st_uid != 0 && st->st_uid != uid)
649 return 0;
650 if ((st->st_mode & 002) != 0)
651 return 0;
652 if ((st->st_mode & 020) != 0) {
653 /* If the file is group-writable, the group in question must
654 * have exactly one member, namely the file's owner.
655 * (Zero-member groups are typically used by setgid
656 * binaries, and are unlikely to be suitable.)
657 */
658 struct passwd *pw;
659 struct group *gr;
660 int members = 0;
661
662 gr = getgrgid(st->st_gid);
663 if (!gr)
664 return 0;
665
666 /* Check primary group memberships. */
667 while ((pw = getpwent()) != NULL) {
668 if (pw->pw_gid == gr->gr_gid) {
669 ++members;
670 if (pw->pw_uid != uid)
671 return 0;
672 }
673 }
674 endpwent();
675
676 pw = getpwuid(st->st_uid);
677 if (!pw)
678 return 0;
679
680 /* Check supplementary group memberships. */
681 if (gr->gr_mem[0]) {
682 ++members;
683 if (strcmp(pw->pw_name, gr->gr_mem[0]) ||
684 gr->gr_mem[1])
685 return 0;
686 }
687
688 if (!members)
689 return 0;
690 }
691 return 1;
692}
693
694int
645tun_open(int tun, int mode) 695tun_open(int tun, int mode)
646{ 696{
647#if defined(CUSTOM_SYS_TUN_OPEN) 697#if defined(CUSTOM_SYS_TUN_OPEN)