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