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