\documentclass{ictlab}

% Copyright (c) 2003 by Nick Urbanik <nicku(at)nicku.org>.
% 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://nicku.org/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{nicku.org} 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}
