Entry(3pm)

πŸ’– Entry(3pm) β€” Mozilla::LDAP::Entry.pm πŸ’–

okay so you found the manual page for Mozilla::LDAP::Entry.pm β€” the object class that holds one single LDAP entry. Bestie, this one is long, so we're doing it in two parts. Buckle up. πŸŽ€


🌸 NAME 🌸

Mozilla::LDAP::Entry.pm β€” the object class whose whole entire job is to hold one LDAP entry. That's it. That's the gig. πŸ‘‘


✨ SYNOPSIS ✨

use Mozilla::LDAP::Conn;
use Mozilla::LDAP::Entry;

πŸ¦‹ ABSTRACT πŸ¦‹

The LDAP::Conn object is the one doing the actual LDAP work β€” searches, updates, adds, deletes. But here's the tea: all of those functions only ever operate on LDAP::Entry objects. Every modification and every addition you make to an LDAP entry happens through this object class. No entry object, no entry. Periodt. πŸ’…


🌈 DESCRIPTION 🌈

The LDAP::Entry object class is built on top of the standard Tie::Hash object class. And that gives us some genuinely iconic superpowers β€” the main one being that it keeps track of what's changing in the LDAP entry. Which means writing LDAP clients that need to update/modify entries is so easy: you just make the changes, and this object class handles the rest. Not you. It. 🫢

We define local functions for STORE, FETCH, DELETE, EXISTS, FIRSTKEY and NEXTKEY in this object class, and inherit everything else from the super class. Overloading those specific functions is how we track what's changing in the entry, and it turns out to be super convenient. It also means we can easily "loop" over the attribute types, skipping the internal data and any deleted attributes. Slay. ✨

Most of the methods here either hand you back the LDAP value you asked for, or a status code. The status code (either 0 or 1) tells you whether a certain operation failed or succeeded. 0 (False) means the operation failed, and a return code of 1 (True) means complete success. Fr fr.

One thing to remember, and this one matters: in LDAP, attribute names are case insensitive. Every method in this class knows this, and will convert all attribute name arguments to lower case before doing any operations. But β€” and stay with me β€” this does not mean the values are case insensitive. On the contrary, all values are considered case sensitive by this module, even if the LDAP server itself treats it as a CIS attribute. 😭


πŸ‘‘ OBJECT CLASS METHODS πŸ‘‘

The LDAP::Entry class implements a whole bunch of methods you can use to access and modify LDAP entries. And it is strongly recommended that you use this API as much as possible, and avoid poking at the internals of the class directly. Because failing to do that may actually break the functionality. Not a vibe. πŸ’€

πŸŽ€ Creating a new entry πŸŽ€

To create a completely new entry, use the new method, for instance:

