17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*36e852a1SRaja Andra * Common Development and Distribution License (the "License"). 6*36e852a1SRaja Andra * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*36e852a1SRaja Andra * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <sys/types.h> 287c478bd9Sstevel@tonic-gate #include <sys/stat.h> 297c478bd9Sstevel@tonic-gate #include <sys/param.h> 307c478bd9Sstevel@tonic-gate #include <errno.h> 317c478bd9Sstevel@tonic-gate #include <string.h> 327c478bd9Sstevel@tonic-gate #include <strings.h> 337c478bd9Sstevel@tonic-gate #include <ctype.h> 347c478bd9Sstevel@tonic-gate #include <malloc.h> 357c478bd9Sstevel@tonic-gate #include <stdlib.h> 367c478bd9Sstevel@tonic-gate #include <deflt.h> 377c478bd9Sstevel@tonic-gate #include <limits.h> 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #include "ldap_parse.h" 407c478bd9Sstevel@tonic-gate #include "ldap_glob.h" 417c478bd9Sstevel@tonic-gate #include "ldap_attr.h" 427c478bd9Sstevel@tonic-gate #include "ldap_util.h" 437c478bd9Sstevel@tonic-gate #include "ldap_map.h" 447c478bd9Sstevel@tonic-gate #include "ldap_ruleval.h" 457c478bd9Sstevel@tonic-gate #include "nis_parse_ldap_conf.h" 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate int yp2ldap = 0; 487c478bd9Sstevel@tonic-gate /* 497c478bd9Sstevel@tonic-gate * List of mapping structures in original (i.e., as in config file) order. 507c478bd9Sstevel@tonic-gate * Lined on the 'seqNext' field. 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate __nis_table_mapping_t *ldapMappingSeq = 0; 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate /* 557c478bd9Sstevel@tonic-gate * Call the parser for the config file 'ldapConfFile', and command line 567c478bd9Sstevel@tonic-gate * attribute settings per 'ldapCLA'. 577c478bd9Sstevel@tonic-gate * 587c478bd9Sstevel@tonic-gate * Returns 597c478bd9Sstevel@tonic-gate * 0 Success 607c478bd9Sstevel@tonic-gate * -1 Config file stat/open or parse error 617c478bd9Sstevel@tonic-gate * 1 No mapping should be used. 627c478bd9Sstevel@tonic-gate */ 637c478bd9Sstevel@tonic-gate int 647c478bd9Sstevel@tonic-gate parseConfig(char **ldapCLA, char *ldapConfFile) { 657c478bd9Sstevel@tonic-gate int ret; 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* 687c478bd9Sstevel@tonic-gate * Establish defaults for ldapDBTableMapping, so that we have 697c478bd9Sstevel@tonic-gate * valid values even if there's no mapping config to parse. 707c478bd9Sstevel@tonic-gate */ 717c478bd9Sstevel@tonic-gate ldapDBTableMapping.initTtlLo = (3600-1800); 727c478bd9Sstevel@tonic-gate ldapDBTableMapping.initTtlHi = (3600+1800); 737c478bd9Sstevel@tonic-gate ldapDBTableMapping.ttl = 3600; 747c478bd9Sstevel@tonic-gate ldapDBTableMapping.enumExpire = 0; 757c478bd9Sstevel@tonic-gate ldapDBTableMapping.fromLDAP = FALSE; 767c478bd9Sstevel@tonic-gate ldapDBTableMapping.toLDAP = FALSE; 777c478bd9Sstevel@tonic-gate ldapDBTableMapping.expire = 0; 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate ret = parse_ldap_migration((const char **)ldapCLA, ldapConfFile); 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate return (ret); 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate /* 857c478bd9Sstevel@tonic-gate * Convert the linked list of __nis_table_mapping_t's (produced by the 867c478bd9Sstevel@tonic-gate * attribute parser) to the 'ldapMappingList', keyed on the objPath. 877c478bd9Sstevel@tonic-gate * 887c478bd9Sstevel@tonic-gate * Once this function has returned, the 'tlist' is invalid, and must 897c478bd9Sstevel@tonic-gate * not be used in any way. 907c478bd9Sstevel@tonic-gate */ 917c478bd9Sstevel@tonic-gate int 927c478bd9Sstevel@tonic-gate linked2hash(__nis_table_mapping_t *tlist) { 937c478bd9Sstevel@tonic-gate __nis_hash_table_mt dbids; 947c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t, *told, *x, **seqNext; 957c478bd9Sstevel@tonic-gate __nis_object_dn_t *o, *to; 967c478bd9Sstevel@tonic-gate char *myself = "linked2hash"; 977c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 987c478bd9Sstevel@tonic-gate char *selectDbid = getenv("NISLDAPSELECTDBID"); 997c478bd9Sstevel@tonic-gate char **sdi, *s; 1007c478bd9Sstevel@tonic-gate int i, nsdi; 1017c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate if (tlist == 0) 1057c478bd9Sstevel@tonic-gate return (0); 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate /* proxyInfo.default_nis_domain must end in a dot */ 1087c478bd9Sstevel@tonic-gate { 1097c478bd9Sstevel@tonic-gate int len = slen(proxyInfo.default_nis_domain); 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate if (len > 0 && proxyInfo.default_nis_domain[len-1] != '.') { 1127c478bd9Sstevel@tonic-gate char *domain = am(myself, len+2); 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate (void) memcpy(domain, proxyInfo.default_nis_domain, 1157c478bd9Sstevel@tonic-gate len); 1167c478bd9Sstevel@tonic-gate domain[len] = '.'; 1177c478bd9Sstevel@tonic-gate domain[len+1] = '\0'; 1187c478bd9Sstevel@tonic-gate sfree(proxyInfo.default_nis_domain); 1197c478bd9Sstevel@tonic-gate proxyInfo.default_nis_domain = domain; 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 1247c478bd9Sstevel@tonic-gate for (nsdi = 0, s = selectDbid; s != 0 && *s != '\0'; s++) { 1257c478bd9Sstevel@tonic-gate if (*s != ' ') { 1267c478bd9Sstevel@tonic-gate nsdi++; 1277c478bd9Sstevel@tonic-gate while (*s != ' ' && *s != '\0') 1287c478bd9Sstevel@tonic-gate s++; 1297c478bd9Sstevel@tonic-gate if (*s == '\0') 1307c478bd9Sstevel@tonic-gate break; 1317c478bd9Sstevel@tonic-gate } 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate if (nsdi > 0) { 1347c478bd9Sstevel@tonic-gate sdi = am(myself, nsdi * sizeof (sdi[0])); 1357c478bd9Sstevel@tonic-gate if (sdi == 0) 1367c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 1377c478bd9Sstevel@tonic-gate "%s: Memory alloc failure for dbId selection", 1387c478bd9Sstevel@tonic-gate myself); 1397c478bd9Sstevel@tonic-gate else { 1407c478bd9Sstevel@tonic-gate for (i = 0, s = selectDbid; *s != '\0'; s++) { 1417c478bd9Sstevel@tonic-gate if (*s != ' ') { 1427c478bd9Sstevel@tonic-gate sdi[i++] = selectDbid; 1437c478bd9Sstevel@tonic-gate while (*s != ' ' && *s != '\0') 1447c478bd9Sstevel@tonic-gate s++; 1457c478bd9Sstevel@tonic-gate if (*s != '\0') { 1467c478bd9Sstevel@tonic-gate *s = '\0'; 1477c478bd9Sstevel@tonic-gate s++; 1487c478bd9Sstevel@tonic-gate } else 1497c478bd9Sstevel@tonic-gate break; 1507c478bd9Sstevel@tonic-gate selectDbid = s; 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate __nis_init_hash_table(&dbids, 0); 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate seqNext = &ldapMappingSeq; 1607c478bd9Sstevel@tonic-gate for (t = tlist; t != 0; t = told) { 1617c478bd9Sstevel@tonic-gate int len; 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 1647c478bd9Sstevel@tonic-gate /* 1657c478bd9Sstevel@tonic-gate * If the dbId doesn't match 'selectDbid', skip this 1667c478bd9Sstevel@tonic-gate * mapping. Re-insert on 'tlist', in order to keep memory 1677c478bd9Sstevel@tonic-gate * leak checking happy. Note that 'tlist' may end up pointing 1687c478bd9Sstevel@tonic-gate * into the real mapping list, so it shouldn't be used once 1697c478bd9Sstevel@tonic-gate * this routine has been called. 1707c478bd9Sstevel@tonic-gate */ 1717c478bd9Sstevel@tonic-gate if (nsdi > 0) { 1727c478bd9Sstevel@tonic-gate for (i = 0; i < nsdi; i++) { 1737c478bd9Sstevel@tonic-gate if (strcmp(sdi[i], t->dbId) == 0) 1747c478bd9Sstevel@tonic-gate break; 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate if (i >= nsdi) { 1777c478bd9Sstevel@tonic-gate told = t->next; 1787c478bd9Sstevel@tonic-gate if (tlist != t) 1797c478bd9Sstevel@tonic-gate t->next = tlist; 1807c478bd9Sstevel@tonic-gate else 1817c478bd9Sstevel@tonic-gate t->next = 0; 1827c478bd9Sstevel@tonic-gate tlist = t; 1837c478bd9Sstevel@tonic-gate continue; 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate told = t->next; 1897c478bd9Sstevel@tonic-gate t->next = 0; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate /* Make sure t->item.name is set correctly */ 1927c478bd9Sstevel@tonic-gate if (t->item.name == 0) 1937c478bd9Sstevel@tonic-gate t->item.name = t->dbId; 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate /* Remove leading dot in object name, if any */ 1967c478bd9Sstevel@tonic-gate len = slen(t->objName); 1977c478bd9Sstevel@tonic-gate while (len > 0 && t->objName[0] == '.') { 1987c478bd9Sstevel@tonic-gate (void) memmove(t->objName, &t->objName[1], len); 1997c478bd9Sstevel@tonic-gate len -= 1; 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate /* 2037c478bd9Sstevel@tonic-gate * Initialize the object path, which is what we'll 2047c478bd9Sstevel@tonic-gate * rehash on. 2057c478bd9Sstevel@tonic-gate */ 2067c478bd9Sstevel@tonic-gate if (yp2ldap) { 2077c478bd9Sstevel@tonic-gate t->objPath = internal_table_name(t->objName, 2087c478bd9Sstevel@tonic-gate t->objPath); 2097c478bd9Sstevel@tonic-gate if (!t->objPath) { 2107c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 2117c478bd9Sstevel@tonic-gate "%s: Failed to obtain internal table name for \"%s\"", 2127c478bd9Sstevel@tonic-gate myself, t->objName); 2137c478bd9Sstevel@tonic-gate return (-1); 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate } else { 2167c478bd9Sstevel@tonic-gate t->objPath = am(myself, len + MAXPATHLEN + 1); 2177c478bd9Sstevel@tonic-gate if (t->objPath == 0) 2187c478bd9Sstevel@tonic-gate return (-1); 2197c478bd9Sstevel@tonic-gate if (internal_table_name(t->objName, 2207c478bd9Sstevel@tonic-gate t->objPath) == 0) { 2217c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 2227c478bd9Sstevel@tonic-gate "%s: Failed to obtain internal table name for \"%s\"", 2237c478bd9Sstevel@tonic-gate myself, t->objName); 2247c478bd9Sstevel@tonic-gate return (-1); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate /* 2297c478bd9Sstevel@tonic-gate * Initialize the column name array. 2307c478bd9Sstevel@tonic-gate */ 2317c478bd9Sstevel@tonic-gate if (!yp2ldap) { 2327c478bd9Sstevel@tonic-gate if (setColumnsDuringConfig && setColumnNames(t)) { 2337c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 2347c478bd9Sstevel@tonic-gate "%s: Unable to find column names for \"%s\"", 2357c478bd9Sstevel@tonic-gate myself, NIL(t->objName)); 2367c478bd9Sstevel@tonic-gate return (-1); 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate /* 2417c478bd9Sstevel@tonic-gate * If there are multiple mapping target containers, make 2427c478bd9Sstevel@tonic-gate * each one into it's own mapping structure. They can all 2437c478bd9Sstevel@tonic-gate * be minimal copies (i.e., share pointers to sub-structures 2447c478bd9Sstevel@tonic-gate * other than the objectDN). 2457c478bd9Sstevel@tonic-gate * 2467c478bd9Sstevel@tonic-gate * If objectDN is NULL, we will never use this structure. 2477c478bd9Sstevel@tonic-gate * In order to allow the rest of the mapping code to assume 2487c478bd9Sstevel@tonic-gate * objectDN != NULL, skip the mapping (even if x == t). 2497c478bd9Sstevel@tonic-gate */ 2507c478bd9Sstevel@tonic-gate for (o = to = t->objectDN; o != 0; o = o->next) { 2517c478bd9Sstevel@tonic-gate __nis_table_mapping_t *p; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate if (o == to) { 2547c478bd9Sstevel@tonic-gate x = t; 2557c478bd9Sstevel@tonic-gate /* 2567c478bd9Sstevel@tonic-gate * Only insert the first mapping for an 2577c478bd9Sstevel@tonic-gate * object on the sequential list. 2587c478bd9Sstevel@tonic-gate */ 2597c478bd9Sstevel@tonic-gate *seqNext = t; 2607c478bd9Sstevel@tonic-gate t->seqNext = 0; 2617c478bd9Sstevel@tonic-gate seqNext = (__nis_table_mapping_t **)&t->seqNext; 2627c478bd9Sstevel@tonic-gate } else { 2637c478bd9Sstevel@tonic-gate x = am(myself, sizeof (*x)); 2647c478bd9Sstevel@tonic-gate if (x == 0) { 2657c478bd9Sstevel@tonic-gate /* 2667c478bd9Sstevel@tonic-gate * This happens during rpc.nisd 2677c478bd9Sstevel@tonic-gate * initialization, and it's an 2687c478bd9Sstevel@tonic-gate * unrecoverable disaster, so don't 2697c478bd9Sstevel@tonic-gate * bother cleaning up. 2707c478bd9Sstevel@tonic-gate */ 2717c478bd9Sstevel@tonic-gate return (-1); 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate memcpy(x, t, sizeof (*x)); 2747c478bd9Sstevel@tonic-gate x->objectDN = o; 2757c478bd9Sstevel@tonic-gate x->next = 0; 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate /* 2797c478bd9Sstevel@tonic-gate * If x->objectDN->write.base is NULL, clone it from 2807c478bd9Sstevel@tonic-gate * x->objectDN->read.base. 2817c478bd9Sstevel@tonic-gate */ 2827c478bd9Sstevel@tonic-gate if (x->objectDN->write.scope != LDAP_SCOPE_UNKNOWN) { 2837c478bd9Sstevel@tonic-gate if (x->objectDN->write.base == 0 && 2847c478bd9Sstevel@tonic-gate x->objectDN->read.base != 0) { 2857c478bd9Sstevel@tonic-gate x->objectDN->write.base = 2867c478bd9Sstevel@tonic-gate sdup(myself, T, 2877c478bd9Sstevel@tonic-gate x->objectDN->read.base); 2887c478bd9Sstevel@tonic-gate if (x->objectDN->write.base == 0) 2897c478bd9Sstevel@tonic-gate return (-1); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate if (x->objectDN->write.attrs == 0 && 2927c478bd9Sstevel@tonic-gate x->objectDN->read.attrs != 0) { 2937c478bd9Sstevel@tonic-gate x->objectDN->write.attrs = 2947c478bd9Sstevel@tonic-gate sdup(myself, T, 2957c478bd9Sstevel@tonic-gate x->objectDN->read.attrs); 2967c478bd9Sstevel@tonic-gate if (x->objectDN->write.attrs == 0) 2977c478bd9Sstevel@tonic-gate return (-1); 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate if (o != to) { 3027c478bd9Sstevel@tonic-gate /* Insert last on the 't->next' list */ 3037c478bd9Sstevel@tonic-gate for (p = t; p->next != 0; p = p->next); 3047c478bd9Sstevel@tonic-gate p->next = x; 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate /* Insert on dbid hash list */ 3097c478bd9Sstevel@tonic-gate if (t->objectDN != 0 && !__nis_insert_item_mt(t, &dbids, 0)) { 3107c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 3117c478bd9Sstevel@tonic-gate "%s: Error inserting mapping for \"%s\" on hash list", 3127c478bd9Sstevel@tonic-gate myself, NIL(t->objName)); 3137c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 3147c478bd9Sstevel@tonic-gate abort(); 3157c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 3167c478bd9Sstevel@tonic-gate return (-1); 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate /* 3217c478bd9Sstevel@tonic-gate * dbids2objs() will remove the entries on 'dbids', so no need 3227c478bd9Sstevel@tonic-gate * to clean up that list from this function. 3237c478bd9Sstevel@tonic-gate */ 3247c478bd9Sstevel@tonic-gate return (dbids2objs(&dbids, &ldapMappingList)); 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate int 3287c478bd9Sstevel@tonic-gate dbids2objs(__nis_hash_table_mt *dbids, __nis_hash_table_mt *objs) { 3297c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t, *o; 3307c478bd9Sstevel@tonic-gate char *myself = "dbids2objs"; 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate while ((t = __nis_pop_item_mt(dbids)) != 0) { 3347c478bd9Sstevel@tonic-gate /* Previous entry for this object ? */ 3357c478bd9Sstevel@tonic-gate o = __nis_find_item_mt(t->objPath, objs, -1, 0); 3367c478bd9Sstevel@tonic-gate if (o != 0) { 3377c478bd9Sstevel@tonic-gate __nis_table_mapping_t *p = o; 3387c478bd9Sstevel@tonic-gate /* 3397c478bd9Sstevel@tonic-gate * Mapping already exists, so this is an alternate. 3407c478bd9Sstevel@tonic-gate * Find the end of the list of any previous alt's, 3417c478bd9Sstevel@tonic-gate * and insert there. 3427c478bd9Sstevel@tonic-gate */ 3437c478bd9Sstevel@tonic-gate while (p->next != 0) { 3447c478bd9Sstevel@tonic-gate p = p->next; 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate p->next = t; 3477c478bd9Sstevel@tonic-gate if (!__nis_release_item(o, objs, -1)) { 3487c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 3497c478bd9Sstevel@tonic-gate "%s: __nis_release_item error", 3507c478bd9Sstevel@tonic-gate myself); 3517c478bd9Sstevel@tonic-gate return (-1); 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate } else { 3547c478bd9Sstevel@tonic-gate t->item.name = t->objPath; 3557c478bd9Sstevel@tonic-gate if (!__nis_insert_item_mt(t, objs, 0)) { 3567c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 3577c478bd9Sstevel@tonic-gate "%s: __nis_insert_item error", 3587c478bd9Sstevel@tonic-gate myself); 3597c478bd9Sstevel@tonic-gate return (-1); 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate } 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate return (0); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate /* 3687c478bd9Sstevel@tonic-gate * internal_table_name() 3697c478bd9Sstevel@tonic-gate * 3707c478bd9Sstevel@tonic-gate * Removes the local domain part from a fully qualified name 3717c478bd9Sstevel@tonic-gate * to create the internal table name for an object. These tables are 3727c478bd9Sstevel@tonic-gate * stored in /var/nis/<hostname> 3737c478bd9Sstevel@tonic-gate * 3747c478bd9Sstevel@tonic-gate * Imported from rpc.nisd/nisdb.c. 3757c478bd9Sstevel@tonic-gate */ 3767c478bd9Sstevel@tonic-gate char * 3777c478bd9Sstevel@tonic-gate internal_table_name(nis_name name, char *res) 3787c478bd9Sstevel@tonic-gate { 3797c478bd9Sstevel@tonic-gate char *s, *t; 3807c478bd9Sstevel@tonic-gate int i, j; 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate if (yp2ldap) { 3837c478bd9Sstevel@tonic-gate if (name == NULL) 3847c478bd9Sstevel@tonic-gate return (NULL); 3857c478bd9Sstevel@tonic-gate res = s_strndup(name, strlen(name)); 3867c478bd9Sstevel@tonic-gate if (res == NULL) 3877c478bd9Sstevel@tonic-gate return (NULL); 3887c478bd9Sstevel@tonic-gate return (res); 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate if (res == NULL) 3927c478bd9Sstevel@tonic-gate return (NULL); 3937c478bd9Sstevel@tonic-gate /* pointer at the first character of the table name */ 3947c478bd9Sstevel@tonic-gate s = relative_name(name); 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate /* 3977c478bd9Sstevel@tonic-gate * If s == NULL then either this is a request for a lookup 3987c478bd9Sstevel@tonic-gate * in our parents namespace (ILLEGAL), or we're the root 3997c478bd9Sstevel@tonic-gate * server and this is a lookup in our namespace. 4007c478bd9Sstevel@tonic-gate */ 4017c478bd9Sstevel@tonic-gate if (s) { 4027c478bd9Sstevel@tonic-gate return (NULL); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate t = strrchr(res, '/'); 4067c478bd9Sstevel@tonic-gate if (t) 4077c478bd9Sstevel@tonic-gate t++; /* Point past the slash */ 4087c478bd9Sstevel@tonic-gate /* Strip off the quotes if they were used here. */ 4097c478bd9Sstevel@tonic-gate if (t[0] == '"') { 4107c478bd9Sstevel@tonic-gate /* Check for simply a quoted quote. */ 4117c478bd9Sstevel@tonic-gate if (t[1] != '"') { 4127c478bd9Sstevel@tonic-gate j = strlen(t); 4137c478bd9Sstevel@tonic-gate /* shift string left by one */ 4147c478bd9Sstevel@tonic-gate for (i = 0; i < j; i++) 4157c478bd9Sstevel@tonic-gate t[i] = t[i+1]; 4167c478bd9Sstevel@tonic-gate t[j-2] = '\0'; /* Trounce trailing dquote */ 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate } 4197c478bd9Sstevel@tonic-gate /* 4207c478bd9Sstevel@tonic-gate * OK so now we have the unique name for the table. 4217c478bd9Sstevel@tonic-gate * At this point we can fix it up to match local 4227c478bd9Sstevel@tonic-gate * file system conventions if we so desire. Since it 4237c478bd9Sstevel@tonic-gate * is only used in this form by _this_ server we can 4247c478bd9Sstevel@tonic-gate * mangle it any way we want, as long as we are consistent 4257c478bd9Sstevel@tonic-gate * about it. :-) 4267c478bd9Sstevel@tonic-gate */ 4277c478bd9Sstevel@tonic-gate __make_legal(res); 4287c478bd9Sstevel@tonic-gate return (res); 4297c478bd9Sstevel@tonic-gate } 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate /* 4327c478bd9Sstevel@tonic-gate * SYSTEM DEPENDENT 4337c478bd9Sstevel@tonic-gate * 4347c478bd9Sstevel@tonic-gate * This function makes the table name "legal" for the underlying file system. 4357c478bd9Sstevel@tonic-gate * 4367c478bd9Sstevel@tonic-gate * Imported from rpc.nisd/nisdb.c. 4377c478bd9Sstevel@tonic-gate */ 4387c478bd9Sstevel@tonic-gate void 4397c478bd9Sstevel@tonic-gate __make_legal(char *s) 4407c478bd9Sstevel@tonic-gate { 4417c478bd9Sstevel@tonic-gate while (*s) { 4427c478bd9Sstevel@tonic-gate if (isupper(*s)) 4437c478bd9Sstevel@tonic-gate *s = tolower(*s); 4447c478bd9Sstevel@tonic-gate s++; 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate /* 4497c478bd9Sstevel@tonic-gate * relative_name() 4507c478bd9Sstevel@tonic-gate * This internal function will remove from the NIS name, the domain 4517c478bd9Sstevel@tonic-gate * name of the current server, this will leave the unique part in 4527c478bd9Sstevel@tonic-gate * the name this becomes the "internal" version of the name. If this 4537c478bd9Sstevel@tonic-gate * function returns NULL then the name we were given to resolve is 4547c478bd9Sstevel@tonic-gate * bad somehow. 4557c478bd9Sstevel@tonic-gate * 4567c478bd9Sstevel@tonic-gate * A dynamically-allocated string is returned. 4577c478bd9Sstevel@tonic-gate * 4587c478bd9Sstevel@tonic-gate * Imported from rpc.nisd/nis_log_common.c 4597c478bd9Sstevel@tonic-gate */ 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate nis_name 4627c478bd9Sstevel@tonic-gate relative_name(s) 4637c478bd9Sstevel@tonic-gate char *s; /* string with the name in it. */ 4647c478bd9Sstevel@tonic-gate { 4657c478bd9Sstevel@tonic-gate char *d; 4667c478bd9Sstevel@tonic-gate char *buf; 4677c478bd9Sstevel@tonic-gate int dl, sl; 4687c478bd9Sstevel@tonic-gate name_pos p; 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate if (s == NULL) 4717c478bd9Sstevel@tonic-gate return (NULL); 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate d = __nis_rpc_domain(); 4747c478bd9Sstevel@tonic-gate if (d == NULL) 4757c478bd9Sstevel@tonic-gate return (NULL); 4767c478bd9Sstevel@tonic-gate dl = strlen(d); /* _always dot terminated_ */ 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate buf = strdup(s); 4797c478bd9Sstevel@tonic-gate if (buf == NULL) 4807c478bd9Sstevel@tonic-gate return (NULL); 4817c478bd9Sstevel@tonic-gate strcpy(buf, s); /* Make a private copy of 's' */ 4827c478bd9Sstevel@tonic-gate sl = strlen(buf); 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate if (dl == 1) { /* We're the '.' directory */ 4857c478bd9Sstevel@tonic-gate buf[sl-1] = '\0'; /* Lose the 'dot' */ 4867c478bd9Sstevel@tonic-gate return (buf); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate p = nis_dir_cmp(buf, d); 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate /* 's' is above 'd' in the tree */ 4927c478bd9Sstevel@tonic-gate if ((p == HIGHER_NAME) || (p == NOT_SEQUENTIAL) || (p == SAME_NAME)) { 4937c478bd9Sstevel@tonic-gate free(buf); 4947c478bd9Sstevel@tonic-gate return (NULL); 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate /* Insert a NUL where the domain name starts in the string */ 4987c478bd9Sstevel@tonic-gate buf[(sl - dl) - 1] = '\0'; 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate /* Don't return a zero length name */ 5017c478bd9Sstevel@tonic-gate if (buf[0] == '\0') { 5027c478bd9Sstevel@tonic-gate free((void *)buf); 5037c478bd9Sstevel@tonic-gate return (NULL); 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate return (buf); 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate /* 5107c478bd9Sstevel@tonic-gate * Wrapper for internal_table_name() that allocates a large enough 5117c478bd9Sstevel@tonic-gate * buffer for the internal name. Return value must be freed by caller. 5127c478bd9Sstevel@tonic-gate * If the input 'name' is NULL, the name of the root directory table 5137c478bd9Sstevel@tonic-gate * is returned. 5147c478bd9Sstevel@tonic-gate */ 5157c478bd9Sstevel@tonic-gate char * 5167c478bd9Sstevel@tonic-gate internalTableName(char *name) { 5177c478bd9Sstevel@tonic-gate char *buf, *res; 5187c478bd9Sstevel@tonic-gate char *myself = "internalTableName"; 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate buf = (char *)am(myself, MAXPATHLEN + NIS_MAXNAMELEN + 1); 5217c478bd9Sstevel@tonic-gate if (buf == 0) 5227c478bd9Sstevel@tonic-gate return (0); 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate if (name == 0) { 5257c478bd9Sstevel@tonic-gate (void) memcpy(buf, ROOTDIRFILE, slen(ROOTDIRFILE)); 5267c478bd9Sstevel@tonic-gate return (buf); 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate res = internal_table_name(name, buf); 5307c478bd9Sstevel@tonic-gate if (res != buf) { 5317c478bd9Sstevel@tonic-gate sfree(buf); 5327c478bd9Sstevel@tonic-gate buf = 0; 5337c478bd9Sstevel@tonic-gate } 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate return (buf); 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate /* 5397c478bd9Sstevel@tonic-gate * Return the object mapping for the object indicated either by the 5407c478bd9Sstevel@tonic-gate * internal DB name ('intNameArg'; preferred), or the FQ object name 5417c478bd9Sstevel@tonic-gate * 'name'. If 'asObj' is non-zero, the caller is interested in the 5427c478bd9Sstevel@tonic-gate * object mapping proper, not a mapping of table entries. Optionally, 5437c478bd9Sstevel@tonic-gate * also indicate if the object is mapped from (read) or to (write) LDAP. 5447c478bd9Sstevel@tonic-gate * 5457c478bd9Sstevel@tonic-gate * Note that there may be more than one mapping of the appropriate type. 5467c478bd9Sstevel@tonic-gate * Use the selectTableMapping() function in ldap_map.c to get all 5477c478bd9Sstevel@tonic-gate * alternatives. However, the function below works as a short-cut if: 5487c478bd9Sstevel@tonic-gate * 5497c478bd9Sstevel@tonic-gate * You only want an indication that _a_ mapping of the desired 5507c478bd9Sstevel@tonic-gate * type exists, or 5517c478bd9Sstevel@tonic-gate * 5527c478bd9Sstevel@tonic-gate * You want the non-objectDN information for an object-mapping 5537c478bd9Sstevel@tonic-gate * proper (i.e., _not_ the mapping for entries in a table). 5547c478bd9Sstevel@tonic-gate */ 5557c478bd9Sstevel@tonic-gate __nis_table_mapping_t * 5567c478bd9Sstevel@tonic-gate getObjMapping(char *name, char *intNameArg, int asObj, 5577c478bd9Sstevel@tonic-gate int *doRead, int *doWrite) { 5587c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t, *x; 5597c478bd9Sstevel@tonic-gate char *intName; 5607c478bd9Sstevel@tonic-gate int freeIntName = 0, rd, wr; 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate if (doRead != 0) 5637c478bd9Sstevel@tonic-gate *doRead = 0; 5647c478bd9Sstevel@tonic-gate if (doWrite != 0) 5657c478bd9Sstevel@tonic-gate *doWrite = 0; 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate if (intNameArg == 0) { 5687c478bd9Sstevel@tonic-gate if (name == 0) 5697c478bd9Sstevel@tonic-gate return (0); 5707c478bd9Sstevel@tonic-gate intName = internalTableName(name); 5717c478bd9Sstevel@tonic-gate if (intName == 0) 5727c478bd9Sstevel@tonic-gate return (0); 5737c478bd9Sstevel@tonic-gate freeIntName = 1; 5747c478bd9Sstevel@tonic-gate } else { 5757c478bd9Sstevel@tonic-gate intName = intNameArg; 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate t = __nis_find_item_mt(intName, &ldapMappingList, 0, 0); 5797c478bd9Sstevel@tonic-gate if (t == 0) { 5807c478bd9Sstevel@tonic-gate if (freeIntName) 5817c478bd9Sstevel@tonic-gate sfree(intName); 5827c478bd9Sstevel@tonic-gate return (0); 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate rd = wr = 0; 5867c478bd9Sstevel@tonic-gate for (x = t; x != 0; x = x->next) { 5877c478bd9Sstevel@tonic-gate /* 5887c478bd9Sstevel@tonic-gate * If we're looking for an object mapping, and this 5897c478bd9Sstevel@tonic-gate * one's for entries in a table, skip it. 5907c478bd9Sstevel@tonic-gate */ 5917c478bd9Sstevel@tonic-gate if (asObj && x->objType == NIS_TABLE_OBJ && 5927c478bd9Sstevel@tonic-gate x->numColumns > 0) 5937c478bd9Sstevel@tonic-gate continue; 5947c478bd9Sstevel@tonic-gate /* Check if we should read/write */ 5957c478bd9Sstevel@tonic-gate if (x->objectDN->read.scope != LDAP_SCOPE_UNKNOWN) 5967c478bd9Sstevel@tonic-gate rd++; 5977c478bd9Sstevel@tonic-gate if (x->objectDN->write.scope != LDAP_SCOPE_UNKNOWN) 5987c478bd9Sstevel@tonic-gate wr++; 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate if (doRead != 0) 6027c478bd9Sstevel@tonic-gate *doRead = (rd > 0) ? 1 : 0; 6037c478bd9Sstevel@tonic-gate if (doWrite != 0) 6047c478bd9Sstevel@tonic-gate *doWrite = (wr > 0) ? 1 : 0; 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate if (freeIntName) 6077c478bd9Sstevel@tonic-gate sfree(intName); 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate return (x); 6107c478bd9Sstevel@tonic-gate } 611