|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T q
Length: 43175 (0xa8a7) Types: TextFile Names: »q-operations.tex«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/doc/manual/q-operations.tex«
% run this through LaTeX with the appropriate wrapper \f \chapter {The Procedural DUA} \label{DUA:proc} The \man libdsap(3n) library defines a set of procedure calls which correspond to each of the X.500 abstract operations. This chapter describes those procedure calls. \f \section {Procedure Model} \label{proc_model} Each operation is accessed via a procedure call of the same name as the operation, prefixed by ``\verb"ds_"''. The procedure is supplied an argument structure, and returns either an error or result structure. For example the \verb"read" operation is invoked by calling \verb"ds_read (argument,error,result)". The return value of the procedures have the following common values, which indicated whether an error or result is returned:- \begin{describe} \item [\verb"DS\_OK":] Operation completed successfully, the result structure will have the corresponding result (if the operation generates results). \item [\verb"DS\_ERROR\_LOCAL":] Error within the DUA module. \item [\verb"DS\_ERROR\_CONNECT":] Failed to connect to a remote DSA. \item [\verb"DS\_ERROR\_PROVIDER":] Other OSI provider error. \item [\verb"DS\_ERROR\_REMOTE":] Remote error. Further details will be in the error parameter in the procedure call. \item [\verb"DS\_X500\_ERROR":] This is the same as \verb"DS_ERROR_REMOTE". \end{describe} These values defined in \file{quipu/ds\_error.h}, which must be included in your program (there are other return values defined here, but these should only occur within the DSA, and should not be returned by a DUA call). \f \section {Common Parameters} All of the DAP operations described in Sections \ref{dap:bind} to \ref{modifyrdn} have certain common parameters in their arguments and results. These structures are now described. \subsection {Arguments} \label{common_args} The common arguments are represented by the following structure:- \begin{quote}\index{CommonArgs}\small\begin{verbatim} typedef struct common_args { ServiceControl ca_servicecontrol; DN ca_requestor; struct op_progress ca_progress; int ca_aliased_rdns; #define CA_NO_ALIASDEREFERENCED -1 struct security_parms * ca_security; struct signature * ca_sig; struct extension * ca_ext; } CommonArgs; \end{verbatim}\end{quote} The fields \verb"ca_ext", \verb"ca_progress", \verb"ca_requestor" and \verb"ca_aliased_rdns" are provided as they are defined within X.500. Neither the QUIPU DSA or DUA use these fields. The field \verb"ca_servicecontrol" is used to select the type of service the DSA should provide, the structure is given below \begin{quote}\index{ServiceControl}\small\begin{verbatim} typedef struct svccontrol { int svc_options; #define SVC_OPT_PREFERCHAIN 0X001 #define SVC_OPT_CHAININGPROHIBIT 0X002 #define SVC_OPT_LOCALSCOPE 0X004 #define SVC_OPT_DONTUSECOPY 0X008 #define SVC_OPT_DONTDERFERERENCEALIAS 0X010 char svc_prio; #define SVC_PRIO_LOW 0 #define SVC_PRIO_MED 1 #define SVC_PRIO_HIGH 2 int svc_timelimit; #define SVC_NOTIMELIMIT -1 int svc_sizelimit; #define SVC_NOSIZELIMIT -1 int svc_scopeofreferral; #define SVC_REFSCOPE_NONE -1 #define SVC_REFSCOPE_DMD 0 #define SVC_REFSCOPE_COUNTRY 1 } svccontrol, ServiceControl; \end{verbatim}\end{quote} The values takes by each field within the ServiceControl structure are described in full in \cite{CCITT.Directory}. \subsection {Results} \label{common_results} \begin{quote}\index{CommonResults}\small\begin{verbatim} typedef struct common_results { DN cr_requestor; char cr_aliasdereferenced; } common_results, CommonResults; \end{verbatim}\end{quote} The filed \verb"cr_aliasdereferenced" is set to \verb"TRUE" if the base object of the operation was an alias, and was dereferenced. The field \verb"cr_requestor" is provided as it is are defined within X.500. Neither the QUIPU DSA or DUA use this field. \section {Continuation References} \label{cont_ref} ``Continuation References'' are returned by the directory when the operation asked for could not be fully completed, in which case the structure \verb"ContinuationRef" is returned as part of the error or results structures. The structure is explained below:- \begin{quote}\index{ContinuationRef}\small\begin{verbatim} typedef struct continuation_ref { DN cr_name; struct op_progress cr_progress; int cr_rdn_resolved; #define CR_RDNRESOLVED_NOTDEFINED -1 int cr_aliasedRDNs; #define CR_NOALIASEDRDNS -1 int cr_reftype; #define RT_UNDEFINED -1 #define RT_SUPERIOR 1 #define RT_SUBORDINATE 2 #define RT_CROSS 3 #define RT_NONSPECIFICSUBORDINATE 4 struct access_point * cr_accesspoints; struct continuation_ref *cr_next; }continuation_ref, *ContinuationRef; \end{verbatim}\end{quote} \begin{describe} \item [\verb"cr\_name":] The DN that has only been partially explored. \item [\verb"cr\_rdn\_resolved":] The number of RDNs in the name that have been examined --- hence how far down the DIT the query has been taken. \item [\verb"cr\_aliasedRDNs":] If \verb"TRUE" then some of the RDNs were aliases. \item [\verb"cr\_reftype":] The type of reference that was used to get this information. \item [\verb"cr\_accesspoints":] The access point of the DSA to contact\footnote{The was an \verb+access\_point+, not \verb+access\_point *+ in ISODE-5.0.}. The structure for an access point is as follows:- \begin{quote}\index{access\_point}\small\begin{verbatim} struct access_point { DN ap_name; struct PSAPaddr *ap_address; struct access_point *ap_next; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"ap\_name":] The DN of the DSA to contact. \item [\verb"ap\_address":] The address of the DSA (derivable from the name)\footnote{The was an \verb+PSAPaddr+, not \verb+PSAPaddr *+ in ISODE-5.0.}. \item [\verb"ap\_next":] There may be more than one access point, hence they form a linked list structure. \end{describe} \item [\verb"cr\_next":] There may be more than one access point, if so they form a linked list structure. \end{describe} \f \section {Errors} All DAP operations return a common error structure, which maps closely onto the service definitions. An error is only returned if the operation failed, if successful (indicated by the return value DS\_OK) the error structure returned is undefined. \begin{quote}\index{DSError}\small\begin{verbatim} struct DSError { int dse_type; #define DSE_LOCALERROR -2 #define DSE_REMOTEERROR -1 #define DSE_NOERROR 0 #define DSE_ATTRIBUTEERROR 1 #define DSE_NAMEERROR 2 #define DSE_SERVICEERROR 3 #define DSE_REFERRAL 4 #define DSE_ABANDONED 5 #define DSE_SECURITYERROR 6 #define DSE_ABANDON_FAILED 7 #define DSE_UPDATEERROR 8 #define DSE_DSAREFERRAL 9 union { struct DSE_attribute dse_un_attribute; struct DSE_name dse_un_name; struct DSE_service dse_un_service; struct DSE_referral dse_un_referral; struct DSE_abandon_fail dse_un_abandon_fail; struct DSE_security dse_un_security; struct DSE_update dse_un_update; } dse_un; }; \end{verbatim}\end{quote} The field \verb"dse_type" is used to indicate what sort of error has occurred, and hence which structure from the union is used. The value \verb"DSE_LOCALERROR" is used to indicate that the error came from within the DUA, there is no associated structure in the union for this error. The value \verb"DSE_REMOTEERROR" is used to indicate that an error occurred at the DSA end, and the request was rejected, again there is no associated structure in the union for this error. The structures in the union for the other error conditions are as described in the following Sections. \subsection{Attribute Error} \begin{quote}\small\begin{verbatim} struct DSE_attribute { DN DSE_at_name; struct DSE_at_problem DSE_at_plist; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"DSE\_at\_name":] The name of the entry causing the error. \item [\verb"DSE\_at\_plist":] A list of the errors:- \begin{quote}\small\begin{verbatim} struct DSE_at_problem { int DSE_at_what; #define DSE_AT_NOSUCHATTRIBUTE 1 #define DSE_AT_INVALIDATTRIBUTESYNTAX 2 #define DSE_AT_UNDEFINEDATTRIBUTETYPE 3 #define DSE_AT_INAPPROPRIATEMATCHING 4 #define DSE_AT_CONSTRAINTVIOLATION 5 #define DSE_AT_TYPEORVALUEEXISTS 6 AttributeType DSE_at_type; AttributeValue DSE_at_value; struct DSE_at_problem * dse_at_next; }; #define DSE_AT_NOPROBLEM ((struct DSE_at_problem*)0) \end{verbatim}\end{quote} The fields are used as follows:- \begin{describe} \item [\verb"DSE\_at\_what":] Indicates which error has occurred. \item [\verb"DSE\_at\_type":] The attribute type causing the error. \item [\verb"DSE\_at\_value":] The associated value (if any). \item [\verb"dse\_at\_next":] There may be more than one such error --- if so they form a linked list. \end{describe} \end{describe} \subsection{Name Error} \begin{quote}\small\begin{verbatim} struct DSE_name { int DSE_na_problem; #define DSE_NA_NOSUCHOBJECT 1 #define DSE_NA_ALIASPROBLEM 2 #define DSE_NA_INVALIDATTRIBIBUTESYNTAX 3 #define DSE_NA_ALIASDEREFERENCE 4 DN DSE_na_matched; }; \end{verbatim}\end{quote} \verb"DSE_na_matched" is the part of the DN successfully matched. \subsection{Referral Errors} \begin{quote}\small\begin{verbatim} struct DSE_referral { ContininuationRef DSE_ref_candidates; DN DSE_ref_prefix; }; \end{verbatim}\end{quote} The continuation reference supplies information on how the continue the query. The structure is described in Section~\ref{cont_ref} The field \verb"DSE_ref_prefix" is for DSP only. Quipu-6.0 will, due to enhanced security, issue more ``referrals'' than Quipu-5.0. You should now generally chase such referrals. \subsection{Security Error} \label{error_sec} \begin{quote}\small\begin{verbatim} struct DSE_security { int DSE_sc_problem; #define DSE_SC_AUTHENTICATION 1 #define DSE_SC_INVALIDCREDENTIALS 2 #define DSE_SC_ACCESSRIGHTS 3 #define DSE_SC_INVALIDSIGNATURE 4 #define DSE_SC_PROTECTIONREQUIRED 5 #define DSE_SC_NOINFORMATION 6 }; \end{verbatim}\end{quote} \subsection{Service Error} \label{error_ser} \begin{quote}\small\begin{verbatim} struct DSE_service { int DSE_sv_problem; #define DSE_SV_BUSY 1 #define DSE_SV_UNAVAILABLE 2 #define DSE_SV_UNWILLINGTOPERFORM 3 #define DSE_SV_CHAININGREQUIRED 4 #define DSE_SV_UNABLETOPROCEED 5 #define DSE_SV_INVALIDREFERENCE 6 #define DSE_SV_TIMELIMITEXCEEDED 7 #define DSE_SV_ADMINLIMITEXCEEDED 8 #define DSE_SV_LOOPDETECT 9 #define DSE_SV_UNAVAILABLECRITICALEXTENSION 10 #define DSE_SV_OUTOFSCOPE 11 #define DSE_SV_DITERROR 12 }; \end{verbatim}\end{quote} \subsection{Update Error} \begin{quote}\small\begin{verbatim} struct DSE_update { int DSE_up_problem; #define DSE_UP_NAMINGVIOLATION 1 #define DSE_UP_OBJECTCLASSVIOLATION 2 #define DSE_UP_NOTONNONLEAF 3 #define DSE_UP_NOTONRDN 4 #define DSE_UP_ALREADYEXISTS 5 #define DSE_UP_AFFECTSMULTIPLEDSAS 6 #define DSE_UP_NOOBJECTCLASSMODS 7 }; \end{verbatim}\end{quote} \subsection{Abandon Failure} If an abandon operation fails then the following is used:- \begin{quote}\small\begin{verbatim} struct DSE_abandon_fail { int DSE_ab_problem; #define DSE_AB_NOSUCHOPERATION 1 #define DSE_AB_TOOLATE 2 #define DSE_AB_CANNOTABANDON 3 int DSE_ab_invokeid; }; \end{verbatim}\end{quote} \subsection {Error Handling Procedures} The \man libdsap(3n) library has three routines for handling errors. \begin{quote}\index{ds\_error}\small\begin{verbatim} ds_error (ps,error) PS ps; struct DSError * error; \end{verbatim}\end{quote} This routine will take the error, and pretty-print the contents to the PStream \verb"ps". \begin{quote}\index{log\_ds\_error}\small\begin{verbatim} log_ds_error (error) struct DSError * error; \end{verbatim}\end{quote} This routine will take the error, print a simple message in ``dsap\_log'' at ``LLOG\_EXCEPTIONS'' logging level, and a more detailed report at ``LLOG\_TRACE'' logging level. \begin{quote}\small\begin{verbatim} ds_error_free (err) struct DSError * err; \end{verbatim}\end{quote} This frees the embedded structures within the error structure, BUT NOT \verb"DSError" itself. \f \section {Binding and Unbinding} \label{dap:bind} Before operations may be invoked, the DUA must BIND to the DSA. The \verb"bind" procedure \begin{quote}\index{secure\_ds\_bind}\small\begin{verbatim} secure_ds_bind (arg, error, result) struct ds_bind_arg * arg; struct ds_bind_arg * result; struct ds_bind_error * error; \end{verbatim}\end{quote} is used for this purpose. You will need to include \file{quipu/bind.h} to use this procedure. The \verb"ds_bind_arg" structure is defined as follows. \begin{quote}\small\begin{verbatim} struct ds_bind_arg { int dba_version; #define DBA_VERSION_V1988 0x001 int dba_auth_type; #define DBA_AUTH_EXTERNAL -1 #define DBA_AUTH_NONE 0 #define DBA_AUTH_SIMPLE 1 #define DBA_AUTH_PROTECTED 2 #define DBA_AUTH_STRONG 3 char *dba_time1; char *dba_time2; struct random_number dba_r1; struct random_number dba_r2; DN dba_dn; int dba_passwd_len; #define DBA_MAX_PASSWD_LEN 512 char dba_passwd[DBA_MAX_PASSWD_LEN]; struct signature *dba_sig; struct certificate_list *dba_cpath; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"dba\_version":] should always be set to \verb"DBA_VERSION_V1988". \item [\verb"dsa\_auth\_type":] is used to select the type of authentication required. \item [\verb"dba\_dn":] is the name of the entity you wish to bind as, this can be \verb"NULLDN" if you only require access to ``publically readable'' information. \item [\verb"dba\_passwd":] The password required to bind as the entity. This will be checked against the ``userPassword'' attribute in the entity. \item [\verb"dba\_passwd\_len"] The length of the string in \verb"dsa_passwd". \item [\verb"dba\_sig"] The strong authentication signature (must be provided if strong authentication is used). \item [\verb"dba\_cpath"] The strong authentication certification path (optional). \item [\verb"dba\_time1"] Used for protected and strong authentication. \item [\verb"dba\_time2"] Optionally used for protected simple authentication. \item [\verb"dba\_r1"] Random number used for protected and strong authentication. \item [\verb"dba\_r2"] Optionally used for protected simple authentication. \end{describe} The \verb"bind" operation will try to connect to the DSA, whose address is defined in the external \verb"char *", ``\verb"dsa_address"'', the syntax of the string is that of an ISODE PSAP address. If \verb"secure_ds_bind()" returns \verb"DS_OK", then you have a successful connection, otherwise a \verb"ds_bind_error" structure will inform you of the error condition. \begin{quote}\small\begin{verbatim} struct ds_bind_error { int dbe_version; char dbe_type; #define DBE_TYPE_SERVICE 0 #define DBE_TYPE_SECURITY 1 int dbe_value; }; \end{verbatim}\end{quote} The filed \verb"dbe_value" takes a value as defined for a \verb"DSE_security" or \verb"DSE_service" error shown in Sections \ref{error_sec} and \ref{error_ser}. \subsection{No Authentication} To bind without using any authentication, \verb+dsa_auth_type+ should be set to \verb+DBA_AUTH_NONE+. The fields \verb+dba_version+ and \verb+dba_dn+ must be filled in. \subsection{Simple Authentication} To bind using simple authentication, the \verb+dsa_auth_type+ field should be set to the value \verb+DBA_AUTH_SIMPLE+. The fields \verb+dba_version+, \verb+dba_dn+, \verb+dba_passwd+ and \verb+dba_passwd_len+ must be filled in. For backwards compatibility the routine \begin{quote}\index{ds\_bind}\small\begin{verbatim} ds_bind (arg, error, result) struct ds_bind_arg * arg; struct ds_bind_arg * result; struct ds_bind_error * error; \end{verbatim}\end{quote} is still supplied, and gives you a unprotected simple bind request. \subsection{Protected Simple Authentication} To bind using protected simple authentication, the \verb+dsa_auth_type+ field should be set to to the value \verb+DBA_AUTH_PROTECTED+. The fields \verb+dba_version+, \verb+dba_dn+, \verb+dba_time1+, \verb+dba_r1+, \verb+dba_passwd+ and \verb+dba_passwd_len+ must be filled in. The fields \verb+dba_time2+ and \verb+dba_r2+ must be either filled in or set to \verb+NULL+. \subsection{Strong Authentication} To bind using strong authentication, the \verb+dsa_auth_type+ field should be set to the value \verb+DBA_AUTH_STRONG+. The fields \verb+dba_version+, \verb+dba_dn+, \verb+dba_time1+, \verb+dba_r1+, and \verb+dba_sig+ must be filled in. The field \verb+dba_cpath+ must be either filled in or set to \verb+NULL+. \section{Unbind} The unbind operation has no parameters. \begin{quote}\index{ds\_unbind}\small\begin{verbatim} ds_unbind () \end{verbatim}\end{quote} and is used to disconnect from the directory. \f \section {Read} The read operation is used to access information from a particular entity in the DSA. \begin{quote}\index{ds\_read}\small\begin{verbatim} ds_read (arg, error, result) struct ds_read_arg * arg; struct ds_read_result * result; struct DSError * error; \end{verbatim}\end{quote} You will need to include \file{quipu/read.h} to use this procedure. The argument \verb"ds_read_arg" is used to formulate the DAP request:- \begin{quote}\small\begin{verbatim} struct ds_read_arg { CommonArgs rda_common; DN rda_object; EntryInfoSelection rda_eis; }; \end{verbatim}\end{quote} The parameters are used as follows:- \begin{describe} \item [\verb"rda\_common":] The common arguments as described in Section~\ref{common_args} \item [\verb"rda\_object":] The DN of the object you want to read \item [\verb"rda\_eis":] The ``Entry Information Selection'', which defines which attributes you want to be returned, this is defined in Section~\ref{eis} \end{describe} The results returned on a \verb"DS_OK" return form the structure shown below:- \begin{quote}\small\begin{verbatim} struct ds_read_result { CommonResults rdr_common; EntryInfo rdr_entry; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"rdr\_common":] The common results as described in Section~\ref{common_results} \item [\verb"rdr\_entry":] The ``Entry Information'', which contains the attributes you requested. The structure is defined in Section~\ref{einfo}. \end{describe} \subsection {Entry Information Selection} \label{eis} Operations that return an Entry Information structure, will have an ``Entry Information Selection'' in their arguments to specify exactly what the DSA should return. The structure is represented thus:- \begin{quote}\index{EntryInfoSelection}\small\begin{verbatim} typedef struct { char eis_allattributes; Attr_Sequence eis_select; char eis_infotypes; #define EIS_ATTRIBUTETYPESONLY 0 #define EIS_ATTRIBUTESANDVALUES 1 } EntryInfoSelection; \end{verbatim}\end{quote} The parameters are used as follows:- \begin{describe} \item [\verb"eis\_allattributes":] If \verb"TRUE" the all attributes are required. \item [\verb"eis\_select":] If \verb"eis_allattributes" is \verb"FALSE" then this field is used to specify the attributes you want. ONLY the attribute types of this structure need to be set, any attribute values will be ignored. \item [\verb"eis\_infotypes":] If \verb"EIS_ATTRIBUTETYPESONLY" is set, then only attribute types will be returned, otherwise the values will also be returned. \end{describe} \subsection {Entry Information} \label{einfo} The structure ``Entry Information'' is used by some of the operations to return data to the DUA. \begin{quote}\index{EntryInfo}\small\begin{verbatim} typedef struct entrystruct { DN ent_dn; Attr_Sequence ent_attr; int ent_iscopy; #define INFO_MASTER 0x000 #define INFO_COPY 0x001 #define INFO_CACHE 0x002 time_t ent_age; struct entrystruct *ent_next; } entrystruct, EntryInfo; \end{verbatim}\end{quote} The parameters are used as follows:- \begin{describe} \item [\verb"ent\_dn":] The DN of the entry. \item [\verb"ent\_attr":] The requested attributes of the requested entry. \item [\verb"ent\_iscopy":] This is either \verb"INFO_MASTER" or \verb"INFO_COPY" indicating whether master data or copied data was used to generate the results. \verb"INFO_CACHE" is not applicable to a DUA. \item [\verb"ent\_age":] This field is for DSA use only. \item [\verb"ent\_next":] There may be many results, this is used to link them. \end{describe} NOTE, the fields \verb"ent_dn" and \verb"ent_attr" will only be partially decoded when this structure is returned. You should call the routines \verb"dn_decode()" and \verb"as_decode()" described in Section~\ref{quipu_conv} if you want to use the structures fully decoded. \f \section {Compare} The compare operation is used to compare an asserted attribute, with an attribute in the directory. \begin{quote}\index{ds\_compare}\small\begin{verbatim} ds_compare (arg, error, result) struct ds_compare_arg * arg; struct ds_compare_result * result; struct DSError * error; \end{verbatim}\end{quote} You will need to include \file{quipu/compare.h} to use this procedure. The argument is as follows:- \begin{quote}\small\begin{verbatim} struct ds_compare_arg { CommonArgs cma_common; DN cma_object; AVA cma_purported; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"cma\_common":] The common arguments as described in Section~\ref{common_args}. \item [\verb"cma\_object":] The DN of the object you want to attribute against. \item [\verb"cma\_purported":] The attribute you want to compare. This structure is defined in Section~\ref{ava}. \end{describe} If successful, the result structure is as follows:- \begin{quote}\small\begin{verbatim} struct ds_compare_result { CommonResults cmr_common; DN cmr_object; char cmr_matched; char cmr_iscopy; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"cmr\_common":] The common results as described in Section~\ref{common_results}. \item [\verb"cmr\_object":] The DN of the entry the attribute was compared against. This may not be the same as the DN supplied in the argument (e.g., if an alias was dereferenced). \item [\verb"cmr\_matched":] If \verb"TRUE" then the attributes were the same, otherwise they were different. \item [\verb"cmr\_iscopy":] If \verb"TRUE" then the compare took place against a copy of the attribute. \end{describe} \subsection {Attribute Value Assertion} \label{ava} An ``Attribute Value Assertion'' is used by some of the operations to specify an attribute type/value pair, the structure used in this case is shown below. \begin{quote}\index{AVA}\small\begin{verbatim} typedef struct { AttributeType ava_type; AttributeValue ava_value; }AVA; \end{verbatim}\end{quote} \f \section {List} The list operation is show below. This returns a list of subordinates of the specified entry. \begin{quote}\index{ds\_list}\small\begin{verbatim} ds_list (arg, error, result) struct ds_list_arg * arg; struct ds_list_result * result; struct DSError * error; \end{verbatim}\end{quote} You will need to include \file{quipu/list.h} to use this procedure. \begin{quote}\small\begin{verbatim} struct ds_list_arg { CommonArgs lsa_common; DN lsa_object; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"lsa\_common":] The common arguments as described in Section~\ref{common_args}. \item [\verb"lsa\_object":] The DN of the object you want to list the children of. \end{describe} The results of a successful list form the following structure:- \begin{quote}\small\begin{verbatim} struct ds_list_result { CommonResults lsr_common; DN lsr_object; int lsr_copy; struct subordinate * lsr_subordinates; int lsr_limitproblem; #define LSR_NOLIMITPROBLEM 0 #define LSR_TIMELIMITEXCEEDED 1 #define LSR_SIZELIMITEXCEEDED 2 #define LSR_ADMINSIZEEXCEEDED 3 ContinuationRef lsr_cr; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"lsr\_common":] The common results as described in Section~\ref{common_results}. \item [\verb"lsr\_object":]The DN of the entry whose children were listed. This may not be the same as the DN supplied in the argument (e.g., if an alias was dereferenced). \item [\verb"lsr\_copy":] If \verb"TRUE" then the list took place against a copy of the object. \item [\verb"lsr\_subordinates":] This structure contains the RDNs that were found below the base object. The structure is as follows:- \begin{quote}\small\begin{verbatim} struct subordinate { RDN sub_rdn; char sub_aliasentry; struct subordinate * sub_next; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"sub\_rdn":] The RDN of this child. \item [\verb"sub\_aliasentry":] If \verb"TRUE" then it is an alias entry. \item [\verb"sub\_next":] A pointer to the next element in the list. \end{describe} \item [\verb"lsr\_limitproblem":] If NON zero, then the specified limit problem occurred during the operation. \item [\verb"lsr\_cr":] A list of continuation references. Continuation References are described in Section~\ref{cont_ref}. \end{describe} \f \section {Search} \label{proc_search} The search operation performs a key Directory functionality. This is done on the basis of filters as described in Section~\ref{filters} below The operation is defined as:- \begin{quote}\index{ds\_search}\small\begin{verbatim} ds_search (arg, error, result) struct ds_search_arg * arg; struct ds_search_result * result; struct DSError * error; \end{verbatim}\end{quote} You will need to include \file{quipu/ds\_search.h} to use this procedure. \begin{quote}\small\begin{verbatim} struct ds_search_arg { CommonArgs sra_common; DN sra_baseobject; int sra_subset; #define SRA_BASEOBJECT 0 #define SRA_ONELEVEL 1 #define SRA_WHOLESUBTREE 2 Filter sra_filter; char sra_searchalias; EntryInfoSelection sra_eis; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"sra\_common":] The common arguments as described in Section~\ref{common_args}. \item [\verb"sra\_baseobject":] The DN of the object you want to start the search from. \item [\verb"sra\_subset":] This specifies which part of the DIT to search. \item [\verb"sra\_filter":] The filter to apply to the searched entries to see if the entry is required. Filters are discussed in Section~\ref{filters} \item [\verb"sra\_searchalias":] If \verb+TRUE+ aliases encountered below the search baseobject are dereferenced, and the dereferenced object searched. Note how this is different to the service control ``\verb+dontderferencealiases+ which is used to control dereferencing of entities above the base object. \item [\verb"sra\_eis":] The ``Entry Information Selection'', which defines which attributes you want to be returned (if the filter is matched), this is defined in Section \ref{eis}. \end{describe} The results form the following structure:- \begin{quote}\small\begin{verbatim} struct ds_search_result { char srr_correlated; union { struct ds_search_unit * srr_unit; struct ds_search_result * srr_parts; } srr_un; struct ds_search_result * srr_next; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"srr\_correlated":] If \verb"TRUE" the the results are said to be correlated, that is, there will only be one element in the list of search results. A DSA may return uncorrelated result, in which case the routine \begin{quote}\index{correlate\_search\_results}\small\begin{verbatim} correlate_search_results(sr_res) struct ds_search_result * sr_res; \end{verbatim}\end{quote} can be called, which will correlate the results. NOTE QUIPU DSAs will always return correlated results. \item [\verb"srr\_un":] If the results are uncorrelated then the union will contain a nested \verb"ds_search_result" structure, which contains a list of the uncorrelated results. If the results are correlated, then this union will contain a pointer to the correlated results. These form the structure \begin{quote}\small\begin{verbatim} struct ds_search_unit { CommonResults srr_common; DN srr_object; EntryInfo * srr_entries; int srr_limitproblem; ContinuationRef srr_cr; }; #define CSR_common srr_un.srr_unit->srr_common #define CSR_object srr_un.srr_unit->srr_object #define CSR_entries srr_un.srr_unit->srr_entries #define CSR_limitproblem srr_un.srr_unit->\ srr_limitproblem #define CSR_cr srr_un.srr_unit->srr_cr \end{verbatim}\end{quote} NOTE the \verb"#define"s to access the elements of this structure. The fields are used as follows: \begin{describe} \item [\verb"srr\_common":] The common results as described in \ref{common_results}. \item [\verb"srr\_object":] The DN of the entry used as the base object of the search. This may not be the same as the DN supplied in the argument (e.g., if an alias was dereferenced). \item [\verb"srr\_entries":] The ``Entry Information'', which contains the attributes you requested. The structure is defined in Section \ref{einfo}. \item [\verb"srr\_limitproblem":] If NON zero, then the specified limit problem occurred during the operation. \item [\verb"srr\_cr":] A list of continuation references. Continuation References are described in Section~\ref{cont_ref}. \end{describe} \item [\verb"srr\_next":] This is a pointer to the next result in a list of uncorrelated results. \end{describe} \subsection {Filters} \label{filters} A filter in its simplest sense is a single \verb"filter_item". This is used to perform one of six basic tests on one attribute of an entry. If the ``match'' is good, then the entry is returned as part of the search result structure. The six basic types of \verb"filter_item" are represented by the structure below:- \begin{quote}\index{filter\_item}\small\begin{verbatim} struct filter_item { int fi_type; #define FILTERITEM_EQUALITY 0 #define FILTERITEM_SUBSTRINGS 1 #define FILTERITEM_GREATEROREQUAL 2 #define FILTERITEM_LESSOREQUAL 3 #define FILTERITEM_PRESENT 4 #define FILTERITEM_APPROX 5 union { AttributeType fi_un_type; AVA fi_un_ava; Filter_Substrings fi_un_substrings; } fi_un; IFP fi_ifp; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"fi\_type":] Defines the type of \verb"filter_item" being represented. \item [\verb"fi\_un.fi\_un\_type":] \verb"FILTERITEM_PRESENT" matches, just supply an AttributeType, an entry matches if this attribute exists within the entry. \item [\verb"fi\_un.fi\_un\_ava":] \verb"FILTERITEM_EQUALITY", \verb"FILTERITEM_GREATEROREQUAL", \verb"FILTERITEM_LESSOREQUAL", and \verb"FILTERITEM_APPROX" searches all take an AVA (Attribute Value Assertion) structure, and return the entries for which the attribute in the entry matches the asserted value. The AVA structure is defined in Section~\ref{ava}. \item [\verb"fi\_un.un\_substrings":] \verb"FILTERITEM_SUBSTRING" matches, use the substring structure defined below, to specify which substrings to look for in the appropriate attribute. \begin{quote}\small\begin{verbatim} typedef struct { AttributeType fi_sub_type; AV_Sequence fi_sub_initial; AV_Sequence fi_sub_any; AV_Sequence fi_sub_final; } Filter_Substrings; \end{verbatim}\end{quote} The \verb"AV_Sequence" structure is used to represent a string, and should be treated as essentially a linked list of \verb"char *" parameters. \begin{describe} \item [\verb"fi\_sub\_type":] The attribute that you want to perform a substring search on. \item [\verb"fi\_sub\_initial":] This contains a single attribute value, that must appear at the start of the string. \item [\verb"fi\_sub\_any":] A set of values, which must appear in order in the middle of the string. \item [\verb"fi\_sun\_final":] This contains a single attribute value, that must appear at the end of the string. \end{describe} \item [\verb"fi\_ifp":] For DSA use only. \end{describe} The single filter items can now be linked into a \verb"filter" structure to build more complex search definitions:- \begin{quote}\index{filter}\small\begin{verbatim} typedef struct filter { char flt_type; #define FILTER_ITEM 0 #define FILTER_AND 1 #define FILTER_OR 2 #define FILTER_NOT 3 struct filter * flt_next; union { struct filter_item flt_un_item; struct filter * flt_un_filter; } flt_un; }filter, *Filter; \end{verbatim}\end{quote} \begin{describe} \item [\verb"flt\_type":] This defines whether the filter is a single item, or a more complex filter made up of one or more components. \item [\verb"flt\_un.flt\_un\_item":] If the filter represents a \verb"filter_item", then the item is placed here. \item [\verb"flt\_un.flt\_un\_filter":] \verb"AND", \verb"OR" and \verb"NOT" filters apply to a linked list of ``children'' filters. This element is a pointer to the head of that list. \item [\verb"flt\_next":] If the parent filter is an \verb"AND", \verb"OR". or \verb"NOT" filter, then the component filters are linked using this field. NOTE that \verb"NOT" filters should contain a list of one child only. \end{describe} As an example, lets us consider a filter to represent a person whose name is either ``Robbins'' OR ( ``Steve'' AND ``Kille'' ). The structure would look something like:- \begin{small} \begin{verbatim} flt_type = FILTER_OR - The filter is an OR filter flt_un_filter.flt_type = FILTER_ITEM - First component or the OR is an item flt_un_filter.flt_un_item = filter_item (Robbins) - The item should match "robbins" flt_un_filter.flt_next->flt_type = FILTER_AND - Second component or the OR is an AND filter flt_un_filter.flt_next->flt_un_filter.flt_type = FILTER_ITEM - First component or the AND is an item flt_un_filter.flt_next->flt_un_filter.flt_un_item = filter_item (Steve) - The item should match "Steve" flt_un_filter.flt_next->flt_un_filter.flt_next->flt_type = FILTER_ITEM - Second component or the AND is an item flt_un_filter.flt_next->flt_un_filter.flt_next->flt_un_item = filter_item (Kille) - The item should match "Kille" \end{verbatim} \end{small} \f \section {Modification Operations}\label{mod-op} There are 4 operations available to modify the directory. NOTE: with Quipu-6.0 DSA's modify operations are only allowed over DAP, attempts to modify over DSP will return referral errors. \subsection {Add} To add an entry to the DIT use \begin{quote}\index{ds\_addentry}\small\begin{verbatim} ds_addentry (arg, error) struct ds_addentry_arg * arg; struct DSError * error; \end{verbatim}\end{quote} You will need to include \file{quipu/add.h} to use this procedure. The argument you must supply is made up as follows:- \begin{quote}\small\begin{verbatim} struct ds_addentry_arg { CommonArgs ada_common; DN ada_object; Attr_Sequence ada_entry; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"ada\_common":] The common arguments as described in \ref{common_args}. \item [\verb"ada\_object":] The DN of the object you want to add. \item [\verb"ada\_entry":] The attributes you want to add for this entry. This must contain the RDN of the entry, and an ``objectclass'' attribute. Then, the other attribute MUST conform to the set of ``optional'' and ``mandatory'' attribute for that object class. \end{describe} \subsection {Remove} This is used to remove an entry from the DIT. Only leaf entries can be removed. \begin{quote}\index{ds\_removeentry}\small\begin{verbatim} ds_removeentry (arg, error) struct ds_removeentry_arg * arg; struct DSError * error; \end{verbatim}\end{quote} You will need to include \file{quipu/remove.h} to use this procedure. The argument you must supply is made up as follows:- \begin{quote}\small\begin{verbatim} struct ds_removeentry_arg { CommonArgs rma_common; DN rma_object; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"rma\_common":] The common arguments as described in \ref{common_args}. \item [\verb"rma\_object":] The DN of the object you want to remove. \end{describe} \subsection {Modify} \verb"ModifyEntry" is used to modify the attributes of the specified entry. There are strong restrictions on this operation as required by X.500. Invalid operations result in errors, and as such none of the requested modifications are made. To modify an attribute you must first \verb"remove" it then \verb"add" a new attribute. You can not modify the RDN, you must use the \verb"ModifyRDN" operation described in Section~\ref{modifyrdn} to do this. \begin{quote}\index{ds\_modifyentry}\small\begin{verbatim} ds_modifyentry (arg, error) struct ds_modifyentry_arg * arg; struct DSError * error; \end{verbatim}\end{quote} You will need to include \file{quipu/modify.h} to use this procedure. The argument you must supply is made up as follows:- \begin{quote}\small\begin{verbatim} struct ds_modifyentry_arg { CommonArgs mea_common; DN mea_object; struct entrymod * mea_changes; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"mea\_common":] The common arguments as described in \ref{common_args}. \item [\verb"mea\_object":] The DN of the object you want to modify. \item [\verb"mea\_changes":] A tree structure defining the changes you want to make to the entry. \begin{quote}\index{entrymod}\small\begin{verbatim} struct entrymod { int em_type; #define EM_ADDATTRIBUTE 0 #define EM_REMOVEATTRIBUTE 1 #define EM_ADDVALUES 2 #define EM_REMOVEVALUES 3 Attr_Sequence em_what; struct entrymod * em_next; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"em\_type":] The type of modification this is. \item [\verb"em\_what":] The attribute you want to add or remove. If the operation type is remove, then this structure should only contain an attribute type, and not a value. \item [\verb"em\_next":] A modify operation is built up with a series of small modifications. Hence this structure is a linked list. The operation is seen as one atomic operation. \end{describe} \end{describe} \subsection {ModifyRDN} \label{modifyrdn} To modify the distinguished attribute values of an entry, you MUST use this operation --- \verb"modifyEntry" can not be used. \begin{quote}\index{ds\_modifyrdn}\small\begin{verbatim} ds_modifyrdn (arg, error) struct ds_modifyrdn_arg * arg; struct DSError * error; \end{verbatim}\end{quote} You will need to include \file{quipu/modifyrdn.h} to use this procedure. The arguments are:- \begin{quote}\small\begin{verbatim} struct ds_modifyrdn_arg { CommonArgs mra_common; DN mra_object; RDN mra_newrdn; char mra_deleterdn; }; \end{verbatim}\end{quote} \begin{describe} \item [\verb"mra\_common":] The common arguments as described in \ref{common_args}. \item [\verb"mra\_object":] The DN of the object you want to modify the name of. \item [\verb"mra\_newrdn":] The new RDN. \item [\verb"mra\_deleterdn":] if \verb"TRUE" then the old RDN will be deleted as an attribute, otherwise it will remain an a non-distinguished attribute. \end{describe} \f \section {Abandon} The abandon operation shown below is slightly different to the other DUA operations. It does not make much sense for a synchronous interface to handle abandon directly. In the next release, transparent use of abandon will be provided. \begin{quote}\index{ds\_abandon}\small\begin{verbatim} ds_abandon (arg, error) struct ds_abandon_arg * arg; struct DSError * error; \end{verbatim}\end{quote} The argument structure contains a single parameter supplies the operation invocation id. \begin{quote}\small\begin{verbatim} struct ds_abandon_arg { int aba_invokeid; }; \end{verbatim}\end{quote} \f \section {Multiple Associations} The procedural interface described so far, has been based on the assumption of a connection to a single DSA. However, it is possible to make connection to multiple DSAs. \subsection {Multiple Binds} The bind and unbind routines needed to make multiple association are as follows:- \begin{quote}\index{dap\_bind}\small\begin{verbatim} dap_bind (ad, arg, error, result, addr) int * ad; struct ds_bind_arg *arg; struct ds_bind_arg *result; struct ds_bind_error *error; struct PSAPaddr *addr; dap_unbind (ad) int ad; \end{verbatim}\end{quote} The \verb"arg", \verb"error" and \verb"result" arguments are as defined in Section~\ref{dap:bind} for the routine \verb"secure_ds_bind". The argument \verb"ad" is the association descriptor of the association. It should be different for each association. The \verb"addr" argument in the address of the DSA you wish to contact. \subsection {Other DAP Operations} The other DAP operations (read, list, modify\ldots), use the same format a already described, but with two extra integer parameters, thus \begin{quote}\index{ds\_read}\small\begin{verbatim} ds_read (arg, error, result) \end{verbatim}\end{quote} becomes \begin{quote}\index{ds\_read}\small\begin{verbatim} dap_read (ad, id, arg, error, result) \end{verbatim}\end{quote} where \verb"ad" is the association descriptor used in the bind, and \verb"id" uniquely identifies the operation with respect to other operation on the same association. \f \section {Asynchronous Access} All of the procedures so far described make synchronous associations to the DSA. In the next release, asynchronous access will be provided.