>From e0c775c7f9dab067e9c6f6e1cf70b89ab2b7e114 Mon Sep 17 00:00:00 2001
From: John Dennis <jdennis@redhat.com>
Date: Fri, 20 Aug 2010 11:57:24 -0400
Subject: [PATCH] Load clients from LDAP
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

---
 doc/examples/389_ds_schema.ldif |  574 +++++++++++++++++++++++++++++++++++++++
 raddb/modules/ldap              |   17 ++
 src/modules/rlm_ldap/rlm_ldap.c |  186 +++++++++++++
 3 files changed, 777 insertions(+), 0 deletions(-)
 create mode 100644 doc/examples/389_ds_schema.ldif

diff --git a/doc/examples/389_ds_schema.ldif b/doc/examples/389_ds_schema.ldif
new file mode 100644
index 0000000..652487c
--- /dev/null
+++ b/doc/examples/389_ds_schema.ldif
@@ -0,0 +1,574 @@
+# This is a LDAPv3 schema for RADIUS attributes.
+# Tested on OpenLDAP 2.0.7
+# Posted by Javier Fernandez-Sanguino Pena <jfernandez@sgi.es>
+# LDAP v3 version by Jochen Friedrich <jochen@scram.de>
+# Updates by Adrian Pavlykevych <pam@polynet.lviv.ua>
+# Modified by John Dennis <jdennis@redhat.com> for use with Directory Sever/IPA
+#
+# Note: These OID's do not seem to be registered, the closest I could find
+# was 1.3.6.1.4.1.3317
+# {iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) gnome(3317)}
+#
+##############
+dn: cn=schema
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.1
+        NAME 'radiusArapFeatures'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.2
+        NAME 'radiusArapSecurity'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.3
+        NAME 'radiusArapZoneAccess'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.44
+        NAME 'radiusAuthType'
+        DESC 'checkItem: Auth-Type'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.4
+        NAME 'radiusCallbackId'
+        DESC 'replyItem: Callback-Id'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.5
+        NAME 'radiusCallbackNumber'
+        DESC 'replyItem: Callback-Number'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.6
+        NAME 'radiusCalledStationId'
+        DESC 'checkItem: Called-Station-Id'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.7
+        NAME 'radiusCallingStationId'
+        DESC 'checkItem: Calling-Station-Id'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.8
+        NAME 'radiusClass'
+        DESC 'replyItem: Class'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.45
+        NAME 'radiusClientIPAddress'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.9
+        NAME 'radiusFilterId'
+        DESC 'replyItem: Filter-Id'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.10
+        NAME 'radiusFramedAppleTalkLink'
+        DESC 'replyItem: Framed-AppleTalk-Link'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.11
+        NAME 'radiusFramedAppleTalkNetwork'
+        DESC 'replyItem: Framed-AppleTalk-Network'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.12
+        NAME 'radiusFramedAppleTalkZone'
+        DESC 'replyItem: Framed-AppleTalk-Zone'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.13
+        NAME 'radiusFramedCompression'
+        DESC 'replyItem: Framed-Compression'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.14
+        NAME 'radiusFramedIPAddress'
+        DESC 'replyItem: Framed-IP-Address'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.15
+        NAME 'radiusFramedIPNetmask'
+        DESC 'replyItem: Framed-IP-Netmask'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.16
+        NAME 'radiusFramedIPXNetwork'
+        DESC 'replyItem: Framed-IPX-Network'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.17
+        NAME 'radiusFramedMTU'
+        DESC 'replyItem: Framed-MTU'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.18
+        NAME 'radiusFramedProtocol'
+        DESC 'replyItem: Framed-Protocol'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.19
+        NAME 'radiusFramedRoute'
+        DESC 'replyItem: Framed-Route'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.20
+        NAME 'radiusFramedRouting'
+        DESC 'replyItem: Framed-Routing'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.46
+        NAME 'radiusGroupName'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.47
+        NAME 'radiusHint'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.48
+        NAME 'radiusHuntgroupName'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.21
+        NAME 'radiusIdleTimeout'
+        DESC 'replyItem: Idle-Timeout'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.22
+        NAME 'radiusLoginIPHost'
+        DESC 'replyItem: Login-IP-Host'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.23
+        NAME 'radiusLoginLATGroup'
+        DESC 'replyItem: Login-LAT-Group'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.24
+        NAME 'radiusLoginLATNode'
+        DESC 'replyItem: Login-LAT-Node'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.25
+        NAME 'radiusLoginLATPort'
+        DESC 'replyItem: Login-LAT-Port'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.26
+        NAME 'radiusLoginLATService'
+        DESC 'replyItem: Login-LAT-Service'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.27
+        NAME 'radiusLoginService'
+        DESC 'replyItem: Login-Service'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.28
+        NAME 'radiusLoginTCPPort'
+        DESC 'replyItem: Login-TCP-Port'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.29
+        NAME 'radiusPasswordRetry'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.30
+        NAME 'radiusPortLimit'
+        DESC 'replyItem: Port-Limit'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.49
+        NAME 'radiusProfileDn'
+        DESC ''
+        EQUALITY distinguishedNameMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.31
+        NAME 'radiusPrompt'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.50
+        NAME 'radiusProxyToRealm'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.51
+        NAME 'radiusReplicateToRealm'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.52
+        NAME 'radiusRealm'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.32
+        NAME 'radiusServiceType'
+        DESC 'replyItem: Service-Type'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.33
+        NAME 'radiusSessionTimeout'
+        DESC 'replyItem: Session-Timeout'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.34
+        NAME 'radiusTerminationAction'
+        DESC 'replyItem: Termination-Action'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.35
+        NAME 'radiusTunnelAssignmentId'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.36
+        NAME 'radiusTunnelMediumType'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.37
+        NAME 'radiusTunnelPassword'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.38
+        NAME 'radiusTunnelPreference'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.39
+        NAME 'radiusTunnelPrivateGroupId'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.40
+        NAME 'radiusTunnelServerEndpoint'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.41
+        NAME 'radiusTunnelType'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.42
+        NAME 'radiusVSA'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.43
+        NAME 'radiusTunnelClientEndpoint'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+#need to change asn1.id
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.53
+        NAME 'radiusSimultaneousUse'
+        DESC 'checkItem: Simultaneous-Use'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.54
+        NAME 'radiusLoginTime'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.55
+        NAME 'radiusUserCategory'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.56
+        NAME 'radiusStripUserName'
+        DESC ''
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.57
+        NAME 'dialupAccess'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.58
+        NAME 'radiusExpiration'
+        DESC 'checkItem: Expiration'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.59
+        NAME 'radiusCheckItem'
+        DESC 'checkItem: $GENERIC$'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.60
+        NAME 'radiusReplyItem'
+        DESC 'replyItem: $GENERIC$'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.61
+        NAME 'radiusNASIpAddress'
+        DESC ''
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.62
+        NAME 'radiusReplyMessage'
+        DESC 'replyItem: Reply-Message'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+objectClasses:
+    ( 1.3.6.1.4.1.3317.4.3.2.1
+        NAME 'radiusprofile'
+        SUP top AUXILIARY
+        DESC ''
+      MUST cn
+        MAY ( radiusArapFeatures $ radiusArapSecurity $ radiusArapZoneAccess $
+            radiusAuthType $ radiusCallbackId $ radiusCallbackNumber $
+            radiusCalledStationId $ radiusCallingStationId $ radiusClass $
+            radiusClientIPAddress $ radiusFilterId $ radiusFramedAppleTalkLink $
+            radiusFramedAppleTalkNetwork $ radiusFramedAppleTalkZone $
+            radiusFramedCompression $ radiusFramedIPAddress $
+            radiusFramedIPNetmask $ radiusFramedIPXNetwork $
+            radiusFramedMTU $ radiusFramedProtocol $
+            radiusCheckItem $ radiusReplyItem $
+            radiusFramedRoute $ radiusFramedRouting $ radiusIdleTimeout $
+            radiusGroupName $ radiusHint $ radiusHuntgroupName $
+            radiusLoginIPHost $ radiusLoginLATGroup $ radiusLoginLATNode $
+            radiusLoginLATPort $ radiusLoginLATService $ radiusLoginService $
+            radiusLoginTCPPort $ radiusLoginTime $ radiusPasswordRetry $
+            radiusPortLimit $ radiusPrompt $ radiusProxyToRealm $
+            radiusRealm $ radiusReplicateToRealm $ radiusServiceType $
+            radiusSessionTimeout $ radiusStripUserName $
+            radiusTerminationAction $ radiusTunnelClientEndpoint $ radiusProfileDn $
+            radiusSimultaneousUse $ radiusTunnelAssignmentId $
+            radiusTunnelMediumType $ radiusTunnelPassword $ radiusTunnelPreference $
+            radiusTunnelPrivateGroupId $ radiusTunnelServerEndpoint $
+            radiusTunnelType $ radiusUserCategory $ radiusVSA $
+            radiusExpiration $ dialupAccess $ radiusNASIpAddress $
+            radiusReplyMessage )
+    )
+objectClasses:
+    ( 1.3.6.1.4.1.3317.4.3.2.2
+        NAME 'radiusObjectProfile'
+        SUP top STRUCTURAL
+        DESC 'A Container Objectclass to be used for creating radius profile object'
+        MUST cn
+        MAY ( uid $ userPassword $ description )
+  )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.64
+        NAME 'radiusClientSecret'
+        DESC 'NAS password'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.65
+        NAME 'radiusClientNASType'
+        DESC 'NAS type'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.66
+        NAME 'radiusClientShortName'
+        DESC 'Descriptive name for NAS'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.67
+        NAME 'radiusClientVirtualServer'
+        DESC 'Assign NAS to this virtual server'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+attributeTypes:
+    ( 1.3.6.1.4.1.3317.4.3.1.68
+        NAME 'radiusClientCOAServer'
+        DESC 'COA server'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    )
+objectClasses:
+    ( 1.3.6.1.4.1.3317.4.3.2.3
+        NAME 'radiusClientProfile'
+        SUP top STRUCTURAL
+        DESC 'A Container Objectclass to be used for describing radius clients'
+        MUST (cn $ radiusClientIPAddress $ radiusClientSecret)
+        MAY ( radiusClientNASType $ radiusClientShortName $ 
+            radiusClientVirtualServer $ radiusClientCOAServer $ description )
+  )
diff --git a/raddb/modules/ldap b/raddb/modules/ldap
index 8a2077a..1b9984f 100644
--- a/raddb/modules/ldap
+++ b/raddb/modules/ldap
@@ -158,6 +158,23 @@ ldap {
 	#  allowed values: {no, yes}
 	# set_auth_type = yes
 
+	# Clients can be read from the LDAP directory,
+	# this is only done at server start up time and will
+	# only be done if clients_basedn is defined.
+	#
+	# The LDAP attributes for a client are:
+	# cn, description,
+	# radiusClientIPAddress, radiusClientSecret
+	# radiusClientNASType, radiusClientShortName
+	# radiusClientVirtualServer, radiusClientCOAServer
+	#
+	# clients_basedn = "o=My Org,c=UA"
+	#
+	# The clients_filter is used in the LDAP search for client
+	# definitions, by default it is "(objectclass=radiusClientProfile)"
+	#
+	# clients_filter = "(objectclass=radiusClientProfile)"
+
 	#  ldap_debug: debug flag for LDAP SDK
 	#  (see OpenLDAP documentation).  Set this to enable
 	#  huge amounts of LDAP debugging on the screen.
diff --git a/src/modules/rlm_ldap/rlm_ldap.c b/src/modules/rlm_ldap/rlm_ldap.c
index 3c12e9f..aaa802e 100644
--- a/src/modules/rlm_ldap/rlm_ldap.c
+++ b/src/modules/rlm_ldap/rlm_ldap.c
@@ -1,3 +1,4 @@
+/* -*- indent-tabs-mode: t; c-basic-offset: 8; -*- */
 /*
  * rlm_ldap.c	LDAP authorization and authentication module.
  *
@@ -144,6 +145,8 @@ typedef struct {
 	char           *base_filter;
 	char           *basedn;
 	char           *default_profile;
+	char           *clients_basedn;
+	char           *clients_filter;
 	char           *profile_attr;
 	char           *access_attr;
 	char           *passwd_hdr;
@@ -283,6 +286,10 @@ static const CONF_PARSER module_config[] = {
 	 offsetof(ldap_instance,default_profile), NULL, NULL},
 	{"profile_attribute", PW_TYPE_STRING_PTR,
 	 offsetof(ldap_instance,profile_attr), NULL, NULL},
+	{"clients_basedn", PW_TYPE_STRING_PTR,
+         offsetof(ldap_instance,clients_basedn), NULL, NULL},
+	{"clients_filter", PW_TYPE_STRING_PTR,
+         offsetof(ldap_instance,clients_filter), NULL, "(objectclass=radiusClientProfile)"},
 
 	/*
 	 *	Getting passwords from the database
@@ -360,6 +367,7 @@ static int ldap_groupcmp(void *, REQUEST *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PA
 static size_t ldap_xlat(void *, REQUEST *, char *, char *, size_t, RADIUS_ESCAPE_STRING);
 static LDAP    *ldap_connect(void *instance, const char *, const char *, int, int *, char **);
 static int     read_mappings(ldap_instance* inst);
+static int generate_ldap_clients(ldap_instance* inst);
 
 static inline int ldap_get_conn(LDAP_CONN *conns,LDAP_CONN **ret,
 				ldap_instance *inst)
@@ -689,6 +697,10 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
 
 	DEBUG("conns: %p",inst->conns);
 
+	if (generate_ldap_clients(inst)) {
+		radlog(L_ERR, "rlm_ldap: Failed to read client list from ldap");
+	}
+
 	*instance = inst;
 
 
@@ -930,6 +942,180 @@ retry:
 	return res;
 }
 
+/*
+ * generate_ldap_clients(). read clients from ldap, append to client list
+ */
+static int generate_ldap_clients(ldap_instance* inst)
+{
+	LDAP_CONN	*conn;
+	int		conn_id = -1;
+	int		res;
+	LDAPMessage    *result, *entry;
+	int		client_idx;
+	char           *prefix_ptr = NULL;
+
+	if (!inst->clients_basedn) {
+		DEBUG("rlm_ldap: generate_ldap_clients, client basedn not set, skipping...");
+		return 0;
+	}
+	DEBUG("rlm_ldap: generate_ldap_clients, client_basedn=%s", inst->clients_basedn);
+
+
+	if ((conn_id = ldap_get_conn(inst->conns,&conn,inst)) == -1){
+		radlog(L_ERR, "rlm_ldap: All ldap connections are in use");
+		return 1;
+	}
+	if ((res = perform_search(inst, conn, inst->clients_basedn, LDAP_SCOPE_SUBTREE,
+				  inst->clients_filter, NULL, &result)) != RLM_MODULE_OK){
+		DEBUG("rlm_ldap::generate_ldap_clients: search failed");
+		ldap_release_conn(conn_id,inst);
+		return 1;
+	}
+
+	for (entry = ldap_first_entry(conn->ld, result), client_idx = 0;
+	     entry != NULL;
+	     entry = ldap_next_entry(conn->ld, entry), client_idx++) {
+		char *val, **vals;
+		RADCLIENT *client; 
+		char *description = NULL;
+
+		client = rad_malloc(sizeof(*client));
+		memset(client, 0, sizeof(*client));
+
+		if ((vals = ldap_get_values(conn->ld, entry, "radiusClientIpAddress")) != NULL) {
+			val = vals[0];
+
+#ifdef WITH_DYNAMIC_CLIENTS
+			client->dynamic = 1;
+#endif
+
+			/*
+			 * Look for prefixes
+			 */
+			client->prefix = -1;
+			prefix_ptr = strchr(val, '/');
+			if (prefix_ptr) {
+				client->prefix = atoi(prefix_ptr + 1);
+				if ((client->prefix < 0) || (client->prefix > 128)) {
+					radlog(L_ERR, "rlm_ldap (%s): Invalid Prefix value '%s' for IP.",
+					       inst->xlat_name, prefix_ptr + 1);
+					free(client);
+					ldap_value_free(vals);
+					continue;
+				}
+				/* Replace '/' with '\0' */
+				*prefix_ptr = '\0';
+			}
+
+			/*
+			 * Always get the numeric representation of IP
+			 */
+			if (ip_hton(val, AF_UNSPEC, &client->ipaddr) < 0) {
+				radlog(L_CONS|L_ERR, "rlm_ldap (%s): Failed to look up hostname %s: %s",
+				       inst->xlat_name,
+				       val, fr_strerror());
+				free(client);
+				ldap_value_free(vals);
+				continue;
+			} else {
+				char buffer[256];
+				ip_ntoh(&client->ipaddr, buffer, sizeof(buffer));
+				client->longname = strdup(buffer);
+			}
+
+			if (client->prefix < 0) switch (client->ipaddr.af) {
+				case AF_INET:
+					client->prefix = 32;
+					break;
+				case AF_INET6:
+					client->prefix = 128;
+					break;
+				default:
+					break;
+				}
+
+
+			ldap_value_free(vals);
+		}
+
+
+		if ((vals = ldap_get_values(conn->ld, entry, "description")) != NULL) {
+			val = vals[0];
+			description = strdup(val);
+			ldap_value_free(vals);
+		}
+
+		if ((vals = ldap_get_values(conn->ld, entry, "radiusClientSecret")) != NULL) {
+			val = vals[0];
+			client->secret = strdup(val);
+			ldap_value_free(vals);
+		}
+
+		if ((vals = ldap_get_values(conn->ld, entry, "radiusClientNASType")) != NULL) {
+			val = vals[0];
+			client->nastype = strdup(val);
+			ldap_value_free(vals);
+		}
+
+
+		if ((vals = ldap_get_values(conn->ld, entry, "radiusClientShortName")) != NULL) {
+			val = vals[0];
+			client->shortname = strdup(val);
+			ldap_value_free(vals);
+		}
+
+
+		if ((vals = ldap_get_values(conn->ld, entry, "radiusClientVirtualServer")) != NULL) {
+			val = vals[0];
+			client->server = strdup(val);
+			ldap_value_free(vals);
+		}
+
+
+#ifdef WITH_COA
+		if ((vals = ldap_get_values(conn->ld, entry, "radiusClientCOAServer")) != NULL) {
+			val = vals[0];
+			client->coa_name = strdup(val);
+			ldap_value_free(vals);
+		}
+#endif
+
+		DEBUG("rlm_ldap (%s): Adding client %s [name=%s server=%s nastype=%s coa_server=%s description=%s]",
+		      inst->xlat_name, client->longname,
+		      client->shortname ? client->shortname : "<none>",
+		      client->server    ? client->server    : "<none>",
+		      client->nastype,
+#ifdef WITH_COA
+		      client->coa_name  ? client->coa_name  : "<none>",
+#else
+		      "<unsupported>",
+#endif
+		      description       ? description       : "<none>");
+
+		if (!client_add(NULL, client)) {
+			DEBUG("rlm_ldap (%s): Failed to add client %s (%s) to clients list.  Maybe there's a duplicate?",
+			      inst->xlat_name, client->longname, client->shortname);
+
+			if (description) free(description);
+			client_free(client);
+			ldap_msgfree(result);
+			ldap_release_conn(conn_id,inst);
+
+			return -1;
+		}
+
+		if (description) {
+			free(description);
+			description = NULL;
+		}
+	}
+
+	DEBUG("rlm_ldap (%s): %d client(s) added", inst->xlat_name, client_idx);
+
+	ldap_msgfree(result);
+	ldap_release_conn(conn_id,inst);
+	return 0;
+}
 
 /*
  *	Translate the LDAP queries.
-- 
1.7.2.1

