This file is indexed.

/usr/share/pynslcd/invalidator.py is in pynslcd 0.9.7-2+deb9u1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
# invalidator.py - functions for invalidating external caches
#
# Copyright (C) 2013 Arthur de Jong
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA

import fcntl
import logging
import os
import subprocess

import cfg


# the file descriptor used for sending messages to the child process
signalfd = None


# mapping between map name and signal character
_db_to_char = dict(
        aliases='A', ethers='E', group='G', hosts='H', netgroup='U',
        networks='N', passwd='P', protocols='L', rpc='R', services='V',
        shadow='S', nfsidmap='F',
    )
_char_to_db = dict((reversed(item) for item in _db_to_char.items()))


def exec_invalidate(*args):
    cmd = ' '.join(args)
    logging.debug('invalidator: %s', cmd)
    try:
        p = subprocess.Popen(args, bufsize=4096, close_fds=True,
                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        output, ignored = p.communicate()
        if output:
            output = ': %s' % output[:1024].strip()
        if p.returncode == 0:
            logging.debug('invalidator: %s (pid %d) success%s',
                          cmd, p.pid, output)
        elif p.returncode > 0:
            logging.debug('invalidator: %s (pid %d) failed (%d)%s',
                          cmd, p.pid, p.returncode, output)
        else:  # p.returncode < 0
            logging.error('invalidator: %s (pid %d) killed by signal %d%s',
                          cmd, p.pid, -p.returncode, output)
    except:
        logging.warn('invalidator: %s failed', cmd, exc_info=True)


def loop(fd):
    # set process title
    try:
        import setproctitle
        setproctitle.setproctitle('(invalidator)')
    except ImportError:
        pass
    # set up clean environment
    os.chdir('/')
    os.environ['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin'
    while True:
        db = os.read(fd, 1)
        if db == '':
            break  # close process down
        db = _char_to_db.get(db, None)
        if db == 'nfsidmap':
            exec_invalidate('nfsidmap', '-c')
        elif db:
            exec_invalidate('nscd', '-i', db)


def start_invalidator():
    r, w = os.pipe()
    # mark write end as non-blocking
    flags = fcntl.fcntl(w, fcntl.F_GETFL)
    fcntl.fcntl(w, fcntl.F_SETFL, flags | os.O_NONBLOCK)
    cpid = os.fork()
    if cpid == 0:
        # we are the child
        os.close(w)
        loop(r)
        os._exit(1)
    # we are the parent
    global signalfd
    signalfd = w
    os.close(r)


def invalidate(db=None):
    if signalfd is None:
        return  # nothing to do
    if db:
        db = _db_to_char.get(db, '')
    else:
        db = ''.join(_db_to_char[x] for x in cfg.reconnect_invalidate)
    try:
        os.write(signalfd, db)
    except:
        logging.warn('requesting invalidation (%s) failed', db, exc_info=True)