\documentclass{ictlab} % Copyright (c) 2003 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.5 $ \usepackage{verbatim,alltt,key,xr,biganswerbox} \usepackage[hang,bf,nooneline]{caption2} \ifx\pdftexversion\undefined \else \usepackage[pdfpagemode=None,pdfauthor={Nick Urbanik}]{hyperref} \fi \externaldocument[ld-]{../../lectures/ldap/ldap-slides} \externaldocument[lp-]{../../lectures/perl-ldap/perl-ldap} \newcommand*{\labTitle}{Making a Start with the Perl Net::LDAP Assignment} \providecommand*{\SNMP}{\acro{SNMP}\xspace} \providecommand*{\MIB}{\acro{MIB}\xspace} \providecommand*{\ID}{\acro{ID}\xspace} \providecommand*{\OID}{\acro{OID}\xspace} \providecommand*{\USM}{\acro{USM}\xspace} \providecommand*{\VACM}{\acro{VACM}\xspace} \renewcommand{\floatpagefraction}{0.75} % default is .5, to increase % density. \renewcommand*{\bottomfraction}{0.6} % default is 0.3 \renewcommand*{\topfraction}{0.85} % default is 0.7 \renewcommand*{\textfraction}{0.1} % default is 0.2 \begin{document} \section{What to Do} \label{sec:what-to-do} \begin{enumerate} \item Search for your own entry under \texttt{ou=sys,o=ICT} with: \begin{alltt} $ \textbf{ldapsearch -x -h ldap1.tyict.vtc.edu.hk -b 'ou=sys,o=ICT' \bs '(uid=\meta{your student ID})'} \end{alltt}%$ \item Search for your own \texttt{ou} under \texttt{o=ICT} with: \begin{alltt} $ \textbf{ldapsearch -x -h ldap1.tyict.vtc.edu.hk -b 'o=ICT' '(ou=\meta{your student ID})'} \end{alltt}%$ \item Search for the \texttt{People} and \texttt{Group} \texttt{ou}s on \path{ldap1.tyict.vtc.edu.hk} with: \begin{alltt} $ \textbf{ldapsearch -x -s one -h ldap1 -b 'ou=sys,o=ICT' '(ou=*)'} \end{alltt}%$ so that you can look at them and understand what you need to do for the next exercise. \begin{itemize} \item Note: the Windows computers in the labs have \texttt{ldapsearch} also. With this, omit \texttt{-x}. Omit the quotes. This program has no default filter, so to search for all entries in my \texttt{ou}, you could make a search like this: \begin{alltt} C:\bs> \textbf{ldapsearch -s one -h ldap1 -b ou=nicku,o=ICT (objectClass=*)} \end{alltt} \end{itemize} \item Install the \texttt{Term::ReadKey} Perl module like this: \begin{alltt} $ \textbf{sudo perl -MCPAN -e shell} cpan shell -- CPAN exploration and modules installation (v1.7601) ReadLine support enabled cpan> \textbf{install Term::ReadKey} \end{alltt}%$ \item Write a program using \texttt{Net::LDAP} that does the following: \begin{enumerate} \item Creates a new \texttt{Net::LDAP} object by connecting to the \LDAP server \path{ldap1.tyict.vtc.edu.hk} \item Use my code at \sloppypar\url{http://ictlab.tyict.vtc.edu.hk/snm/assignments/assignment-perl-ldap/programs/read_password.pl} to get your password. \item Binds as your \DN: \texttt{uid=\meta{your~student~ID},ou=People,ou=sys,o=ICT}. Your password will be the same as it was on \texttt{ictlab.tyict.vtc.edu.hk} last week. \item Creates an entry \texttt{ou=People,ou=\meta{your~student~ID},o=ICT} \item Creates an entry \texttt{ou=Group,ou=\meta{your~student~ID},o=ICT} \item Update these on the server. \item Add support for \texttt{start\_tls} if you are not using Windows. \end{enumerate} \end{enumerate} \section{How to Pass Parameters? How to\ldots} \label{sec:howto} Some people have asked me, ``Nick, how can I pass parameters to this subroutine?'', where they have shown me a nice subroutine that wants parameters passed to it. Well, here is a simple example; a subroutine that takes a \texttt{NET::LDAP::Entry} object and adds it to a \texttt{Net::LDAP} object: \begin{verbatim} sub add_entry($$) { my ( $ldap, $entry ) = @_; my $mesg = $entry->update( $ldap ); die "cannot add entry: ", $mesg->error if $mesg->code; } \end{verbatim}%$ However, suppose the entry is already in the directory? Do we want our program to die in a screaming heap just because it is already in the directory? No? Well, we can see in \texttt{Net::LDAP::Constant} that there is a constant \texttt{LDAP\_ALREADY\_EXISTS}. We can test \texttt{\$mesg->code} to see if it has that value. As \begin{alltt} $ \textbf{perldoc Net::LDAP::Constant} \end{alltt}%$ tells us, we must import that symbol before we can use it. So we can write this instead if you like: \begin{verbatim} use Net::LDAP qw( LDAP_ALREADY_EXISTS ); sub add_entry($$) { my ( $ldap, $entry ) = @_; my $mesg = $entry->update( $ldap ); if ( $mesg->code == LDAP_ALREADY_EXISTS ) { warn "The entry ", $entry->dn, " already is in the directory\n"; return; } elsif ( $mesg->code ) { die "cannot add entry: ", $mesg->error; } return 1; } \end{verbatim}%$ Note that this function can return and still fail, so we should return a false value if we failed, and a true value if we were successful. The idiom for returning a false value is to just put an empty \texttt{return} statement. This works whether we are expecting an array or a scalar value. The value will be \texttt{undef} in a scalar context, or an empty list in a list context. \subsection{Function Prototypes} \label{sec:function-prototypes} What is the ``\texttt{(\$\$)}'' business in the two function definitions above? In Perl, these are called \emph{function prototypes}, although they are different from function prototypes in C or \Cpp. If a function prototype appears before you call the function, then (in this case), there will be a compile-time error if the function is called with anything other than two scalar parameters. It also means that you can omit the parentheses after the function name in the function call, since Perl knows exactly how many parameters to expect. There are some other benefits to using function prototypes in Perl\@. Read \begin{alltt} $ \textbf{perldoc perlsub} \end{alltt}%$ for more about them. \end{document}