This file is indexed.

/usr/lib/python2.7/dist-packages/remctl.py is in python-remctl 3.9-1+b2.

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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# Python interface to remctl.
#
# This is the high-level interface that most Python programs that use remctl
# should be using.  It's a Python wrapper around the _remctl C module, which
# exposes exactly the libremctl API.
#
# Original implementation by Thomas L. Kula <kula@tproa.net>
# Copyright 2008 Thomas L. Kula <kula@tproa.net>
# Copyright 2008, 2011, 2012
#     The Board of Trustees of the Leland Stanford Junior University
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted, provided
# that the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of Thomas L. Kula not be used in
# advertising or publicity pertaining to distribution of the software without
# specific, written prior permission. Thomas L. Kula makes no representations
# about the suitability of this software for any purpose.  It is provided "as
# is" without express or implied warranty.
#
# THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

"""Interface to remctl.

   This module is an interface to remctl, a client/server
   protocol for running single commands on a remote host
   using Kerberos v5 authentication.
"""

VERSION = '3.9'

import _remctl

# Exception classes.

class RemctlError(Exception):
    """The underlying remctl library has returned an error."""
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return str(self.value)

class RemctlProtocolError(RemctlError):
    """A remctl protocol error occurred.

    This exception is only used with the remctl.remctl() simple interface;
    for the full interface, errors are returned as a regular output token.
    """
    pass

class RemctlNotOpenedError(RemctlError):
    """No open connection to a server."""
    pass

# Simple interface.

class RemctlSimpleResult:
    """An object holding the results from the simple interface."""
    def __init__(self):
        self.stdout = None
        self.stderr = None
        self.status = None

def remctl(host, port = None, principal = None, command = []):
    """Simple interface to remctl.

    Connect to HOST on PORT, using PRINCIPAL as the server principal for
    authentication, and issue COMMAND.  Returns the result as a
    RemctlSimpleResult object, which has three attributes.  stdout holds the
    complete standard output, stderr holds the complete standard error, and
    status holds the exit status.
    """
    if port == None:
        port = 0
    else:
        try:
            port = int(port)
        except ValueError:
            raise TypeError, 'port must be a number: ' + `port`
    if (port < 0) or (port > 65535):
        raise ValueError, 'invalid port number: ' + `port`
    if isinstance(command, (basestring, bool, int, float)):
        raise TypeError, 'command must be a sequence or iterator'

    # Convert the command to a list of strings.
    mycommand = []
    for item in command:
        mycommand.append(str(item))
    if len(mycommand) < 1:
        raise ValueError, 'command must not be empty'

    # At this point, things should be sane.  Call the low-level interface.
    output = _remctl.remctl(host, port, principal, mycommand)
    if output[0] != None:
        raise RemctlProtocolError, output[0]
    result = RemctlSimpleResult()
    setattr(result, 'stdout', output[1])
    setattr(result, 'stderr', output[2])
    setattr(result, 'status', output[3])
    return result

# Complex interface.

class Remctl:
    def __init__(self, host = None, port = None, principal = None):
        self.r = _remctl.remctl_new()
        self.opened = False

        if host != None:
            self.open(host, port, principal)

    def set_ccache(self, ccache):
        if not _remctl.remctl_set_ccache(self.r, ccache):
            raise RemctlError, self.error()

    def set_source_ip(self, source):
        if not _remctl.remctl_set_source_ip(self.r, source):
            raise RemctlError, self.error()

    def set_timeout(self, timeout):
        if not _remctl.remctl_set_timeout(self.r, timeout):
            raise RemctlError, self.error()

    def open(self, host, port = None, principal = None):
        if port == None:
            port = 0
        else:
            try:
                port = int(port)
            except ValueError:
                raise TypeError, 'port must be a number: ' + `port`
        if (port < 0) or (port > 65535):
            raise ValueError, 'invalid port number: ' + `port`

        # At this point, things should be sane.  Call the low-level interface.
        if not _remctl.remctl_open(self.r, host, port, principal):
            raise RemctlError, self.error()
        self.opened = True

    def command(self, comm):
        commlist = []
        if not self.opened:
            raise RemctlNotOpenedError, 'no currently open connection'
        if isinstance(comm, (basestring, bool, int, float)):
            raise TypeError, 'command must be a sequence or iterator'

        # Convert the command to a list of strings.
        for item in comm:
            commlist.append(str(item))
        if len(commlist) < 1:
            raise ValueError, 'command must not be empty'

        # At this point, things should be sane.  Call the low-level interface.
        if not _remctl.remctl_commandv(self.r, commlist):
            raise RemctlError, self.error()

    def output(self):
        if not self.opened:
            raise RemctlNotOpenedError, 'no currently open connection'
        output = _remctl.remctl_output(self.r)
        if len(output) == 0:
            raise RemctlError, self.error()
        return output

    def noop(self):
        if not self.opened:
            raise RemctlNotOpenedError, 'no currently open connection'
        if not _remctl.remctl_noop(self.r):
            raise RemctlError, self.error()

    def close(self):
        del(self.r)
        self.r = None
        self.opened = False

    def error(self):
        if self.r == None:
            # We do this instead of throwing an exception so that callers
            # don't have to handle an exception when they are trying to find
            # out why an exception occured.
            return 'no currently open connection'
        return _remctl.remctl_error(self.r)