$entry = Mozilla::LDAP::Entry->new()
$entry->setDN("uid=leif,ou=people,dc=netscape,dc=com");
$entry->{objectclass} = [ "top", "person", "inetOrgPerson" ];
$entry->addValue("cn", "Leif Hedstrom");
$entry->addValue("sn", "Hedstrom");
$entry->addValue("givenName", "Leif");
$entry->addValue("mail", "leif@netscape.com);

$conn->add($entry);

This is the minimum requirements for an LDAP entry. It must have a DN, and it must have at least one objectclass. And as it turns out, by adding the person and inetOrgPerson classes, we also have to provide some more attributes, like CN and SN. That's because those object classes have these attributes marked as "required", and we'd get a schema violation without those values. Schema said no. 🚫

In the example above we use both native API methods to add values, and set an attribute's entire value set directly. Note that the value set is a pointer to an array, and not the array itself. In the example above, the object classes are set using an anonymous array, which the API handles properly. It's important to be aware that the attribute value list is indeed a pointer. πŸ’…

Finally, as you can see, there's only one way to add new LDAP entries, and it's called add(). It normally takes an LDAP::Entry object instance as argument, but it can also be called with a regular hash array if so desired.

πŸ“ Adding and removing attributes and values πŸ“

This is the main functionality of this module. Use these methods to do any modifications and updates to your LDAP entries. Let's go. πŸ”₯

  • addValue β€” Add a value to an attribute. If the attribute value already exists, or we couldn't add the value for any other reason, we'll return FALSE (0), otherwise we return TRUE (1). The first two arguments are the attribute name, and the value to add.

The optional third argument is a flag, indicating that we want to add the attribute without checking for duplicates. This is useful if you know the values are unique already, or if you perhaps want to allow duplicates for a particular attribute. The fourth argument (again optional) is a flag indicating that we want to perform DN normalization on the attribute. The final, fifth, optional argument indicates that the attribute values are case insensitive (CIS).

To add a CN to an existing entry/attribute, do:

$entry->addValue("cn", "Leif Hedstrom");
  • addDNValue β€” Just like addValue, except this method assumes the value is a DN attribute, and will enforce DN normalization. For instance:
$dn = "uid=Leif, dc=Netscape, dc=COM";
$entry->addDNValue("uniqueMember", $dn);

will only add the DN for "uid=leif" if it does not exist as a DN in the uniqueMember attribute. πŸ’…

  • attrModified β€” This is an internal function, that can be used to force the API to consider an attribute (value) to have been modified. The only argument is the name of the attribute. In almost all situations, you never, ever, should call this. If you do, please contact the developers, and ask us to fix the API. Example:
$entry->attrModified("cn");
  • copy β€” Copy the value of one attribute to another. Requires at least two arguments. The first argument is the name of the attribute to copy, and the second argument is the name of the new attribute to copy to. The new attribute can not currently exist in the entry, else the copy will fail. There is an optional third argument (a boolean flag), which, when set to 1, will force an override and copy to the new attribute even if it already exists. Returns TRUE if the copy was successful.
$entry->copy("cn", "description");
  • exists β€” Return TRUE if the specified attribute is defined in the LDAP entry. This is useful to know if an entry has a particular attribute, regardless of the value. For instance:
if ($entry->exists("jpegphoto")) { # do something special }
  • getDN β€” Return the DN for the entry. For instance:
print "The DN is: ", $entry->getDN(), "\n";

Just like setDN, this method also has an optional argument, which indicates we should normalize the DN before returning it to the caller.

  • getValues β€” Returns an entire array of values for the attribute specified. Note that this returns an array, and not a pointer to an array. In a scalar context, this returns the first value. This is different β€” this method used to always return an array, which meant the array size in a scalar context. If you need to get the array size, use the size method described below.
@someArray = $entry->getValues("description");
$scalval = $entry->getValues("cn");
  • hasValue β€” Return TRUE or FALSE if the attribute has the specified value. A typical usage is to see if an entry is of a certain object class, e.g.
if ($entry->hasValue("objectclass", "person", 1)) { # do something }

The (optional) third argument indicates if the string comparison should be case insensitive or not, and the (optional) fourth argument indicates whether we should normalize the string as if it was a DN. The first two arguments are the name and value of the attribute, respectively.

  • hasDNValue β€” Exactly like hasValue, except we assume the attribute values are DN attributes. πŸ’…
  • isAttr β€” This method can be used to decide if an attribute name really is a valid LDAP attribute in the current entry. Use of this method is fairly limited, but could potentially be useful. Usage is like previous examples, like:
if ($entry->isAttr("cn")) { # do something }

The code section will only be executed if these criteria are true:

  1. The name of the attribute is a non-empty string.
  2. The name of the attribute does not begin, and end, with an underscore character (_).
  3. The attribute has one or more values in the entry.

(yes bestie, the numbering says 2 twice β€” we're keeping it exactly as the original wrote it, no cap 🫢)

  • isDeleted β€” This is almost identical to isModified, except it tests if an attribute has been deleted. You use it the same way as above, like:
if (! $entry->isDeleted("cn")) { # do something }
  • isModified β€” This is a somewhat more useful method, which will return the internal modification status of a particular attribute. The argument is the name of the attribute, and the return value is True or False. If the attribute has been modified, in any way, we return True (1), otherwise we return False (0). For example:
if ($entry->isModified("cn")) { # do something }
  • isEntryModified β€” This is a wrapper over isModified(), and it will check if any attribute in the entry object has been modified or deleted. πŸ‘‘
  • matchValue β€” This is very similar to hasValue, except it does a regular expression match instead of a full string match. It takes the same arguments, including the optional third argument to specify case insensitive matching. The usage is identical to the example for hasValue, e.g.
if ($entry->matchValue("objectclass", "pers", 1)) { # do something }
  • matchDNValue β€” Like matchValue, except the attribute values are considered being DNs.
  • move β€” Identical to the copy method, except the original attribute is deleted once the move to the new attribute is complete.
$entry->move("cn", "sn");
  • printLDIF β€” Print the entry in a format called LDIF (LDAP Data Interchange Format, RFC xxxx). An example of an LDIF entry is:

…and bestie, that's where part 1 ends β€” the LDIF example is coming right up in part 2, so don't go anywhere πŸ’–

so like, here's the vibe of what comes out the other side:

dn: uid=leif,ou=people,dc=netscape,dc=com
objectclass: top
objectclass: person
objectclass: inetOrgPerson
uid: leif
cn: Leif Hedstrom
mail: leif@netscape.com

and that whole thing up there? yeah, that's literally just the result of

$entry->printLDIF();

If you need to write to a file, open it and then select() it, bestie. And if you want the real LDIF experience, go check out the Mozilla::LDAP::LDIF.pm module β€” it's giving way more functionality. ✨


remove

This one straight-up removes the entire attribute, including all its values, from the entry. Gone. Deleted. Not coming back. πŸ’€

The only argument is the name of the attribute you want to remove. So say you want to nuke every single mailAlternateAddress value β€” like, the whole attribute should just leave the entry:

$entry->remove("mailAlternateAddress");

removeValue

Removes one value from an attribute, if it exists. And if the attribute doesn't even have that value? We're not gonna try to remove it, we just return a False (0) status code instead. Polite. 🫢

The arguments are the name of the attribute, and the specific value you want to remove. Big heads up though: values are considered case sensitive, so make sure you preserve case properly, okay? An example:

$entry->removeValue("objectclass", "nscpPerson");

removeDNValue

This is almost identical to removeValue, except it normalizes the attribute values before trying to remove them. Which is highkey useful when you know the attribute is a DN value but the values are, like, not consistent across all your LDAP entries. For example:

$dn = "uid=Leif, dc=Netscape, dc=COM";
$entry->removeDNValue("owner", $dn);

will remove the owner "uid=leif,dc=netscape,dc=com" no matter how it's capitalized and formatted in the entry. Iconic, honestly. πŸ’…

setDN

Sets the DN to the specified value. Only do this on new entries though β€” it will not work well if you try it on an existing entry. 🚨

If you wish to rename an entry, use the Mozilla::Conn::modifyRDN method instead. And eventually there'll be a complete "rename" method, so stay tuned.

To set the DN for a newly created entry, we can do:

$entry->setDN("uid=leif,ou=people,dc=netscape,dc=com");

There's an optional third argument β€” a boolean flag β€” indicating that we should normalize the DN before setting it. That'll assure a consistent format of your DNs. Slay.

setValues

Sets the specified attribute to the new value (or values), overwriting whatever old values it had before. Which is a little dangerous, ngl β€” you can lose attribute values you didn't intend to remove. So it's usually recommended to use removeValue() and setValues(). If you know exactly what the new values should look like, you can use it like:

$entry->setValues("cn", "Leif Hedstrom", "The Swede");
$entry->setValues("mail", @mailAddresses);

or, if it's a single value attribute:

$entry->setValues("uidNumber", "12345");

size

Returns the number of values for a particular attribute. For instance:

$entry->{cn} = [ "Leif Hedstrom", "The Swede" ];
$numVals = $entry->size("cn");

That'll set $numVals to two (2). The only argument is the name of the attribute, and the return value is the size of the value array. Easy math, bestie. πŸ“


Deleting entries

To delete an LDAP entry off the LDAP server, you have to use the delete method from the Mozilla::LDAP::Conn module. It will actually delete any entry, if you provide a legitimate DN. No vibes, just deletion. πŸ”₯

Renaming entries

Again β€” there is no functionality in this object class to rename the entry (i.e. changing its DN). So for now, there's a way to modify the RDN component of a DN through the Mozilla::LDAP::Conn module, with modifyRDN.

And eventually, hopefully, there'll be a complete rename method that's capable of renaming any entry, in any way, including moving it to a different part of the DIT (Directory Information Tree). Manifesting it. πŸ™


EXAMPLES

There are plenty of examples to look at, in the examples directory. And we're adding more examples every day (almost). Obsessed with the grind, fr fr. ✨

INSTALLATION

Installing this package is part of the Makefile supplied in the package. See the installation procedures which are part of this package. πŸ“¦

AVAILABILITY

This package can be retrieved from a number of places, including:

CREDITS

Most of this code was developed by Leif Hedstrom, Netscape Communications Corporation. King behavior. πŸ‘‘

BUGS

None. :)

(no literally, that's the whole bug section. we ate and left no crumbs. πŸ’…)

SEE ALSO

Mozilla::LDAP::Conn, Mozilla::LDAP::API, and of course Perl. πŸͺ


okay and that's a wrap on this page, bestie β€” shoutout to perl v5.40.0 and the date 2025-01-03, which is when this whole thing was stamped. go forth and LDAP responsibly πŸ’–πŸ¦‹

πŸ“¦ where this page comes from