1NAME 2 3 DBD::LDAP - A DBI driver for LDAP databases. LDAP stands for the 4 "Lightweight Directory Access Protocol". For more information, 5 see: http://www.ogre.com/ldap/docs.html 6 7SYNOPSIS 8 9 use DBI; 10 $dbh = DBI->connect("DBI:LDAP:ldapdb",'user','password') #USER LOGIN. 11 or die "Cannot connect as user: " . $DBI::errstr; 12 13 $dbh = DBI->connect("DBI:LDAP:ldapdb") #ANONYMOUS LOGIN (Read-only). 14 or die "Cannot connect as guest (readonly): " . $DBI::errstr; 15 16 $sth = $dbh->prepare("select * from people where (cn like 'Smith%')") 17 or die "Cannot prepare: " . $dbh->errstr(); 18 $sth->execute() or die "Cannot execute: " . $sth->errstr(); 19 while ((@results) = $sth->fetchrow_array) 20 { 21 print "--------------------------------------------------------\n"; 22 ++$cnt; 23 while (@results) 24 { 25 print "------>".join('|',split(/\0/, shift(@results)))."\n"; 26 } 27 } 28 $sth->finish(); 29 $dbh->disconnect(); 30 31DESCRIPTION 32 33DBD::LDAP is a DBI extension module adding an SQL database interface to 34standard LDAP databases to Perl's database-independent database interface. 35You will need access to an existing LDAP database or set up your own using 36an LDAP server, ie. "OpenLDAP", see (http://www.openldap.org). 37 38JLdap.pm is included in this module as a separate file, and is required. 39 40The main advantage of DBD::LDAP is the ability to query LDAP databases via 41standard SQL queries in leu of cryptic LDAP "filters". LDAP is optimized for 42quick lookup of existing data, but DBD::LDAP does support entry inserts, 43updates, and deletes with commit/rollback via the standard SQL commands! 44 45LDAP databases are "heirarchical" in structure, whereas other DBD-supported 46databases are "relational" and there is no Ldap-equivalent to SQL "tables", so 47DBD::LDAP maps a "table" interface over the LDAP "tree" via a configuration 48file you must set up. Each "table" is mapped to a common "base DN". For 49example, consider a typical LDAP database of employees within different 50departments within a company. You might have a "company" names "Acme" and 51the root "dn" of "dc=Acme, dc=com" (Acme.com). Below the company level, are 52divisions, ie. "Widgets", and "Blivets". Each division would have an entry 53with a "dn" of "ou=Widgets, dc=Acme, dc=com". Employees within each division 54could have a "dn" of "cn=John Doe, ou=Widgets, dc=Acme, dc=com". 55With DBD::LDAP, we could create tables to access these different levels, 56ie. "top", which would have a "DN" of "dc=Acme, dc=com", "WidgetDivision" for 57"ou=Widgets, dc=Acme, dc=com". Tables can also be constained by additional 58attribute specifications (filters), ie constraining by "objectclass", ie. 59"(objectclass=person)". Then, doing a "select * from WidgetDivision" would 60display all "person"s with a "dn" containing ""ou=Widgets, dc=Acme, dc=com". 61 62Prerequisites 63 64 Convert::ANS1 (required by Net::LDAP) 65 Net::LDAP 66 DBI 67 - an LDAP database to connect to. 68 69Installation 70 71 Installing this module (and the prerequisites from above) is quite 72 simple. You just fetch the archive, extract it with 73 74 gzip -cd DBD-LDAP-####.tar.gz | tar xf - 75 76 -or- 77 78 tar -xzvf DBD-LDAP-####.tar.gz 79 80 (this is for Unix users, Windows users would prefer WinZip or something 81 similar) and then enter the following: 82 83 cd DBD-LDAP-#.### 84 perl Makefile.PL 85 make 86 make test 87 88 If any tests fail, let me know. Otherwise go on with 89 90 make install 91 92 Note that you almost definitely need root or administrator permissions. 93 If you don't have them, read the ExtUtils::MakeMaker man page for 94 details on installing in your own directories. 95 96Getting started: 97 98 1) Create a "database", ie. "foo" by creating a text file "foo.ldb". The 99 general format of this file is: 100 101---------------------------------------------------------- 102hostname[;port][:[root-dn][:[loginrule]]] 103tablename1:[basedn]:[basefilter]:dnattrs:[visableattrs]:[insertattrs]:[ldap_options] 104tablename2:[basedn]:[basefilter]:dnattrs:[visableattrs]:[insertattrs]:[ldap_options] 105... 106---------------------------------------------------------- 107 108 <hostname> represents the ldap server host name. 109 <port> represents the server's port, default is 389. 110 <root-dn> if specified, is appended to the end of each tablename's 111 base-dn. 112 <loginrule> if specified, converts single word "usernames" to the 113 appropriate DN, ie: 114 115 "cn=*,<ROOT>" would convert user name "foo" to "cn=foo, " and 116 append the "<root-dn>" onto that. The asterisk is converted to 117 the user-name specified in the "connect" method. If not specified, 118 the username specified in the "connect" method must be a full DN. 119 If the "<root-dn>" is not specified, then the "<loginrule>" would 120 need to be a full DN. 121 122 tablename - represents the name to be used in SQL statements for a given 123 set of entries which make up a virtual "table". 124 basedn - if specified, is appended to the "<root-dn>" to make up the 125 common base DN for all entries in this table. If "<root-dn>" is 126 not specified, then a full DN must be specified; otherwise, the 127 default is the root-dn. 128 basefilter - if specified, specifies a filter to be used if no "where"- 129 clause is specified in SQL queries. If a "where"-clause is 130 specified, the resulting filter is "and"-ed with this one. The 131 default is "(objectclass=*)". 132 dnattrs - specifies which attributes that values for which are to be 133 appended to the left of the basedn to create DNs for new entries 134 being inserted into the table. 135 visableattrs - if specified, one or more attributes separated by commas 136 which will be sought when the SQL statement does not specify 137 attributes, ie. "select * from tablename". If not specified, the 138 attributes of the first matching entry are returned and used for 139 all entries matching a given query. 140 insertattrs - if specified, one or more attribute/value combinations to be 141 added to any new entry inserted into the table, usually needed for 142 objectclass values. The attributes and values usually correspond 143 to those specivied in the "<basefilter>". The general format is: 144 attr1=value1[|value2...],attr2=value1...,... 145 These attributes and values will be joined with any user-specified 146 values for these attributes. 147 ldap_options - if specified, can be any one or more of the following: 148 149 ldap_sizelimit - Limit the number of entries fetch by a query to this 150 number (0 = no limit) - default: 0. 151 ldap_timelimit - Limit the search to this number of seconds per query. 152 (0 = no limit) - default: 0. 153 ldap_scope - specify the "scope" of the search. Values are: "base", 154 "one", and "sub", see Net::LDAP docs. Default is "one", 155 meaning the set of records one level below the basedn. "base" 156 means search only the basedn, and "sub" means the union 157 of entries at the "base" level and "one" level below. 158 ldap_inseparator - specify the separator character/string to be used 159 in queries to separate multiple values being specified for 160 a given attribute. Default is "|". 161 ldap_outseparator - specify the separator character/string to be used 162 in queryies to separate multiple values displayed as a result 163 of a query. Default is "|". 164 ldap_firstonly - only display the 1st value fetched for each attribute 165 per entry. This makes "ldap_outseparator" unnecessary. 166 167 2) write your script to use DBI, ie: 168 169 #!/usr/bin/perl 170 use DBI; 171 172 $dbh = DBI->connect('DBD:LDAP:mydb','me','mypassword') || 173 die "Could not connect (".$DBI->err.':'.$DBI->errstr.")!"; 174 ... 175 #CREATE A TABLE, INSERT SOME RECORDS, HAVE SOME FUN! 176 177 3) get your application working. 178 179Inserting, fetching and modifying data 180 181 1st, we'll create a database called "ldapdb" with the tables previously 182 mentioned in the example in the DESCRIPTION section: 183 184----------------- file "ldapdb.ldb" ---------------- 185ldapserver:dc=Acme, dc=com:cn=*,<ROOT> 186top:::dc 187WidgetDivision:ou=Widgets, :&(objectclass=top)(objectclass=person):cn:cn,sn,ou,title,telephonenumber,description,objectclass,dn:objectclass=top|person|organizationalPerson:ldap_outseparator => ":" 188---------------------------------------------------- 189 190 The following examples insert some data in a table and fetch it back: 191 First all data in the string: 192 193 $dbh->do(<<END_SQL); 194 INSERT INTO top (ou, cn, objectclass) 195 VALUES ('Widgets', 'WidgetDivision', 'top|organizationalUnit') 196END_SQL 197 198 Next an example using parameters: 199 200 $dbh->do("INSERT INTO WidgetDivision (cn,sn,title,telephonenumber) VALUES (?, ?, ?, ?)", 201 'John Doe','DoeJ','Manager','123-1111'); 202END_SQL 203 $dbh->commit(); 204 205 NOTE: Unlike most other DBD modules which support transactions, changes 206 made do NOT show up until the "commit" function is called, unless 207 "AutoCommit" is set. This is due to the fact that fetches are done 208 from the LDAP server and changes do not take effect there until the 209 Net::LDAP "update" function is called, which is called by "commit". 210 211 NOTE: The "dn" field is generated automatically from the base "dn" and the 212 dn component fields specified by "dnattrs", If you try to insert a 213 value directly into it, it will be ignored. Also, if not specified, 214 any attribute/value combinations specified in the "insertattrs" 215 option will be added automatically. 216 217 To retrieve data, you can use the following: 218 219 my($query) = "SELECT * FROM WidgetDivision WHERE cn like 'John%' ORDER BY cn"; 220 my($sth) = $dbh->prepare($query); 221 $sth->execute(); 222 while (my $entry = $sth->fetchrow_hashref) { 223 print("Found result record: cn = ", $entry->{'cn'}, 224 ", phone = ", $row->{'telephonenumber'}); 225 } 226 $sth->finish(); 227 228 The SQL "SELECT" statement above (combined with the table information 229 in the "ldapdb.ldb" database file would generate and execute the following 230 equivalent LDAP Search: 231 232 base => 'ou=Widgets, dc=Acme, dc=com', 233 filter => '(&(&(objectclass=top)(objectclass=person))(cn=John*))', 234 scope => 'one', 235 attrs => 'cn,sn,ou,title,telephonenumber,description,objectclass,dn' 236 237 See the DBI(3) manpage for details on these methods. See the 238 239 Data rows are modified with the UPDATE statement: 240 241 $dbh->do("UPDATE WidgetDivision SET description = 'Outstanding Employee' WHERE cn = 'John Doe'"); 242 243 NOTE: You can NOT change the "dn" field directly - direct changes will be 244 ignored. You change the "rdn" component of the "dn" field by changing 245 the value of the other field(s) which are appended to the base "dn". 246 Also, if not specified, any attribute/value combinations specified in 247 the "insertattrs" option will be added automatically. 248 249 Likewise you use the DELETE statement for removing entries: 250 251 $dbh->do("DELETE FROM WidgetDivision WHERE description = 'Outstanding Employee'"); 252 253Metadata 254 255 The following attributes are handled by DBI itself and not by DBD::LDAP, 256 thus they should all work as expected. 257 258 PrintError 259 RaiseError 260 Warn 261 262 The following DBI attributes are handled by DBD::LDAP: 263 264 AutoCommit 265 Works 266 267 NUM_OF_FIELDS 268 Valid after `$sth->execute' 269 270 NUM_OF_PARAMS 271 Valid after `$sth->prepare' 272 273 NAME 274 Valid after `$sth->execute'; undef for Non-Select statements. 275 276 NULLABLE 277 Not really working. Always returns an array ref of one's, as 278 DBD::LDAP always allows NULL (handled as an empty string). 279 Valid after `$sth->execute'. 280 281 LongReadLen 282 Should work 283 284 LongTruncOk 285 Should work 286 287 These attributes and methods are not supported: 288 289 bind_param_inout 290 CursorName 291 292 In addition to the DBI attributes, you can use the following dbh 293 attributes. These attributes are read-only after "connect". 294 295 ldap_dbuser 296 Current database user. 297 298 ldap_HOME 299 Environment variable specifying a path to search for LDAP 300 databases (*.sdb) files. 301 302Driver private methods 303 304 DBI->data_sources() 305 The `data_sources' method returns a list of "databases" (.ldb files) 306 found in the current directory and, if specified, the path in 307 the ldap_HOME environment variable. 308 309 $dbh->tables() 310 This method returns a list of table names specified in the current 311 database. 312 Example: 313 314 my($dbh) = DBI->connect("DBI:LDAP:mydatabase",'me','mypswd'); 315 my(@list) = $dbh->func('tables'); 316 317Restrictions 318 319 DBD::LDAP currently treats all data as strings and all fields as 320 VARCHAR(255). 321 322 Currently, you must define tables manually in the "<database>.ldb" file 323 using your favorite text editor. Someday, if I have too much time on my 324 hands, I hope to add support for the SQL "Create Table", "Alter Table", 325 and "Drop Table" functions to handle this eventually (Patches welcome!) 326 327TODO 328 329 "Create Table", "Alter Table", and "Drop Table" SQL functions for 330 creating, altering, and deleting the tables defined in the 331 "<database>.ldb" file. 332 333 Some kind of datatype support, ie. numeric (for sorting), CHAR for padding, 334 Long/Blob - for >255 chars per field, etc. 335 336KNOWN BUGS 337 338 none - (yet). 339 340AUTHOR AND COPYRIGHT 341 342 This module is Copyright (C) 2000-2004 by 343 344 Jim Turner 345 346 Email: turnerjw@wwol.com 347 348 All rights reserved. 349 350 You may distribute this module under the terms of either the GNU General 351 Public License or the Artistic License, as specified in the Perl README 352 file. 353 354CHANGES 355 356 See Changes file. 357 358SEE ALSO 359 360 Net::LDAP(3), DBI(3), perl(1) 361 362 For general information on DBI see 363 364 http://www.symbolstone.org/technology/perl/DBI 365