This file is indexed.

/usr/share/pyshared/dsml.py is in python-ldap 2.4.10-1.

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
"""
dsml - generate and parse DSMLv1 data
(see http://www.oasis-open.org/committees/dsml/)

See http://www.python-ldap.org/ for details.

$Id: dsml.py,v 1.27 2012/06/07 18:40:59 stroeder Exp $

Python compability note:
Tested with Python 2.0+.
"""

__version__ = '2.4.10'

import string,base64


special_entities = (
  ('&','&'),
  ('<','&lt;'),
  ('"','&quot;'),
  ("'",'&apos;'),
)


def replace_char(s):
  for char,entity in special_entities:
    s = string.replace(s,char,entity)
  return s


class DSMLWriter:
  """
  Class for writing LDAP entry records to a DSMLv1 file.

  Arguments:

  f
      File object for output.
  base64_attrs
      Attribute types to be base64-encoded.
  dsml_comment
      Text placed in comment lines behind <dsml:dsml>.
  indent
      String used for indentiation of next nested level.
  """

  def __init__(
    self,f,base64_attrs=[],dsml_comment='',indent='    '
  ):
    self._output_file = f
    self._base64_attrs = {}.fromkeys(map(string.lower,base64_attrs))
    self._dsml_comment = dsml_comment
    self._indent = indent

  def _needs_base64_encoding(self,attr_type,attr_value):
    if self._base64_attrs:
      return self._base64_attrs.has_key(string.lower(attr_type))
    else:
      try:
        unicode(attr_value,'utf-8')
      except UnicodeError:
        return 1
      else:
        return 0

  def writeHeader(self):
    """
    Write the header
    """
    self._output_file.write('\n'.join([
        '<?xml version="1.0" encoding="UTF-8"?>',
        '<!DOCTYPE root PUBLIC "dsml.dtd" "http://www.dsml.org/1.0/dsml.dtd">',
        '<dsml:dsml xmlns:dsml="http://www.dsml.org/DSML">',
        '%s<dsml:directory-entries>\n' % (self._indent),
      ])
    )
    if self._dsml_comment:
      self._output_file.write('%s<!--\n' % (self._indent))
      self._output_file.write('%s%s\n' % (self._indent,self._dsml_comment))
      self._output_file.write('%s-->\n' % (self._indent))

  def writeFooter(self):
    """
    Write the footer
    """
    self._output_file.write('%s</dsml:directory-entries>\n' % (self._indent))
    self._output_file.write('</dsml:dsml>\n')

  def unparse(self,dn,entry):
    return self.writeRecord(dn,entry)

  def writeRecord(self,dn,entry):
    """
    dn
          string-representation of distinguished name
    entry
          dictionary holding the LDAP entry {attr:data}
    """

    # Write line dn: first
    self._output_file.write(
      '%s<dsml:entry dn="%s">\n' % (
        self._indent*2,replace_char(dn)
      )
    )

    objectclasses = entry.get('objectclass',entry.get('objectClass',[]))

    self._output_file.write('%s<dsml:objectclass>\n' % (self._indent*3))
    for oc in objectclasses:
      self._output_file.write('%s<dsml:oc-value>%s</dsml:oc-value>\n' % (self._indent*4,oc))
    self._output_file.write('%s</dsml:objectclass>\n' % (self._indent*3))

    attr_types = entry.keys()[:]
    try:
      attr_types.remove('objectclass')
      attr_types.remove('objectClass')
    except ValueError:
      pass
    attr_types.sort()
    for attr_type in attr_types:
      self._output_file.write('%s<dsml:attr name="%s">\n' % (self._indent*3,attr_type))
      for attr_value_item in entry[attr_type]:
        needs_base64_encoding = self._needs_base64_encoding(
          attr_type,attr_value_item
        )
        if needs_base64_encoding:
          attr_value_item = base64.encodestring(attr_value_item)
        else:
          attr_value_item = replace_char(attr_value_item)
        self._output_file.write('%s<dsml:value%s>\n' % (
            self._indent*4,
            ' encoding="base64"'*needs_base64_encoding
          )
        )
        self._output_file.write('%s%s\n' % (
            self._indent*5,
            attr_value_item
          )
        )
        self._output_file.write('%s</dsml:value>\n' % (
            self._indent*4,
          )
        )
      self._output_file.write('%s</dsml:attr>\n' % (self._indent*3))
    self._output_file.write('%s</dsml:entry>\n' % (self._indent*2))
    return


