10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*11262SRajagopal.Andra@Sun.COM * Common Development and Distribution License (the "License"). 6*11262SRajagopal.Andra@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*11262SRajagopal.Andra@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate 270Sstevel@tonic-gate #include <sys/types.h> 280Sstevel@tonic-gate #include <sys/stat.h> 290Sstevel@tonic-gate #include <sys/param.h> 300Sstevel@tonic-gate #include <errno.h> 310Sstevel@tonic-gate #include <string.h> 320Sstevel@tonic-gate #include <strings.h> 330Sstevel@tonic-gate #include <ctype.h> 340Sstevel@tonic-gate #include <malloc.h> 350Sstevel@tonic-gate #include <stdlib.h> 360Sstevel@tonic-gate #include <deflt.h> 370Sstevel@tonic-gate #include <limits.h> 380Sstevel@tonic-gate 390Sstevel@tonic-gate #include "ldap_parse.h" 400Sstevel@tonic-gate #include "ldap_glob.h" 410Sstevel@tonic-gate #include "ldap_attr.h" 420Sstevel@tonic-gate #include "ldap_util.h" 430Sstevel@tonic-gate #include "ldap_map.h" 440Sstevel@tonic-gate #include "ldap_ruleval.h" 450Sstevel@tonic-gate #include "nis_parse_ldap_conf.h" 460Sstevel@tonic-gate 470Sstevel@tonic-gate int yp2ldap = 0; 480Sstevel@tonic-gate /* 490Sstevel@tonic-gate * List of mapping structures in original (i.e., as in config file) order. 500Sstevel@tonic-gate * Lined on the 'seqNext' field. 510Sstevel@tonic-gate */ 520Sstevel@tonic-gate __nis_table_mapping_t *ldapMappingSeq = 0; 530Sstevel@tonic-gate 540Sstevel@tonic-gate /* 550Sstevel@tonic-gate * Call the parser for the config file 'ldapConfFile', and command line 560Sstevel@tonic-gate * attribute settings per 'ldapCLA'. 570Sstevel@tonic-gate * 580Sstevel@tonic-gate * Returns 590Sstevel@tonic-gate * 0 Success 600Sstevel@tonic-gate * -1 Config file stat/open or parse error 610Sstevel@tonic-gate * 1 No mapping should be used. 620Sstevel@tonic-gate */ 630Sstevel@tonic-gate int 640Sstevel@tonic-gate parseConfig(char **ldapCLA, char *ldapConfFile) { 650Sstevel@tonic-gate int ret; 660Sstevel@tonic-gate 670Sstevel@tonic-gate /* 680Sstevel@tonic-gate * Establish defaults for ldapDBTableMapping, so that we have 690Sstevel@tonic-gate * valid values even if there's no mapping config to parse. 700Sstevel@tonic-gate */ 710Sstevel@tonic-gate ldapDBTableMapping.initTtlLo = (3600-1800); 720Sstevel@tonic-gate ldapDBTableMapping.initTtlHi = (3600+1800); 730Sstevel@tonic-gate ldapDBTableMapping.ttl = 3600; 740Sstevel@tonic-gate ldapDBTableMapping.enumExpire = 0; 750Sstevel@tonic-gate ldapDBTableMapping.fromLDAP = FALSE; 760Sstevel@tonic-gate ldapDBTableMapping.toLDAP = FALSE; 770Sstevel@tonic-gate ldapDBTableMapping.expire = 0; 780Sstevel@tonic-gate 790Sstevel@tonic-gate ret = parse_ldap_migration((const char **)ldapCLA, ldapConfFile); 800Sstevel@tonic-gate 810Sstevel@tonic-gate return (ret); 820Sstevel@tonic-gate } 830Sstevel@tonic-gate 840Sstevel@tonic-gate /* 850Sstevel@tonic-gate * Convert the linked list of __nis_table_mapping_t's (produced by the 860Sstevel@tonic-gate * attribute parser) to the 'ldapMappingList', keyed on the objPath. 870Sstevel@tonic-gate * 880Sstevel@tonic-gate * Once this function has returned, the 'tlist' is invalid, and must 890Sstevel@tonic-gate * not be used in any way. 900Sstevel@tonic-gate */ 910Sstevel@tonic-gate int 920Sstevel@tonic-gate linked2hash(__nis_table_mapping_t *tlist) { 930Sstevel@tonic-gate __nis_hash_table_mt dbids; 940Sstevel@tonic-gate __nis_table_mapping_t *t, *told, *x, **seqNext; 950Sstevel@tonic-gate __nis_object_dn_t *o, *to; 960Sstevel@tonic-gate char *myself = "linked2hash"; 970Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 980Sstevel@tonic-gate char *selectDbid = getenv("NISLDAPSELECTDBID"); 990Sstevel@tonic-gate char **sdi, *s; 1000Sstevel@tonic-gate int i, nsdi; 1010Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate if (tlist == 0) 1050Sstevel@tonic-gate return (0); 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate /* proxyInfo.default_nis_domain must end in a dot */ 1080Sstevel@tonic-gate { 1090Sstevel@tonic-gate int len = slen(proxyInfo.default_nis_domain); 1100Sstevel@tonic-gate 1110Sstevel@tonic-gate if (len > 0 && proxyInfo.default_nis_domain[len-1] != '.') { 1120Sstevel@tonic-gate char *domain = am(myself, len+2); 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate (void) memcpy(domain, proxyInfo.default_nis_domain, 1150Sstevel@tonic-gate len); 1160Sstevel@tonic-gate domain[len] = '.'; 1170Sstevel@tonic-gate domain[len+1] = '\0'; 1180Sstevel@tonic-gate sfree(proxyInfo.default_nis_domain); 1190Sstevel@tonic-gate proxyInfo.default_nis_domain = domain; 1200Sstevel@tonic-gate } 1210Sstevel@tonic-gate } 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 1240Sstevel@tonic-gate for (nsdi = 0, s = selectDbid; s != 0 && *s != '\0'; s++) { 1250Sstevel@tonic-gate if (*s != ' ') { 1260Sstevel@tonic-gate nsdi++; 1270Sstevel@tonic-gate while (*s != ' ' && *s != '\0') 1280Sstevel@tonic-gate s++; 1290Sstevel@tonic-gate if (*s == '\0') 1300Sstevel@tonic-gate break; 1310Sstevel@tonic-gate } 1320Sstevel@tonic-gate } 1330Sstevel@tonic-gate if (nsdi > 0) { 1340Sstevel@tonic-gate sdi = am(myself, nsdi * sizeof (sdi[0])); 1350Sstevel@tonic-gate if (sdi == 0) 1360Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 1370Sstevel@tonic-gate "%s: Memory alloc failure for dbId selection", 1380Sstevel@tonic-gate myself); 1390Sstevel@tonic-gate else { 1400Sstevel@tonic-gate for (i = 0, s = selectDbid; *s != '\0'; s++) { 1410Sstevel@tonic-gate if (*s != ' ') { 1420Sstevel@tonic-gate sdi[i++] = selectDbid; 1430Sstevel@tonic-gate while (*s != ' ' && *s != '\0') 1440Sstevel@tonic-gate s++; 1450Sstevel@tonic-gate if (*s != '\0') { 1460Sstevel@tonic-gate *s = '\0'; 1470Sstevel@tonic-gate s++; 1480Sstevel@tonic-gate } else 1490Sstevel@tonic-gate break; 1500Sstevel@tonic-gate selectDbid = s; 1510Sstevel@tonic-gate } 1520Sstevel@tonic-gate } 1530Sstevel@tonic-gate } 1540Sstevel@tonic-gate } 1550Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate __nis_init_hash_table(&dbids, 0); 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate seqNext = &ldapMappingSeq; 1600Sstevel@tonic-gate for (t = tlist; t != 0; t = told) { 1610Sstevel@tonic-gate int len; 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 1640Sstevel@tonic-gate /* 1650Sstevel@tonic-gate * If the dbId doesn't match 'selectDbid', skip this 1660Sstevel@tonic-gate * mapping. Re-insert on 'tlist', in order to keep memory 1670Sstevel@tonic-gate * leak checking happy. Note that 'tlist' may end up pointing 1680Sstevel@tonic-gate * into the real mapping list, so it shouldn't be used once 1690Sstevel@tonic-gate * this routine has been called. 1700Sstevel@tonic-gate */ 1710Sstevel@tonic-gate if (nsdi > 0) { 1720Sstevel@tonic-gate for (i = 0; i < nsdi; i++) { 1730Sstevel@tonic-gate if (strcmp(sdi[i], t->dbId) == 0) 1740Sstevel@tonic-gate break; 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate if (i >= nsdi) { 1770Sstevel@tonic-gate told = t->next; 1780Sstevel@tonic-gate if (tlist != t) 1790Sstevel@tonic-gate t->next = tlist; 1800Sstevel@tonic-gate else 1810Sstevel@tonic-gate t->next = 0; 1820Sstevel@tonic-gate tlist = t; 1830Sstevel@tonic-gate continue; 1840Sstevel@tonic-gate } 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate told = t->next; 1890Sstevel@tonic-gate t->next = 0; 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate /* Make sure t->item.name is set correctly */ 1920Sstevel@tonic-gate if (t->item.name == 0) 1930Sstevel@tonic-gate t->item.name = t->dbId; 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate /* Remove leading dot in object name, if any */ 1960Sstevel@tonic-gate len = slen(t->objName); 1970Sstevel@tonic-gate while (len > 0 && t->objName[0] == '.') { 1980Sstevel@tonic-gate (void) memmove(t->objName, &t->objName[1], len); 1990Sstevel@tonic-gate len -= 1; 2000Sstevel@tonic-gate } 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate /* 2030Sstevel@tonic-gate * Initialize the object path, which is what we'll 2040Sstevel@tonic-gate * rehash on. 2050Sstevel@tonic-gate */ 2060Sstevel@tonic-gate if (yp2ldap) { 2070Sstevel@tonic-gate t->objPath = internal_table_name(t->objName, 2080Sstevel@tonic-gate t->objPath); 2090Sstevel@tonic-gate if (!t->objPath) { 2100Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 2110Sstevel@tonic-gate "%s: Failed to obtain internal table name for \"%s\"", 2120Sstevel@tonic-gate myself, t->objName); 2130Sstevel@tonic-gate return (-1); 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate } else { 2160Sstevel@tonic-gate t->objPath = am(myself, len + MAXPATHLEN + 1); 2170Sstevel@tonic-gate if (t->objPath == 0) 2180Sstevel@tonic-gate return (-1); 2190Sstevel@tonic-gate if (internal_table_name(t->objName, 2200Sstevel@tonic-gate t->objPath) == 0) { 2210Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 2220Sstevel@tonic-gate "%s: Failed to obtain internal table name for \"%s\"", 2230Sstevel@tonic-gate myself, t->objName); 2240Sstevel@tonic-gate return (-1); 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate } 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate /* 2290Sstevel@tonic-gate * Initialize the column name array. 2300Sstevel@tonic-gate */ 2310Sstevel@tonic-gate if (!yp2ldap) { 2320Sstevel@tonic-gate if (setColumnsDuringConfig && setColumnNames(t)) { 2330Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 2340Sstevel@tonic-gate "%s: Unable to find column names for \"%s\"", 2350Sstevel@tonic-gate myself, NIL(t->objName)); 2360Sstevel@tonic-gate return (-1); 2370Sstevel@tonic-gate } 2380Sstevel@tonic-gate } 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate /* 2410Sstevel@tonic-gate * If there are multiple mapping target containers, make 2420Sstevel@tonic-gate * each one into it's own mapping structure. They can all 2430Sstevel@tonic-gate * be minimal copies (i.e., share pointers to sub-structures 2440Sstevel@tonic-gate * other than the objectDN). 2450Sstevel@tonic-gate * 2460Sstevel@tonic-gate * If objectDN is NULL, we will never use this structure. 2470Sstevel@tonic-gate * In order to allow the rest of the mapping code to assume 2480Sstevel@tonic-gate * objectDN != NULL, skip the mapping (even if x == t). 2490Sstevel@tonic-gate */ 2500Sstevel@tonic-gate for (o = to = t->objectDN; o != 0; o = o->next) { 2510Sstevel@tonic-gate __nis_table_mapping_t *p; 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate if (o == to) { 2540Sstevel@tonic-gate x = t; 2550Sstevel@tonic-gate /* 2560Sstevel@tonic-gate * Only insert the first mapping for an 2570Sstevel@tonic-gate * object on the sequential list. 2580Sstevel@tonic-gate */ 2590Sstevel@tonic-gate *seqNext = t; 2600Sstevel@tonic-gate t->seqNext = 0; 2610Sstevel@tonic-gate seqNext = (__nis_table_mapping_t **)&t->seqNext; 2620Sstevel@tonic-gate } else { 2630Sstevel@tonic-gate x = am(myself, sizeof (*x)); 2640Sstevel@tonic-gate if (x == 0) { 2650Sstevel@tonic-gate /* 2660Sstevel@tonic-gate * This happens during rpc.nisd 2670Sstevel@tonic-gate * initialization, and it's an 2680Sstevel@tonic-gate * unrecoverable disaster, so don't 2690Sstevel@tonic-gate * bother cleaning up. 2700Sstevel@tonic-gate */ 2710Sstevel@tonic-gate return (-1); 2720Sstevel@tonic-gate } 2730Sstevel@tonic-gate memcpy(x, t, sizeof (*x)); 2740Sstevel@tonic-gate x->objectDN = o; 2750Sstevel@tonic-gate x->next = 0; 2760Sstevel@tonic-gate } 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate /* 2790Sstevel@tonic-gate * If x->objectDN->write.base is NULL, clone it from 2800Sstevel@tonic-gate * x->objectDN->read.base. 2810Sstevel@tonic-gate */ 2820Sstevel@tonic-gate if (x->objectDN->write.scope != LDAP_SCOPE_UNKNOWN) { 2830Sstevel@tonic-gate if (x->objectDN->write.base == 0 && 2840Sstevel@tonic-gate x->objectDN->read.base != 0) { 2850Sstevel@tonic-gate x->objectDN->write.base = 2860Sstevel@tonic-gate sdup(myself, T, 2870Sstevel@tonic-gate x->objectDN->read.base); 2880Sstevel@tonic-gate if (x->objectDN->write.base == 0) 2890Sstevel@tonic-gate return (-1); 2900Sstevel@tonic-gate } 2910Sstevel@tonic-gate if (x->objectDN->write.attrs == 0 && 2920Sstevel@tonic-gate x->objectDN->read.attrs != 0) { 2930Sstevel@tonic-gate x->objectDN->write.attrs = 2940Sstevel@tonic-gate sdup(myself, T, 2950Sstevel@tonic-gate x->objectDN->read.attrs); 2960Sstevel@tonic-gate if (x->objectDN->write.attrs == 0) 2970Sstevel@tonic-gate return (-1); 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate } 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate if (o != to) { 3020Sstevel@tonic-gate /* Insert last on the 't->next' list */ 3030Sstevel@tonic-gate for (p = t; p->next != 0; p = p->next); 3040Sstevel@tonic-gate p->next = x; 3050Sstevel@tonic-gate } 3060Sstevel@tonic-gate } 3070Sstevel@tonic-gate 3080Sstevel@tonic-gate /* Insert on dbid hash list */ 3090Sstevel@tonic-gate if (t->objectDN != 0 && !__nis_insert_item_mt(t, &dbids, 0)) { 3100Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 3110Sstevel@tonic-gate "%s: Error inserting mapping for \"%s\" on hash list", 3120Sstevel@tonic-gate myself, NIL(t->objName)); 3130Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 3140Sstevel@tonic-gate abort(); 3150Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 3160Sstevel@tonic-gate return (-1); 3170Sstevel@tonic-gate } 3180Sstevel@tonic-gate } 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate /* 3210Sstevel@tonic-gate * dbids2objs() will remove the entries on 'dbids', so no need 3220Sstevel@tonic-gate * to clean up that list from this function. 3230Sstevel@tonic-gate */ 3240Sstevel@tonic-gate return (dbids2objs(&dbids, &ldapMappingList)); 3250Sstevel@tonic-gate } 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate int 3280Sstevel@tonic-gate dbids2objs(__nis_hash_table_mt *dbids, __nis_hash_table_mt *objs) { 3290Sstevel@tonic-gate __nis_table_mapping_t *t, *o; 3300Sstevel@tonic-gate char *myself = "dbids2objs"; 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate while ((t = __nis_pop_item_mt(dbids)) != 0) { 3340Sstevel@tonic-gate /* Previous entry for this object ? */ 3350Sstevel@tonic-gate o = __nis_find_item_mt(t->objPath, objs, -1, 0); 3360Sstevel@tonic-gate if (o != 0) { 3370Sstevel@tonic-gate __nis_table_mapping_t *p = o; 3380Sstevel@tonic-gate /* 3390Sstevel@tonic-gate * Mapping already exists, so this is an alternate. 3400Sstevel@tonic-gate * Find the end of the list of any previous alt's, 3410Sstevel@tonic-gate * and insert there. 3420Sstevel@tonic-gate */ 3430Sstevel@tonic-gate while (p->next != 0) { 3440Sstevel@tonic-gate p = p->next; 3450Sstevel@tonic-gate } 3460Sstevel@tonic-gate p->next = t; 3470Sstevel@tonic-gate if (!__nis_release_item(o, objs, -1)) { 3480Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 3490Sstevel@tonic-gate "%s: __nis_release_item error", 3500Sstevel@tonic-gate myself); 3510Sstevel@tonic-gate return (-1); 3520Sstevel@tonic-gate } 3530Sstevel@tonic-gate } else { 3540Sstevel@tonic-gate t->item.name = t->objPath; 3550Sstevel@tonic-gate if (!__nis_insert_item_mt(t, objs, 0)) { 3560Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 3570Sstevel@tonic-gate "%s: __nis_insert_item error", 3580Sstevel@tonic-gate myself); 3590Sstevel@tonic-gate return (-1); 3600Sstevel@tonic-gate } 3610Sstevel@tonic-gate } 3620Sstevel@tonic-gate } 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate return (0); 3650Sstevel@tonic-gate } 3660Sstevel@tonic-gate 3670Sstevel@tonic-gate /* 3680Sstevel@tonic-gate * internal_table_name() 3690Sstevel@tonic-gate * 3700Sstevel@tonic-gate * Removes the local domain part from a fully qualified name 3710Sstevel@tonic-gate * to create the internal table name for an object. These tables are 3720Sstevel@tonic-gate * stored in /var/nis/<hostname> 3730Sstevel@tonic-gate * 3740Sstevel@tonic-gate * Imported from rpc.nisd/nisdb.c. 3750Sstevel@tonic-gate */ 3760Sstevel@tonic-gate char * 3770Sstevel@tonic-gate internal_table_name(nis_name name, char *res) 3780Sstevel@tonic-gate { 3790Sstevel@tonic-gate char *s, *t; 3800Sstevel@tonic-gate int i, j; 3810Sstevel@tonic-gate 3820Sstevel@tonic-gate if (yp2ldap) { 3830Sstevel@tonic-gate if (name == NULL) 3840Sstevel@tonic-gate return (NULL); 3850Sstevel@tonic-gate res = s_strndup(name, strlen(name)); 3860Sstevel@tonic-gate if (res == NULL) 3870Sstevel@tonic-gate return (NULL); 3880Sstevel@tonic-gate return (res); 3890Sstevel@tonic-gate } 3900Sstevel@tonic-gate 3910Sstevel@tonic-gate if (res == NULL) 3920Sstevel@tonic-gate return (NULL); 3930Sstevel@tonic-gate /* pointer at the first character of the table name */ 3940Sstevel@tonic-gate s = relative_name(name); 3950Sstevel@tonic-gate 3960Sstevel@tonic-gate /* 3970Sstevel@tonic-gate * If s == NULL then either this is a request for a lookup 3980Sstevel@tonic-gate * in our parents namespace (ILLEGAL), or we're the root 3990Sstevel@tonic-gate * server and this is a lookup in our namespace. 4000Sstevel@tonic-gate */ 4010Sstevel@tonic-gate if (s) { 4020Sstevel@tonic-gate return (NULL); 4030Sstevel@tonic-gate } 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate t = strrchr(res, '/'); 4060Sstevel@tonic-gate if (t) 4070Sstevel@tonic-gate t++; /* Point past the slash */ 4080Sstevel@tonic-gate /* Strip off the quotes if they were used here. */ 4090Sstevel@tonic-gate if (t[0] == '"') { 4100Sstevel@tonic-gate /* Check for simply a quoted quote. */ 4110Sstevel@tonic-gate if (t[1] != '"') { 4120Sstevel@tonic-gate j = strlen(t); 4130Sstevel@tonic-gate /* shift string left by one */ 4140Sstevel@tonic-gate for (i = 0; i < j; i++) 4150Sstevel@tonic-gate t[i] = t[i+1]; 4160Sstevel@tonic-gate t[j-2] = '\0'; /* Trounce trailing dquote */ 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate } 4190Sstevel@tonic-gate /* 4200Sstevel@tonic-gate * OK so now we have the unique name for the table. 4210Sstevel@tonic-gate * At this point we can fix it up to match local 4220Sstevel@tonic-gate * file system conventions if we so desire. Since it 4230Sstevel@tonic-gate * is only used in this form by _this_ server we can 4240Sstevel@tonic-gate * mangle it any way we want, as long as we are consistent 4250Sstevel@tonic-gate * about it. :-) 4260Sstevel@tonic-gate */ 4270Sstevel@tonic-gate __make_legal(res); 4280Sstevel@tonic-gate return (res); 4290Sstevel@tonic-gate } 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate /* 4320Sstevel@tonic-gate * SYSTEM DEPENDENT 4330Sstevel@tonic-gate * 4340Sstevel@tonic-gate * This function makes the table name "legal" for the underlying file system. 4350Sstevel@tonic-gate * 4360Sstevel@tonic-gate * Imported from rpc.nisd/nisdb.c. 4370Sstevel@tonic-gate */ 4380Sstevel@tonic-gate void 4390Sstevel@tonic-gate __make_legal(char *s) 4400Sstevel@tonic-gate { 4410Sstevel@tonic-gate while (*s) { 4420Sstevel@tonic-gate if (isupper(*s)) 4430Sstevel@tonic-gate *s = tolower(*s); 4440Sstevel@tonic-gate s++; 4450Sstevel@tonic-gate } 4460Sstevel@tonic-gate } 4470Sstevel@tonic-gate 4480Sstevel@tonic-gate /* 4490Sstevel@tonic-gate * relative_name() 4500Sstevel@tonic-gate * This internal function will remove from the NIS name, the domain 4510Sstevel@tonic-gate * name of the current server, this will leave the unique part in 4520Sstevel@tonic-gate * the name this becomes the "internal" version of the name. If this 4530Sstevel@tonic-gate * function returns NULL then the name we were given to resolve is 4540Sstevel@tonic-gate * bad somehow. 4550Sstevel@tonic-gate * 4560Sstevel@tonic-gate * A dynamically-allocated string is returned. 4570Sstevel@tonic-gate * 4580Sstevel@tonic-gate * Imported from rpc.nisd/nis_log_common.c 4590Sstevel@tonic-gate */ 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate nis_name 4620Sstevel@tonic-gate relative_name(s) 4630Sstevel@tonic-gate char *s; /* string with the name in it. */ 4640Sstevel@tonic-gate { 4650Sstevel@tonic-gate char *d; 4660Sstevel@tonic-gate char *buf; 4670Sstevel@tonic-gate int dl, sl; 4680Sstevel@tonic-gate name_pos p; 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate if (s == NULL) 4710Sstevel@tonic-gate return (NULL); 4720Sstevel@tonic-gate 4730Sstevel@tonic-gate d = __nis_rpc_domain(); 4740Sstevel@tonic-gate if (d == NULL) 4750Sstevel@tonic-gate return (NULL); 4760Sstevel@tonic-gate dl = strlen(d); /* _always dot terminated_ */ 4770Sstevel@tonic-gate 4780Sstevel@tonic-gate buf = strdup(s); 4790Sstevel@tonic-gate if (buf == NULL) 4800Sstevel@tonic-gate return (NULL); 4810Sstevel@tonic-gate strcpy(buf, s); /* Make a private copy of 's' */ 4820Sstevel@tonic-gate sl = strlen(buf); 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate if (dl == 1) { /* We're the '.' directory */ 4850Sstevel@tonic-gate buf[sl-1] = '\0'; /* Lose the 'dot' */ 4860Sstevel@tonic-gate return (buf); 4870Sstevel@tonic-gate } 4880Sstevel@tonic-gate 4890Sstevel@tonic-gate p = nis_dir_cmp(buf, d); 4900Sstevel@tonic-gate 4910Sstevel@tonic-gate /* 's' is above 'd' in the tree */ 4920Sstevel@tonic-gate if ((p == HIGHER_NAME) || (p == NOT_SEQUENTIAL) || (p == SAME_NAME)) { 4930Sstevel@tonic-gate free(buf); 4940Sstevel@tonic-gate return (NULL); 4950Sstevel@tonic-gate } 4960Sstevel@tonic-gate 4970Sstevel@tonic-gate /* Insert a NUL where the domain name starts in the string */ 4980Sstevel@tonic-gate buf[(sl - dl) - 1] = '\0'; 4990Sstevel@tonic-gate 5000Sstevel@tonic-gate /* Don't return a zero length name */ 5010Sstevel@tonic-gate if (buf[0] == '\0') { 5020Sstevel@tonic-gate free((void *)buf); 5030Sstevel@tonic-gate return (NULL); 5040Sstevel@tonic-gate } 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate return (buf); 5070Sstevel@tonic-gate } 5080Sstevel@tonic-gate 5090Sstevel@tonic-gate /* 5100Sstevel@tonic-gate * Wrapper for internal_table_name() that allocates a large enough 5110Sstevel@tonic-gate * buffer for the internal name. Return value must be freed by caller. 5120Sstevel@tonic-gate * If the input 'name' is NULL, the name of the root directory table 5130Sstevel@tonic-gate * is returned. 5140Sstevel@tonic-gate */ 5150Sstevel@tonic-gate char * 5160Sstevel@tonic-gate internalTableName(char *name) { 5170Sstevel@tonic-gate char *buf, *res; 5180Sstevel@tonic-gate char *myself = "internalTableName"; 5190Sstevel@tonic-gate 5200Sstevel@tonic-gate buf = (char *)am(myself, MAXPATHLEN + NIS_MAXNAMELEN + 1); 5210Sstevel@tonic-gate if (buf == 0) 5220Sstevel@tonic-gate return (0); 5230Sstevel@tonic-gate 5240Sstevel@tonic-gate if (name == 0) { 5250Sstevel@tonic-gate (void) memcpy(buf, ROOTDIRFILE, slen(ROOTDIRFILE)); 5260Sstevel@tonic-gate return (buf); 5270Sstevel@tonic-gate } 5280Sstevel@tonic-gate 5290Sstevel@tonic-gate res = internal_table_name(name, buf); 5300Sstevel@tonic-gate if (res != buf) { 5310Sstevel@tonic-gate sfree(buf); 5320Sstevel@tonic-gate buf = 0; 5330Sstevel@tonic-gate } 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate return (buf); 5360Sstevel@tonic-gate } 5370Sstevel@tonic-gate 5380Sstevel@tonic-gate /* 5390Sstevel@tonic-gate * Return the object mapping for the object indicated either by the 5400Sstevel@tonic-gate * internal DB name ('intNameArg'; preferred), or the FQ object name 5410Sstevel@tonic-gate * 'name'. If 'asObj' is non-zero, the caller is interested in the 5420Sstevel@tonic-gate * object mapping proper, not a mapping of table entries. Optionally, 5430Sstevel@tonic-gate * also indicate if the object is mapped from (read) or to (write) LDAP. 5440Sstevel@tonic-gate * 5450Sstevel@tonic-gate * Note that there may be more than one mapping of the appropriate type. 5460Sstevel@tonic-gate * Use the selectTableMapping() function in ldap_map.c to get all 5470Sstevel@tonic-gate * alternatives. However, the function below works as a short-cut if: 5480Sstevel@tonic-gate * 5490Sstevel@tonic-gate * You only want an indication that _a_ mapping of the desired 5500Sstevel@tonic-gate * type exists, or 5510Sstevel@tonic-gate * 5520Sstevel@tonic-gate * You want the non-objectDN information for an object-mapping 5530Sstevel@tonic-gate * proper (i.e., _not_ the mapping for entries in a table). 5540Sstevel@tonic-gate */ 5550Sstevel@tonic-gate __nis_table_mapping_t * 5560Sstevel@tonic-gate getObjMapping(char *name, char *intNameArg, int asObj, 5570Sstevel@tonic-gate int *doRead, int *doWrite) { 5580Sstevel@tonic-gate __nis_table_mapping_t *t, *x; 5590Sstevel@tonic-gate char *intName; 5600Sstevel@tonic-gate int freeIntName = 0, rd, wr; 5610Sstevel@tonic-gate 5620Sstevel@tonic-gate if (doRead != 0) 5630Sstevel@tonic-gate *doRead = 0; 5640Sstevel@tonic-gate if (doWrite != 0) 5650Sstevel@tonic-gate *doWrite = 0; 5660Sstevel@tonic-gate 5670Sstevel@tonic-gate if (intNameArg == 0) { 5680Sstevel@tonic-gate if (name == 0) 5690Sstevel@tonic-gate return (0); 5700Sstevel@tonic-gate intName = internalTableName(name); 5710Sstevel@tonic-gate if (intName == 0) 5720Sstevel@tonic-gate return (0); 5730Sstevel@tonic-gate freeIntName = 1; 5740Sstevel@tonic-gate } else { 5750Sstevel@tonic-gate intName = intNameArg; 5760Sstevel@tonic-gate } 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate t = __nis_find_item_mt(intName, &ldapMappingList, 0, 0); 5790Sstevel@tonic-gate if (t == 0) { 5800Sstevel@tonic-gate if (freeIntName) 5810Sstevel@tonic-gate sfree(intName); 5820Sstevel@tonic-gate return (0); 5830Sstevel@tonic-gate } 5840Sstevel@tonic-gate 5850Sstevel@tonic-gate rd = wr = 0; 5860Sstevel@tonic-gate for (x = t; x != 0; x = x->next) { 5870Sstevel@tonic-gate /* 5880Sstevel@tonic-gate * If we're looking for an object mapping, and this 5890Sstevel@tonic-gate * one's for entries in a table, skip it. 5900Sstevel@tonic-gate */ 5910Sstevel@tonic-gate if (asObj && x->objType == NIS_TABLE_OBJ && 5920Sstevel@tonic-gate x->numColumns > 0) 5930Sstevel@tonic-gate continue; 5940Sstevel@tonic-gate /* Check if we should read/write */ 5950Sstevel@tonic-gate if (x->objectDN->read.scope != LDAP_SCOPE_UNKNOWN) 5960Sstevel@tonic-gate rd++; 5970Sstevel@tonic-gate if (x->objectDN->write.scope != LDAP_SCOPE_UNKNOWN) 5980Sstevel@tonic-gate wr++; 5990Sstevel@tonic-gate } 6000Sstevel@tonic-gate 6010Sstevel@tonic-gate if (doRead != 0) 6020Sstevel@tonic-gate *doRead = (rd > 0) ? 1 : 0; 6030Sstevel@tonic-gate if (doWrite != 0) 6040Sstevel@tonic-gate *doWrite = (wr > 0) ? 1 : 0; 6050Sstevel@tonic-gate 6060Sstevel@tonic-gate if (freeIntName) 6070Sstevel@tonic-gate sfree(intName); 6080Sstevel@tonic-gate 6090Sstevel@tonic-gate return (x); 6100Sstevel@tonic-gate } 611