1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _LDAP_PARSE_H 28 #define _LDAP_PARSE_H 29 30 #include <lber.h> 31 #include <ldap.h> 32 #include <rpcsvc/nis.h> 33 34 #include "nis_hashitem.h" 35 36 /* Pick up N2L file names */ 37 #include <ndbm.h> 38 #include "yptol/shim.h" 39 #include "yptol/yptol.h" 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 /* 46 * New <ldap.h> doesn't define LDAP_SCOPE_UNKNOWN, but we still need it. 47 */ 48 #ifndef LDAP_SCOPE_UNKNOWN 49 #define LDAP_SCOPE_UNKNOWN 0xFF 50 #endif 51 52 /* Attribute/value hash list element */ 53 typedef struct { 54 __nis_hash_item_mt item; /* item.name is the attr name */ 55 int numValues; 56 char **value; /* Array of values */ 57 bool_t isDefault; /* True if value is a default */ 58 } __nis_ldap_attribute_t; 59 60 /* YP Domains structure */ 61 typedef struct { 62 int numDomains; /* number of domains listed in mapping file */ 63 char **domainLabels; /* the labels for particular domain names */ 64 char **domains; /* Array of LDAP domains */ 65 int numYppasswdd; /* Number of yppasswddDomainLabels */ 66 char **yppasswddDomainLabels; /* yppasswdd domain labels */ 67 } __yp_domain_context_t; 68 69 /* 70 * Begin object mappings 71 * 72 * Note that the definitions, where necessary, proceed from the bottom 73 * (i.e., the "atomic" components) up. 74 */ 75 76 /* 77 * String match/print descriptor 78 * 79 * Intended for use together with a __nis_mapping_match_type_t, which will 80 * determine which field of the union is valid. 81 * 82 * string Pointer to a NUL-terminated string 83 * single Represents a single-character match such as '[a-bTe-w]', 84 * which would become 85 * { 86 * 3, numRange 87 * {'a', 'T', 'e'}, lo 88 * {'b', 'T', 'w'} hi 89 * } 90 * Each pair lo[i]/hi[i] (0 <= i < numRange) defines the 91 * range of the wild-card match. 92 * limit No use currrently defined; will probably be removed 93 * berString Pointer to a string containing a single formatting 94 * character as defined by ber_printf(3LDAP). Example: "i" 95 * for a binary integer. 96 */ 97 typedef union { 98 char *string; 99 struct { 100 int numRange; 101 unsigned char *lo; /* Array of numRange elements */ 102 unsigned char *hi; /* Array of numRange elements */ 103 } single; 104 enum { 105 bos, 106 eos 107 } limit; 108 char *berString; 109 } __nis_mapping_match_t; 110 111 /* 112 * String match/print types and descriptor 113 * 114 * Used to describe print or match conversions. The 'match' field has 115 * the following interpretation: 116 * 117 * Type __nis_mapping_match_t Comment 118 * 119 * mmt_item <unused> Value as indicated by corresponding 120 * element in __nis_mapping_item_t or 121 * __nis_mapping_sub_element_t array 122 * mmt_string string 123 * mmt_single single 124 * mmt_limit limit Probably not needed 125 * mmt_any <unused> Match any number of any character 126 * mmt_berstring berString 127 * mmt_begin <unused> Indicates beginning of format; optional 128 * mmt_end <unused> Indicates end of format; REQUIRED to 129 * mark the end of an array of 130 * __nis_mapping_format_t's 131 */ 132 typedef enum {mmt_item, mmt_string, mmt_single, mmt_limit, mmt_any, 133 mmt_berstring, mmt_begin, mmt_end} 134 __nis_mapping_match_type_t; 135 136 typedef struct { 137 __nis_mapping_match_type_t type; 138 __nis_mapping_match_t match; 139 } __nis_mapping_format_t; 140 141 /* Forward */ 142 struct __nis_mapping_element_struct; 143 struct __nis_mapping_item_struct; 144 145 /* 146 * LDAP search triple 147 * 148 * Used to represent a search triple like 149 * ou=Group,?one?cn=staff 150 * or 151 * ou=Group,?one?(&(cn=staff)(gidNumber=10)) 152 * or 153 * ou=Hosts,?one?("cn=%s", (cname, "%s.*")) 154 * 155 * base The base DN; defaultSearchBase appended if 'base' ends with 156 * a comma. 157 * scope One of LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL, or 158 * LDAP_SCOPE_SUBTREE; LDAP_SCOPE_UNKNOWN means that this 159 * __nis_search_triple_t is inactive 160 * attrs Either a filter, or a list of attribute/value pairs, depending 161 * on context. 162 * element Pointer to a value element. If 'element' is non-NULL, the 163 * 'attrs' value is derived by evaluating 'element'. 164 */ 165 typedef struct { 166 char *base; 167 int scope; 168 char *attrs; 169 struct __nis_mapping_element_struct *element; 170 } __nis_search_triple_t; 171 172 /* 173 * NIS+ index spec 174 * 175 * Represents a NIS+ index list, such as 176 * name=staff,gid=10 177 * 178 * numIndexes The number of entries in the 'name'/'value' arrays 179 * name Array of column names 180 * value Array of column values; uses __nis_mapping_format_t so that 181 * wild-cards can be represented 182 * 183 * Example 184 * name=staff,gid=10 185 * 2, numIndexes 186 * { name 187 * "name", 188 * "gid" 189 * }, 190 * { value 191 * { 192 * {mmt_begin}, 193 * {mmt_string, "staff"}, 194 * {mmt_end} 195 * }, 196 * { 197 * {mmt_begin}, 198 * {mmt_string, "gid"}, 199 * {mmt_end} 200 * } 201 * } 202 */ 203 typedef struct { 204 int numIndexes; 205 char **name; 206 __nis_mapping_format_t **value; 207 } __nis_index_t; 208 209 /* What to do with the LDAP data when a NIS+ entry is deleted */ 210 typedef enum {dd_always, dd_perDbId, dd_never} __nis_delete_disp_t; 211 212 /* Type of an element in a mapping rule */ 213 typedef enum {me_item, me_print, me_split, me_match, me_extract} 214 __nis_mapping_element_type_t; 215 216 /* Type of an item in a mapping rule */ 217 typedef enum {mit_any, mit_nisplus, mit_ldap} __nis_mapping_item_type_t; 218 219 /* 220 * NIS+ object name, with index 221 * 222 * Used to represent a name like 223 * [name = staff, gid = 10]group.org_dir 224 * (Note: spaces around "=" and after "," to make cstyle happy; such spaces 225 * are not usually part of the syntax, but they are allowed.) 226 * 227 * index The index part of the name. numIndexes == 0 means there is 228 * no index. 229 * name The object name proper. If it doesn't end in a dot, the 230 * nisplusLDAPbaseDomain is appended. 231 */ 232 typedef struct { 233 __nis_index_t index; 234 char *name; 235 } __nis_obj_spec_t; 236 237 /* 238 * Complete representation of a subset of either the DIT or a NIS+ object. 239 * Intended for use in a __nis_mapping_item_t, where the 'type' field 240 * determines which field of the __nis_triple_or_obj_t is active. 241 */ 242 typedef union { 243 __nis_search_triple_t triple; 244 __nis_obj_spec_t obj; 245 } __nis_triple_or_obj_t; 246 247 /* 248 * Mapping item 249 * 250 * The mapping item is a single LDAP attribute, or a NIS+ table column, such as 251 * ldap:gidNumber:ou=Group, ?one?cn=staff 252 * or 253 * nisplus:gid[name = staff]group.org_dir 254 * (Note: spaces around "=" and after "," to make cstyle happy; such spaces 255 * are not usually part of the syntax, but they are allowed.) 256 * 257 * type mit_ldap or mit_nisplus 258 * name Attribute/column name 259 * searchSpec LDAP search triple, or NIS+ indexed object name 260 * repeat True if item should be repeated if necessary. This is used 261 * to represent implied lists, such as '(memberUid)', which 262 * denotes all values of the 'memberUid' attribute. 263 * exItem forward mapping item for supporting removespec syntax. 264 * 265 */ 266 typedef struct __nis_mapping_item_struct { 267 __nis_mapping_item_type_t type; 268 char *name; 269 __nis_triple_or_obj_t searchSpec; 270 bool_t repeat; 271 struct __nis_mapping_item_struct *exItem; 272 } __nis_mapping_item_t; 273 274 /* 275 * Sub-element of a mapping rule element 276 * 277 * Each element/sub-element represents the value(s) derived according to 278 * the semantics of the element. Although not explicitly represented here, 279 * values are either strings or BER byte sequences. 280 * 281 * type Type of the 'element' union 282 * element.item A single item 283 * element.print printf(3C)-style value 284 * fmt Array of formatting elements, terminated by 'mmt_end' 285 * numItems Number of items in the 'item' array 286 * item Array of 'numItems' items 287 * doElide Should the last character of the (string) value be 288 * removed ? 289 * elide Character to be removed 290 * element.split Item value string split into multiple values 291 * item A single item 292 * delim The separator character for the split 293 * element.extract Extraction of a sub-string from an item value 294 * fmt Array of formatting elements, terminated by 'mmt_end' 295 * item A single item 296 * 297 * Examples (see __nis_mapping_element_t below for examples using the 'item' 298 * field of __nis_mapping_sub_element_t). For notational convenience, 299 * __nis_mapping_item_t's are shortened to just the item name. 300 * 301 * (1) String value consisting of the string "{crypt}" followed by the 302 * value of the 'passwd' column. The NIS+LDAPmapping(5) representation 303 * is 304 * ("{crypt}%s", passwd) 305 * and the element.print contains 306 * { fmt 307 * {mmt_begin}, 308 * {mmt_string, "{crypt}"}, 309 * {mmt_item}, 310 * {mmt_end} 311 * }, 312 * 1, numItems 313 * { item 314 * {"passwd"} 315 * } 316 * FALSE, doElide 317 * '\0' elide (unused) 318 * 319 * (2) Split a value such as "member1,member2,member3" into multiple 320 * (three, here) values using ',' as the separator. 321 * (members, ",") 322 * element.split 323 * {"members"}, item 324 * ',' delim 325 * 326 * (3) Given a 'cname' column with the value "some.dom.ain.", extract 327 * "some", which becomes the value of the expression. 328 * (cname, "%s.*") 329 * element.extract 330 * { fmt 331 * {mmt_begin}, 332 * {mmt_item}, 333 * {mmt_string, "."}, 334 * {mmt_any}, 335 * {mmt_end} 336 * }, 337 * {"cname"} item 338 */ 339 typedef struct { 340 __nis_mapping_element_type_t type; 341 union { 342 __nis_mapping_item_t item; 343 struct { 344 __nis_mapping_format_t *fmt; 345 int numItems; 346 __nis_mapping_item_t *item; 347 bool_t doElide; 348 unsigned char elide; 349 } print; 350 struct { 351 __nis_mapping_item_t item; 352 unsigned char delim; 353 } split; 354 struct { 355 __nis_mapping_format_t *fmt; 356 __nis_mapping_item_t item; 357 } extract; 358 } element; 359 } __nis_mapping_sub_element_t; 360 361 /* 362 * Mapping rule element 363 * 364 * Each element/sub-element represents the value(s) derived according to 365 * the semantics of the element. Although not explicitly represented here, 366 * values are either strings or BER byte sequences. 367 * 368 * type Type of the 'element' union 369 * element.item A single item 370 * element.print printf(3C)-style value 371 * fmt Array of formatting elements, terminated by 'mmt_end' 372 * numSubElements Number of sub-elements in the 'subElement' array 373 * subElement Array of 'numSubElements' sub-elements 374 * doElide Should the last character of the (string) value(s) be 375 * removed ? 376 * elide Character to be removed 377 * element.split Item value string split into multiple values 378 * item A single item 379 * delim The separator character for the split 380 * element.match Assignment of item values by matching to a format 381 * fmt Array of formatting elements, terminated by 'mmt_end' 382 * numItems Number of items in the 'item' array 383 * item Array of 'numItems' items 384 * element.extract Extraction of a sub-string from an item value 385 * fmt Array of formatting elements, terminated by 'mmt_end' 386 * item A single item 387 * 388 * Examples; items represented by just the item name. 389 * 390 * (1) The value of the 'name' column. 391 * name 392 * element.item 393 * {"name"} item 394 * 395 * (2) Example (1) for a sub-element showed how to construct a value from 396 * a printf(3C)-style format string and one or more item values. 397 * However that example is only valid when used as a sub-expression 398 * (in place of an item in a 'print' list, for example). If 399 * ("{crypt}%s", passwd) 400 * was part of a rule like 401 * userPassword=("{crypt}%s", passwd) 402 * the representation would use a __nis_mapping_element_t as follows. 403 * element.print 404 * { fmt 405 * {mmt_begin}, 406 * {mmt_string, "{crypt}"}, 407 * {mmt_item}, 408 * {mmt_end} 409 * }, 410 * 1, numSubElements 411 * { subElement 412 * me_item, type 413 * {"passwd"} item 414 * }, 415 * FALSE, doElide 416 * '\0' elide (unused) 417 * 418 * (3) Match a value such as "{dh-1024}abcdef000234" to a template format 419 * "{%s}%s", assign "dh-1024" to the 'auth_type' column, and 420 * "abcdef000234" to the 'public_data' column. 421 * ("{%s}%s", auth_type, public_data) 422 * element.match 423 * { fmt 424 * {mmt_begin}, 425 * {mmt_string, "{"}, 426 * {mmt_item}, 427 * {mmt_string, "}"}, 428 * {mmt_item}, 429 * {mmt_end} 430 * } 431 * 2, numItems 432 * { item 433 * {"auth_type"}, 434 * {"public_data"} 435 * } 436 */ 437 typedef struct __nis_mapping_element_struct { 438 __nis_mapping_element_type_t type; 439 union { 440 __nis_mapping_item_t item; 441 struct { 442 __nis_mapping_format_t *fmt; 443 int numSubElements; 444 __nis_mapping_sub_element_t *subElement; 445 bool_t doElide; 446 unsigned char elide; 447 } print; 448 struct { 449 __nis_mapping_item_t item; 450 unsigned char delim; 451 } split; 452 struct { 453 __nis_mapping_format_t *fmt; 454 int numItems; 455 __nis_mapping_item_t *item; 456 } match; 457 struct { 458 __nis_mapping_format_t *fmt; 459 __nis_mapping_item_t item; 460 } extract; 461 } element; 462 } __nis_mapping_element_t; 463 464 /* 465 * One side (left or right) of a mapping rule 466 * 467 * Example 468 * The rule 469 * userPassword=("{crypt}%s", passwd) 470 * would be reprsented by a __nis_mapping_rule_t as follows 471 * { lhs 472 * 1, numElements 473 * { element 474 * me_item, 475 * {"userPassword"} 476 * } 477 * }, 478 * { rhs 479 * 1, numElements 480 * { element 481 * me_print, 482 * { 483 * See example (2) under 484 * __nis_mapping_element_t 485 * above 486 * } 487 * } 488 * } 489 */ 490 typedef struct { 491 int numElements; 492 __nis_mapping_element_t *element; 493 } __nis_mapping_rlhs_t; 494 495 /* A single mapping rule: attribute -> column or column -> attribute */ 496 typedef struct { 497 __nis_mapping_rlhs_t lhs; 498 __nis_mapping_rlhs_t rhs; 499 } __nis_mapping_rule_t; 500 501 /* 502 * Map (sub-set of) NIS+ object to location(s) in the LDAP DB 503 * 504 * read base/scope/filter triple used to read data from LDAP; 505 * LDAP_SCOPE_UNKNOWN indicates that 'read' is unused 506 * write base/scope/attrlist triple used to write data to LDAP; 507 * LDAP_SCOPE_UNKNOWN indicates that 'write' is unused 508 * delDisp What should happen to the LDAP entry when the corresponding 509 * NIS+ data is deleted. 510 * dbIdName The dbId for the delete rule set (if any) 511 * numDbIds The number of rules in the 'dbId' rule set 512 * dbId The delete rule set; this field must point to a valid 513 * rule set if 'delDisp' is 'dd_perDbId'; ignored otherwise 514 * next Pointer to the next __nis_object_dn_t structure for this 515 * NIS+ object. 516 * 517 * Example 518 * The "group.org_dir.x.y.z." NIS+ table should be read from and 519 * written to the "ou=Group" container at "dc=x,dc=y,dc=z". Upon 520 * NIS+ entry deletion, we should always attempt to delete the 521 * corresponding LDAP attributes. 522 * 523 * { read 524 * "ou=Group,dc=x,dc=y,dc=z", 525 * LDAP_SCOPE_ONELEVEL, 526 * "objectClass=posixGroup" 527 * }, 528 * { write 529 * "ou=Group,dc=x,dc=y,dc=z", 530 * LDAP_SCOPE_ONELEVEL, 531 * "objectClass=posixGroup" 532 * }, 533 * dd_always, delDisp 534 * NULL, dbIdName 535 * 0, 536 * NULL, dbId 537 * NULL next 538 */ 539 typedef struct { 540 __nis_search_triple_t read; 541 __nis_search_triple_t write; 542 __nis_delete_disp_t delDisp; 543 char *dbIdName; 544 int numDbIds; 545 __nis_mapping_rule_t **dbId; /* Delete rule set */ 546 void *next; 547 } __nis_object_dn_t; 548 549 /* 550 * Per-dbId or -object mapping 551 * 552 * Initially collected per-dbId (so that item.name=dbId), the 553 * __nis_table_mapping_t's are later stored per-object (whereupon 554 * item.name=objName). 555 * 556 * item Structure used by the hash_item functions 557 * dbId The dbId associated with the __nis_table_mapping_t 558 * structure 559 * index Object sub-set specification; only defined for 560 * tables; index.numIndexes equal to zero means that 561 * the 'index' is unused. 562 * next Pointer to next table sub-set, if any 563 * numColumns Number of columns if the object is a table 564 * column Column names 565 * initTtlLo Lower limit on the initial TTL 566 * initTtlHi Upper limit on the initial TTL 567 * ttl TTL set after refresh 568 * commentChar NIS map comment character 569 * objectDN Location in the LDAP DB 570 * numSplits number of split fields 571 * separatorStr separator string to break up NIS split field attributes 572 * usedns_flag indicates if the -b option to makedbm is used for a map. 573 * securemap_flag indicates if the -s option to makedbm is used for a map. 574 * __nis_mapping_element_t Parsed format strings and name fields storage 575 * numRulesFromLDAP Number of rules (and hence elements in the 576 * 'ruleFromLDAP' array) for mapping LDAP entries 577 * to NIS+ objects 578 * ruleFromLDAP 579 * numRulesToLDAP Number of rules (and hence elements in the 580 * 'ruleToLDAP' array) for mapping NIS+ objects to 581 * LDAP entries 582 * ruleToLDAP 583 * objType The NIS+ object type; NIS_BOGUS_OBJ used to indicate 584 * not set (in which case the other object data fields 585 * should be assumed to be invalid) 586 * objName The fully qualified name of the NIS+ object 587 * objPath The name used internally by libnisdb (which 588 * is path to the data file for the table/directory 589 * containing the object) 590 * obj A copy of the object itself 591 * isMaster Set if this machine is the master for the object 592 * (actually for the directory containing it) 593 * seq_num A sequence number representing the order of the maps 594 * as listed in the NISLDAPmapping.template file. 595 * 596 * Example 597 * Map the subset of the NIS+ 'group.org_dir.x.y.z.' table for which 598 * is true that the 'name' starts with 'a' or 'o' to location per 599 * the __nis_object_dn_t example above. No translation rules. 600 * 601 * { item 602 * "group.org_dir.x.y.z." name 603 * <omitted> 604 * }, 605 * "group_subset", dbId 606 * 1, numIndexes 607 * { index 608 * 1, 609 * {"name"}, 610 * { 611 * {mmt_begin}, 612 * { 613 * mmt_single, 614 * 2, 615 * {'a', 'o'}, 616 * {'a', 'o'}, 617 * } 618 * {mmt_any}, 619 * {mmt_end} 620 * } 621 * } 622 * NULL, next 623 * 4, numColumns 624 * { column 625 * "name", 626 * "passwd", 627 * "gid", 628 * "members" 629 * }, 630 * 1800, initTtlLo 631 * 5400, initTtlHi 632 * 3600, ttl 633 * '#', commentChar 634 * <see __nis_object_dn_t example>, objectDN 635 * 0, numSplits 636 * NULL, separatorStr 637 * 0, usedns_flag 638 * 0, securemap_flag 639 * <see __nis_mapping_element_t example>, e 640 * 0, numRulesFromLDAP 641 * NULL, ruleFromLDAP 642 * 0, numRulesToLDAP 643 * NULL ruleToLDAP 644 * NIS_TABLE_OBJ, objType 645 * "group.org_dir.x.y.z.", objName 646 * "/var/nis/data/group.org_dir" objPath 647 * <pointer to NIS+ object> obj 648 * 1 isMaster 649 */ 650 typedef struct { 651 __nis_hash_item_mt item; /* item.name=dbId||objName */ 652 char *dbId; /* Used during initializaton */ 653 __nis_index_t index; 654 void *next; /* Next sub-set spec */ 655 void *seqNext; /* Next in config sequence */ 656 int numColumns; 657 char **column; 658 time_t initTtlLo; 659 time_t initTtlHi; 660 time_t ttl; 661 char commentChar; 662 __nis_object_dn_t *objectDN; 663 int numSplits; 664 char *separatorStr; 665 int usedns_flag; 666 int securemap_flag; 667 __nis_mapping_element_t *e; 668 int numRulesFromLDAP; 669 __nis_mapping_rule_t **ruleFromLDAP; 670 int numRulesToLDAP; 671 __nis_mapping_rule_t **ruleToLDAP; 672 /* 673 * The following fields contain information about the mapped object. 674 */ 675 zotypes objType; 676 char *objName; /* FQ object name */ 677 char *objPath; /* nisdb's internal name */ 678 nis_object *obj; /* NIS+ object */ 679 int isMaster; /* Master for this object ? */ 680 int seq_num; 681 } __nis_table_mapping_t; 682 683 /* End object mappings */ 684 685 /* Default config file paths */ 686 #define DEFAULTCONFFILE "/var/nis/NIS+LDAPmapping" 687 #define ETCCONFFILE "/etc/default/rpc.nisd" 688 #define YP_DEFAULTCONFFILE NTOL_MAP_FILE 689 #define YP_ETCCONFFILE NTOL_CONFIG_FILE 690 691 /* Path to the root object dir file */ 692 #define ROOTDIRFILE "/var/nis/data/root_dir" 693 /* Path to the root object file */ 694 #define ROOTOBJFILE "/var/nis/data/root.object" 695 696 extern __nis_table_mapping_t *ldapMappingSeq; 697 extern int yp2ldap; 698 699 /* Exported functions */ 700 int parseConfig(char **ldapCLA, char *ldapConfFile); 701 int linked2hash(__nis_table_mapping_t *tlist); 702 int dbids2objs(__nis_hash_table_mt *objs, 703 __nis_hash_table_mt *dbids); 704 void __make_legal(char *s); 705 char *internal_table_name(nis_name name, char *res); 706 nis_name relative_name(char *s); 707 char *internalTableName(char *name); 708 __nis_table_mapping_t *getObjMapping(char *name, char *intNameArg, 709 int asObj, 710 int *doRead, int *doWrite); 711 712 #ifdef __cplusplus 713 } 714 #endif /* __cplusplus */ 715 716 #endif /* _LDAP_PARSE_H */ 717