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>2014-02-09 23:43:40 +0000
commit2bb37315c1e077bc176e703fbf0028a1f6315d37 (patch)
tree8c0fc9e5af8b442fbfa6688bfa03ca05fc9f0c19 /misc.c
parent05609b1cb381eafb999214bf4a95138e63abdbf2 (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 c3c809943..eb57bfc1b 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
@@ -58,6 +59,7 @@
58#include "misc.h" 59#include "misc.h"
59#include "log.h" 60#include "log.h"
60#include "ssh.h" 61#include "ssh.h"
62#include "platform.h"
61 63
62/* remove newline at end of string */ 64/* remove newline at end of string */
63char * 65char *
@@ -642,6 +644,71 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
642 return -1; 644 return -1;
643} 645}
644 646
647/*
648 * return 1 if the specified uid is a uid that may own a system directory
649 * otherwise 0.
650 */
651int
652platform_sys_dir_uid(uid_t uid)
653{
654 if (uid == 0)
655 return 1;
656#ifdef PLATFORM_SYS_DIR_UID
657 if (uid == PLATFORM_SYS_DIR_UID)
658 return 1;
659#endif
660 return 0;
661}
662
663int
664secure_permissions(struct stat *st, uid_t uid)
665{
666 if (!platform_sys_dir_uid(st->st_uid) && st->st_uid != uid)
667 return 0;
668 if ((st->st_mode & 002) != 0)
669 return 0;
670 if ((st->st_mode & 020) != 0) {
671 /* If the file is group-writable, the group in question must
672 * have exactly one member, namely the file's owner.
673 * (Zero-member groups are typically used by setgid
674 * binaries, and are unlikely to be suitable.)
675 */
676 struct passwd *pw;
677 struct group *gr;
678 int members = 0;
679
680 gr = getgrgid(st->st_gid);
681 if (!gr)
682 return 0;
683
684 /* Check primary group memberships. */
685 while ((pw = getpwent()) != NULL) {
686 if (pw->pw_gid == gr->gr_gid) {
687 ++members;
688 if (pw->pw_uid != uid)
689 return 0;
690 }
691 }
692 endpwent();
693
694 pw = getpwuid(st->st_uid);
695 if (!pw)
696 return 0;
697
698 /* Check supplementary group memberships. */
699 if (gr->gr_mem[0]) {
700 ++members;
701 if (strcmp(pw->pw_name, gr->gr_mem[0]) ||
702 gr->gr_mem[1])
703 return 0;
704 }
705
706 if (!members)
707 return 0;
708 }
709 return 1;
710}
711
645int 712int
646tun_open(int tun, int mode) 713tun_open(int tun, int mode)
647{ 714{