Projet

Général

Profil

0004-add-new-application-authentic2_provisionning.patch

Benjamin Dauvergne, 23 mars 2015 16:28

Télécharger (62,6 ko)

Voir les différences:

Subject: [PATCH 4/4] add new application authentic2_provisionning

Goal is to allow synchronizing users from the authentic2 db to an LDAP
directory. The application also contain helper class to do unittest
against an OpenLDAP server, for this OpenLDAP must be installed on your
computer.
 setup.py                                           |   1 +
 src/authentic2_provisionning/__init__.py           |   3 +
 src/authentic2_provisionning/app_settings.py       |  24 +
 src/authentic2_provisionning/ldap_utils.py         | 307 +++++++++++
 .../management/__init__.py                         |   0
 .../management/commands/__init__.py                |   0
 .../management/commands/provision.py               | 184 +++++++
 src/authentic2_provisionning/tests/__init__.py     |   0
 src/authentic2_provisionning/tests/core.ldif       | 600 +++++++++++++++++++++
 src/authentic2_provisionning/tests/cosine.ldif     | 200 +++++++
 .../tests/inetorgperson.ldif                       |  69 +++
 src/authentic2_provisionning/tests/test_ldap.py    |  82 +++
 12 files changed, 1470 insertions(+)
 create mode 100644 src/authentic2_provisionning/__init__.py
 create mode 100644 src/authentic2_provisionning/app_settings.py
 create mode 100644 src/authentic2_provisionning/ldap_utils.py
 create mode 100644 src/authentic2_provisionning/management/__init__.py
 create mode 100644 src/authentic2_provisionning/management/commands/__init__.py
 create mode 100644 src/authentic2_provisionning/management/commands/provision.py
 create mode 100644 src/authentic2_provisionning/tests/__init__.py
 create mode 100644 src/authentic2_provisionning/tests/core.ldif
 create mode 100644 src/authentic2_provisionning/tests/cosine.ldif
 create mode 100644 src/authentic2_provisionning/tests/inetorgperson.ldif
 create mode 100644 src/authentic2_provisionning/tests/test_ldap.py
setup.py
142 142
          'compile_translations': compile_translations,
143 143
          'sdist': eo_sdist},
144 144
      entry_points={
145 145
          'authentic2.plugin': [
146 146
              'authentic2-auth-ssl = authentic2.auth2_auth.auth2_ssl:Plugin',
147 147
              'authentic2-idp-saml2 = authentic2.idp.saml:Plugin',
148 148
              'authentic2-idp-openid = authentic2_idp_openid:Plugin',
149 149
              'authentic2-idp-cas = authentic2_idp_cas:Plugin',
150
              'authentic2-provisionning = authentic2_provisionning:Plugin',
150 151
          ],
151 152
      },
152 153
)
src/authentic2_provisionning/__init__.py
1
class Plugin(object):
2
    def get_apps(self):
3
        return [__name__]
src/authentic2_provisionning/app_settings.py
1
class AppSettings(object):
2
    __DEFAULTS = {
3
            'RESSOURCES': {},
4
    }
5

  
6
    def __init__(self, prefix):
7
        self.prefix = prefix
8

  
9
    def _setting(self, name, dflt):
10
        from django.conf import settings
11
        return getattr(settings, self.prefix + name, dflt)
12

  
13
    def __getattr__(self, name):
14
        if name not in self.__DEFAULTS:
15
            raise AttributeError(name)
16
        return self._setting(name, self.__DEFAULTS[name])
17

  
18

  
19
# Ugly? Guido recommends this himself ...
20
# http://mail.python.org/pipermail/python-ideas/2012-May/014969.html
21
import sys
22
app_settings = AppSettings('A2_PROVISIONNING_')
23
app_settings.__name__ = __name__
24
sys.modules[__name__] = app_settings
src/authentic2_provisionning/ldap_utils.py
1
import socket
2
import time
3
import tempfile
4
import shutil
5
import subprocess
6
import os
7
import ldap
8
import ldap.modlist
9
from ldap.ldapobject import ReconnectLDAPObject
10
import ldap.sasl
11
from ldap.controls import SimplePagedResultsControl
12
import ldif
13
import StringIO
14

  
15

  
16
SLAPD_PATH = None
17
SLAPADD_PATH = None
18
SLAPD_PATHS = ['/bin', '/usr/bin', '/sbin', '/usr/sbin', '/usr/local/bin', '/usr/local/sbin']
19

  
20

  
21
def has_slapd():
22
    global SLAPD_PATH, SLAPADD_PATH, PATHS
23
    if not SLAPD_PATH or not SLAPADD_PATH:
24
        for path in SLAPD_PATHS:
25
            slapd_path = os.path.join(path, 'slapd')
26
            if os.path.exists(slapd_path):
27
                SLAPD_PATH = slapd_path
28
            slapadd_path = os.path.join(path, 'slapadd')
29
            if os.path.exists(slapd_path):
30
                SLAPADD_PATH = slapadd_path
31
    return not (SLAPD_PATH is None or SLAPADD_PATH is None)
32

  
33
class ListLDIFParser(ldif.LDIFParser):
34
    def __init__(self, *args, **kwargs):
35
        self.entries = []
36
        ldif.LDIFParser.__init__(self, *args, **kwargs)
37

  
38
    def handle(self, dn, entry):
39
        self.entries.append((dn, entry))
40

  
41
    def add(self, conn):
42
        for dn, entry in self.entries:
43
            conn.add_s(dn, ldap.modlist.addModlist(entry))
44

  
45
class Slapd(object):
46
    '''Initiliaze an OpenLDAP server with just one database containing branch
47
       o=orga and loading the core schema. ACL are very permissive.
48
    '''
49
    config_ldif = '''dn: cn=config
50
objectClass: olcGlobal
51
cn: config
52
olcToolThreads: 1
53
olcLogLevel: none
54

  
55
dn: cn=module{{0}},cn=config
56
objectClass: olcModuleList
57
cn: module{{0}}
58
olcModulePath: /usr/lib/ldap
59
olcModuleLoad: {{0}}back_hdb
60
olcModuleLoad: {{1}}back_monitor
61
olcModuleLoad: {{2}}back_mdb
62
olcModuleLoad: {{3}}accesslog
63
olcModuleLoad: {{4}}unique
64
olcModuleLoad: {{5}}refint
65
olcModuleLoad: {{6}}constraint
66
olcModuleLoad: {{7}}syncprov
67

  
68
dn: cn=schema,cn=config
69
objectClass: olcSchemaConfig
70
cn: schema
71

  
72
dn: olcDatabase={{-1}}frontend,cn=config
73
objectClass: olcDatabaseConfig
74
objectClass: olcFrontendConfig
75
olcDatabase: {{-1}}frontend
76
olcAccess: {{0}}to *
77
   by dn.exact=gidNumber={gid}+uidNumber={uid},cn=peercred,cn=external,cn=auth manage
78
   by * break
79
olcAccess: {{1}}to dn.exact="" by * read
80
olcAccess: {{2}}to dn.base="cn=Subschema" by * read
81
olcSizeLimit: unlimited
82
olcTimeLimit: unlimited
83

  
84
dn: olcDatabase={{0}}config,cn=config
85
objectClass: olcDatabaseConfig
86
olcDatabase: {{0}}config
87
olcRootDN: uid=admin,cn=config
88
olcRootPW: admin
89
olcAccess: {{0}}to *
90
   by dn.exact=gidNumber={gid}+uidNumber={uid},cn=peercred,cn=external,cn=auth manage 
91
   by * break
92
'''
93
    first_db_ldif = '''dn: olcDatabase={{1}}mdb,cn=config
94
objectClass: olcDatabaseConfig
95
objectClass: olcMdbConfig
96
olcDatabase: {{1}}mdb
97
olcSuffix: o=orga
98
olcDbDirectory: {path}
99
olcRootDN: uid=admin,o=orga
100
olcRootPW: admin
101
olcReadOnly: FALSE
102
# Index
103
olcAccess: {{0}}to * by manage
104

  
105
dn: o=orga
106
objectClass: organization
107
o: orga
108
'''
109
    process = None
110
    data_dir_name = 'data'
111
    schemas_ldif = [
112
            open(os.path.join(os.path.dirname(__file__), 'tests', 'core.ldif')).read(),
113
            open(os.path.join(os.path.dirname(__file__), 'tests', 'cosine.ldif')).read(),
114
            open(os.path.join(os.path.dirname(__file__), 'tests', 'inetorgperson.ldif')).read(),
115
    ]
116

  
117
    def create_process(self, args):
