|
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: 19481 (0x4c19) Types: TextFile Names: »q-dsap.tex«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/doc/manual/q-dsap.tex«
% run this through LaTeX with the appropriate wrapper \f \chapter {Programming the Directory} This part of the manual is written for implementors who wish to access the Directory using the \man libdsap(3n) library. This might be an OSI application wishing to look up information, or an interactive Directory user-interface. The interface to the Directory is defined as a series of procedures which closely parallel the service defined in \cite{CCITT.Directory}. This section defines the procedures, and shows how they relate to the standard. To avoid unnecessary wordiness, the user is expected to be familiar with the standard. \f \section {Conventions} \label{quipu_conv} The library defines various C structures, described in the following sections Associated with the C structures, are routines which: \begin {itemize} \item allocate structures \item free structures, including sub-structures \item compare structures \item copy structures \item print structures \item parse structures \end {itemize} The following conventions are followed in many routines, which are then briefly identified later. For a general structure x, there will be the following routines: \begin{itemize} \item Allocation: \begin{quote}\small\begin{verbatim} struct x *x_alloc () \end{verbatim}\end{quote} Allocate memory for structure \verb"x". \item Freeing: \begin{quote}\small\begin{verbatim} x_free (a) struct x * a; \end{verbatim}\end{quote} Free structure \verb"x", and any nested structures. If the structure, \verb"x", is a linked-list type of structure, then as well as the routines described above, there will be routines of the form \verb"x_comp_function" (where \verb"function" is \verb"alloc", \verb"free", and so on). These act upon a single element of the list rather than the list as a whole. \item Copying: \begin{quote}\small\begin{verbatim} struct x * x_cpy (a) struct x *a; \end{verbatim}\end{quote} Return a copy of structure \verb"a". \item Comparing: \begin{quote}\small\begin{verbatim} int x_cmp (a, b) struct x *a, *b; \end{verbatim}\end{quote} Return \verb"0" if the structures \verb"a" and \verb"b" same. Return \verb"-1" if \verb"a<b", or \verb"1" if \verb"a>b". For some structures the notion of \verb"a>b" and \verb"a<b" is not defined, but will be consistent. \item Printing: \begin{quote} \index{rdn\_print}\index{dn\_print}\index{as\_print}\index{avs\_print} \index{AttrT\_print}\index{AttrV\_print} \small\begin{verbatim} int x_print (ps, a, format) PS ps; struct x *a; int format; \end{verbatim}\end{quote} Print the structure \verb"a" to the presentation stream \verb"ps", using the specified format, either \verb"READOUT", for a pretty-printed format (for example the output of a showentry from \pgm{dish}); or, \verb"EDBOUT", for a format suitable for inclusion in an EDB file. The \verb"PS" structure is described in \volone/ of this manual. For the structures representing a DN and RDN there is an extra format :- \verb"DIROUT", which is used to get a representation of the name suitable for inclusion in a \unix/ filename (essentially \verb"EDBOUT" with the \verb"@" symbols replaced with \verb"/" seperators). \item String format: \begin{quote} \index{str2rdn}\index{str2dn}\index{str2as} \index{str2AttrV}\index{str2AttrT} \small\begin{verbatim} struct x * str2x (str) char * str; \end{verbatim}\end{quote} Every known syntax has a string representation. A string of the required syntax can be converted to the relevant c structure with the ``str2x'' function. Each of the string parsers assumes the input string has had multiple spaces and tabs removed, and replaced with single spaces. The fuction \begin{quote}\small\begin{verbatim} char * Tidy_String (a) char * a; \end{verbatim}\end{quote} will do the relevant tidying if required. Strings printed with the \verb"EDBOUT" format of x\_print should be parsable. NOTE \verb"str2AttrV()" \index{str2AttrV} does not follow the ``convention'' and has an extra parameter, which is the expected syntax of the string. \item Decoding: \begin{quote}\small\begin{verbatim} x_decode (a) struct x *a; \end{verbatim}\end{quote} For efficiency reasons, when information is read from a DSA any structures that contain nested AttributeTypes and AttributeValues will not be fully decoded. This will not matter if you only intend to use the structures internally, but if you intend to show the structure to a ``user'' or write to a log file, you should call this routine to complete the decoding, which will replace the various ``unfriendly'' structures (such as OID) with string representations. \end{itemize} The structures following the ``convention'' are listed below. The ``prefix'' column shows the value \verb"x" should be replaced by to use the routines for the associated structure. \index{RDN} \index{DN} \index{AttributeType}\index{AttrT} \index{AttributeValue}\index{AttrV} \index{AV\_Sequence}\index{avs} \index{Attr\_Sequence}\index{as} \index{acl} \index{dn\_seq} \index{tree\_struct} \index{edb\_info} \index{EntryInfo} \[\begin{tabular}{|l|l|} \hline Structure & Prefix \\ \hline RDN & rdn \\ DN & dn \\ AttributeType & AttrT \\ AttributeValue & AttrV \\ AV\_Sequence & avs \\ Attr\_Sequence & as \\ acl & acl \\ dn\_seq & dn\_seq \\ tree\_struct & tree\_struct \\ edb\_info & edb\_info \\ EntryInfo& entryinfo \\ \hline \end{tabular}\] \f \section {Attributes} Attributes are fundamental components of the directory. Attributes have two parts, types and values, which is represented by the structures \verb"AttributeType" and \verb"AttributeValue". For programing purposes you should include the file \file{quipu/attrvalue.h} into your programs, which contains the following structure definitions:- \begin{quote}\index{AttributeType}\small\begin{verbatim} typedef struct { OID at_oid; oid_table_attr * at_table; } attrType, * AttributeType; #define NULLAttrT (AttributeType) NULL \end{verbatim}\end{quote} The \verb"AttributeType" structure contains two components, only one of which is used at any one time. An \verb"AttributeType" is defined in \cite{CCITT.Directory} as an OBJECT IDENTIFIER, hence the field \verb"at_oid". But \man libdsap(3n) goes further than this, and has a table (described in Section~\ref{oidtables}) which maps strings onto these OIDs. The second field (\verb"at_table") is a pointer to this table. The table then contains the OID. This table must be loaded by calling \begin{quote}\index{load\_oid\_table}\small\begin{verbatim} load_oid_table(name) char * name; \end{verbatim}\end{quote} The \verb"name" parameter should be the name of the oidtable to load. For most purposes this should be ``\verb"oidtable"''. The call \begin{quote}\index{dsap\_init}\small\begin{verbatim} dsap_init(argc,argv) int *argc; char *** argv; \end{verbatim}\end{quote} can be used to load the oidtable for you, with the additional benifit that it will read the file \file{/etc/dsaptailor} to find the location on the oidtable. The parameters it expects are the pointers to the \verb"argc" and \verb"argv" parameters passed to your ``main()'' routine. If a ``\tt -c\rm '' flag is found then this is used as the name of the DSA to contact as per dish (see Section~\ref{dish_bind}). Other parameters are ignored. The oidtables are represented using the following structures:- \begin{quote}\index{oid\_table}\small\begin{verbatim} typedef struct { char ot_name [BUFSIZE]; char ot_stroid [BUFSIZE]; OID ot_oid; } oid_table; #define NULLTABLE ((oid_table * )0) typedef struct { oid_table oa_ot; int oa_syntax; } oid_table_attr; #define NULLTABLE_ATTR ((oid_table_attr *)0) \end{verbatim}\end{quote} As structures come across the network, the AttributeType is decoded into the \verb"at_oid" field. If you want to use the string representation you must call \verb"AttrT_decode" (described in Section~\ref{quipu_conv}), if you do not decode the structure, the print routines will still work, but the result will numeric OIDs. If successfully decoded the field \verb"at_oid" will be set to \verb"NULLOID", to indicate that the is a table version of the oid. The table consists to two fields, an integer syntax :- \verb"oa_syntax". This can take one of the following values:- \begin{quote}\small\begin{verbatim} #define AV_UNKNOWN 0 #define AV_CASEEXACTSTRING 1 #define AV_CASEIGNORESTRING 2 #define AV_ACL 3 #define AV_ASN 4 #define AV_NUMERICSTRING 5 #define AV_PRESENTATIONADDRESS 6 #define AV_DN 7 #define AV_SCHEMA 8 #define AV_UPDATE 9 #define AV_BOOLEAN 10 #define AV_INTEGER 11 #define AV_TIME 12 #define AV_OID 13 #define AV_FILE 14 #define AV_OBJECTCLASS 15 #define AV_PHOTO 16 \end{verbatim}\end{quote} The second field \verb"oa_ot" is a reference to a \verb"oid_table" structure, which contain the oid -- \verb"ot_oid", a numeric string representation of the oid -- \verb"ot_stroid", and the local key string -- \verb"ot_name". To create an \verb"AttributeType" given a string representation of an OID, you should use \begin{quote}\index{str2AttrT}\small\begin{verbatim} AttributeType str2AttrT (str) char *str; \end{verbatim}\end{quote} which looks up the string ``\verb"str"'' in the OID table, and creates an \verb"AttributeType" structure. There are various low level routines to manipulate entries in the OID table, however the \verb"AttributeType" routines described in Section~\ref{quipu_conv} will be sufficient for most uses, so the details of these ``invisible'' routines are omitted here. Attribute values are represented by the structure \verb"AttributeValue":- \begin{quote}\index{AttributeValue}\small\begin{verbatim} typedef struct { PE av_pe; int av_syntax; union { char * av_str; struct acl * av_acl; PE av_asn; char * av_num; struct PSAPaddr * av_psap; struct dn_seq * av_dnlist; struct tree_struct * av_tree; struct edb_info * av_update; char av_boolean; int av_integer; time_t av_time; objectclass * av_objectclass; struct file_syntax av_file; OID av_oid; } av_un; } * AttributeValue; #define NULLAttrV (AttributeValue) NULL \end{verbatim}\end{quote} The \verb"AttributeValue" structure can hold attribute values in two formats. Firstly as a specialised {\em C\/} structure in the \verb"av_un", the field \verb"av_syntax" defines which element of the union to use. Secondly as a presentation element, this is the case when an attribute has been received from the net, but not decoded (indicated by \verb"AV_UNKNOWN"). The routine \verb"AttrV_decode" will burst this presentation element into the relevant member of the union. Unlike AttributeTypes the files \verb"av_pe" is NOT set to \verb"NULL" once the structure has been decoded. Attribute values can now be linked together to form a multi-value attribute value. For this the \verb"AV_Sequence" structure is used. \begin{quote}\index{AV\_Sequence}\small\begin{verbatim} typedef struct avseqcomp { AttributeValue avseq_av; Soundex avseq_soundex; struct avseqcomp *avseq_next; } avseqcomp, *AV_Sequence; #define NULLAV ((AV_Sequence) 0) \end{verbatim}\end{quote} This is simply a linked list of AttributeValues. The \verb"Soundex" component is a ``soundex'' key, created when approximate searching is used. To create an \verb"AV_Sequence" the two routines \begin{quote}\index{avs\_comp\_new}\index{avs\_merge}\small\begin{verbatim} AV_Sequence avs_comp_new (av) AttributeValue av; AV_Sequence avs_merge (a,b) AV_Sequence a,b; \end{verbatim}\end{quote} can be used. Finally an attribute can now be formed by linking the attribute type, and multiple attribute values using the \verb"AttrSequence" structure:- \begin{quote}\index{Attr\_Sequence}\small\begin{verbatim} typedef struct attrcomp { AttributeType attr_type; AV_Sequence attr_value; struct attrcomp *attr_link; struct acl_info *attr_acl; } attrcomp, *Attr_Sequence; #define NULLATTR ((Attr_Sequence) 0) \end{verbatim}\end{quote} This structure is used singularly to represent an attribute, and as a linked list (linked using \verb"attr_link") to represent a set of attributes. To create an \verb"Attr_Sequence" the two routines \begin{quote}\index{as\_comp\_new}\index{as\_merge}\small\begin{verbatim} Attr_Sequence as_comp_new (at,as,acl) AttributeType at; AV_Sequence as; struct acl_info * acl; Attr_Sequence as_merge (a,b) Attr_Sequence a,b; \end{verbatim}\end{quote} can be used. The \verb"acl" parameter is only used by the DSA, for use in a DUA it should be set to \verb"NULLACL_INFO". \section {Distinguished Names} The structures which define names are critical. Names are essentially made up of attributes, but because of their importance, a different --- more specific structure is used. \begin{quote}\index{RDN}\small\begin{verbatim} typedef struct rdncomp { AttributeType rdn_at; AttributeValue rdn_av; struct rdncomp *rdn_next; } rdncomp, *RDN; #define NULLRDN ((RDN) 0) \end{verbatim}\end{quote} An RDN consists of a set of Attribute Types (\verb"rdn_at") and Attribute Values (\verb"rdn_av"), the set is linked using \verb"rdn_next". RDNs can the be joined in a sequence to form a Distinguished Name (DN):- \begin{quote}\index{DN}\small\begin{verbatim} typedef struct dncomp { RDN dn_rdn; struct dncomp *dn_parent; } dncomp, *DN; #define NULLDN ((DN) 0) \end{verbatim}\end{quote} The following routines are provided in addition to the routines defined is Section~\ref{quipu_conv} to allow the user to create and manipulate names \begin{itemize} \item Create a DN given an RDN: \begin{quote}\index{dn\_comp\_new}\small\begin{verbatim} dn_comp_new (rdn) RDN rdn; \end{verbatim}\end{quote} \item Append a DN to the end of another DN: \begin{quote}\index{dn\_append}\small\begin{verbatim} dn_append (dn1, dn2) DN dn1, dn2; \end{verbatim}\end{quote} \verb"dn2" is added to \verb"dn1". An error results in the return NOTOK. \item Create a RDN given and AttributeType and AttributeValue: \begin{quote}\small\index{rdn\_comp\_new}\begin{verbatim} RDN rdn_comp_new (at, av) AttributeType at; AttributeValue av; \end{verbatim}\end{quote} \item Merge two RDNs: \begin{quote}\small\index{rdn\_merge}\begin{verbatim} RDN rdn_merge (rdn1, rdn2) RDN rdn1, rdn2; \end{verbatim}\end{quote} RDN's form a set, to make comparisons easier, this implementation assumes them to be ordered sets. This routine takes two ordered RDN sets, and merges them. If RDNs received across the network are not ordered, the decoding process will order them for you. \end{itemize} The approach to access control is defined in \cite{QUIPU.Design}. The representation of the attribute for access control is given by the structure shown below. This closely follows the ASN.1 definition. \begin{quote}\small\begin{verbatim} struct acl_info { int acl_categories; #define ACL_NONE 0 #define ACL_DETECT 1 #define ACL_COMPARE 2 #define ACL_READ 3 #define ACL_ADD 4 #define ACL_WRITE 5 int acl_selector_type; #define ACL_ENTRY 0 #define ACL_OTHER 1 #define ACL_PREFIX 2 #define ACL_GROUP 3 DN acl_name; struct acl_info *acl_next; }; \end{verbatim}\end{quote} The DN \verb"acl_name" is used for the type \verb"ACL_PREFIX" and \verb"ACL_OTHER" only. \section {Adding New Syntaxes to QUIPU} It will probably be necessary to add knowledge of extra syntaxes to Directory User Interfaces as the range of applications grow. QUIPU has been designed to make this as easy as possible. This section describes how you might do this, by adding knowledge of a \verb"FOOBAR" syntax to \man libdsap(3n) library. \verb"FOOBAR" is represented by the c structure ``\tt struct foobar \{\ldots\};\rm ''. The DSA does not need to know about the new structure, as it will handle unknown syntaxes as blocks of ASN.1. The new syntax has to be defined for the DUA programs in various places:- \begin{itemize} \item \verb"h/quipu/attr.h": This file includes a definition for ``\tt AttributeValue\rm '' which contains a union of all the known syntaxes. You will need to add an element to the union to contain the structure foobar, and a definition of \tt AV\_FOOBAR\rm , so that it is known when the union contains a foobar attribute. \item \verb"dsap/common/oid.c": This file is used to read the oidtables. The tables will have to have entries for the attributes whose syntax is ``foobar'' added. The syntax of the entires will be defined as ``foobar''. In the file oid.c there is a table mapping strings onto numeric identifiers. So an extra entry of the form \begin{quote}\small\begin{verbatim} "foobar", AV_FOOBAR, \end{verbatim}\end{quote} will be needed in the table. \end{itemize} This is sufficient to define the new syntax, now some routines to manipulate the new c structure are required. Each of the new routines will be called from the file \verb"dsap/common/attrv.c". Most of the routines in this file will need modification to have knowledge of the type \tt AV\_FOOBAR\rm \ built in. In particular the following are needed:- \begin{description} \item [input:] A routine to get the attribute value from the standard input is needed. This will read the input, and generate a representation of the input in the structure \tt foobar \rm . This routine will be called by \verb"str2AttrV()". \item [output:] Given a \tt foobar \rm \ c structure, a routine is needed to output a representation of the attribute. This routine will be called by \verb"AttrV_Print()". \item [comparing:] If the new attribute can take on multiple values, it is necessary to impose an ordering on the values, so that the X500 compare operation can work correctly with sets. The compare function is called by \verb"AttrV_cmp()" \item [copying:] It is often necessary to copy an attribute, for this reason a routine (called by \verb"AttrV_cpy()") must also be supplied. \item [asn encoding:] Two routines are needed to convert the c structure to ASN.1 and vice-versa. It is likely that these routines will be \man pepy(1) generated. The routines \verb"grab_pe()" and \verb"AttrV_decode()" found in the file \verb"dsap/X500as/asn_ext.c" need to have an extra case added to their \verb"switch" statement to build in the knowledge of the \verb"FOOBAR" syntax. In the switch, the relevant encoder/decoder should be called. \end{description} Having made these changes and after re-compiling the DUA should be able to handle the new syntax corrctly. If you have problems, mail quipu-support, whose address is given on page \pageref{quipu:support}. In future versions of QUIPU, it is hoped to simplify this process using function pointers. This will also reduce the size of binaries that use the \man libdsap(3n) library.