From c805bd2960935e82edf22e5edec08c95b0d20837 Mon Sep 17 00:00:00 2001 From: Benoit Chesneau Date: Mon, 28 Dec 2015 12:33:54 +0100 Subject: [PATCH] check auth before trying to own a file fix #1157 --- gunicorn/glogging.py | 5 +++-- gunicorn/util.py | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/gunicorn/glogging.py b/gunicorn/glogging.py index 70daf079..d368b497 100644 --- a/gunicorn/glogging.py +++ b/gunicorn/glogging.py @@ -338,8 +338,9 @@ class Logger(object): util.check_is_writeable(output) h = logging.FileHandler(output) # make sure the user can reopen the file - os.chown(h.baseFilename, self.cfg.user, self.cfg.group) - + if not util.is_writable(h.baseFilename, self.cfg.user, + self.cfg.group): + os.chown(h.baseFilename, self.cfg.user, self.cfg.group) h.setFormatter(fmt) h._gunicorn = True log.addHandler(h) diff --git a/gunicorn/util.py b/gunicorn/util.py index 15cfb943..029afbfa 100644 --- a/gunicorn/util.py +++ b/gunicorn/util.py @@ -7,12 +7,15 @@ from __future__ import print_function import email.utils import fcntl +import grp import io import os import pkg_resources +import pwd import random import resource import socket +import stat import sys import textwrap import time @@ -159,6 +162,21 @@ def chown(path, uid, gid): gid = abs(gid) & 0x7FFFFFFF # see note above. os.chown(path, uid, gid) +def is_writable(path, uid, gid): + gid = abs(gid) & 0x7FFFFFFF + st = os.stat(path) + + if st.st_uid == uid: + return st.st_mode & st.S_IWUSR != 0 + + user = pwd.getpwuid(uid)[0] + groups = [g.gr_gid for g in grp.getgrall() if user in g.gr_mem] + groups.append(gid) + + if st.st_gid in groups: + return st.st_mode & stat.S_IWGRP != 0 + + return st.st_mode & stat.S_IWOTH != 0 if sys.platform.startswith("win"): def _waitfor(func, pathname, waitall=False):