GOto::LDAP(3) Support library for goto-* scripts to access LDAP


use GOto::Common qw(:ldap);
use GOto::LDAP qw(ldap_get_object);

my $ldapinfo = goto_ldap_parse_config_ex(); #ref to hash
my ($ldapbase,$ldapuris) = ($ldapinfo->{"LDAP_BASE"}, $ldapinfo->{"LDAP_URIS"});

my $ldap = Net::LDAP->new( $ldapuris, timeout => $timeout ) or die;
$ldap->bind() ; # anonymous bind
# list context
my @results = ldap_get_object(ldap => $ldap,
basedn => $ldapbase,
user => $user,
timeout => $timeout,
filter => $filter,
debug => $debug,
objectClass => $objectClass,
cnou => $cn,
subquery => $subquery,
sublevel => $sublevel,
subconflict => $subconflict,
attributeSelectionRegexes => \@attributeSelectionRegexes,
enctrigger => $enctrigger,
format => $format,
dups => $dups,
mergeResults => $mergeResults
@results or die;

# scalar context
my $result = ldap_get_object(...);
$result or die;

DESCRIPTION of ldap_get_object

"ldap_get_object()" reads information about an object (usually a user, but can also be a workstation, a POSIX group,...) from LDAP. "ldap_get_object()" understands gosaGroupOfNames and posixGroups and will not only return properties of the queried object itself but also properties inherited from groups of both types.


An object of type Net::LDAP that is already bound. Required.
The base DN to use for all searches. Required.
user/cnou and objectClass
You must pass either "user" or "cnou". If you pass "user", "objectClass" is ignored and "ldap_get_object()" will search for an object with "objectClass=posixAccount" and "uid" equal to the value passed as "user".

If you pass "cnou", then you must also pass "objectClass" and "ldap_get_object()" will search for an object with the given "objectClass" and a "cn" equal to the value passed as "cnou". If no such object is found, it will attempt to find an object with the given "objectClass" and "ou" equal to the value of "cnou".

attributeSelectionRegexes and CONFLICT RESOLUTION
A reference to a an array of regular expressions (as strings) that select the attributes to be returned and determines how to proceed in case there are multiple sources for an attribute (e.g. the user's posixAccount node and a posixGroup the user is a member of).

Each regex selects all attributes with matching names.

If the regex starts with the character "@" (which is ignored for the matching), then attribute values from different sources will be merged (i.e. the result will include all values).

If attributeRegex does NOT start with "@", then an attribute from the queried object's own node beats a posix group, which beats an object group (=gosaGroupOfNames) that includes the object directly which beats an object group that contains a posix group containing the object. Object groups containing other object groups are not supported by GOsa, so this case cannot occur.

If 2 sources with the same precedence (e.g. 2 posix groups) provide an attribute of the same name, selected by a regex that doesn not start with "@", then a WARNING is signalled and the program picks one of the conflicting attributes.

If multiple attribute regexes match the same attribute, the 1st matching attribute regex's presence or absence of "@" determines conflict resolution.

Matching is always performed against the complete attribute name as if the regex had been enclosed in "^...$", i.e. an attribute regex "name" will NOT match an attribute called "surname". Neither will the regex "sur".

Matching is always performed case-insensitive.

If the parameter "attributeSelectionRegexes" is not passed, it defaults to "@.*".

If "mergeResults" is "false" and "ldap_get_object()" is evaluated in list context, then it will return a list of Net::LDAP::Entry objects where each object represents the attributes on a given precedence level. The first entry gives the attributes that come from the own node, i.e. those with the highest precedence.

Attributes selected with a non-"@" regex, i.e. those for which only one source is permitted, are always found in the first entry and only there. For these attributes all conflicting values from lower precedence levels are always discarded, so "mergeResults=false" only makes sense when requesting merged attributes via "@".

If "mergeResults" is "true" (the default) or if "ldap_get_object()" is evaluated in scalar context, then only one Net::LDAP::Entry will be returned that contains all of the requested attributes.

Net::LDAP::Entry does not perform duplicate removal on its attribute value lists by default. If "dups=true" (the default), the results returned from "ldap_get_object()" may contain attributes that contain duplicate entries. If this would confuse your code, pass "dups=false" and duplicate values will be eliminated (at the cost of a few CPU cycles).
If "timeout" is passed, LDAP requests will use a timeout of this number of seconds. Note that this does not mean that "ldap_get_object" will finish within this time limit, since several LDAP requests may be involved.

Default timeout is 10s.

"filter" is an LDAP-Expression that will be ANDed with all user/object/group searches done by this program.

Use this to filter by "gosaUnitTag".

The "subquery" parameter is an LDAP filter such as "objectClass=gotoMenuItem". For the subtrees rooted at the object's own node and at all of its containing groups' nodes, an LDAP query using this filter will be done. The attributes of all of the objects resulting from these queries will be treated as if they were attributes of the node at which the search was rooted. The names of these pseudo-attributes have the form "foo/bar/attr".
"sublevel" specifies the maximum number of slashes the pseudo-attribute names will contain. If the complete name of a pseudo-attribute has more slashes than the given number, the name will be shortened to the longest suffix that contains this many slashes. Specifying a "sublevel" of 0 will effectively merge all subquery nodes with the user/object/group node so that in the end result their attributes are indistinguishable from those of the user/object/group node.

Default "sublevel" is 9999.

Note: attribute regex matching is performed on the full name with all slashes.

"subconflict" is a number that determines when 2 pseudo-attributes are treated as being in conflict with each other. 2 pseudo-attributes are treated as conflicting if the results of removing the shortest suffixes containing "subconflict" slashes from their names (shortened according to "sublevel") are identical. E.g. with "subconflict=0" the pseudo-attributes "foo/bar" and "foo/zoo" are not conflicting, whereas with "subconflict=1" they are. Default "subconflict" is 1.
If "debug" is "true", then lots of debug output (mostly all of the nodes considered in constructing the result) is printed to stdout.
This parameter is only relevant when "debug" is "true". It affects the way, attribute values are printed. If "enctrigger" is passed, it is interpreted as a regular expression and all DNs and attribute values will be tested against this regex. Whenever a value matches, it will be output base64 encoded. Matching is performed case-sensitive and unless ^ and $ are used in the regex, matching substrings are enough to trigger encoding.

If no "enctrigger" is specified, the default "[\x00-\x1f]" is used (i.e. base64 encoding will be used whenever a value contains a control character). If you pass "enctrigger=none", encoding will be completely disabled.

This parameter is only relevant when "debug" is "true". It affects the way, attribute values are printed. Format "a:v" means to print "attributeName: value" pairs. Format "v" means to print the values only.