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