This file is indexed.

/usr/lib/python2.7/dist-packages/sagenb/notebook/auth.py is in python-sagenb 1.0.1+ds1-2.

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
class AuthMethod():
    """
    Abstract class for authmethods that are used by ExtAuthUserManager
    All auth methods must implement the following methods
    """

    def __init__(self, conf):
        self._conf = conf

    def check_user(self, username):
        raise NotImplementedError

    def check_password(self, username, password):
        raise NotImplementedError

    def get_attrib(self, username, attrib):
        raise NotImplementedError


class LdapAuth(AuthMethod):
    """
    Authentication via LDAP

    User authentication basically works like this:
    1.1) bind to LDAP with either
            - generic configured DN and password (simple bind)
            - GSSAPI (e.g. Kerberos)
    1.2) find the ldap object matching username.

    2) if 1 succeeds, try simple bind with the supplied user DN and password
    """

    def _require_ldap(default_return):
        """
        function decorator to
            - disable LDAP auth
            - return a "default" value (decorator argument)
        if importing ldap fails
        """
        def wrap(f):
            def wrapped_f(self, *args, **kwargs):
                try:
                    from ldap import __version__ as ldap_version
                except ImportError:
                    print("cannot 'import ldap', disabling LDAP auth")
                    self._conf['auth_ldap'] = False
                    return default_return
                else:
                    return f(self, *args, **kwargs)
            return wrapped_f
        return wrap

    def __init__(self, conf):
        AuthMethod.__init__(self, conf)

    def _ldap_search(self, query, attrlist=None, sizelimit=20):
        """
        runs any ldap query passed as arg
        """
        import ldap
        from ldap.sasl import gssapi
        conn = ldap.initialize(self._conf['ldap_uri'])

        try:
            if self._conf['ldap_gssapi']:
                token = gssapi()
                conn.sasl_interactive_bind_s('', token)
            else:
                conn.simple_bind_s(
                    self._conf['ldap_binddn'], self._conf['ldap_bindpw'])

            result = conn.search_ext_s(
                self._conf['ldap_basedn'],
                ldap.SCOPE_SUBTREE,
                filterstr=query,
                attrlist=attrlist,
                timeout=self._conf['ldap_timeout'],
                sizelimit=sizelimit)
        except ldap.LDAPError as e:
            print('LDAP Error: %s' % str(e))
            return []
        finally:
            conn.unbind_s()

        return result

    def _get_ldapuser(self, username, attrlist=None):
        """
        Returns a tuple containing the DN and a dict of attributes of the given
        username, or (None, None) if the username is not found
        """
        from ldap.filter import filter_format

        query = filter_format(
            '(%s=%s)', (self._conf['ldap_username_attrib'], username))

        result = self._ldap_search(query, attrlist)

        # only allow one unique result
        # (len(result) will probably always be 0 or 1)
        return result[0] if len(result) == 1 else (None, None)

    @_require_ldap(False)
    def check_user(self, username):
        # LDAP is NOT case sensitive while sage is, so only allow lowercase
        if not username.islower():
            return False
        dn, attribs = self._get_ldapuser(username)
        return dn is not None

    @_require_ldap(False)
    def check_password(self, username, password):
        import ldap

        dn, attribs = self._get_ldapuser(username)
        if not dn:
            return False

        # try to bind with found DN
        conn = ldap.initialize(uri=self._conf['ldap_uri'])
        try:
            conn.simple_bind_s(dn, password)
            return True
        except ldap.INVALID_CREDENTIALS:
            return False
        except ldap.LDAPError as e:
            print('LDAP Error: %s' % str(e))
            return False
        finally:
            conn.unbind_s()

    @_require_ldap('')
    def get_attrib(self, username, attrib):
        # 'translate' attribute names used in ExtAuthUserManager
        # to their ldap equivalents

        # "email" is "mail"
        if attrib == 'email':
            attrib = 'mail'

        dn, attribs = self._get_ldapuser(username, [attrib])
        if not attribs:
            return ''

        # return the first item or '' if the attribute is missing
        return attribs.get(attrib, [''])[0]