try:

  import xml.sax,xml.sax.handler

except ImportError:
  pass

else:

  class DSMLv1Handler(xml.sax.handler.ContentHandler):
    """
    Content handler class for DSMLv1
    """

    def __init__(self,parser_instance):
      self._parser_instance = parser_instance
      xml.sax.handler.ContentHandler.__init__(self)

    def startDocument(self):
      pass

    def endDocument(self):
      pass

    def startElement(self,raw_name,attrs):
      assert raw_name.startswith(''),'Illegal name'
      name = raw_name[5:]
      if name=='dsml':
        pass
      elif name=='directory-entries':
        self._parsing_entries = 1
      elif name=='entry':
        self._dn = attrs['dn']
        self._entry = {}
      elif name=='attr':
        self._attr_type = attrs['name'].encode('utf-8')
        self._attr_values = []
      elif name=='value':
        self._attr_value = ''
        self._base64_encoding = attrs.get('encoding','').lower()=='base64'
      # Handle object class tags
      elif name=='objectclass':
        self._object_classes = []
      elif name=='oc-value':
        self._oc_value = ''
      # Unhandled tags
      else:
        raise ValueError,'Unknown tag %s' % (raw_name)

    def endElement(self,raw_name):
      assert raw_name.startswith('dsml:'),'Illegal name'
      name = raw_name[5:]
      if name=='dsml':
        pass
      elif name=='directory-entries':
        self._parsing_entries = 0
      elif name=='entry':
        self._parser_instance.handle(self._dn,self._entry)
        del self._dn
        del self._entry
      elif name=='attr':
        self._entry[self._attr_type] = self._attr_values
        del self._attr_type
        del self._attr_values
      elif name=='value':
        if self._base64_encoding:
          attr_value = base64.decodestring(self._attr_value.strip())
        else:
          attr_value = self._attr_value.strip().encode('utf-8')
        self._attr_values.append(attr_value)
        del attr_value
        del self._attr_value
        del self._base64_encoding
      # Handle object class tags
      elif name=='objectclass':
        self._entry['objectClass'] = self._object_classes
        del self._object_classes
      elif name=='oc-value':
        self._object_classes.append(self._oc_value.strip().encode('utf-8'))
        del self._oc_value
      # Unhandled tags
      else:
        raise ValueError,'Unknown tag %s' % (raw_name)

    def characters(self,ch):
      if self.__dict__.has_key('_oc_value'):
        self._oc_value = self._oc_value + ch
      elif self.__dict__.has_key('_attr_value'):
        self._attr_value = self._attr_value + ch
      else:
        pass


  class DSMLParser:
    """
    Base class for a DSMLv1 parser. Applications should sub-class this
    class and override method handle() to implement something meaningful.

    Public class attributes:

    records_read
        Counter for records processed so far

    Arguments:

    input_file
        File-object to read the DSMLv1 input from
    ignored_attr_types
        Attributes with these attribute type names will be ignored.
    max_entries
        If non-zero specifies the maximum number of entries to be
        read from f.
    line_sep
        String used as line separator
    """

    def __init__(
      self,
      input_file,
      ContentHandlerClass,
      ignored_attr_types=None,
      max_entries=0,
    ):
      self._input_file = input_file
      self._max_entries = max_entries
      self._ignored_attr_types = {}.fromkeys(map(string.lower,(ignored_attr_types or [])))
      self._current_record = None,None
      self.records_read = 0
      self._parser = xml.sax.make_parser()
      self._parser.setFeature(xml.sax.handler.feature_namespaces,0)
      content_handler = ContentHandlerClass(self)
      self._parser.setContentHandler(content_handler)

    def handle(self,*args,**kwargs):
      """
      Process a single DSMLv1 entry record. This method should be
      implemented by applications using DSMLParser.
      """
      import pprint
      pprint.pprint(args)
      pprint.pprint(kwargs)

    def parse(self):
      """
      Continously read and parse DSML records
      """
      self._parser.parse(self._input_file)