20080821 parsing an ldap schema with netldapschema - plembo/onemoretech GitHub Wiki

title: Parsing an LDAP schema with Net::LDAP::Schema link: https://onemoretech.wordpress.com/2008/08/21/parsing-an-ldap-schema-with-netldapschema/ author: lembobro description: post_id: 467 created: 2008/08/21 00:28:19 created_gmt: 2008/08/21 00:28:19 comment_status: open post_name: parsing-an-ldap-schema-with-netldapschema status: publish post_type: post

Parsing an LDAP schema with Net::LDAP::Schema

Being able to parse the LDAP schema is something that can come in handy at times. For example, many years ago I wrote a cgi script to display our entire production schema for my company’s user administration and development teams. Recently we needed to generate a .csv file to do the same thing.

Net::LDAP::Schema has gone through a few changes over the years. A major refactoring took place in 2002, involving significant differences in the methods exposed.

What I’ll do in this article is demonstrate how you would use a few of those methods in the hopes that whoever reads this won’t have to endure the same steep learning curve I did.

Of course reading the POD is an indispensable prerequisite, as usual, but unfortuately the examples given there are not as exhaustive as one would like. Or need.

Let’s start with a skeleton script to make things easy to experiment with.

`

#!/usr/bin/perl
use strict;
use Net::LDAP;
use Net::LDAP::Schema;
	
my $ldaphost = "myldap.mydomain.com";
	
my $ldap = Net::LDAP->new($dirHost);
my $mesg = $ldap->bind();
	
my $schema = $ldap->schema();
	
[DO STUFF HERE]
	
$ldap->unbind;

`

OK. So far so good. Now lets do something with objectclasses.

`

my @ocs = $schema->all_objectclasses();
foreach my $oc(@ocs) {
	
    my $ocname = $oc->name{name};
    my $ocoid = $oc->{oid};
	
    print "$ocname,$ocoidn";
	
}

`

Now for something not obvious (at least to me!) in all the documentation. Let’s list out all the manadatory attributes for our objectclasses.

`

print $ocname, "n";
	
my @musts = $schema->must($ocname);
	
print  "_Must_n";
	
foreach my $must(@musts) {
    print $must->{name}, "n";
}
	
print "n";

`

Notice that while we’re iterating over the array of attributes that are listed in @musts, we’re using a method to get the text to be printed. That’s because what @musts contains is actually an array of hash references. If you simply printed “$must”, you’d get one of those references. Doing the “$must->{name}” calls out the text value that is the member attribute’s name.

There’s lots more fun stuff you can have with this. Moving on to attributes, I want to point out a couple of “gotchas” that had me banging my head against the desk until I figured it out. First the setup.

`

my @attrs = $schema->all_attributes();
	
foreach my $attr(@attrs) {
	
    my $attrname = $attr->{name};
    my $oid = $attr->{oid};
    my $desc = $attr->{desc};
	
    print "$attrname,$oid,"$desc"n";
	
}

`

Now for something a little more interesting. We all know most LDAP attributes in the standard schema are multi-valued, much to the chagrin of our developers. Why not include information on which attributes are single-valued?

`

my $singleflag = $attr->{'single-value'};
if($singleflag == '1') {
    $singleflag = "SINGLE-VALUE";
}
else {
    $singleflag = "MULTI-VALUED";
}
	
print "$attrname,$singleflagn";

`

While the above code may not be elegant, it does illustrate two important points. First, the hash key for “single-value” must be in quotes. Perl won’t know what to do if they’re left out. Second, the value returned by the method is “1” if true (i.e., the attribute is SINGLE-VALUE) and nothing if false (i.e., the attribute is MULTI-VALUED).

So much for the kid stuff. Now for the icing on the cake, something I haven’t seen anyone else do that I’m kind of proud of.

Instead of forcing readers to do lookups of syntax identifiers for attributes, why not give them the text labels for the syntaxes returned?

To do this you need to first set up a hash of your own that contains each label and its corresponding code.

`

my %syntaxlabels = (
	
    "1.3.6.1.4.1.1466.115.121.1.15","CASE_IGNORE_STRING",
    "1.3.6.1.4.1.1466.115.121.1.26","CASE_EXACT_STRING",
    "1.3.6.1.4.1.1466.115.121.1.5","BINARY",
    "1.3.6.1.4.1.1466.115.121.1.27","INTEGER",
    "1.3.6.1.4.1.1466.115.121.1.12","DN",
    "1.3.6.1.4.1.1466.115.121.1.50","TELEPHONE_NUMBER",
    "1.3.6.1.4.1.1466.115.121.1.41","POSTAL_ADDRESS",
    "1.3.6.1.4.1.1466.115.121.1.24","GENERALIZED_TIME"
	
);

`

Now let’s use this hash to call out and display syntax information for each attribute.

`

my $syntaxoid = $attr->{syntax};
my $syntaxname = $syntaxlabels{$syntaxoid};
	
print "$attrname,$syntaxnamen";

`

So there you have it. Undoubtedly I’ll find something wrong with this little tutorial around 15 seconds after posting it, or someone else will point out an error (or two, or three) I missed. In the meantime, hopefully someone else will find it useful — or at least somewhat enlightening.

Copyright 2004-2019 Phil Lembo