\errorcontextlines=99 %\documentclass[colorBG,slideColor,troispoints,pdf]{prosper} \documentclass[total,pdf]{prosper} %\documentclass[12pt,colorBG,total,slideColor,pdf]{ppr-prv-nick} %\documentclass[colorBG,slideColor,ps]{prosper} \usepackage{alltt,key,xr,cols,rcs,acro,nick,% graphicx,varioref,explanation,booktabs,multicol} %\RequirePackage[unknownkeysallowed,a4paper,scale=0.93]{geometry} % \usepackage[nolineno,noindent]{lgrind} \usepackage[toc,highlight,Tycja]{HA-prosper} %\usepackage[toc,highlight,vsimple]{HA-prosper} %\definecolor{green}{rgb}{0,1,0} % Copyright (c) 2004 by Nick Urbanik . % This material may be distributed only subject to the terms and % conditions set forth in the Open Publication License, v1.0 or later % (the latest version is presently available at % http://www.opencontent.org/openpub/). \RCS $Revision: 1.3 $ \renewcommand*{\bs}{\texttt{\char '134}} % Backslash `\' %\newcommand*{\labTitle}{LDAP Directories} \newcommand*{\subject}{Systems and Network Management} \newcommand*{\emphcolour}[1]{\emph{\red#1}} \providecommand*{\RPM}{\acro{RPM}\xspace} \providecommand*{\CD}{\acro{CD}\xspace} \providecommand*{\IPC}{\acro{IPC}\xspace} \providecommand*{\UID}{\acro{UID}\xspace} \providecommand*{\GID}{\acro{GID}\xspace} \providecommand*{\SMP}{\acro{SMP}\xspace} \providecommand*{\API}{\acro{API}\xspace} \providecommand*{\OK}{\acro{OK}\xspace} \providecommand*{\IETF}{\acro{OK}\xspace} \providecommand*{\MS}{\acro{MS}\xspace} \newlength{\lift} \settoheight{\lift}{$\triangleleft$} \newcommand*{\generalises}{$\triangleleft$\rule[0.5\lift]{1.7\lift}{.4pt}} \title{\blue{}Programming LDAP with Perl} \subtitle{Net::LDAP} %% \author{Nick Urbanik \texttt{}\\ %% \footnotesize{}Copyright Conditions: Open Publication License (see %% \url{http://www.opencontent.org/openpub/})}% %% \institution{Department of Information and Communications Technology} \author{Nick Urbanik \texttt{}\\ \footnotesize{}Copyright Conditions: Open Publication License\\ \footnotesize{}(see \url{http://www.opencontent.org/openpub/})\\ \institution{Department of Information and Communications Technology}}% %\footnotesize{}Copyright Conditions: GNU FDL (see %\url{http://www.gnu.org/licenses/fdl.html})} \slideCaption{SNM --- LDAP Directories --- ver. \RCSRevision} \Logo{\includegraphics[width=15mm]{ict-logo-smaller}} \DefaultTransition{Wipe} \TitleSlideNav{FullScreen} \NormalSlideNav{ShowBookmarks} \LeftFoot{SNM --- ver. \RCSRevision} \RightFoot{Network Directories and their Structure} \begin{document} \maketitle %\begin{notes} %\end{notes} \tsection{Introduction to Net::LDAP} \begin{slide}{What is Net::LDAP?} \label{sld:what-is-net-ldap} \begin{itemize} \item Mature and fully-featured Perl library \item Pure Perl; very easy to install on any platform \begin{itemize} \item On Windows, do \begin{alltt}\footnotesize D:\bs>\textbf{ppm} PPM - Programmer's Package Manager version 3.1. Copyright (c) 2001 ActiveState SRL. All Rights Reserved. ... ppm> \textbf{install perl-ldap} \end{alltt} \item On other platforms, do: \begin{alltt} $ \textbf{sudo perl -MCPAN -e 'install Net::LDAP'} \end{alltt}%$ \end{itemize} \item Excellent documentation \begin{itemize} \item Start with \begin{alltt} $ \textbf{perldoc Net::LDAP} \end{alltt}%$ \end{itemize} \item Helpful mailing list \end{itemize} \end{slide} \tsection{Net::LDAP Operations} \begin{slide}{Connecting} \label{sld:connecting} \begin{itemize} \item Connect when construct the Net::LDAP object: \begin{alltt} my $ldap = Net::LDAP->new( $hostname ) or die "Unable to connect to $hostname: $!"; \end{alltt} \item See \texttt{perldoc Net::LDAP} for many other parameters you can pass in constructor \end{itemize} \end{slide} \begin{slide}{Authentication} \label{sld:authentication} \begin{itemize} \item The \emph{bind} operation \item Three types: \emphcolour{anonymous}, \emphcolour{simple}, \emphcolour{SASL} \item Anonymous: \begin{alltt} my $result = $ldap->bind; \end{alltt} \item Simple: \begin{alltt} my $result = $ldap->bind( $dn, password => $password ); \end{alltt} \begin{itemize} \item Danger! Password sent in clear text unless use \TLS (see slide~\S\ref{sld:start-tls}) \end{itemize} \end{itemize} \end{slide} \begin{slide}{Return Values} \label{sld:return-values} \begin{itemize} \item Most Net::LDAP methods return an object \begin{itemize} \item returned object provides method to obtain results of operation \end{itemize} \item result code returned by \texttt{\$result->code} \item error message returned by \texttt{\$result->error} \item Example: \begin{alltt} warn \$result->error if \$result->code; \end{alltt} \end{itemize} \end{slide} \begin{slide}{Searching} \label{sld:searching} \begin{itemize} \item Need three things for a search: \begin{itemize} \item \emphcolour{search base}, \emphcolour{scope} and \emphcolour{filter} \end{itemize} \begin{alltt} my $result = $ldap->search( base => 'dc=tyict,dc=vtc,dc=edu,dc=hk', scope => 'sub', filter => '(uid=nicku)' ); die $result->error if $result->code; \end{alltt} \item The result also contains the matching entries: \begin{verbatim} foreach my $entry ( $result->entries ) { $entry->dump; } \end{verbatim}%$ \begin{itemize} \item Methods of the object that results from a search documented in \texttt{perldoc~Net::LDAP::Search} \end{itemize} \end{itemize} \end{slide} \begin{slide}{Entry Object} \label{sld:entry-object} \begin{itemize} \item Entry object is used: \begin{itemize} \item to create new entries and \item is available from a search \end{itemize} \item Documented in \texttt{perldoc~Net::LDAP::Entry} \item Methods: \begin{description} \item[\texttt{dn}] returns the \DN for the entry: \begin{verbatim} my $dn = $entry->dn; \end{verbatim} \item[\texttt{exists}] tests if an attribute exists in the entry: \begin{verbatim} do_something() if $entry->exists( 'cn' ); \end{verbatim}%$ \end{description} \end{itemize} \end{slide} \begin{slide}{Entry Object --- 2} \begin{itemize} \item Methods: \begin{description} \item[\texttt{get\_value}] obtain the value(s) for an attribute in the entry \begin{verbatim} my $value = $entry->get_value( 'cn' ); \end{verbatim} \item[{Multivalued attributes:}] Some attributes have more than one value. For these, \texttt{get\_value} returns the first value in a scalar context, and all of them in a list context: {\small \begin{verbatim} my $first = $entry->get_value( 'objectClass' ); my @values = $entry->get_value( 'objectClass' ); \end{verbatim}% %% my $values = $entry->get_value( 'objectClass', %% asref => 1 ); }%$ \item[\texttt{attributes}] returns a list of attributes the entry contains \begin{verbatim} my @attrs = $entry->attributes; \end{verbatim}%$ \end{description} \end{itemize} \end{slide} \begin{slide}{Displaying an Entry} \label{sld:displating-entries} \begin{itemize} \item If all attributes can be printed, then this function could display an entry: \par\medskip\par \begin{verbatim} sub display_entry { my $entry = shift; my @attrs = $entry->attributes; foreach my $attr ( @attrs ) { my @value = $entry->get_value( $attr ); foreach my $value ( @value ) { print "$attr: $value\n"; } } } \end{verbatim} \end{itemize} \end{slide} \begin{slide}[toc=Limit Returns]{Controlling What's Returned} \label{sld:controlling-whats-returned} \begin{itemize} \item By default, \LDAP server returns attributes and their values for each entry. \item Can ask server for just the types; then value returned for each attribute is empty: \begin{verbatim} my $r = $ldap->search( base => 'dc=tyict,dc=vtc,dc=edu,dc=hk', filter => '(cn=Nick*)', typesonly => 1, ); \end{verbatim}%$ \item Access control limits what attributes are returned; can limit further by specifying a list of required attributes: \begin{verbatim} my $r = $ldap->search( base => 'dc=tyict,dc=vtc,dc=edu,dc=hk', filter => '(cn=Nick*)', attrs => [ qw(uid cn) ], ); \end{verbatim}%$ \item Can test for specific attributes by asking for \texttt{typesonly} as well as specifying an attribute list. \end{itemize} \end{slide} \begin{slide}{Adding New Entries} \label{sld:adding-new-entries} \ptsize{14} \begin{itemize} \item Net::LDAP supports four ways of adding new entries to a directory: \begin{itemize} \item the \texttt{add} method; \item the Entry class; \item \LDIF: Same as adding with the Entry class, except Entry is read from a file via the \LDIF module \item \acro{DSML}: Same as adding with the Entry class, except Entry is read from a file via the \acro{DSML} module \end{itemize} \end{itemize} \end{slide} \begin{slide}{Adding Entries} \label{sld:adding} \begin{itemize} \item Pass an array reference of attribute and value pairs to the \texttt{add} method: {\footnotesize% \begin{verbatim} my $r = $ldap->add( $dn, attrs => [ cn => 'HP5000-A204e', objectClass => [ qw/device ieee802Device/ ], description => 'Printer in A204e', ], ); \end{verbatim}%$ } \item \ldots\,or, create an Entry object and call the \texttt{update} method: %% {\small %% \begin{verbatim} %% my $dn = 'ou=devices,dc=tyict,dc=vtc,dc=edu,dc=hk'; %% my $e = Net::LDAP::Entry->new( $dn ); %% $e->add( cn => 'HP5000-A204e' ); %% $e->add( %% objectClass => 'device', %% description => 'Printer in A204e', %% ); %% $r = $ldap->add( $e ); %% \end{verbatim} %% } {\footnotesize \begin{verbatim} my $dn = 'ou=devices,dc=tyict,dc=vtc,dc=edu,dc=hk'; my $entry = Net::LDAP::Entry->new; $entry->dn( $dn ); $entry->add( cn => 'HP5000-A204e' ); $entry->add( objectClass => 'device', description => 'Printer in A204e', ); $mesg = $entry->update( $ldap ); \end{verbatim} } \end{itemize} \end{slide} \begin{slide}{Deleting an Entry} \label{sld:deleting-an-entry} \begin{itemize} \item Can delete an entry by passing a \DN: \begin{verbatim} my $dn = 'ou=dev,dc=tyict,dc=vtc,dc=edu,dc=hk'; my $r = $ldap->delete( $dn ); \end{verbatim} \item \ldots\,or like many Net::LDAP methods, you can pass an entry where a \DN is expected: \begin{verbatim} $entry = find_entry_to_delete(); $r = $ldap->delete( $entry ); \end{verbatim} \end{itemize} \end{slide} \begin{slide}{Modifying an Entry} \label{sld:modifying-an-entry} \ptsize{12} \begin{itemize} \item \texttt{modify} operation has four sub-operations: \begin{description} \item[\texttt{add}] \mbox{} \begin{itemize} \item add new attributes \item add values to existing multivalued attributes \end{itemize} \item[\texttt{delete}] \mbox{} \begin{itemize} \item delete whole attributes \item delete values from within existing attributes \end{itemize} \item[\texttt{replace}] replace attributes or add if necessary \item[\texttt{moddn}] rename an entry under same or different parent \end{description} \end{itemize} \end{slide} \begin{slide}{Modify --- \texttt{add}} \label{sld:modify-add} \ptsize{12} \begin{itemize} \item Add a new attribute, or a new value to an existing multi-valued attribute: \par\medskip\par \begin{verbatim} $r = $ldap->modify( $dn, add => { mail => 'nicku@vtc.edu.hk' } ); \end{verbatim}%$ \item An error is returned if: \begin{itemize} \item the attribute exists and is not multi-valued; \item the attribute exists and is multi-valued and the value already exists; \item the schema does not allow the attribute. \end{itemize} \end{itemize} \end{slide} \begin{slide}{Modify --- \texttt{delete}} \label{sld:modify-delete} \begin{itemize} \item To delete all instances of the attribute in the entry: \begin{verbatim} $r = $ldap->modify( $dn, delete => [ 'mail' ] ); \end{verbatim}%$ \item You can delete specific values: \begin{verbatim} $r = $ldap->modify( $dn, delete => { 'mail' => [ 'nicku@abc.com' ] } ); \end{verbatim}%$ \end{itemize} \end{slide} \begin{slide}{Modify --- \texttt{replace}} \label{sld:modify-replace} \begin{itemize} \item Replace whole attributes: \begin{verbatim} $r = $ldap->modify( $dn, replace => { 'mail' => 'nicku@xyz.com' } ); \end{verbatim}%$ \item Multi-valued: \begin{verbatim} $r = $ldap->modify( $dn, replace => { 'mail' => [ qw(nicku@xyz.com nick@iohk.com) ] } ); \end{verbatim}%$ \end{itemize} \end{slide} \tsection{Encryption} \begin{slide}{Using Start TLS} \label{sld:start-tls} \begin{itemize} \item \LDAP{}v3 supports the \emph{Start TLS} extension \item Allows a client to request that the server begin encrypting traffic with client \item Essential when using simple authentication; avoid password being sent in clear text over the network \item Here is the simplest use, where there is no requirement to store local copies of the certificates, but the identity of the server is not checked: \begin{verbatim} my $r = $ldap->start_tls( verify => 'none' ); \end{verbatim}%$ \item See \texttt{perldoc~Net::LDAP} and \texttt{perldoc~Net::LDAP::Security} for details and examples. \end{itemize} \end{slide} \begin{slide}{References} \label{sld:references} \ptsize{8}% \begin{itemize} \item See the excellent documentation with Net::LDAP: \par\smallskip\par {\scriptsize\setlength{\extrarowheight}{-1pt}% \begin{tabular}{@{}ll@{}} Net::LDAP & Net::LDAP::FAQ \\ Net::LDAP::Constant & Net::LDAP::Filter \\ Net::LDAP::Control & Net::LDAPI \\ Net::LDAP::Control::Paged & Net::LDAP::LDIF \\ Net::LDAP::Control::ProxyAuth & Net::LDAP::Message \\ Net::LDAP::Control::Sort & Net::LDAP::Reference \\ Net::LDAP::Control::SortResult & Net::LDAP::RFC \\ Net::LDAP::Control::VLV & Net::LDAP::RootDSE \\ Net::LDAP::Control::VLVResponse& Net::LDAPS \\ Net::LDAP::DSML & Net::LDAP::Schema \\ Net::LDAP::Entry & Net::LDAP::Search \\ {\red{}Net::LDAP::Examples} & Net::LDAP::Security \\ Net::LDAP::Extra & Net::LDAP::Util \end{tabular}} \item See the web site for Net::LDAP: \url{http://ldap.perl.org/} \item Graham Barr wrote slides on which these notes are based: \url{http://ldap.perl.org/perl-ldap-oscon2001.pdf} \item David N. Blank-Edelman, \emph{Perl for System Administration}, O'Reilly, July 2000, ISBN: 1565926099. \item Gerald Carter, \emph{LDAP System Administration}, O'Reilly, March 2003, ISBN: 1565924916. \item Clayton Donley, \emph{LDAP Programming, Management and Integration}, Manning, 2003, ISBN: 1930110405. \end{itemize} \end{slide} \end{document}