This file is indexed.

/usr/share/pyca/pylib/ldif.py is in pyca 20031119-0.

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
186
187
188
189
190
191
192
193
"""
ldif.py - Various routines for handling LDIF data

This module is distributed under the terms of the
GPL (GNU GENERAL PUBLIC LICENSE) Version 2
(see http://www.gnu.org/copyleft/gpl.html)
"""

__version__ = '0.2.5'

import sys,string,binascii,re

try:
  from cStringIO import StringIO
except ImportError:
  from StringIO import StringIO

attr_pattern = r'[\w;.]+(;[\w_-]+)*'
data_pattern = '([^,]+|".*?")'
rdn_pattern = attr_pattern + r'[\s]*=[\s]*' + data_pattern
dn_pattern   = rdn_pattern + r'([\s]*,[\s]*' + rdn_pattern + r')*'

#rdn_regex   = re.compile('^%s$' % rdn_pattern)
dn_regex   = re.compile('^%s$' % dn_pattern)

ldif_pattern = '^((dn(:|::) %(dn_pattern)s)|(%(attr_pattern)s(:|::) %(data_pattern)s)$)+' % vars()

ldif_regex   = re.compile('^%s$' % ldif_pattern,re.M)

def is_dn(s):
  """
  returns 1 if s is a LDAP DN
  """
  rm = dn_regex.match(s)
  return rm!=None and rm.group(0)==s

def is_ascii(s):
  """
  returns 1 if s is plain ASCII
  """
  if s:
    pos=0 ; s_len = len(s)
    while ((ord(s[pos]) & 0x80) == 0) and (pos<s_len-1):
      pos=pos+1
    if pos<s_len-1:
      return 0
    else:
      return (ord(s[pos]) & 0x80) == 0
  else:
    return 1

def BinaryAttribute(attr,buf,col=77):
  """
  Convert buf to a binary attribute representation
  """
  b64buf = '%s:: ' % (attr)
  buflen = len(buf)
  pos=0
  while pos<buflen:
    b64buf = '%s%s' % (b64buf,binascii.b2a_base64(buf[pos:min(buflen,pos+57)])[:-1])
    pos = pos+57

  b64buflen = len(b64buf)
  pos=col
  result = b64buf[0:min(b64buflen,col)]
  while pos<b64buflen:
    result = '%s\n %s' % (result,b64buf[pos:min(b64buflen,pos+col-1)])
    pos = pos+col-1
  return '%s\n' % result


def CreateLDIF(
  dn,			# string-represantation of distinguished name
  entry={},		# dictionary holding the LDAP entry {attr:data}
  binary_attrs=[]
):
  """
  Create LDIF formatted entry.
  
  The trailing empty line is NOT added.
  """
  # Write line dn: first
  if is_ascii(dn):
    result = ['dn: %s\n' % (dn)]
  else:
    result = [BinaryAttribute('dn',dn)]

  objectclasses = entry.get('objectclass',entry.get('objectClass',[]))
  for oc in objectclasses:
    result.append('objectclass: %s\n' % oc)
  attrs = entry.keys()[:]
  try:
    attrs.remove('objectclass')
    attrs.remove('objectClass')
  except ValueError:
    pass
  attrs.sort()
  for attr in attrs:
    if attr in binary_attrs:
      for data in entry[attr]:
        result.append(BinaryAttribute(attr,data))
    else:
      for data in entry[attr]:
        if is_ascii(data):
  	  result.append('%s: %s\n' % (attr,data))
	else:
          result.append(BinaryAttribute(attr,data))
  return string.join(result,'')


def ParseLDIF(
  f=StringIO(),		# file-object for reading LDIF input
  ignore_attrs=[],	# list of attribute types to ignore
  maxentries=0		# (if non-zero) specifies the maximum number of
  			# entries to be read from f
):
  """
  Parse LDIF data read from file object f
  """
  
  result = []

  # lower-case all
  ignored_attrs = map(string.lower,ignore_attrs)

  # Read very first line
  s = f.readline()

  entries_read = 0

  while s and (not maxentries or entries_read<maxentries):

    # Reading new entry

    # Reset entry data
    dn = ''; entry = {}; attr = ''; data = ''

    s = string.rstrip(s)

    while s:
    
      # Reading new attribute line
      attr,data=string.split(s,':',1)
      if data[0]==':':
        # Read attr:: data line => binary data assumed
        data = data[1:]
        binary = 1
      else:
        # Read attr: data line
        binary = 0

      s = f.readline()
      s = string.rstrip(s)

      # Reading continued multi-line data
      while s and s[0]==' ':
        data = data + string.strip(s)
        # Read next line
        s = f.readline()
        s = string.rstrip(s)

      attr = string.lower(string.strip(attr))

      if not attr in ignored_attrs:

	if binary:
          # binary data has to be BASE64 decoded
          data = binascii.a2b_base64(data)
	else:
          data = string.strip(data)

        # Add attr: data to entry
	if attr=='dn':
          dn = string.strip(data) ; attr = '' ; data = ''
          if not is_dn(dn):
	    raise ValueError, 'No valid string-representation of distinguished name.'
	else:
          if entry.has_key(attr):
            entry[attr].append(data)
          else:
            entry[attr]=[data]

    # end of entry reached marked by newline character(s)

    if entry:
      # append entry to result list
      result.append((dn,entry))
      entries_read = entries_read+1

    # Start reading next entry
    s = f.readline()

  return result