#!/usr/bin/python

# Hardens permissions on files.  See Bug89563.

import os
import syslog
import pwd
import grp
import errno

# permInfo: [ perms, owner, group ]
# perms must be specified with a leading '0'
# paths ending with '*' will cause permInfo to be applied to all files and
# subdirectories within the specified directory (equivalent of recursive="yes"
# attribute in /etc/mcp/sys/user_preserve_files.xml)
paths = {
    '/etc/ifs/hardware.xml' :                   [ 0640, 'root', 'wheel' ],
    '/etc/ifs/drives.xml' :                     [ 0640, 'root', 'wheel' ],
    '/etc/ifs/gmp.xml' :                        [ 0640, 'root', 'wheel' ],
    '/etc/ifs/gmp_serial' :                     [ 0640, 'root', 'wheel' ],
    '/etc/ifs/isi_dnsiq_d.xml' :                [ 0640, 'root', 'wheel' ],
    '/etc/ifs/flexnetconfig.xml' :              [ 0640, 'root', 'wheel' ],
    '/etc/ifs/node_status.gc' :                 [ 0640, 'root', 'wheel' ],
    # For simplicity mark all overrides as 0640 then revert a select few
    '/etc/mcp/override/*' :                     [ 0640, 'root', 'wheel' ],
    '/etc/mcp/sync/*' :                         [ 0600, 'root', 'wheel' ],
    '/etc/periodic/*' :                         [ 0755, 'root', 'wheel' ],
    '/etc/mcp/templates/sshd_config' :          [ 0640, 'root', 'wheel' ],
    '/etc/mcp/templates/vsftpd.conf' :          [ 0640, 'root', 'wheel' ],
    '/etc/local/*' :                            [ 0640, 'root', 'wheel' ],
    '/etc/ifs/flx_config.xml' :                 [ 0640, 'root', 'wheel' ],
    '/usr/local/etc/smb.conf' :                 [ 0640, 'root', 'wheel' ],
    '/usr/local/etc/sudoers' :                  [ 0440, 'root', 'wheel' ],
    '/usr/local/private' :                      [ 0640, 'root', 'wheel' ],
    '/usr/local/etc/apache/httpd.conf' :        [ 0640, 'root', 'wheel' ],
    '/etc/rc.isi_first_boot_already_ran' :      [ 0640, 'root', 'wheel' ],
    '/etc/mcp/mlist.xml' :                      [ 0640, 'root', 'wheel' ],
    # Bug 121589. Allow wheel group to modify SSL keys/certs.
    '/usr/local/apache2/conf' :                 [ 0750, 'root', 'wheel' ],
    '/usr/local/apache2/conf/extra' :           [ 0640, 'root', 'wheel' ],
    '/usr/local/apache2/conf/httpd.conf' :      [ 0640, 'root', 'wheel' ],
    '/usr/local/apache2/conf/magic' :           [ 0640, 'root', 'wheel' ],
    '/usr/local/apache2/conf/mime.types' :      [ 0640, 'root', 'wheel' ],
    '/usr/local/apache2/conf/ssl.crt' :         [ 0770, 'root', 'wheel' ],
    '/usr/local/apache2/conf/ssl.key' :         [ 0770, 'root', 'wheel' ],
    '/usr/local/apache2/conf/ssl.crt/*' :       [ 0660, 'root', 'wheel' ],
    '/usr/local/apache2/conf/ssl.key/*' :       [ 0660, 'root', 'wheel' ],
    '/usr/local/apache2/conf/webui_httpd.conf' : [ 0640, 'root', 'wheel' ],
    '/usr/local/apache2/logs/*' :               [ 0640, 'root', 'wheel' ],
    '/usr/share/ssl/*' :                        [ 0440, 'root', 'wheel' ],
    '/ifs/.ifsvar/db/already_copied_patches' :  [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/db/celog/events.db' :         [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/db/celog/notifications.db' :  [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/db/celog/packages.db' :       [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/db/node_info_cache/*' :       [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/ifs/default_coalescing_set' : [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/ifs/default_perms_set' :      [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/iscsi/access.conf.lock' :     [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/iscsi/iscsi.conf.lock' :      [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/iscsi/isns.state.lock' :      [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/iscsi/options.conf.lock' :    [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/iscsi/smartcache_fix.flag' :  [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/iscsi/smartcache_fix.lock' :  [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/isi_update_slash_pkg.lock' :  [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/isi_update_slash_pkg.status' : [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/main_config.gc.lck' :         [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/main_config_changes.log' :    [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/auth/sam/sam.db' :    [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/auth/priv_config.gc.lck' :
                                                [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/cbind/cbind_config.gc.lck' :
                                                [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/celog/notification_upgrade.lock' :
                                                [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/celog/notification_upgrade_done' :
                                                [ 0400, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/fc/devices.xml' :     [ 0400, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/fsa/jobs.gc' :        [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/jobengine/config.gc' : [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/jobengine/config.gc.lck' :
                                                [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/jobengine/pre_hab_upgrade' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/jobengine/pre_hab_upgrade_done' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/jobengine/status.gc' : [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/jobengine/status.gc.lck' :
                                                [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/ndmp/config.xml.lock' : [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/nfs/chopu-nfs-upgrade-complete' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/nfs/nfs_default.xml' : [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/quotas/config.gc.lck' : [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/quotas/email_upgraded' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/quotas/email_upgraded.lck' :
                                                [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/quotas/notify/sched_ckp' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/quotas/qnr/qnr_revision' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/smartpools/init-lock' : [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/smartpools/initialized' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/stats/persistence.db' : [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/stats/persistence.db-journal' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/tsm/backup/.mav-upgrade-done' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/tsm/backup/pre-mav.tgz' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/tsm/config/.upgrade.lock' :
                                                [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/tsm/config/siq-conf.gc' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/modules/tsm/config/siq-conf.gc.lck' :
                                                [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/tmp/chopu-auth-upgrade.log' : [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/tmp/chopu-auth-upgraded' :    [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/tmp/chopu-email-transform.log' :
                                                [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/tmp/chopu-nfs-upgrade.log' :  [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/tmp/chopu-nfs-upgraded' :     [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/tmp/chopu-smb-upgrade.log' :  [ 0640, 'root', 'wheel' ],
    '/ifs/.ifsvar/tmp/chopu-smb-upgraded' :     [ 0600, 'root', 'wheel' ],
    '/ifs/.ifsvar/tmp/nfs_default.xml' :        [ 0640, 'root', 'wheel' ],
}

# Bug 121589 allow compadmin to refresh ssl keys.
noChange = [ 
    '/etc/mcp/override/motd',
]

def chmod_chown(file, permInfo):
    try:
        syslog.syslog(syslog.LOG_DEBUG,
            "perm_harden: changing permissions on %s to 0%o" % \
            (file, permInfo[0]))
        os.chmod(file, permInfo[0])

        uid = pwd.getpwnam(permInfo[1]).pw_uid
        gid = grp.getgrnam(permInfo[2]).gr_gid

        syslog.syslog(syslog.LOG_DEBUG,
            "perm_harden: changing ownership/group on %s to %s:%s (%d:%d)" %
            (file, permInfo[1], permInfo[2], uid, gid))
        os.chown(file, uid, gid)
    except OSError, e:
        # not all files are necessarily present, so don't treat ENOENT as
        # an error
        if e.errno != errno.ENOENT:
            syslog.syslog(syslog.LOG_ERR, "perm_harden: " + str(e))
            return 1
    except KeyError, e:
        syslog.syslog(syslog.LOG_ERR,
            "perm_harden: unknown user or group name (%s/%s) for %s" %
            (permInfo[1], permInfo[2], file))
        return 1
    except:
        syslog.syslog(syslog.LOG_ERR,
            "perm_harden: unexpected error: " + str(sys.exc_info[0]))
        raise

    return 0

syslog.syslog(syslog.LOG_NOTICE, "perm_harden: starting permissions hardening")
numErrors = 0

for path, permInfo in paths.iteritems():
    if path[-1] != '*':
        numErrors += chmod_chown(path, permInfo)
    else:
        for (root, dirs, files) in os.walk(path[:-2]):
            for dir in dirs:
                if os.path.join(root, dir) in noChange:
                    continue
                numErrors += chmod_chown(os.path.join(root, dir), permInfo)
            for file in files:
                if os.path.join(root, file) in noChange:
                    continue
                numErrors += chmod_chown(os.path.join(root, file), permInfo)

syslog.syslog(syslog.LOG_NOTICE,
    "perm_harden: permissions hardening complete, %d error(s)" % numErrors)
