summaryrefslogtreecommitdiff
path: root/rpmlint-checks-master/CheckLogrotate.py
blob: 7a5ac4d3bcd7a15d1b52cb2b1ef35778bee4b8fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# vim:sw=4:et
#############################################################################
# File          : CheckLogrotate.py
# Package       : rpmlint
# Author        : Ludwig Nussel
# Purpose       : Check for insecure logrotate directories
#############################################################################

from Filter import *
import AbstractCheck
import re
import os
import string

class LogrotateCheck(AbstractCheck.AbstractCheck):
    def __init__(self):
        AbstractCheck.AbstractCheck.__init__(self, "CheckLogrotate")

    def check(self, pkg):
        if pkg.isSource():
            return

        files = pkg.files()
        dirs = {}

        for f, pkgfile in files.items():
            if f in pkg.ghostFiles():
                continue

            if f.startswith("/etc/logrotate.d/"):
                try:
                    for n, o in self.parselogrotateconf(pkg.dirName(), f).items():
                        if n in dirs and dirs[n] != o:
                            printError(pkg, "logrotate-duplicate", n)
                        else:
                            dirs[n] = o
                except Exception, x:
                    printError(pkg, 'rpmlint-exception', "%(file)s raised an exception: %(x)s" % {'file':f, 'x':x})

        for d in sorted(dirs.keys()):
            if not d in files:
                if d != '/var/log':
                    printError(pkg, 'suse-logrotate-log-dir-not-packaged', d)
                continue
            mode = files[d].mode&0777
            if files[d].user != 'root' and (dirs[d] is None or dirs[d][0] != files[d].user):
                printError(pkg, 'suse-logrotate-user-writable-log-dir', \
                        "%s %s:%s %04o"%(d, files[d].user, files[d].group, mode))
            elif files[d].group != 'root' and mode&020 and (dirs[d] is None or dirs[d][1] != files[d].group):
                    printError(pkg, 'suse-logrotate-user-writable-log-dir', \
                        "%s %s:%s %04o"%(d, files[d].user, files[d].group, mode))

    # extremely primitive logrotate parser
    def parselogrotateconf(self, root, f):
        dirs = {}
        fd = open('/'.join((root, f)))
        currentdirs = []
        for line in fd.readlines():
            line = line.strip()
            if line.startswith('#'):
                continue
            if not currentdirs:
                if line.endswith('{'):
                    insection = True
                    for logfile in line.split(' '):
                        logfile = logfile.strip()
                        if len(logfile) == 0 or logfile == '{':
                            continue
                        dn = os.path.dirname(logfile)
                        if not dn in dirs:
                            currentdirs.append(dn)
                            dirs[dn] = None
            else:
                if line.endswith('}'):
                    currentdirs = []
                elif line.startswith("su "):
                    a = line.split(" ")
                    for dn in currentdirs:
                        dirs[dn] = (a[1], a[2])
        return dirs


check=LogrotateCheck()

if Config.info:
    addDetails(
'suse-logrotate-duplicate',
"""There are dupliated logrotate entries with different settings for
the specified file""",
'suse-logrotate-user-writable-log-dir',
"""The log directory is writable by unprivileged users. Please fix
the permissions so only root can write there or add the 'su' option
to your logrotate config""",
'suse-logrotate-log-dir-not-packaged',
"""Please add the specified directory to the file list to be able to
check permissions"""
)