118
        return subprocess.Popen(args, stdin=subprocess.PIPE,
119
                env=os.environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
120

  
121
    def __init__(self, **kwargs):
122
        assert has_slapd()
123
        self.__dict__.update(kwargs)
124
        self.checkpoints = []
125
        self.slapd_dir = tempfile.mkdtemp(prefix='a2-provision-slapd')
126
        self.config_dir = os.path.join(self.slapd_dir, 'slapd.d')
127
        os.mkdir(self.config_dir)
128
        self.data_dir = os.path.join(self.slapd_dir, self.data_dir_name)
129
        os.mkdir(self.data_dir)
130
        self.socket = os.path.join(self.slapd_dir, 'socket')
131
        self.ldapi_url = 'ldapi://%s' % self.socket.replace('/', '%2F')
132
        self.slapadd(self.config_ldif)
133
        for schema_ldif in self.schemas_ldif:
134
            self.slapadd(schema_ldif, do_format=False)
135
        self.start()
136
        self.add_ldif(self.first_db_ldif, do_format=True)
137

  
138
    def slapadd(self, ldif, do_format=True):
139
        if do_format:
140
            ldif = ldif.format(path=self.data_dir, gid=os.getgid(), uid=os.getuid())
141
        slapadd = self.create_process([SLAPADD_PATH, '-v', '-n0', '-F', self.config_dir])
142
        stdout, stderr = slapadd.communicate(input=ldif)
143
        assert slapadd.returncode == 0, 'slapadd failed: %s' % stderr
144

  
145
    def start(self):
146
        '''Launch slapd'''
147
        if self.process and self.process.returncode is None:
148
            self.stop()
149
        cmd = [SLAPD_PATH, 
150
                '-d0', # put slapd in foreground
151
                '-F' + self.config_dir, 
152
                '-h', self.ldapi_url]
153
        self.process = self.create_process(cmd)
154
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
155
        # Detect slapd listening
156
        while True:
157
            try:
158
                sock.connect(self.socket)
159
            except socket.error:
160
                # Yield so that slapd has time to initialize
161
                time.sleep(0)
162
            else:
163
                break
164

  
165
    def stop(self):
166
        '''Send SIGTERM to slapd'''
167
        if self.process:
168
            self.process.terminate()
169
            self.process.wait()
170
            self.process = None
171

  
172
    def checkpoint(self):
173
        '''Stop slapd and save current data state'''
174
        self.checkpoints.append(os.path.join(self.slapd_dir, 'checkpoint-%d' % len(self.checkpoints)))
175
        self.stop()
176
        shutil.copytree(self.data_dir, self.checkpoints[-1])
177
        self.start()
178

  
179
    def restore(self):
180
        '''Stop slapd and restore last data state'''
181
        assert self.checkpoints, 'no checkpoint exists'
182
        self.stop()
183
        shutil.rmtree(self.data_dir)
184
        shutil.copytree(self.checkpoints[-1], self.data_dir)
185
        shutil.rmtree(self.checkpoints[-1])
186
        self.checkpoints.pop()
187
        self.start()
188

  
189
    # Clean behind us
190
    def __del__(self):
191
        self.clean()
192

  
193
    def clean(self):
194
        '''Remove directory'''
195
        import os.path # we are maybe in a desctructor, imported module may have vanished
196
        if os.path.exists(self.slapd_dir):
197
            self.stop()
198
            shutil.rmtree(self.slapd_dir, ignore_errors=True)
199

  
200
    def __enter__(self):
201
        return self
202

  
203
    def __exit__(self, type, value, tb):
204
        self.clean()
205

  
206
    def add_ldif(self, ldif, do_format=False):
207
        if do_format:
208
            ldif = ldif.format(path=self.data_dir, gid=os.getgid(), uid=os.getuid())
209
        parser = ListLDIFParser(StringIO.StringIO(ldif))
210
        parser.parse()
211
        conn = self.get_connection()
212
        conn.simple_bind_s('uid=admin,cn=config', 'admin')
213
        parser.add(conn)
214

  
215
    def get_connection(self):
216
        return ldap.initialize(self.ldapi_url)
217

  
218
class PagedResultsSearchObject:
219
  page_size = 500
220

  
221
  def paged_search_ext_s(self,base,scope,filterstr='(objectClass=*)',attrlist=None,attrsonly=0,serverctrls=None,clientctrls=None,timeout=-1,sizelimit=0):
222
    """
223
    Behaves exactly like LDAPObject.search_ext_s() but internally uses the
224
    simple paged results control to retrieve search results in chunks.
225

  
226
    This is non-sense for really large results sets which you would like
227
    to process one-by-one
228
    """
229

  
230
    while True: # loop for reconnecting if necessary
231

  
232
      req_ctrl = SimplePagedResultsControl(True,size=self.page_size,cookie='')
233

  
234
      try:
235

  
236
        # Send first search request
237
        msgid = self.search_ext(
238
          base,
239
          scope,
240
          filterstr=filterstr,
241
          attrlist=attrlist,
242
          attrsonly=attrsonly,
243
          serverctrls=(serverctrls or [])+[req_ctrl],
244
          clientctrls=clientctrls,
245
          timeout=timeout,
246
          sizelimit=sizelimit
247
        )
248

  
249
        all_results = []
250

  
251
        while True:
252
          rtype, rdata, rmsgid, rctrls = self.result3(msgid)
253
          for result in rdata:
254
              yield result
255
          all_results.extend(rdata)
256
          # Extract the simple paged results response control
257
          pctrls = [
258
            c
259
            for c in rctrls
260
            if c.controlType == SimplePagedResultsControl.controlType
261
          ]
262
          if pctrls:
263
            if pctrls[0].cookie:
264
                # Copy cookie from response control to request control
265
                req_ctrl.cookie = pctrls[0].cookie
266
                msgid = self.search_ext(
267
                  base,
268
                  scope,
269
                  filterstr=filterstr,
270
                  attrlist=attrlist,
271
                  attrsonly=attrsonly,
272
                  serverctrls=(serverctrls or [])+[req_ctrl],
273
                  clientctrls=clientctrls,
274
                  timeout=timeout,
275
                  sizelimit=sizelimit
276
                )
277
            else:
278
              break # no more pages available
279

  
280
      except ldap.SERVER_DOWN:
281
        self.reconnect(self._uri)
282
      else:
283
        break
284

  
285

  
286
class PagedLDAPObject(ReconnectLDAPObject,PagedResultsSearchObject):
287
  pass
288

  
289
if __name__ == '__main__':
290
    with Slapd() as slapd:
291
        conn = slapd.get_connection()
292
        conn.simple_bind_s('uid=admin,o=orga', 'admin')
293
        assert conn.whoami_s() == 'dn:uid=admin,o=orga'
294
        slapd.checkpoint()
295
        slapd.add_ldif('''dn: uid=admin,o=orga
296
objectClass: person
297
objectClass: uidObject
298
uid: admin
299
cn: admin
300
sn: admin
301
''')
302
        conn = slapd.get_connection()
303
        print conn.search_s('o=orga', ldap.SCOPE_SUBTREE)
304
        slapd.restore()
305
        conn = slapd.get_connection()
306
        print conn.search_s('o=orga', ldap.SCOPE_SUBTREE)
307

  
src/authentic2_provisionning/management/commands/provision.py
1
from optparse import make_option
2

  
3
try:
4
    import ldap
5
    from ldap.dn import str2dn, dn2str
6
    from ldap.filter import filter_format
7
except ImportError:
8
    ldap = None
9

  
10
from django.core.management.base import BaseCommand
11

  
12
from authentic2.attributes_ng.engine import get_attributes
13
from authentic2 import compat, utils
14

  
15
from authentic2_provisionning import app_settings, ldap_utils
16

  
17
ADD = 1
18
REPLACE = 2
19
DELETE = 3
20

  
21

  
22

  
23
class Command(BaseCommand):
24
    can_import_django_settings = True
25
    output_transaction = True
26
    requires_model_validation = True
27
    option_list = BaseCommand.option_list + (
28
        make_option('--fake',
29
            action='store_true',
30
            default=False,
31
            help='Do nothing, just simulate'),
32
        make_option('--batch-size',
33
            action='store',
34
            type='int',
35
            default=200,
36
            help='Batch size'),
37
    )
38

  
39
    def handle(self, *args, **options):
40
        ressources = app_settings.RESSOURCES
41
        if args:
42
            ressources = [ressource for ressource in ressources
43
                    if ressource.get('name') in args]
44
        for ressource in ressources:
45
            self.sync_ressource(ressource, **options)
46

  
47
    def sync_ressource(self, ressource, **options):
48
        self.sync_ldap_ressource(ressource, **options)
49

  
50
    def add_values(self, ldap_attributes, ldap_attribute, values):
51
        if not isinstance(values, (list, tuple)):
52
            values = [values]
53
        ldap_values = ldap_attributes.setdefault(ldap_attribute, [])
54
        for value in values:
55
            if isinstance(value, unicode):
56
                value = value.encode('utf-8')
57
            elif isinstance(value, str):
58
                pass # must be well encoded
59
            else:
60
                raise NotImplementedError('value %r not supported' % value)
61
            ldap_values.append(value)
62

  
63
    def build_dn_and_filter(self, ressource, ldap_attributes):
64
        '''Build the target record dn'''
65
        base_dn = ressource['base_dn']
66
        rdn_attributes = ressource['rdn_attributes']
67
        dn = str2dn(base_dn)
68
        rdn = []
69
        for ldap_attribute in rdn_attributes:
70
            values = ldap_attributes.get(ldap_attribute, [])
71
            assert len(values) == 1, 'RDN attribute must have exactly one value %r %r' % \
72
                (rdn_attributes, ldap_attributes)
73
            rdn.append((ldap_attribute, values[0], 1))
74
        dn = [rdn] + dn
75
        return dn2str(dn), ('&', [(a,b) for a, b, c in rdn])
76

  
77
    def format_filter(self, filters):
78
        if isinstance(filters, basestring):
79
            return filters
80
        assert len(filters) == 2, 'filters %r' % (filters,)
81
        if isinstance(filters[1], (list, tuple)):
82
            return '(%s%s)' % (filters[0], ''.join(self.format_filter(x) for x in filters[1]))
83
        else:
84
            return filter_format('(%s=%%s)' % filters[0], (filters[1],))
85

  
86
    def sync_ldap_ressource(self, ressource, **options):
87
        verbosity = int(options['verbosity'])
88
        fake = options['fake']
89
        # FIXME: Check ressource well formedness
90
        conn = ldap_utils.PagedLDAPObject(ressource['url'], retry_max=10,
91
                retry_delay=2)
92
        base_dn = ressource['base_dn']
93
        use_tls = ressource.get('use_tls')
94
        bind_dn = ressource.get('bind_dn')
95
        bind_pw = ressource.get('bind_pw')
96
        if use_tls:
97
            conn.start_tls_s()
98
        if bind_dn:
99
            conn.simple_bind_s(bind_dn, bind_pw)
100
        attribute_mapping = utils.lower_keys(ressource['attribute_mapping'])
101
        static_attributes = utils.lower_keys(ressource.get('static_attributes', {}))
102
        format_mapping = utils.lower_keys(ressource.get('format_mapping', {}))
103
        attributes = set(attribute_mapping.keys()) | set(static_attributes.keys())
104
        default_ctx = ressource.get('attribute_context', {})
105
        ldap_filter = ressource.get('ldap_filter', '(objectclass=*)')
106
        delete = ressource.get('delete', True)
107
        User = compat.get_user_model()
108
        qs = User.objects.filter(**ressource.get('a2_filter', {}))
109
        todelete = set()
110
        user_dns = set()
111
        for batch in utils.batch(qs, options['batch_size']):
112
            ldap_users = {}
113
            filters = []
114
            for user in batch:
115
                ctx = default_ctx.copy()
116
                ctx['user'] = user
117
                ctx = get_attributes(ctx)
118
                ldap_attributes = {}
119
                for ldap_attribute, a2_attributes in attribute_mapping.iteritems():
120
                    if not isinstance(a2_attributes, (tuple, list)):
121
                        a2_attributes = [a2_attributes]
122
                    for a2_attribute in a2_attributes:
123
                        self.add_values(ldap_attributes, ldap_attribute, ctx.get(a2_attribute))
124
                for ldap_attribute, values in static_attributes.iteritems():
125
                    self.add_values(ldap_attributes, ldap_attribute, values)
126
                for ldap_attribute, fmt_tpls in format_mapping.iteritems():
127
                    for fmt_tpl in fmt_tpls:
128
                        self.add_values(ldap_attributes, ldap_attribute, 
129
                                [fmt_tpl.format(**ctx)])
130
                dn, filt = self.build_dn_and_filter(ressource, ldap_attributes)
131
                user_dns.add(dn)
132
                ldap_users[dn] = ldap_attributes
133
                filters.append(filt)
134
            batch_filter = ldap_filter
135
            if filters:
136
                batch_filter = self.format_filter(('&', (batch_filter, ('|',
137
                    filters))))
138
            existing_dn = set()
139
            for dn, entry in conn.paged_search_ext_s(base_dn,
140
                     ldap.SCOPE_SUBTREE,
141
                     batch_filter, list(attributes)):
142
                entry = utils.to_dict_of_set(utils.lower_keys(entry))
143
                if dn not in ldap_users:
144
                    todelete.add(dn)
145
                    continue
146
                if entry == utils.to_dict_of_set(ldap_users[dn]):
147
                    # no need to update, entry is already ok
148
                    del ldap_users[dn]
149
                    continue
150
                existing_dn.add(dn)
151
            for dn, ldap_attributes in ldap_users.iteritems():
152
                if dn in existing_dn:
153
                    modlist = []
154
                    for key, values in ldap_attributes:
155
                        modlist.append((ldap.MOD_REPLACE, key, values))
156
                    if not fake:
157
                        conn.modify(dn, modlist)
158
                    if verbosity > 1:
159
                        print '- Replace %s values for %s' % (dn, ', '.join(ldap_attributes.keys()))
160
                else:
161
                    if not fake:
162
                        conn.add(dn, ldap.modlist.addModlist(ldap_attributes))
163
                    if verbosity > 1:
164
                        print '- Add %s with values for %s' % (dn, ', '.join(ldap_attributes.keys()))
165
            # wait for results
166
            if not fake:
167
                for x in ldap_users:
168
                    conn.result()
169
        for dn, entry in conn.paged_search_ext_s(base_dn,
170
                ldap.SCOPE_SUBTREE, ldap_filter):
171
            # ignore the basedn
172
            if dn == base_dn:
173
                continue
174
            if dn not in user_dns and dn not in todelete:
175
                if not fake:
176
                    todelete.add(dn)
177
        if delete:
178
            if verbosity > 1:
179
                print '- Deleting:', ', '.join(todelete)
180
            if not fake:
181
                for dn in todelete:
182
                    conn.delete(dn)
183
                for dn in todelete:
184
                    conn.result()
src/authentic2_provisionning/tests/core.ldif
1
# OpenLDAP Core schema
2
# $OpenLDAP: pkg/ldap/servers/slapd/schema/core.ldif,v 1.1.2.5 2007/01/02 21:44:09 kurt Exp $
3
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
##
5
## Copyright 1998-2007 The OpenLDAP Foundation.
6
## All rights reserved.
7
##
8
## Redistribution and use in source and binary forms, with or without
9
## modification, are permitted only as authorized by the OpenLDAP
10
## Public License.
11
##
12
## A copy of this license is available in the file LICENSE in the
13
## top-level directory of the distribution or, alternatively, at
14
## <http://www.OpenLDAP.org/license.html>.
15
#
16

  
17
# The version of this file as distributed by the OpenLDAP Foundation
18
# contains text claiming copyright by the Internet Society and including
19
# the IETF RFC license, which does not meet Debian's Free Software
20
# Guidelines.  However, apart from short and obvious comments, the text of
21
# this file is purely a functional interface specification, which is not
22
# subject to that license and is not copyrightable under US law.
23
#
24
# The license statement is retained below so as not to remove credit, but
25
# as best as we can determine, it is not applicable to the contents of
26
# this file.
27

  
28
## Portions Copyright (C) The Internet Society (1997-2003).
29
## All Rights Reserved.
30
##
31
## This document and translations of it may be copied and furnished to
32
## others, and derivative works that comment on or otherwise explain it
33
## or assist in its implementation may be prepared, copied, published
34
## and distributed, in whole or in part, without restriction of any
35
## kind, provided that the above copyright notice and this paragraph are
36
## included on all such copies and derivative works.  However, this
37
## document itself may not be modified in any way, such as by removing
38
## the copyright notice or references to the Internet Society or other
39
## Internet organizations, except as needed for the purpose of
40
## developing Internet standards in which case the procedures for
41
## copyrights defined in the Internet Standards process must be         
42
## followed, or as required to translate it into languages other than
43
## English.
44
##                                                                      
45
## The limited permissions granted above are perpetual and will not be  
46
## revoked by the Internet Society or its successors or assigns.        
47
## 
48
## This document and the information contained herein is provided on an 
49
## "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
50
## TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
51
## BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
52
## HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
53
## MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
54
#
55
#
56
#
57
# Includes LDAPv3 schema items from:
58
#	RFC 2252/2256 (LDAPv3)
59
#
60
# Select standard track schema items:
61
#	RFC 1274 (uid/dc)
62
#	RFC 2079 (URI)
63
#	RFC 2247 (dc/dcObject)
64
#	RFC 2587 (PKI)
65
#	RFC 2589 (Dynamic Directory Services)
66
#
67
# Select informational schema items:
68
#	RFC 2377 (uidObject)
69
#
70
#
71
# Standard attribute types from RFC 2256
72
#
73
dn: cn=core,cn=schema,cn=config
74
objectClass: olcSchemaConfig
75
cn: core
76
#
77
# system schema
78
#olcAttributeTypes: ( 2.5.4.0 NAME 'objectClass'
79
#	DESC 'RFC2256: object classes of the entity'
80
#	EQUALITY objectIdentifierMatch
81
#	SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
82
#
83
# system schema
84
#olcAttributeTypes: ( 2.5.4.1 NAME ( 'aliasedObjectName' 'aliasedEntryName' )
85
#	DESC 'RFC2256: name of aliased object'
86
#	EQUALITY distinguishedNameMatch
87
#	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
88
#
89
olcAttributeTypes: ( 2.5.4.2 NAME 'knowledgeInformation'
90
  DESC 'RFC2256: knowledge information'
91
  EQUALITY caseIgnoreMatch
92
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
93
#
94
# system schema
95
#olcAttributeTypes: ( 2.5.4.3 NAME ( 'cn' 'commonName' )
96
#	DESC 'RFC2256: common name(s) for which the entity is known by'
97
#	SUP name )
98
#
99
olcAttributeTypes: ( 2.5.4.4 NAME ( 'sn' 'surname' )
100
  DESC 'RFC2256: last (family) name(s) for which the entity is known by'
101
  SUP name )
102
#
103
olcAttributeTypes: ( 2.5.4.5 NAME 'serialNumber'
104
  DESC 'RFC2256: serial number of the entity'
105
  EQUALITY caseIgnoreMatch
106
  SUBSTR caseIgnoreSubstringsMatch
107
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} )
108
#
109
olcAttributeTypes: ( 2.5.4.6 NAME ( 'c' 'countryName' )
110
  DESC 'RFC2256: ISO-3166 country 2-letter code'
111
  SUP name SINGLE-VALUE )
112
#
113
olcAttributeTypes: ( 2.5.4.7 NAME ( 'l' 'localityName' )
114
  DESC 'RFC2256: locality which this object resides in'
115
  SUP name )
116
#
117
olcAttributeTypes: ( 2.5.4.8 NAME ( 'st' 'stateOrProvinceName' )
118
  DESC 'RFC2256: state or province which this object resides in'
119
  SUP name )
120
#
121
olcAttributeTypes: ( 2.5.4.9 NAME ( 'street' 'streetAddress' )
122
  DESC 'RFC2256: street address of this object'
123
  EQUALITY caseIgnoreMatch
124
  SUBSTR caseIgnoreSubstringsMatch
125
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
126
#
127
olcAttributeTypes: ( 2.5.4.10 NAME ( 'o' 'organizationName' )
128
  DESC 'RFC2256: organization this object belongs to'
129
  SUP name )
130
#
131
olcAttributeTypes: ( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' )
132
  DESC 'RFC2256: organizational unit this object belongs to'
133
  SUP name )
134
#
135
olcAttributeTypes: ( 2.5.4.12 NAME 'title'
136
  DESC 'RFC2256: title associated with the entity'
137
  SUP name )
138
#
139
# system schema
140
#olcAttributeTypes: ( 2.5.4.13 NAME 'description'
141
#	DESC 'RFC2256: descriptive information'
142
#	EQUALITY caseIgnoreMatch
143
#	SUBSTR caseIgnoreSubstringsMatch
144
#	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )
145
#
146
# Deprecated by enhancedSearchGuide
147
olcAttributeTypes: ( 2.5.4.14 NAME 'searchGuide'
148
  DESC 'RFC2256: search guide, deprecated by enhancedSearchGuide'
149
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 )
150
#
151
olcAttributeTypes: ( 2.5.4.15 NAME 'businessCategory'
152
  DESC 'RFC2256: business category'
153
  EQUALITY caseIgnoreMatch
154
  SUBSTR caseIgnoreSubstringsMatch
155
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
156
#
157
olcAttributeTypes: ( 2.5.4.16 NAME 'postalAddress'
158
  DESC 'RFC2256: postal address'
159
  EQUALITY caseIgnoreListMatch
160
  SUBSTR caseIgnoreListSubstringsMatch
161
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
162
#
163
olcAttributeTypes: ( 2.5.4.17 NAME 'postalCode'
164
  DESC 'RFC2256: postal code'
165
  EQUALITY caseIgnoreMatch
166
  SUBSTR caseIgnoreSubstringsMatch
167
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )
168
#
169
olcAttributeTypes: ( 2.5.4.18 NAME 'postOfficeBox'
170
  DESC 'RFC2256: Post Office Box'
171
  EQUALITY caseIgnoreMatch
172
  SUBSTR caseIgnoreSubstringsMatch
173
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )
174
#
175
olcAttributeTypes: ( 2.5.4.19 NAME 'physicalDeliveryOfficeName'
176
  DESC 'RFC2256: Physical Delivery Office Name'
177
  EQUALITY caseIgnoreMatch
178
  SUBSTR caseIgnoreSubstringsMatch
179
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
180
#
181
olcAttributeTypes: ( 2.5.4.20 NAME 'telephoneNumber'
182
  DESC 'RFC2256: Telephone Number'
183
  EQUALITY telephoneNumberMatch
184
  SUBSTR telephoneNumberSubstringsMatch
185
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )
186
#
187
olcAttributeTypes: ( 2.5.4.21 NAME 'telexNumber'
188
  DESC 'RFC2256: Telex Number'
189
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 )
190
#
191
olcAttributeTypes: ( 2.5.4.22 NAME 'teletexTerminalIdentifier'
192
  DESC 'RFC2256: Teletex Terminal Identifier'
193
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 )
194
#
195
olcAttributeTypes: ( 2.5.4.23 NAME ( 'facsimileTelephoneNumber' 'fax' )
196
  DESC 'RFC2256: Facsimile (Fax) Telephone Number'
197
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 )
198
#
199
olcAttributeTypes: ( 2.5.4.24 NAME 'x121Address'
200
  DESC 'RFC2256: X.121 Address'
201
  EQUALITY numericStringMatch
202
  SUBSTR numericStringSubstringsMatch
203
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{15} )
204
#
205
olcAttributeTypes: ( 2.5.4.25 NAME 'internationaliSDNNumber'
206
  DESC 'RFC2256: international ISDN number'
207
  EQUALITY numericStringMatch
208
  SUBSTR numericStringSubstringsMatch
209
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} )
210
#
211
olcAttributeTypes: ( 2.5.4.26 NAME 'registeredAddress'
212
  DESC 'RFC2256: registered postal address'
213
  SUP postalAddress
214
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
215
#
216
olcAttributeTypes: ( 2.5.4.27 NAME 'destinationIndicator'
217
  DESC 'RFC2256: destination indicator'
218
  EQUALITY caseIgnoreMatch
219
  SUBSTR caseIgnoreSubstringsMatch
220
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128} )
221
#
222
olcAttributeTypes: ( 2.5.4.28 NAME 'preferredDeliveryMethod'
223
  DESC 'RFC2256: preferred delivery method'
224
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.14
225
  SINGLE-VALUE )
226
#
227
olcAttributeTypes: ( 2.5.4.29 NAME 'presentationAddress'
228
  DESC 'RFC2256: presentation address'
229
  EQUALITY presentationAddressMatch
230
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.43
231
  SINGLE-VALUE )
232
#
233
olcAttributeTypes: ( 2.5.4.30 NAME 'supportedApplicationContext'
234
  DESC 'RFC2256: supported application context'
235
  EQUALITY objectIdentifierMatch
236
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
237
#
238
olcAttributeTypes: ( 2.5.4.31 NAME 'member'
239
  DESC 'RFC2256: member of a group'
240
  SUP distinguishedName )
241
#
242
olcAttributeTypes: ( 2.5.4.32 NAME 'owner'
243
  DESC 'RFC2256: owner (of the object)'
244
  SUP distinguishedName )
245
#
246
olcAttributeTypes: ( 2.5.4.33 NAME 'roleOccupant'
247
  DESC 'RFC2256: occupant of role'
248
  SUP distinguishedName )
249
#
250
# system schema
251
#olcAttributeTypes: ( 2.5.4.34 NAME 'seeAlso'
252
#	DESC 'RFC2256: DN of related object'
253
#	SUP distinguishedName )
254
#
255
# system schema
256
#olcAttributeTypes: ( 2.5.4.35 NAME 'userPassword'
257
#	DESC 'RFC2256/2307: password of user'
258
#	EQUALITY octetStringMatch
259
#	SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
260
#
261
# Must be transferred using ;binary
262
# with certificateExactMatch rule (per X.509)
263
olcAttributeTypes: ( 2.5.4.36 NAME 'userCertificate'
264
  DESC 'RFC2256: X.509 user certificate, use ;binary'
265
  EQUALITY certificateExactMatch
266
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )
267
#
268
# Must be transferred using ;binary
269
# with certificateExactMatch rule (per X.509)
270
olcAttributeTypes: ( 2.5.4.37 NAME 'cACertificate'
271
  DESC 'RFC2256: X.509 CA certificate, use ;binary'
272
  EQUALITY certificateExactMatch
273
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )
274
#
275
# Must be transferred using ;binary
276
olcAttributeTypes: ( 2.5.4.38 NAME 'authorityRevocationList'
277
  DESC 'RFC2256: X.509 authority revocation list, use ;binary'
278
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )
279
#
280
# Must be transferred using ;binary
281
olcAttributeTypes: ( 2.5.4.39 NAME 'certificateRevocationList'
282
  DESC 'RFC2256: X.509 certificate revocation list, use ;binary'
283
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )
284
#
285
# Must be stored and requested in the binary form
286
olcAttributeTypes: ( 2.5.4.40 NAME 'crossCertificatePair'
287
  DESC 'RFC2256: X.509 cross certificate pair, use ;binary'
288
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.10 )
289
#
290
# 2.5.4.41 is defined above as it's used for subtyping
291
#olcAttributeTypes: ( 2.5.4.41 NAME 'name'
292
#	EQUALITY caseIgnoreMatch
293
#	SUBSTR caseIgnoreSubstringsMatch
294
#	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
295
#
296
olcAttributeTypes: ( 2.5.4.42 NAME ( 'givenName' 'gn' )
297
  DESC 'RFC2256: first name(s) for which the entity is known by'
298
  SUP name )
299
#
300
olcAttributeTypes: ( 2.5.4.43 NAME 'initials'
301
  DESC 'RFC2256: initials of some or all of names, but not the surname(s).'
302
  SUP name )
303
#
304
olcAttributeTypes: ( 2.5.4.44 NAME 'generationQualifier'
305
  DESC 'RFC2256: name qualifier indicating a generation'
306
  SUP name )
307
#
308
olcAttributeTypes: ( 2.5.4.45 NAME 'x500UniqueIdentifier'
309
  DESC 'RFC2256: X.500 unique identifier'
310
  EQUALITY bitStringMatch
311
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )
312
#
313
olcAttributeTypes: ( 2.5.4.46 NAME 'dnQualifier'
314
  DESC 'RFC2256: DN qualifier'
315
  EQUALITY caseIgnoreMatch
316
  ORDERING caseIgnoreOrderingMatch
317
  SUBSTR caseIgnoreSubstringsMatch
318
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )
319
#
320
olcAttributeTypes: ( 2.5.4.47 NAME 'enhancedSearchGuide'
321
  DESC 'RFC2256: enhanced search guide'
322
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 )
323
#
324
olcAttributeTypes: ( 2.5.4.48 NAME 'protocolInformation'
325
  DESC 'RFC2256: protocol information'
326
  EQUALITY protocolInformationMatch
327
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )
328
#
329
# 2.5.4.49 is defined above as it's used for subtyping
330
#olcAttributeTypes: ( 2.5.4.49 NAME 'distinguishedName'
331
#	EQUALITY distinguishedNameMatch
332
#	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
333
#
334
olcAttributeTypes: ( 2.5.4.50 NAME 'uniqueMember'
335
  DESC 'RFC2256: unique member of a group'
336
  EQUALITY uniqueMemberMatch
337
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )
338
#
339
olcAttributeTypes: ( 2.5.4.51 NAME 'houseIdentifier'
340
  DESC 'RFC2256: house identifier'
341
  EQUALITY caseIgnoreMatch
342
  SUBSTR caseIgnoreSubstringsMatch
343
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
344
#
345
# Must be transferred using ;binary
346
olcAttributeTypes: ( 2.5.4.52 NAME 'supportedAlgorithms'
347
  DESC 'RFC2256: supported algorithms'
348
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.49 )
349
#
350
# Must be transferred using ;binary
351
olcAttributeTypes: ( 2.5.4.53 NAME 'deltaRevocationList'
352
  DESC 'RFC2256: delta revocation list; use ;binary'
353
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )
354
#
355
olcAttributeTypes: ( 2.5.4.54 NAME 'dmdName'
356
  DESC 'RFC2256: name of DMD'
357
  SUP name )
358
#
359
olcAttributeTypes: ( 2.5.4.65 NAME 'pseudonym'
360
  DESC 'X.520(4th): pseudonym for the object'
361
  SUP name )
362
#
363
# Standard object classes from RFC2256
364
#
365
# system schema
366
#olcObjectClasses: ( 2.5.6.1 NAME 'alias'
367
#	DESC 'RFC2256: an alias'
368
#	SUP top STRUCTURAL
369
#	MUST aliasedObjectName )
370
#
371
olcObjectClasses: ( 2.5.6.2 NAME 'country'
372
  DESC 'RFC2256: a country'
373
  SUP top STRUCTURAL
374
  MUST c
375
  MAY ( searchGuide $ description ) )
376
#
377
olcObjectClasses: ( 2.5.6.3 NAME 'locality'
378
  DESC 'RFC2256: a locality'
379
  SUP top STRUCTURAL
380
  MAY ( street $ seeAlso $ searchGuide $ st $ l $ description ) )
381
#
382
olcObjectClasses: ( 2.5.6.4 NAME 'organization'
383
  DESC 'RFC2256: an organization'
384
  SUP top STRUCTURAL
385
  MUST o
386
  MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
387
  x121Address $ registeredAddress $ destinationIndicator $
388
  preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
389
  telephoneNumber $ internationaliSDNNumber $ 
390
  facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
391
  postalAddress $ physicalDeliveryOfficeName $ st $ l $ description ) )
392
#
393
olcObjectClasses: ( 2.5.6.5 NAME 'organizationalUnit'
394
  DESC 'RFC2256: an organizational unit'
395
  SUP top STRUCTURAL
396
  MUST ou
397
  MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
398
  x121Address $ registeredAddress $ destinationIndicator $
399
  preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
400
  telephoneNumber $ internationaliSDNNumber $
401
  facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
402
  postalAddress $ physicalDeliveryOfficeName $ st $ l $ description ) )
403
#
404
olcObjectClasses: ( 2.5.6.6 NAME 'person'
405
  DESC 'RFC2256: a person'
406
  SUP top STRUCTURAL
407
  MUST ( sn $ cn )
408
  MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
409
#
410
olcObjectClasses: ( 2.5.6.7 NAME 'organizationalPerson'
411
  DESC 'RFC2256: an organizational person'
412
  SUP person STRUCTURAL
413
  MAY ( title $ x121Address $ registeredAddress $ destinationIndicator $
414
  preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
415
  telephoneNumber $ internationaliSDNNumber $ 
416
  facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
417
  postalAddress $ physicalDeliveryOfficeName $ ou $ st $ l ) )
418
#
419
olcObjectClasses: ( 2.5.6.8 NAME 'organizationalRole'
420
  DESC 'RFC2256: an organizational role'
421
  SUP top STRUCTURAL
422
  MUST cn
423
  MAY ( x121Address $ registeredAddress $ destinationIndicator $
424
  preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
425
  telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
426
  seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $
427
  postOfficeBox $ postalCode $ postalAddress $
428
  physicalDeliveryOfficeName $ ou $ st $ l $ description ) )
429
#
430
olcObjectClasses: ( 2.5.6.9 NAME 'groupOfNames'
431
  DESC 'RFC2256: a group of names (DNs)'
432
  SUP top STRUCTURAL
433
  MUST ( member $ cn )
434
  MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )
435
#
436
olcObjectClasses: ( 2.5.6.10 NAME 'residentialPerson'
437
  DESC 'RFC2256: an residential person'
438
  SUP person STRUCTURAL
439
  MUST l
440
  MAY ( businessCategory $ x121Address $ registeredAddress $
441
  destinationIndicator $ preferredDeliveryMethod $ telexNumber $
442
  teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $
443
  facsimileTelephoneNumber $ preferredDeliveryMethod $ street $
444
  postOfficeBox $ postalCode $ postalAddress $
445
  physicalDeliveryOfficeName $ st $ l ) )
446
#
447
olcObjectClasses: ( 2.5.6.11 NAME 'applicationProcess'
448
  DESC 'RFC2256: an application process'
449
  SUP top STRUCTURAL
450
  MUST cn
451
  MAY ( seeAlso $ ou $ l $ description ) )
452
#
453
olcObjectClasses: ( 2.5.6.12 NAME 'applicationEntity'
454
  DESC 'RFC2256: an application entity'
455
  SUP top STRUCTURAL
456
  MUST ( presentationAddress $ cn )
457
  MAY ( supportedApplicationContext $ seeAlso $ ou $ o $ l $
458
  description ) )
459
#
460
olcObjectClasses: ( 2.5.6.13 NAME 'dSA'
461
  DESC 'RFC2256: a directory system agent (a server)'
462
  SUP applicationEntity STRUCTURAL
463
  MAY knowledgeInformation )
464
#
465
olcObjectClasses: ( 2.5.6.14 NAME 'device'
466
  DESC 'RFC2256: a device'
467
  SUP top STRUCTURAL
468
  MUST cn
469
  MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description ) )
470
#
471
olcObjectClasses: ( 2.5.6.15 NAME 'strongAuthenticationUser'
472
  DESC 'RFC2256: a strong authentication user'
473
  SUP top AUXILIARY
474
  MUST userCertificate )
475
#
476
olcObjectClasses: ( 2.5.6.16 NAME 'certificationAuthority'
477
  DESC 'RFC2256: a certificate authority'
478
  SUP top AUXILIARY
479
  MUST ( authorityRevocationList $ certificateRevocationList $
480
  cACertificate ) MAY crossCertificatePair )
481
#
482
olcObjectClasses: ( 2.5.6.17 NAME 'groupOfUniqueNames'
483
  DESC 'RFC2256: a group of unique names (DN and Unique Identifier)'
484
  SUP top STRUCTURAL
485
  MUST ( uniqueMember $ cn )
486
  MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )
487
#
488
olcObjectClasses: ( 2.5.6.18 NAME 'userSecurityInformation'
489
  DESC 'RFC2256: a user security information'
490
  SUP top AUXILIARY
491
  MAY ( supportedAlgorithms ) )
492
#
493
olcObjectClasses: ( 2.5.6.16.2 NAME 'certificationAuthority-V2'
494
  SUP certificationAuthority
495
  AUXILIARY MAY ( deltaRevocationList ) )
496
#
497
olcObjectClasses: ( 2.5.6.19 NAME 'cRLDistributionPoint'
498
  SUP top STRUCTURAL
499
  MUST ( cn )
500
  MAY ( certificateRevocationList $ authorityRevocationList $
501
  deltaRevocationList ) )
502
#
503
olcObjectClasses: ( 2.5.6.20 NAME 'dmd'
504
  SUP top STRUCTURAL
505
  MUST ( dmdName )
506
  MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
507
  x121Address $ registeredAddress $ destinationIndicator $
508
  preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
509
  telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
510
  street $ postOfficeBox $ postalCode $ postalAddress $
511
  physicalDeliveryOfficeName $ st $ l $ description ) )
512
#
513
#
514
# Object Classes from RFC 2587
515
#
516
olcObjectClasses: ( 2.5.6.21 NAME 'pkiUser'
517
  DESC 'RFC2587: a PKI user'
518
  SUP top AUXILIARY
519
  MAY userCertificate )
520
#
521
olcObjectClasses: ( 2.5.6.22 NAME 'pkiCA'
522
  DESC 'RFC2587: PKI certificate authority'
523
  SUP top AUXILIARY
524
  MAY ( authorityRevocationList $ certificateRevocationList $
525
  cACertificate $ crossCertificatePair ) )
526
#
527
olcObjectClasses: ( 2.5.6.23 NAME 'deltaCRL'
528
  DESC 'RFC2587: PKI user'
529
  SUP top AUXILIARY
530
  MAY deltaRevocationList )
531
#
532
#
533
# Standard Track URI label schema from RFC 2079
534
# system schema
535
#olcAttributeTypes: ( 1.3.6.1.4.1.250.1.57 NAME 'labeledURI'
536
#	DESC 'RFC2079: Uniform Resource Identifier with optional label'
537
#	EQUALITY caseExactMatch
538
#	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
539
#
540
olcObjectClasses: ( 1.3.6.1.4.1.250.3.15 NAME 'labeledURIObject'
541
  DESC 'RFC2079: object that contains the URI attribute type'
542
  MAY ( labeledURI )
543
  SUP top AUXILIARY )
544
#
545
#
546
# Derived from RFC 1274, but with new "short names"
547
#
548
#olcAttributeTypes: ( 0.9.2342.19200300.100.1.1
549
#	NAME ( 'uid' 'userid' )
550
#	DESC 'RFC1274: user identifier'
551
#	EQUALITY caseIgnoreMatch
552
#	SUBSTR caseIgnoreSubstringsMatch
553
#	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
554
#
555
olcAttributeTypes: ( 0.9.2342.19200300.100.1.3
556
  NAME ( 'mail' 'rfc822Mailbox' )
557
  DESC 'RFC1274: RFC822 Mailbox'
558
    EQUALITY caseIgnoreIA5Match
559
    SUBSTR caseIgnoreIA5SubstringsMatch
560
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
561
#
562
olcObjectClasses: ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject'
563
  DESC 'RFC1274: simple security object'
564
  SUP top AUXILIARY
565
  MUST userPassword )
566
#
567
# RFC 1274 + RFC 2247
568
olcAttributeTypes: ( 0.9.2342.19200300.100.1.25
569
  NAME ( 'dc' 'domainComponent' )
570
  DESC 'RFC1274/2247: domain component'
571
  EQUALITY caseIgnoreIA5Match
572
  SUBSTR caseIgnoreIA5SubstringsMatch
573
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
574
#
575
# RFC 2247
576
olcObjectClasses: ( 1.3.6.1.4.1.1466.344 NAME 'dcObject'
577
  DESC 'RFC2247: domain component object'
578
  SUP top AUXILIARY MUST dc )
579
#
580
# RFC 2377
581
olcObjectClasses: ( 1.3.6.1.1.3.1 NAME 'uidObject'
582
  DESC 'RFC2377: uid object'
583
  SUP top AUXILIARY MUST uid )
584
#
585
# From COSINE Pilot
586
olcAttributeTypes: ( 0.9.2342.19200300.100.1.37
587
  NAME 'associatedDomain'
588
  DESC 'RFC1274: domain associated with object'
589
  EQUALITY caseIgnoreIA5Match
590
  SUBSTR caseIgnoreIA5SubstringsMatch
591
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
592
#
593
# RFC 2459 -- deprecated in favor of 'mail' (in cosine.schema)
594
olcAttributeTypes: ( 1.2.840.113549.1.9.1
595
  NAME ( 'email' 'emailAddress' 'pkcs9email' )
596
  DESC 'RFC3280: legacy attribute for email addresses in DNs'
597
  EQUALITY caseIgnoreIA5Match
598
  SUBSTR caseIgnoreIA5SubstringsMatch
599
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
600
#
src/authentic2_provisionning/tests/cosine.ldif
1
# RFC1274: Cosine and Internet X.500 schema
2
# $OpenLDAP$
3
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
##
5
## Copyright 1998-2012 The OpenLDAP Foundation.
6
## All rights reserved.
7
##
8
## Redistribution and use in source and binary forms, with or without
9
## modification, are permitted only as authorized by the OpenLDAP
10
## Public License.
11
##
12
## A copy of this license is available in the file LICENSE in the
13
## top-level directory of the distribution or, alternatively, at
14
## <http://www.OpenLDAP.org/license.html>.
15
#
16
# RFC1274: Cosine and Internet X.500 schema
17
#
18
# This file contains LDAPv3 schema derived from X.500 COSINE "pilot"
19
# schema.  As this schema was defined for X.500(89), some
20
# oddities were introduced in the mapping to LDAPv3.  The
21
# mappings were based upon: draft-ietf-asid-ldapv3-attributes-03.txt
22
# (a work in progress)
23
#
24
# Note: It seems that the pilot schema evolved beyond what was
25
# described in RFC1274.  However, this document attempts to describes
26
# RFC1274 as published.
27
#
28
# Depends on core.ldif
29
#
30
# This file was automatically generated from cosine.schema; see that
31
# file for complete background.
32
#
33
dn: cn=cosine,cn=schema,cn=config
34
objectClass: olcSchemaConfig
35
cn: cosine
36
olcAttributeTypes: ( 0.9.2342.19200300.100.1.2 NAME 'textEncodedORAddress' 
37
 EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.
38
 1466.115.121.1.15{256} )
39
olcAttributeTypes: ( 0.9.2342.19200300.100.1.4 NAME 'info' DESC 'RFC1274: g
40
 eneral information' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch
41
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{2048} )
42
olcAttributeTypes: ( 0.9.2342.19200300.100.1.5 NAME ( 'drink' 'favouriteDri
43
 nk' ) DESC 'RFC1274: favorite drink' EQUALITY caseIgnoreMatch SUBSTR caseIgno
44
 reSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
45
olcAttributeTypes: ( 0.9.2342.19200300.100.1.6 NAME 'roomNumber' DESC 'RFC1
46
 274: room number' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch S
47
 YNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
48
olcAttributeTypes: ( 0.9.2342.19200300.100.1.7 NAME 'photo' DESC 'RFC1274: 
49
 photo (G3 fax)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.23{25000} )
50
olcAttributeTypes: ( 0.9.2342.19200300.100.1.8 NAME 'userClass' DESC 'RFC12
51
 74: category of user' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMat
52
 ch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
53
olcAttributeTypes: ( 0.9.2342.19200300.100.1.9 NAME 'host' DESC 'RFC1274: h
54
 ost computer' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTA
55
 X 1.3.6.1.4.1.1466.115.121.1.15{256} )
56
olcAttributeTypes: ( 0.9.2342.19200300.100.1.10 NAME 'manager' DESC 'RFC127
57
 4: DN of manager' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115
58
 .121.1.12 )
59
olcAttributeTypes: ( 0.9.2342.19200300.100.1.11 NAME 'documentIdentifier' D
60
 ESC 'RFC1274: unique identifier of document' EQUALITY caseIgnoreMatch SUBSTR 
61
 caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
62
olcAttributeTypes: ( 0.9.2342.19200300.100.1.12 NAME 'documentTitle' DESC '
63
 RFC1274: title of document' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstri
64
 ngsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
65
olcAttributeTypes: ( 0.9.2342.19200300.100.1.13 NAME 'documentVersion' DES
66
 C 'RFC1274: version of document' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSu
67
 bstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
68
olcAttributeTypes: ( 0.9.2342.19200300.100.1.14 NAME 'documentAuthor' DESC
69
  'RFC1274: DN of author of document' EQUALITY distinguishedNameMatch SYNTAX 1
70
 .3.6.1.4.1.1466.115.121.1.12 )
71
olcAttributeTypes: ( 0.9.2342.19200300.100.1.15 NAME 'documentLocation' DE
72
 SC 'RFC1274: location of document original' EQUALITY caseIgnoreMatch SUBSTR c
73
 aseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
74
olcAttributeTypes: ( 0.9.2342.19200300.100.1.20 NAME ( 'homePhone' 'homeTe
75
 lephoneNumber' ) DESC 'RFC1274: home telephone number' EQUALITY telephoneNumb
76
 erMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121
77
 .1.50 )
78
olcAttributeTypes: ( 0.9.2342.19200300.100.1.21 NAME 'secretary' DESC 'RFC
79
 1274: DN of secretary' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.146
80
 6.115.121.1.12 )
81
olcAttributeTypes: ( 0.9.2342.19200300.100.1.22 NAME 'otherMailbox' SYNTAX
82
  1.3.6.1.4.1.1466.115.121.1.39 )
83
olcAttributeTypes: ( 0.9.2342.19200300.100.1.26 NAME 'aRecord' EQUALITY ca
84
 seIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
85
olcAttributeTypes: ( 0.9.2342.19200300.100.1.27 NAME 'mDRecord' EQUALITY c
86
 aseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
87
olcAttributeTypes: ( 0.9.2342.19200300.100.1.28 NAME 'mXRecord' EQUALITY c
88
 aseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
89
olcAttributeTypes: ( 0.9.2342.19200300.100.1.29 NAME 'nSRecord' EQUALITY c
90
 aseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
91
olcAttributeTypes: ( 0.9.2342.19200300.100.1.30 NAME 'sOARecord' EQUALITY 
92
 caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
93
olcAttributeTypes: ( 0.9.2342.19200300.100.1.31 NAME 'cNAMERecord' EQUALIT
94
 Y caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
95
olcAttributeTypes: ( 0.9.2342.19200300.100.1.38 NAME 'associatedName' DESC
96
  'RFC1274: DN of entry associated with domain' EQUALITY distinguishedNameMatc
97
 h SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
98
olcAttributeTypes: ( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress' D
99
 ESC 'RFC1274: home postal address' EQUALITY caseIgnoreListMatch SUBSTR caseIg
100
 noreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
101
olcAttributeTypes: ( 0.9.2342.19200300.100.1.40 NAME 'personalTitle' DESC 
102
 'RFC1274: personal title' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstring
103
 sMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
104
olcAttributeTypes: ( 0.9.2342.19200300.100.1.41 NAME ( 'mobile' 'mobileTel
105
 ephoneNumber' ) DESC 'RFC1274: mobile telephone number' EQUALITY telephoneNum
106
 berMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.12
107
 1.1.50 )
108
olcAttributeTypes: ( 0.9.2342.19200300.100.1.42 NAME ( 'pager' 'pagerTelep
109
 honeNumber' ) DESC 'RFC1274: pager telephone number' EQUALITY telephoneNumber
110
 Match SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1
111
 .50 )
112
olcAttributeTypes: ( 0.9.2342.19200300.100.1.43 NAME ( 'co' 'friendlyCount
113
 ryName' ) DESC 'RFC1274: friendly country name' EQUALITY caseIgnoreMatch SUBS
114
 TR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
115
olcAttributeTypes: ( 0.9.2342.19200300.100.1.44 NAME 'uniqueIdentifier' DE
116
 SC 'RFC1274: unique identifer' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.14
117
 66.115.121.1.15{256} )
118
olcAttributeTypes: ( 0.9.2342.19200300.100.1.45 NAME 'organizationalStatus
119
 ' DESC 'RFC1274: organizational status' EQUALITY caseIgnoreMatch SUBSTR caseI
120
 gnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
121
olcAttributeTypes: ( 0.9.2342.19200300.100.1.46 NAME 'janetMailbox' DESC '
122
 RFC1274: Janet mailbox' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5Subst
123
 ringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
124
olcAttributeTypes: ( 0.9.2342.19200300.100.1.47 NAME 'mailPreferenceOption
125
 ' DESC 'RFC1274: mail preference option' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
126
  )
127
olcAttributeTypes: ( 0.9.2342.19200300.100.1.48 NAME 'buildingName' DESC '
128
 RFC1274: name of building' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstrin
129
 gsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
130
olcAttributeTypes: ( 0.9.2342.19200300.100.1.49 NAME 'dSAQuality' DESC 'RF
131
 C1274: DSA Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.19 SINGLE-VALUE )
132
olcAttributeTypes: ( 0.9.2342.19200300.100.1.50 NAME 'singleLevelQuality' 
133
 DESC 'RFC1274: Single Level Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.13 SIN
134
 GLE-VALUE )
135
olcAttributeTypes: ( 0.9.2342.19200300.100.1.51 NAME 'subtreeMinimumQualit
136
 y' DESC 'RFC1274: Subtree Mininum Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.
137
 13 SINGLE-VALUE )
138
olcAttributeTypes: ( 0.9.2342.19200300.100.1.52 NAME 'subtreeMaximumQualit
139
 y' DESC 'RFC1274: Subtree Maximun Quality' SYNTAX 1.3.6.1.4.1.1466.115.121.1.
140
 13 SINGLE-VALUE )
141
olcAttributeTypes: ( 0.9.2342.19200300.100.1.53 NAME 'personalSignature' D
142
 ESC 'RFC1274: Personal Signature (G3 fax)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.
143
 23 )
144
olcAttributeTypes: ( 0.9.2342.19200300.100.1.54 NAME 'dITRedirect' DESC 'R
145
 FC1274: DIT Redirect' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466
146
 .115.121.1.12 )
147
olcAttributeTypes: ( 0.9.2342.19200300.100.1.55 NAME 'audio' DESC 'RFC1274
148
 : audio (u-law)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.4{25000} )
149
olcAttributeTypes: ( 0.9.2342.19200300.100.1.56 NAME 'documentPublisher' D
150
 ESC 'RFC1274: publisher of document' EQUALITY caseIgnoreMatch SUBSTR caseIgno
151
 reSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
152
olcObjectClasses: ( 0.9.2342.19200300.100.4.4 NAME ( 'pilotPerson' 'newPilo
153
 tPerson' ) SUP person STRUCTURAL MAY ( userid $ textEncodedORAddress $ rfc822
154
 Mailbox $ favouriteDrink $ roomNumber $ userClass $ homeTelephoneNumber $ hom
155
 ePostalAddress $ secretary $ personalTitle $ preferredDeliveryMethod $ busine
156
 ssCategory $ janetMailbox $ otherMailbox $ mobileTelephoneNumber $ pagerTelep
157
 honeNumber $ organizationalStatus $ mailPreferenceOption $ personalSignature 
158
 ) )
159
olcObjectClasses: ( 0.9.2342.19200300.100.4.5 NAME 'account' SUP top STRUCT
160
 URAL MUST userid MAY ( description $ seeAlso $ localityName $ organizationNam
161
 e $ organizationalUnitName $ host ) )
162
olcObjectClasses: ( 0.9.2342.19200300.100.4.6 NAME 'document' SUP top STRUC
163
 TURAL MUST documentIdentifier MAY ( commonName $ description $ seeAlso $ loca
164
 lityName $ organizationName $ organizationalUnitName $ documentTitle $ docume
165
 ntVersion $ documentAuthor $ documentLocation $ documentPublisher ) )
166
olcObjectClasses: ( 0.9.2342.19200300.100.4.7 NAME 'room' SUP top STRUCTURA
167
 L MUST commonName MAY ( roomNumber $ description $ seeAlso $ telephoneNumber 
168
 ) )
169
olcObjectClasses: ( 0.9.2342.19200300.100.4.9 NAME 'documentSeries' SUP top
170
  STRUCTURAL MUST commonName MAY ( description $ seeAlso $ telephonenumber $ l
171
 ocalityName $ organizationName $ organizationalUnitName ) )
172
olcObjectClasses: ( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP top STRUCT
173
 URAL MUST domainComponent MAY ( associatedName $ organizationName $ descripti
174
 on $ businessCategory $ seeAlso $ searchGuide $ userPassword $ localityName $
175
  stateOrProvinceName $ streetAddress $ physicalDeliveryOfficeName $ postalAdd
176
 ress $ postalCode $ postOfficeBox $ streetAddress $ facsimileTelephoneNumber 
177
 $ internationalISDNNumber $ telephoneNumber $ teletexTerminalIdentifier $ tel
178
 exNumber $ preferredDeliveryMethod $ destinationIndicator $ registeredAddress
179
  $ x121Address ) )
180
olcObjectClasses: ( 0.9.2342.19200300.100.4.14 NAME 'RFC822localPart' SUP d
181
 omain STRUCTURAL MAY ( commonName $ surname $ description $ seeAlso $ telepho
182
 neNumber $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOffi
183
 ceBox $ streetAddress $ facsimileTelephoneNumber $ internationalISDNNumber $ 
184
 telephoneNumber $ teletexTerminalIdentifier $ telexNumber $ preferredDelivery
185
 Method $ destinationIndicator $ registeredAddress $ x121Address ) )
186
olcObjectClasses: ( 0.9.2342.19200300.100.4.15 NAME 'dNSDomain' SUP domain 
187
 STRUCTURAL MAY ( ARecord $ MDRecord $ MXRecord $ NSRecord $ SOARecord $ CNAME
188
 Record ) )
189
olcObjectClasses: ( 0.9.2342.19200300.100.4.17 NAME 'domainRelatedObject' D
190
 ESC 'RFC1274: an object related to an domain' SUP top AUXILIARY MUST associat
191
 edDomain )
192
olcObjectClasses: ( 0.9.2342.19200300.100.4.18 NAME 'friendlyCountry' SUP c
193
 ountry STRUCTURAL MUST friendlyCountryName )
194
olcObjectClasses: ( 0.9.2342.19200300.100.4.20 NAME 'pilotOrganization' SU
195
 P ( organization $ organizationalUnit ) STRUCTURAL MAY buildingName )
196
olcObjectClasses: ( 0.9.2342.19200300.100.4.21 NAME 'pilotDSA' SUP dsa STR
197
 UCTURAL MAY dSAQuality )
198
olcObjectClasses: ( 0.9.2342.19200300.100.4.22 NAME 'qualityLabelledData' 
199
 SUP top AUXILIARY MUST dsaQuality MAY ( subtreeMinimumQuality $ subtreeMaximu
200
 mQuality ) )
src/authentic2_provisionning/tests/inetorgperson.ldif
1
# InetOrgPerson (RFC2798)
2
# $OpenLDAP$
3
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
##
5
## Copyright 1998-2012 The OpenLDAP Foundation.
6
## All rights reserved.
7
##
8
## Redistribution and use in source and binary forms, with or without
9
## modification, are permitted only as authorized by the OpenLDAP
10
## Public License.
11
##
12
## A copy of this license is available in the file LICENSE in the
13
## top-level directory of the distribution or, alternatively, at
14
## <http://www.OpenLDAP.org/license.html>.
15
#
16
# InetOrgPerson (RFC2798)
17
#
18
# Depends upon
19
#   Definition of an X.500 Attribute Type and an Object Class to Hold
20
#   Uniform Resource Identifiers (URIs) [RFC2079]
21
#	(core.ldif)
22
#
23
#   A Summary of the X.500(96) User Schema for use with LDAPv3 [RFC2256]
24
#	(core.ldif)
25
#
26
#   The COSINE and Internet X.500 Schema [RFC1274] (cosine.ldif)
27
#
28
# This file was automatically generated from inetorgperson.schema; see
29
# that file for complete references.
30
#
31
dn: cn=inetorgperson,cn=schema,cn=config
32
objectClass: olcSchemaConfig
33
cn: inetorgperson
34
olcAttributeTypes: ( 2.16.840.1.113730.3.1.1 NAME 'carLicense' DESC 'RFC279
35
 8: vehicle license or registration plate' EQUALITY caseIgnoreMatch SUBSTR cas
36
 eIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
37
olcAttributeTypes: ( 2.16.840.1.113730.3.1.2 NAME 'departmentNumber' DESC '
38
 RFC2798: identifies a department within an organization' EQUALITY caseIgnoreM
39
 atch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
40
olcAttributeTypes: ( 2.16.840.1.113730.3.1.241 NAME 'displayName' DESC 'RFC
41
 2798: preferred name to be used when displaying entries' EQUALITY caseIgnoreM
42
 atch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SI
43
 NGLE-VALUE )
44
olcAttributeTypes: ( 2.16.840.1.113730.3.1.3 NAME 'employeeNumber' DESC 'RF
45
 C2798: numerically identifies an employee within an organization' EQUALITY ca
46
 seIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.12
47
 1.1.15 SINGLE-VALUE )
48
olcAttributeTypes: ( 2.16.840.1.113730.3.1.4 NAME 'employeeType' DESC 'RFC2
49
 798: type of employment for a person' EQUALITY caseIgnoreMatch SUBSTR caseIgn
50
 oreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
51
olcAttributeTypes: ( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' DESC 'RFC2
52
 798: a JPEG image' SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 )
53
olcAttributeTypes: ( 2.16.840.1.113730.3.1.39 NAME 'preferredLanguage' DESC
54
  'RFC2798: preferred written or spoken language for a person' EQUALITY caseIg
55
 noreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.
56
 15 SINGLE-VALUE )
57
olcAttributeTypes: ( 2.16.840.1.113730.3.1.40 NAME 'userSMIMECertificate' D
58
 ESC 'RFC2798: PKCS#7 SignedData used to support S/MIME' SYNTAX 1.3.6.1.4.1.14
59
 66.115.121.1.5 )
60
olcAttributeTypes: ( 2.16.840.1.113730.3.1.216 NAME 'userPKCS12' DESC 'RFC2
61
 798: personal identity information, a PKCS #12 PFX' SYNTAX 1.3.6.1.4.1.1466.1
62
 15.121.1.5 )
63
olcObjectClasses: ( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' DESC 'RFC2
64
 798: Internet Organizational Person' SUP organizationalPerson STRUCTURAL MAY 
65
 ( audio $ businessCategory $ carLicense $ departmentNumber $ displayName $ em
66
 ployeeNumber $ employeeType $ givenName $ homePhone $ homePostalAddress $ ini
67
 tials $ jpegPhoto $ labeledURI $ mail $ manager $ mobile $ o $ pager $ photo 
68
 $ roomNumber $ secretary $ uid $ userCertificate $ x500uniqueIdentifier $ pre
69
 ferredLanguage $ userSMIMECertificate $ userPKCS12 ) )
src/authentic2_provisionning/tests/test_ldap.py
1
import ldap
2

  
3
from django.test import TestCase
4
from unittest import skipUnless
5

  
6
from authentic2_provisionning.ldap_utils import Slapd, has_slapd
7
from django.core.management import call_command
8
from authentic2 import compat
9

  
10

  
11
@skipUnless(has_slapd(), 'slapd is not installed')
12
class LDAPBaseTestCase(TestCase):
13
    slapd = None
14

  
15
    def setUp(self):
16
        if self.slapd is None:
17
            self.slapd = Slapd()
18
        self.slapd.checkpoint()
19
        # fresh connection
20
        self.conn = self.slapd.get_connection()
21

  
22
    def tearDown(self):
23
        self.slapd.restore()
24

  
25
class WhoamiTest(LDAPBaseTestCase):
26
    def test_whoami(self):
27
        self.conn.simple_bind_s('uid=admin,o=orga', 'admin')
28
        assert self.conn.whoami_s() == 'dn:uid=admin,o=orga'
29

  
30
class ProvisionTest(LDAPBaseTestCase):
31
    def test_ldap_provisionning(self):
32
        ressources = [{
33
            'name': 'ldap',
34
            'url': self.slapd.ldapi_url,
35
            'bind_dn': 'uid=admin,o=orga',
36
            'bind_pw': 'admin',
37
            'base_dn': 'o=orga',
38
            'rdn_attributes': ['uid',],
39
            'attribute_mapping': {
40
                'uid': 'django_user_username',
41
                'givenName': 'django_user_first_name',
42
                'sn': 'django_user_last_name',
43
                'mail': 'django_user_email',
44
            },
45
            'format_mapping': {
46
                'cn': ['{django_user_first_name} {django_user_last_name}'],
47
            },
48
            'static_attributes': {
49
                'objectclass': 'inetorgperson',
50
            },
51
            'ldap_filter': '(objectclass=inetorgperson)',
52
        }]
53
        User = compat.get_user_model()
54
        users = [User(username='john.doe%s' % i,
55
                first_name='john',
56
                last_name='doe',
57
                email='john.doe@example.com') for i in range(1000)]
58

  
59
        User.objects.bulk_create(users)
60
        self.slapd.add_ldif('''dn: uid=test,o=orga
61
objectClass: inetOrgPerson
62
uid: test
63
cn: test
64
sn: test
65
gn: test
66
mail: test''')
67
        with self.settings(A2_PROVISIONNING_RESSOURCES=ressources):
68
            call_command('provision', 'ldap', batch_size=1000)
69
        results = self.conn.search_s('o=orga', ldap.SCOPE_ONELEVEL)
70
        self.assertEqual(len(results), 1000)
71
        for dn, entry in results:
72
            uid = entry['uid'][0]
73
            self.assertTrue(uid.startswith('john.doe'))
74
            self.assertEquals(entry, {
75
                        'objectClass': ['inetOrgPerson'],
76
                        'uid': [uid],
77
                        'sn': [users[0].last_name],
78
                        'givenName': [users[0].first_name],
79
                        'cn': ['%s %s' % (users[0].first_name, users[0].last_name)],
80
                        'mail': [users[0].email]})
81

  
82

  
0
-