/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _LDAP_PARSE_H #define _LDAP_PARSE_H #include #include #include #include "nis_hashitem.h" /* Pick up N2L file names */ #include #include "yptol/shim.h" #include "yptol/yptol.h" #ifdef __cplusplus extern "C" { #endif /* * New doesn't define LDAP_SCOPE_UNKNOWN, but we still need it. */ #ifndef LDAP_SCOPE_UNKNOWN #define LDAP_SCOPE_UNKNOWN 0xFF #endif /* Attribute/value hash list element */ typedef struct { __nis_hash_item_mt item; /* item.name is the attr name */ int numValues; char **value; /* Array of values */ bool_t isDefault; /* True if value is a default */ } __nis_ldap_attribute_t; /* YP Domains structure */ typedef struct { int numDomains; /* number of domains listed in mapping file */ char **domainLabels; /* the labels for particular domain names */ char **domains; /* Array of LDAP domains */ int numYppasswdd; /* Number of yppasswddDomainLabels */ char **yppasswddDomainLabels; /* yppasswdd domain labels */ } __yp_domain_context_t; /* * Begin object mappings * * Note that the definitions, where necessary, proceed from the bottom * (i.e., the "atomic" components) up. */ /* * String match/print descriptor * * Intended for use together with a __nis_mapping_match_type_t, which will * determine which field of the union is valid. * * string Pointer to a NUL-terminated string * single Represents a single-character match such as '[a-bTe-w]', * which would become * { * 3, numRange * {'a', 'T', 'e'}, lo * {'b', 'T', 'w'} hi * } * Each pair lo[i]/hi[i] (0 <= i < numRange) defines the * range of the wild-card match. * limit No use currrently defined; will probably be removed * berString Pointer to a string containing a single formatting * character as defined by ber_printf(3LDAP). Example: "i" * for a binary integer. */ typedef union { char *string; struct { int numRange; unsigned char *lo; /* Array of numRange elements */ unsigned char *hi; /* Array of numRange elements */ } single; enum { bos, eos } limit; char *berString; } __nis_mapping_match_t; /* * String match/print types and descriptor * * Used to describe print or match conversions. The 'match' field has * the following interpretation: * * Type __nis_mapping_match_t Comment * * mmt_item Value as indicated by corresponding * element in __nis_mapping_item_t or * __nis_mapping_sub_element_t array * mmt_string string * mmt_single single * mmt_limit limit Probably not needed * mmt_any Match any number of any character * mmt_berstring berString * mmt_begin Indicates beginning of format; optional * mmt_end Indicates end of format; REQUIRED to * mark the end of an array of * __nis_mapping_format_t's */ typedef enum {mmt_item, mmt_string, mmt_single, mmt_limit, mmt_any, mmt_berstring, mmt_begin, mmt_end} __nis_mapping_match_type_t; typedef struct { __nis_mapping_match_type_t type; __nis_mapping_match_t match; } __nis_mapping_format_t; /* Forward */ struct __nis_mapping_element_struct; struct __nis_mapping_item_struct; /* * LDAP search triple * * Used to represent a search triple like * ou=Group,?one?cn=staff * or * ou=Group,?one?(&(cn=staff)(gidNumber=10)) * or * ou=Hosts,?one?("cn=%s", (cname, "%s.*")) * * base The base DN; defaultSearchBase appended if 'base' ends with * a comma. * scope One of LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL, or * LDAP_SCOPE_SUBTREE; LDAP_SCOPE_UNKNOWN means that this * __nis_search_triple_t is inactive * attrs Either a filter, or a list of attribute/value pairs, depending * on context. * element Pointer to a value element. If 'element' is non-NULL, the * 'attrs' value is derived by evaluating 'element'. */ typedef struct { char *base; int scope; char *attrs; struct __nis_mapping_element_struct *element; } __nis_search_triple_t; /* * NIS+ index spec * * Represents a NIS+ index list, such as * name=staff,gid=10 * * numIndexes The number of entries in the 'name'/'value' arrays * name Array of column names * value Array of column values; uses __nis_mapping_format_t so that * wild-cards can be represented * * Example * name=staff,gid=10 * 2, numIndexes * { name * "name", * "gid" * }, * { value * { * {mmt_begin}, * {mmt_string, "staff"}, * {mmt_end} * }, * { * {mmt_begin}, * {mmt_string, "gid"}, * {mmt_end} * } * } */ typedef struct { int numIndexes; char **name; __nis_mapping_format_t **value; } __nis_index_t; /* What to do with the LDAP data when a NIS+ entry is deleted */ typedef enum {dd_always, dd_perDbId, dd_never} __nis_delete_disp_t; /* Type of an element in a mapping rule */ typedef enum {me_item, me_print, me_split, me_match, me_extract} __nis_mapping_element_type_t; /* Type of an item in a mapping rule */ typedef enum {mit_any, mit_nisplus, mit_ldap} __nis_mapping_item_type_t; /* * NIS+ object name, with index * * Used to represent a name like * [name = staff, gid = 10]group.org_dir * (Note: spaces around "=" and after "," to make cstyle happy; such spaces * are not usually part of the syntax, but they are allowed.) * * index The index part of the name. numIndexes == 0 means there is * no index. * name The object name proper. If it doesn't end in a dot, the * nisplusLDAPbaseDomain is appended. */ typedef struct { __nis_index_t index; char *name; } __nis_obj_spec_t; /* * Complete representation of a subset of either the DIT or a NIS+ object. * Intended for use in a __nis_mapping_item_t, where the 'type' field * determines which field of the __nis_triple_or_obj_t is active. */ typedef union { __nis_search_triple_t triple; __nis_obj_spec_t obj; } __nis_triple_or_obj_t; /* * Mapping item * * The mapping item is a single LDAP attribute, or a NIS+ table column, such as * ldap:gidNumber:ou=Group, ?one?cn=staff * or * nisplus:gid[name = staff]group.org_dir * (Note: spaces around "=" and after "," to make cstyle happy; such spaces * are not usually part of the syntax, but they are allowed.) * * type mit_ldap or mit_nisplus * name Attribute/column name * searchSpec LDAP search triple, or NIS+ indexed object name * repeat True if item should be repeated if necessary. This is used * to represent implied lists, such as '(memberUid)', which * denotes all values of the 'memberUid' attribute. * exItem forward mapping item for supporting removespec syntax. * */ typedef struct __nis_mapping_item_struct { __nis_mapping_item_type_t type; char *name; __nis_triple_or_obj_t searchSpec; bool_t repeat; struct __nis_mapping_item_struct *exItem; } __nis_mapping_item_t; /* * Sub-element of a mapping rule element * * Each element/sub-element represents the value(s) derived according to * the semantics of the element. Although not explicitly represented here, * values are either strings or BER byte sequences. * * type Type of the 'element' union * element.item A single item * element.print printf(3C)-style value * fmt Array of formatting elements, terminated by 'mmt_end' * numItems Number of items in the 'item' array * item Array of 'numItems' items * doElide Should the last character of the (string) value be * removed ? * elide Character to be removed * element.split Item value string split into multiple values * item A single item * delim The separator character for the split * element.extract Extraction of a sub-string from an item value * fmt Array of formatting elements, terminated by 'mmt_end' * item A single item * * Examples (see __nis_mapping_element_t below for examples using the 'item' * field of __nis_mapping_sub_element_t). For notational convenience, * __nis_mapping_item_t's are shortened to just the item name. * * (1) String value consisting of the string "{crypt}" followed by the * value of the 'passwd' column. The NIS+LDAPmapping(5) representation * is * ("{crypt}%s", passwd) * and the element.print contains * { fmt * {mmt_begin}, * {mmt_string, "{crypt}"}, * {mmt_item}, * {mmt_end} * }, * 1, numItems * { item * {"passwd"} * } * FALSE, doElide * '\0' elide (unused) * * (2) Split a value such as "member1,member2,member3" into multiple * (three, here) values using ',' as the separator. * (members, ",") * element.split * {"members"}, item * ',' delim * * (3) Given a 'cname' column with the value "some.dom.ain.", extract * "some", which becomes the value of the expression. * (cname, "%s.*") * element.extract * { fmt * {mmt_begin}, * {mmt_item}, * {mmt_string, "."}, * {mmt_any}, * {mmt_end} * }, * {"cname"} item */ typedef struct { __nis_mapping_element_type_t type; union { __nis_mapping_item_t item; struct { __nis_mapping_format_t *fmt; int numItems; __nis_mapping_item_t *item; bool_t doElide; unsigned char elide; } print; struct { __nis_mapping_item_t item; unsigned char delim; } split; struct { __nis_mapping_format_t *fmt; __nis_mapping_item_t item; } extract; } element; } __nis_mapping_sub_element_t; /* * Mapping rule element * * Each element/sub-element represents the value(s) derived according to * the semantics of the element. Although not explicitly represented here, * values are either strings or BER byte sequences. * * type Type of the 'element' union * element.item A single item * element.print printf(3C)-style value * fmt Array of formatting elements, terminated by 'mmt_end' * numSubElements Number of sub-elements in the 'subElement' array * subElement Array of 'numSubElements' sub-elements * doElide Should the last character of the (string) value(s) be * removed ? * elide Character to be removed * element.split Item value string split into multiple values * item A single item * delim The separator character for the split * element.match Assignment of item values by matching to a format * fmt Array of formatting elements, terminated by 'mmt_end' * numItems Number of items in the 'item' array * item Array of 'numItems' items * element.extract Extraction of a sub-string from an item value * fmt Array of formatting elements, terminated by 'mmt_end' * item A single item * * Examples; items represented by just the item name. * * (1) The value of the 'name' column. * name * element.item * {"name"} item * * (2) Example (1) for a sub-element showed how to construct a value from * a printf(3C)-style format string and one or more item values. * However that example is only valid when used as a sub-expression * (in place of an item in a 'print' list, for example). If * ("{crypt}%s", passwd) * was part of a rule like * userPassword=("{crypt}%s", passwd) * the representation would use a __nis_mapping_element_t as follows. * element.print * { fmt * {mmt_begin}, * {mmt_string, "{crypt}"}, * {mmt_item}, * {mmt_end} * }, * 1, numSubElements * { subElement * me_item, type * {"passwd"} item * }, * FALSE, doElide * '\0' elide (unused) * * (3) Match a value such as "{dh-1024}abcdef000234" to a template format * "{%s}%s", assign "dh-1024" to the 'auth_type' column, and * "abcdef000234" to the 'public_data' column. * ("{%s}%s", auth_type, public_data) * element.match * { fmt * {mmt_begin}, * {mmt_string, "{"}, * {mmt_item}, * {mmt_string, "}"}, * {mmt_item}, * {mmt_end} * } * 2, numItems * { item * {"auth_type"}, * {"public_data"} * } */ typedef struct __nis_mapping_element_struct { __nis_mapping_element_type_t type; union { __nis_mapping_item_t item; struct { __nis_mapping_format_t *fmt; int numSubElements; __nis_mapping_sub_element_t *subElement; bool_t doElide; unsigned char elide; } print; struct { __nis_mapping_item_t item; unsigned char delim; } split; struct { __nis_mapping_format_t *fmt; int numItems; __nis_mapping_item_t *item; } match; struct { __nis_mapping_format_t *fmt; __nis_mapping_item_t item; } extract; } element; } __nis_mapping_element_t; /* * One side (left or right) of a mapping rule * * Example * The rule * userPassword=("{crypt}%s", passwd) * would be reprsented by a __nis_mapping_rule_t as follows * { lhs * 1, numElements * { element * me_item, * {"userPassword"} * } * }, * { rhs * 1, numElements * { element * me_print, * { * See example (2) under * __nis_mapping_element_t * above * } * } * } */ typedef struct { int numElements; __nis_mapping_element_t *element; } __nis_mapping_rlhs_t; /* A single mapping rule: attribute -> column or column -> attribute */ typedef struct { __nis_mapping_rlhs_t lhs; __nis_mapping_rlhs_t rhs; } __nis_mapping_rule_t; /* * Map (sub-set of) NIS+ object to location(s) in the LDAP DB * * read base/scope/filter triple used to read data from LDAP; * LDAP_SCOPE_UNKNOWN indicates that 'read' is unused * write base/scope/attrlist triple used to write data to LDAP; * LDAP_SCOPE_UNKNOWN indicates that 'write' is unused * delDisp What should happen to the LDAP entry when the corresponding * NIS+ data is deleted. * dbIdName The dbId for the delete rule set (if any) * numDbIds The number of rules in the 'dbId' rule set * dbId The delete rule set; this field must point to a valid * rule set if 'delDisp' is 'dd_perDbId'; ignored otherwise * next Pointer to the next __nis_object_dn_t structure for this * NIS+ object. * * Example * The "group.org_dir.x.y.z." NIS+ table should be read from and * written to the "ou=Group" container at "dc=x,dc=y,dc=z". Upon * NIS+ entry deletion, we should always attempt to delete the * corresponding LDAP attributes. * * { read * "ou=Group,dc=x,dc=y,dc=z", * LDAP_SCOPE_ONELEVEL, * "objectClass=posixGroup" * }, * { write * "ou=Group,dc=x,dc=y,dc=z", * LDAP_SCOPE_ONELEVEL, * "objectClass=posixGroup" * }, * dd_always, delDisp * NULL, dbIdName * 0, * NULL, dbId * NULL next */ typedef struct { __nis_search_triple_t read; __nis_search_triple_t write; __nis_delete_disp_t delDisp; char *dbIdName; int numDbIds; __nis_mapping_rule_t **dbId; /* Delete rule set */ void *next; } __nis_object_dn_t; /* * Per-dbId or -object mapping * * Initially collected per-dbId (so that item.name=dbId), the * __nis_table_mapping_t's are later stored per-object (whereupon * item.name=objName). * * item Structure used by the hash_item functions * dbId The dbId associated with the __nis_table_mapping_t * structure * index Object sub-set specification; only defined for * tables; index.numIndexes equal to zero means that * the 'index' is unused. * next Pointer to next table sub-set, if any * numColumns Number of columns if the object is a table * column Column names * initTtlLo Lower limit on the initial TTL * initTtlHi Upper limit on the initial TTL * ttl TTL set after refresh * commentChar NIS map comment character * objectDN Location in the LDAP DB * numSplits number of split fields * separatorStr separator string to break up NIS split field attributes * usedns_flag indicates if the -b option to makedbm is used for a map. * securemap_flag indicates if the -s option to makedbm is used for a map. * __nis_mapping_element_t Parsed format strings and name fields storage * numRulesFromLDAP Number of rules (and hence elements in the * 'ruleFromLDAP' array) for mapping LDAP entries * to NIS+ objects * ruleFromLDAP * numRulesToLDAP Number of rules (and hence elements in the * 'ruleToLDAP' array) for mapping NIS+ objects to * LDAP entries * ruleToLDAP * objType The NIS+ object type; NIS_BOGUS_OBJ used to indicate * not set (in which case the other object data fields * should be assumed to be invalid) * objName The fully qualified name of the NIS+ object * objPath The name used internally by libnisdb (which * is path to the data file for the table/directory * containing the object) * obj A copy of the object itself * isMaster Set if this machine is the master for the object * (actually for the directory containing it) * seq_num A sequence number representing the order of the maps * as listed in the NISLDAPmapping.template file. * * Example * Map the subset of the NIS+ 'group.org_dir.x.y.z.' table for which * is true that the 'name' starts with 'a' or 'o' to location per * the __nis_object_dn_t example above. No translation rules. * * { item * "group.org_dir.x.y.z." name * * }, * "group_subset", dbId * 1, numIndexes * { index * 1, * {"name"}, * { * {mmt_begin}, * { * mmt_single, * 2, * {'a', 'o'}, * {'a', 'o'}, * } * {mmt_any}, * {mmt_end} * } * } * NULL, next * 4, numColumns * { column * "name", * "passwd", * "gid", * "members" * }, * 1800, initTtlLo * 5400, initTtlHi * 3600, ttl * '#', commentChar * , objectDN * 0, numSplits * NULL, separatorStr * 0, usedns_flag * 0, securemap_flag * , e * 0, numRulesFromLDAP * NULL, ruleFromLDAP * 0, numRulesToLDAP * NULL ruleToLDAP * NIS_TABLE_OBJ, objType * "group.org_dir.x.y.z.", objName * "/var/nis/data/group.org_dir" objPath * obj * 1 isMaster */ typedef struct { __nis_hash_item_mt item; /* item.name=dbId||objName */ char *dbId; /* Used during initializaton */ __nis_index_t index; void *next; /* Next sub-set spec */ void *seqNext; /* Next in config sequence */ int numColumns; char **column; time_t initTtlLo; time_t initTtlHi; time_t ttl; char commentChar; __nis_object_dn_t *objectDN; int numSplits; char *separatorStr; int usedns_flag; int securemap_flag; __nis_mapping_element_t *e; int numRulesFromLDAP; __nis_mapping_rule_t **ruleFromLDAP; int numRulesToLDAP; __nis_mapping_rule_t **ruleToLDAP; /* * The following fields contain information about the mapped object. */ zotypes objType; char *objName; /* FQ object name */ char *objPath; /* nisdb's internal name */ nis_object *obj; /* NIS+ object */ int isMaster; /* Master for this object ? */ int seq_num; } __nis_table_mapping_t; /* End object mappings */ /* Default config file paths */ #define DEFAULTCONFFILE "/var/nis/NIS+LDAPmapping" #define ETCCONFFILE "/etc/default/rpc.nisd" #define YP_DEFAULTCONFFILE NTOL_MAP_FILE #define YP_ETCCONFFILE NTOL_CONFIG_FILE /* Path to the root object dir file */ #define ROOTDIRFILE "/var/nis/data/root_dir" /* Path to the root object file */ #define ROOTOBJFILE "/var/nis/data/root.object" extern __nis_table_mapping_t *ldapMappingSeq; extern int yp2ldap; /* Exported functions */ int parseConfig(char **ldapCLA, char *ldapConfFile); int linked2hash(__nis_table_mapping_t *tlist); int dbids2objs(__nis_hash_table_mt *objs, __nis_hash_table_mt *dbids); void __make_legal(char *s); char *internal_table_name(nis_name name, char *res); nis_name relative_name(char *s); char *internalTableName(char *name); __nis_table_mapping_t *getObjMapping(char *name, char *intNameArg, int asObj, int *doRead, int *doWrite); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _LDAP_PARSE_H */