summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2014-02-09 16:09:58 +0000
committerColin Watson <cjwatson@debian.org>2016-02-29 12:33:29 +0000
commit6f05f80017871238b4e50fc4e09d57d722416743 (patch)
tree1bfe799dc3909da0ffc4bb5640955d8f1be80b16 /misc.c
parent5c2c0e042d57cee75528686f47b4c47db434ad8b (diff)
Allow harmless group-writability
Allow secure files (~/.ssh/config, ~/.ssh/authorized_keys, etc.) to be group-writable, provided that the group in question contains only the file's owner. Rejected upstream for IMO incorrect reasons (e.g. a misunderstanding about the contents of gr->gr_mem). Given that per-user groups and umask 002 are the default setup in Debian (for good reasons - this makes operating in setgid directories with other groups much easier), we need to permit this by default. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1060 Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=314347 Last-Update: 2013-09-14 Patch-Name: user-group-modes.patch
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/misc.c b/misc.c
index de7e1facd..5704fa6c4 100644
--- a/misc.c
+++ b/misc.c
@@ -51,8 +51,9 @@
51#include <netdb.h> 51#include <netdb.h>
52#ifdef HAVE_PATHS_H 52#ifdef HAVE_PATHS_H
53# include <paths.h> 53# include <paths.h>
54#include <pwd.h>
55#endif 54#endif
55#include <pwd.h>
56#include <grp.h>
56#ifdef SSH_TUN_OPENBSD 57#ifdef SSH_TUN_OPENBSD
57#include <net/if.h> 58#include <net/if.h>
58#endif 59#endif
@@ -61,6 +62,7 @@
61#include "misc.h" 62#include "misc.h"
62#include "log.h" 63#include "log.h"
63#include "ssh.h" 64#include "ssh.h"
65#include "platform.h"
64 66
65/* remove newline at end of string */ 67/* remove newline at end of string */
66char * 68char *
@@ -647,6 +649,71 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
647 return -1; 649 return -1;
648} 650}
649 651
652/*
653 * return 1 if the specified uid is a uid that may own a system directory
654 * otherwise 0.
655 */
656int
657platform_sys_dir_uid(uid_t uid)
658{
659 if (uid == 0)
660 return 1;
661#ifdef PLATFORM_SYS_DIR_UID
662 if (uid == PLATFORM_SYS_DIR_UID)
663 return 1;
664#endif
665 return 0;
666}
667
668int
669secure_permissions(struct stat *st, uid_t uid)
670{
671 if (!platform_sys_dir_uid(st->st_uid) && st->st_uid != uid)
672 return 0;
673 if ((st->st_mode & 002) != 0)
674 return 0;
675 if ((st->st_mode & 020) != 0) {
676 /* If the file is group-writable, the group in question must
677 * have exactly one member, namely the file's owner.
678 * (Zero-member groups are typically used by setgid
679 * binaries, and are unlikely to be suitable.)
680 */
681 struct passwd *pw;
682 struct group *gr;
683 int members = 0;
684
685 gr = getgrgid(st->st_gid);
686 if (!gr)
687 return 0;
688
689 /* Check primary group memberships. */
690 while ((pw = getpwent()) != NULL) {
691 if (pw->pw_gid == gr->gr_gid) {
692 ++members;
693 if (pw->pw_uid != uid)
694 return 0;
695 }
696 }
697 endpwent();
698
699 pw = getpwuid(st->st_uid);
700 if (!pw)
701 return 0;
702
703 /* Check supplementary group memberships. */
704 if (gr->gr_mem[0]) {
705 ++members;
706 if (strcmp(pw->pw_name, gr->gr_mem[0]) ||
707 gr->gr_mem[1])
708 return 0;
709 }
710
711 if (!members)
712 return 0;
713 }
714 return 1;
715}
716
650int 717int
651tun_open(int tun, int mode) 718tun_open(int tun, int mode)
652{ 719{