1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 32*7c478bd9Sstevel@tonic-gate #include <errno.h> 33*7c478bd9Sstevel@tonic-gate #include <string.h> 34*7c478bd9Sstevel@tonic-gate #include <strings.h> 35*7c478bd9Sstevel@tonic-gate #include <ctype.h> 36*7c478bd9Sstevel@tonic-gate #include <malloc.h> 37*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 38*7c478bd9Sstevel@tonic-gate #include <deflt.h> 39*7c478bd9Sstevel@tonic-gate #include <limits.h> 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include "ldap_parse.h" 42*7c478bd9Sstevel@tonic-gate #include "ldap_glob.h" 43*7c478bd9Sstevel@tonic-gate #include "ldap_attr.h" 44*7c478bd9Sstevel@tonic-gate #include "ldap_util.h" 45*7c478bd9Sstevel@tonic-gate #include "ldap_map.h" 46*7c478bd9Sstevel@tonic-gate #include "ldap_ruleval.h" 47*7c478bd9Sstevel@tonic-gate #include "nis_parse_ldap_conf.h" 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate int yp2ldap = 0; 50*7c478bd9Sstevel@tonic-gate /* 51*7c478bd9Sstevel@tonic-gate * List of mapping structures in original (i.e., as in config file) order. 52*7c478bd9Sstevel@tonic-gate * Lined on the 'seqNext' field. 53*7c478bd9Sstevel@tonic-gate */ 54*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *ldapMappingSeq = 0; 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* 57*7c478bd9Sstevel@tonic-gate * Call the parser for the config file 'ldapConfFile', and command line 58*7c478bd9Sstevel@tonic-gate * attribute settings per 'ldapCLA'. 59*7c478bd9Sstevel@tonic-gate * 60*7c478bd9Sstevel@tonic-gate * Returns 61*7c478bd9Sstevel@tonic-gate * 0 Success 62*7c478bd9Sstevel@tonic-gate * -1 Config file stat/open or parse error 63*7c478bd9Sstevel@tonic-gate * 1 No mapping should be used. 64*7c478bd9Sstevel@tonic-gate */ 65*7c478bd9Sstevel@tonic-gate int 66*7c478bd9Sstevel@tonic-gate parseConfig(char **ldapCLA, char *ldapConfFile) { 67*7c478bd9Sstevel@tonic-gate int ret; 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate /* 70*7c478bd9Sstevel@tonic-gate * Establish defaults for ldapDBTableMapping, so that we have 71*7c478bd9Sstevel@tonic-gate * valid values even if there's no mapping config to parse. 72*7c478bd9Sstevel@tonic-gate */ 73*7c478bd9Sstevel@tonic-gate ldapDBTableMapping.initTtlLo = (3600-1800); 74*7c478bd9Sstevel@tonic-gate ldapDBTableMapping.initTtlHi = (3600+1800); 75*7c478bd9Sstevel@tonic-gate ldapDBTableMapping.ttl = 3600; 76*7c478bd9Sstevel@tonic-gate ldapDBTableMapping.enumExpire = 0; 77*7c478bd9Sstevel@tonic-gate ldapDBTableMapping.fromLDAP = FALSE; 78*7c478bd9Sstevel@tonic-gate ldapDBTableMapping.toLDAP = FALSE; 79*7c478bd9Sstevel@tonic-gate ldapDBTableMapping.expire = 0; 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate ret = parse_ldap_migration((const char **)ldapCLA, ldapConfFile); 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate return (ret); 84*7c478bd9Sstevel@tonic-gate } 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate /* 87*7c478bd9Sstevel@tonic-gate * Convert the linked list of __nis_table_mapping_t's (produced by the 88*7c478bd9Sstevel@tonic-gate * attribute parser) to the 'ldapMappingList', keyed on the objPath. 89*7c478bd9Sstevel@tonic-gate * 90*7c478bd9Sstevel@tonic-gate * Once this function has returned, the 'tlist' is invalid, and must 91*7c478bd9Sstevel@tonic-gate * not be used in any way. 92*7c478bd9Sstevel@tonic-gate */ 93*7c478bd9Sstevel@tonic-gate int 94*7c478bd9Sstevel@tonic-gate linked2hash(__nis_table_mapping_t *tlist) { 95*7c478bd9Sstevel@tonic-gate __nis_hash_table_mt dbids; 96*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t, *told, *x, **seqNext; 97*7c478bd9Sstevel@tonic-gate __nis_object_dn_t *o, *to; 98*7c478bd9Sstevel@tonic-gate char *myself = "linked2hash"; 99*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 100*7c478bd9Sstevel@tonic-gate char *selectDbid = getenv("NISLDAPSELECTDBID"); 101*7c478bd9Sstevel@tonic-gate char **sdi, *s; 102*7c478bd9Sstevel@tonic-gate int i, nsdi; 103*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate if (tlist == 0) 107*7c478bd9Sstevel@tonic-gate return (0); 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate /* proxyInfo.default_nis_domain must end in a dot */ 110*7c478bd9Sstevel@tonic-gate { 111*7c478bd9Sstevel@tonic-gate int len = slen(proxyInfo.default_nis_domain); 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate if (len > 0 && proxyInfo.default_nis_domain[len-1] != '.') { 114*7c478bd9Sstevel@tonic-gate char *domain = am(myself, len+2); 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate (void) memcpy(domain, proxyInfo.default_nis_domain, 117*7c478bd9Sstevel@tonic-gate len); 118*7c478bd9Sstevel@tonic-gate domain[len] = '.'; 119*7c478bd9Sstevel@tonic-gate domain[len+1] = '\0'; 120*7c478bd9Sstevel@tonic-gate sfree(proxyInfo.default_nis_domain); 121*7c478bd9Sstevel@tonic-gate proxyInfo.default_nis_domain = domain; 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate } 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 126*7c478bd9Sstevel@tonic-gate for (nsdi = 0, s = selectDbid; s != 0 && *s != '\0'; s++) { 127*7c478bd9Sstevel@tonic-gate if (*s != ' ') { 128*7c478bd9Sstevel@tonic-gate nsdi++; 129*7c478bd9Sstevel@tonic-gate while (*s != ' ' && *s != '\0') 130*7c478bd9Sstevel@tonic-gate s++; 131*7c478bd9Sstevel@tonic-gate if (*s == '\0') 132*7c478bd9Sstevel@tonic-gate break; 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate if (nsdi > 0) { 136*7c478bd9Sstevel@tonic-gate sdi = am(myself, nsdi * sizeof (sdi[0])); 137*7c478bd9Sstevel@tonic-gate if (sdi == 0) 138*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 139*7c478bd9Sstevel@tonic-gate "%s: Memory alloc failure for dbId selection", 140*7c478bd9Sstevel@tonic-gate myself); 141*7c478bd9Sstevel@tonic-gate else { 142*7c478bd9Sstevel@tonic-gate for (i = 0, s = selectDbid; *s != '\0'; s++) { 143*7c478bd9Sstevel@tonic-gate if (*s != ' ') { 144*7c478bd9Sstevel@tonic-gate sdi[i++] = selectDbid; 145*7c478bd9Sstevel@tonic-gate while (*s != ' ' && *s != '\0') 146*7c478bd9Sstevel@tonic-gate s++; 147*7c478bd9Sstevel@tonic-gate if (*s != '\0') { 148*7c478bd9Sstevel@tonic-gate *s = '\0'; 149*7c478bd9Sstevel@tonic-gate s++; 150*7c478bd9Sstevel@tonic-gate } else 151*7c478bd9Sstevel@tonic-gate break; 152*7c478bd9Sstevel@tonic-gate selectDbid = s; 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate __nis_init_hash_table(&dbids, 0); 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate seqNext = &ldapMappingSeq; 162*7c478bd9Sstevel@tonic-gate for (t = tlist; t != 0; t = told) { 163*7c478bd9Sstevel@tonic-gate int len; 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * If the dbId doesn't match 'selectDbid', skip this 168*7c478bd9Sstevel@tonic-gate * mapping. Re-insert on 'tlist', in order to keep memory 169*7c478bd9Sstevel@tonic-gate * leak checking happy. Note that 'tlist' may end up pointing 170*7c478bd9Sstevel@tonic-gate * into the real mapping list, so it shouldn't be used once 171*7c478bd9Sstevel@tonic-gate * this routine has been called. 172*7c478bd9Sstevel@tonic-gate */ 173*7c478bd9Sstevel@tonic-gate if (nsdi > 0) { 174*7c478bd9Sstevel@tonic-gate for (i = 0; i < nsdi; i++) { 175*7c478bd9Sstevel@tonic-gate if (strcmp(sdi[i], t->dbId) == 0) 176*7c478bd9Sstevel@tonic-gate break; 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate if (i >= nsdi) { 179*7c478bd9Sstevel@tonic-gate told = t->next; 180*7c478bd9Sstevel@tonic-gate if (tlist != t) 181*7c478bd9Sstevel@tonic-gate t->next = tlist; 182*7c478bd9Sstevel@tonic-gate else 183*7c478bd9Sstevel@tonic-gate t->next = 0; 184*7c478bd9Sstevel@tonic-gate tlist = t; 185*7c478bd9Sstevel@tonic-gate continue; 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate told = t->next; 191*7c478bd9Sstevel@tonic-gate t->next = 0; 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate /* Make sure t->item.name is set correctly */ 194*7c478bd9Sstevel@tonic-gate if (t->item.name == 0) 195*7c478bd9Sstevel@tonic-gate t->item.name = t->dbId; 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate /* Remove leading dot in object name, if any */ 198*7c478bd9Sstevel@tonic-gate len = slen(t->objName); 199*7c478bd9Sstevel@tonic-gate while (len > 0 && t->objName[0] == '.') { 200*7c478bd9Sstevel@tonic-gate (void) memmove(t->objName, &t->objName[1], len); 201*7c478bd9Sstevel@tonic-gate len -= 1; 202*7c478bd9Sstevel@tonic-gate } 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate /* 205*7c478bd9Sstevel@tonic-gate * Initialize the object path, which is what we'll 206*7c478bd9Sstevel@tonic-gate * rehash on. 207*7c478bd9Sstevel@tonic-gate */ 208*7c478bd9Sstevel@tonic-gate if (yp2ldap) { 209*7c478bd9Sstevel@tonic-gate t->objPath = internal_table_name(t->objName, 210*7c478bd9Sstevel@tonic-gate t->objPath); 211*7c478bd9Sstevel@tonic-gate if (!t->objPath) { 212*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 213*7c478bd9Sstevel@tonic-gate "%s: Failed to obtain internal table name for \"%s\"", 214*7c478bd9Sstevel@tonic-gate myself, t->objName); 215*7c478bd9Sstevel@tonic-gate return (-1); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate } else { 218*7c478bd9Sstevel@tonic-gate t->objPath = am(myself, len + MAXPATHLEN + 1); 219*7c478bd9Sstevel@tonic-gate if (t->objPath == 0) 220*7c478bd9Sstevel@tonic-gate return (-1); 221*7c478bd9Sstevel@tonic-gate if (internal_table_name(t->objName, 222*7c478bd9Sstevel@tonic-gate t->objPath) == 0) { 223*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 224*7c478bd9Sstevel@tonic-gate "%s: Failed to obtain internal table name for \"%s\"", 225*7c478bd9Sstevel@tonic-gate myself, t->objName); 226*7c478bd9Sstevel@tonic-gate return (-1); 227*7c478bd9Sstevel@tonic-gate } 228*7c478bd9Sstevel@tonic-gate } 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate /* 231*7c478bd9Sstevel@tonic-gate * Initialize the column name array. 232*7c478bd9Sstevel@tonic-gate */ 233*7c478bd9Sstevel@tonic-gate if (!yp2ldap) { 234*7c478bd9Sstevel@tonic-gate if (setColumnsDuringConfig && setColumnNames(t)) { 235*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 236*7c478bd9Sstevel@tonic-gate "%s: Unable to find column names for \"%s\"", 237*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName)); 238*7c478bd9Sstevel@tonic-gate return (-1); 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate /* 243*7c478bd9Sstevel@tonic-gate * If there are multiple mapping target containers, make 244*7c478bd9Sstevel@tonic-gate * each one into it's own mapping structure. They can all 245*7c478bd9Sstevel@tonic-gate * be minimal copies (i.e., share pointers to sub-structures 246*7c478bd9Sstevel@tonic-gate * other than the objectDN). 247*7c478bd9Sstevel@tonic-gate * 248*7c478bd9Sstevel@tonic-gate * If objectDN is NULL, we will never use this structure. 249*7c478bd9Sstevel@tonic-gate * In order to allow the rest of the mapping code to assume 250*7c478bd9Sstevel@tonic-gate * objectDN != NULL, skip the mapping (even if x == t). 251*7c478bd9Sstevel@tonic-gate */ 252*7c478bd9Sstevel@tonic-gate for (o = to = t->objectDN; o != 0; o = o->next) { 253*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *p; 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate if (o == to) { 256*7c478bd9Sstevel@tonic-gate x = t; 257*7c478bd9Sstevel@tonic-gate /* 258*7c478bd9Sstevel@tonic-gate * Only insert the first mapping for an 259*7c478bd9Sstevel@tonic-gate * object on the sequential list. 260*7c478bd9Sstevel@tonic-gate */ 261*7c478bd9Sstevel@tonic-gate *seqNext = t; 262*7c478bd9Sstevel@tonic-gate t->seqNext = 0; 263*7c478bd9Sstevel@tonic-gate seqNext = (__nis_table_mapping_t **)&t->seqNext; 264*7c478bd9Sstevel@tonic-gate } else { 265*7c478bd9Sstevel@tonic-gate x = am(myself, sizeof (*x)); 266*7c478bd9Sstevel@tonic-gate if (x == 0) { 267*7c478bd9Sstevel@tonic-gate /* 268*7c478bd9Sstevel@tonic-gate * This happens during rpc.nisd 269*7c478bd9Sstevel@tonic-gate * initialization, and it's an 270*7c478bd9Sstevel@tonic-gate * unrecoverable disaster, so don't 271*7c478bd9Sstevel@tonic-gate * bother cleaning up. 272*7c478bd9Sstevel@tonic-gate */ 273*7c478bd9Sstevel@tonic-gate return (-1); 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate memcpy(x, t, sizeof (*x)); 276*7c478bd9Sstevel@tonic-gate x->objectDN = o; 277*7c478bd9Sstevel@tonic-gate x->next = 0; 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate /* 281*7c478bd9Sstevel@tonic-gate * If x->objectDN->write.base is NULL, clone it from 282*7c478bd9Sstevel@tonic-gate * x->objectDN->read.base. 283*7c478bd9Sstevel@tonic-gate */ 284*7c478bd9Sstevel@tonic-gate if (x->objectDN->write.scope != LDAP_SCOPE_UNKNOWN) { 285*7c478bd9Sstevel@tonic-gate if (x->objectDN->write.base == 0 && 286*7c478bd9Sstevel@tonic-gate x->objectDN->read.base != 0) { 287*7c478bd9Sstevel@tonic-gate x->objectDN->write.base = 288*7c478bd9Sstevel@tonic-gate sdup(myself, T, 289*7c478bd9Sstevel@tonic-gate x->objectDN->read.base); 290*7c478bd9Sstevel@tonic-gate if (x->objectDN->write.base == 0) 291*7c478bd9Sstevel@tonic-gate return (-1); 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate if (x->objectDN->write.attrs == 0 && 294*7c478bd9Sstevel@tonic-gate x->objectDN->read.attrs != 0) { 295*7c478bd9Sstevel@tonic-gate x->objectDN->write.attrs = 296*7c478bd9Sstevel@tonic-gate sdup(myself, T, 297*7c478bd9Sstevel@tonic-gate x->objectDN->read.attrs); 298*7c478bd9Sstevel@tonic-gate if (x->objectDN->write.attrs == 0) 299*7c478bd9Sstevel@tonic-gate return (-1); 300*7c478bd9Sstevel@tonic-gate } 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate if (o != to) { 304*7c478bd9Sstevel@tonic-gate /* Insert last on the 't->next' list */ 305*7c478bd9Sstevel@tonic-gate for (p = t; p->next != 0; p = p->next); 306*7c478bd9Sstevel@tonic-gate p->next = x; 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate /* Insert on dbid hash list */ 311*7c478bd9Sstevel@tonic-gate if (t->objectDN != 0 && !__nis_insert_item_mt(t, &dbids, 0)) { 312*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 313*7c478bd9Sstevel@tonic-gate "%s: Error inserting mapping for \"%s\" on hash list", 314*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName)); 315*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 316*7c478bd9Sstevel@tonic-gate abort(); 317*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 318*7c478bd9Sstevel@tonic-gate return (-1); 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate } 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate /* 323*7c478bd9Sstevel@tonic-gate * dbids2objs() will remove the entries on 'dbids', so no need 324*7c478bd9Sstevel@tonic-gate * to clean up that list from this function. 325*7c478bd9Sstevel@tonic-gate */ 326*7c478bd9Sstevel@tonic-gate return (dbids2objs(&dbids, &ldapMappingList)); 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate int 330*7c478bd9Sstevel@tonic-gate dbids2objs(__nis_hash_table_mt *dbids, __nis_hash_table_mt *objs) { 331*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t, *o; 332*7c478bd9Sstevel@tonic-gate char *myself = "dbids2objs"; 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate while ((t = __nis_pop_item_mt(dbids)) != 0) { 336*7c478bd9Sstevel@tonic-gate /* Previous entry for this object ? */ 337*7c478bd9Sstevel@tonic-gate o = __nis_find_item_mt(t->objPath, objs, -1, 0); 338*7c478bd9Sstevel@tonic-gate if (o != 0) { 339*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *p = o; 340*7c478bd9Sstevel@tonic-gate /* 341*7c478bd9Sstevel@tonic-gate * Mapping already exists, so this is an alternate. 342*7c478bd9Sstevel@tonic-gate * Find the end of the list of any previous alt's, 343*7c478bd9Sstevel@tonic-gate * and insert there. 344*7c478bd9Sstevel@tonic-gate */ 345*7c478bd9Sstevel@tonic-gate while (p->next != 0) { 346*7c478bd9Sstevel@tonic-gate p = p->next; 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate p->next = t; 349*7c478bd9Sstevel@tonic-gate if (!__nis_release_item(o, objs, -1)) { 350*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 351*7c478bd9Sstevel@tonic-gate "%s: __nis_release_item error", 352*7c478bd9Sstevel@tonic-gate myself); 353*7c478bd9Sstevel@tonic-gate return (-1); 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate } else { 356*7c478bd9Sstevel@tonic-gate t->item.name = t->objPath; 357*7c478bd9Sstevel@tonic-gate if (!__nis_insert_item_mt(t, objs, 0)) { 358*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 359*7c478bd9Sstevel@tonic-gate "%s: __nis_insert_item error", 360*7c478bd9Sstevel@tonic-gate myself); 361*7c478bd9Sstevel@tonic-gate return (-1); 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate return (0); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate /* 370*7c478bd9Sstevel@tonic-gate * internal_table_name() 371*7c478bd9Sstevel@tonic-gate * 372*7c478bd9Sstevel@tonic-gate * Removes the local domain part from a fully qualified name 373*7c478bd9Sstevel@tonic-gate * to create the internal table name for an object. These tables are 374*7c478bd9Sstevel@tonic-gate * stored in /var/nis/<hostname> 375*7c478bd9Sstevel@tonic-gate * 376*7c478bd9Sstevel@tonic-gate * Imported from rpc.nisd/nisdb.c. 377*7c478bd9Sstevel@tonic-gate */ 378*7c478bd9Sstevel@tonic-gate char * 379*7c478bd9Sstevel@tonic-gate internal_table_name(nis_name name, char *res) 380*7c478bd9Sstevel@tonic-gate { 381*7c478bd9Sstevel@tonic-gate char *s, *t; 382*7c478bd9Sstevel@tonic-gate int i, j; 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate if (yp2ldap) { 385*7c478bd9Sstevel@tonic-gate if (name == NULL) 386*7c478bd9Sstevel@tonic-gate return (NULL); 387*7c478bd9Sstevel@tonic-gate res = s_strndup(name, strlen(name)); 388*7c478bd9Sstevel@tonic-gate if (res == NULL) 389*7c478bd9Sstevel@tonic-gate return (NULL); 390*7c478bd9Sstevel@tonic-gate return (res); 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate if (res == NULL) 394*7c478bd9Sstevel@tonic-gate return (NULL); 395*7c478bd9Sstevel@tonic-gate /* pointer at the first character of the table name */ 396*7c478bd9Sstevel@tonic-gate s = relative_name(name); 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate /* 399*7c478bd9Sstevel@tonic-gate * If s == NULL then either this is a request for a lookup 400*7c478bd9Sstevel@tonic-gate * in our parents namespace (ILLEGAL), or we're the root 401*7c478bd9Sstevel@tonic-gate * server and this is a lookup in our namespace. 402*7c478bd9Sstevel@tonic-gate */ 403*7c478bd9Sstevel@tonic-gate if (s) { 404*7c478bd9Sstevel@tonic-gate strcpy(res, nis_data(s)); 405*7c478bd9Sstevel@tonic-gate free((void *)s); 406*7c478bd9Sstevel@tonic-gate } else if (nis_dir_cmp(name, __nis_rpc_domain()) == SAME_NAME) { 407*7c478bd9Sstevel@tonic-gate strcpy(res, nis_data("ROOT_DIR")); 408*7c478bd9Sstevel@tonic-gate } else { 409*7c478bd9Sstevel@tonic-gate return (NULL); 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate t = strrchr(res, '/'); 413*7c478bd9Sstevel@tonic-gate if (t) 414*7c478bd9Sstevel@tonic-gate t++; /* Point past the slash */ 415*7c478bd9Sstevel@tonic-gate /* Strip off the quotes if they were used here. */ 416*7c478bd9Sstevel@tonic-gate if (t[0] == '"') { 417*7c478bd9Sstevel@tonic-gate /* Check for simply a quoted quote. */ 418*7c478bd9Sstevel@tonic-gate if (t[1] != '"') { 419*7c478bd9Sstevel@tonic-gate j = strlen(t); 420*7c478bd9Sstevel@tonic-gate /* shift string left by one */ 421*7c478bd9Sstevel@tonic-gate for (i = 0; i < j; i++) 422*7c478bd9Sstevel@tonic-gate t[i] = t[i+1]; 423*7c478bd9Sstevel@tonic-gate t[j-2] = '\0'; /* Trounce trailing dquote */ 424*7c478bd9Sstevel@tonic-gate } 425*7c478bd9Sstevel@tonic-gate } 426*7c478bd9Sstevel@tonic-gate /* 427*7c478bd9Sstevel@tonic-gate * OK so now we have the unique name for the table. 428*7c478bd9Sstevel@tonic-gate * At this point we can fix it up to match local 429*7c478bd9Sstevel@tonic-gate * file system conventions if we so desire. Since it 430*7c478bd9Sstevel@tonic-gate * is only used in this form by _this_ server we can 431*7c478bd9Sstevel@tonic-gate * mangle it any way we want, as long as we are consistent 432*7c478bd9Sstevel@tonic-gate * about it. :-) 433*7c478bd9Sstevel@tonic-gate */ 434*7c478bd9Sstevel@tonic-gate __make_legal(res); 435*7c478bd9Sstevel@tonic-gate return (res); 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate /* 439*7c478bd9Sstevel@tonic-gate * SYSTEM DEPENDENT 440*7c478bd9Sstevel@tonic-gate * 441*7c478bd9Sstevel@tonic-gate * This function makes the table name "legal" for the underlying file system. 442*7c478bd9Sstevel@tonic-gate * 443*7c478bd9Sstevel@tonic-gate * Imported from rpc.nisd/nisdb.c. 444*7c478bd9Sstevel@tonic-gate */ 445*7c478bd9Sstevel@tonic-gate void 446*7c478bd9Sstevel@tonic-gate __make_legal(char *s) 447*7c478bd9Sstevel@tonic-gate { 448*7c478bd9Sstevel@tonic-gate while (*s) { 449*7c478bd9Sstevel@tonic-gate if (isupper(*s)) 450*7c478bd9Sstevel@tonic-gate *s = tolower(*s); 451*7c478bd9Sstevel@tonic-gate s++; 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate /* 456*7c478bd9Sstevel@tonic-gate * relative_name() 457*7c478bd9Sstevel@tonic-gate * This internal function will remove from the NIS name, the domain 458*7c478bd9Sstevel@tonic-gate * name of the current server, this will leave the unique part in 459*7c478bd9Sstevel@tonic-gate * the name this becomes the "internal" version of the name. If this 460*7c478bd9Sstevel@tonic-gate * function returns NULL then the name we were given to resolve is 461*7c478bd9Sstevel@tonic-gate * bad somehow. 462*7c478bd9Sstevel@tonic-gate * 463*7c478bd9Sstevel@tonic-gate * A dynamically-allocated string is returned. 464*7c478bd9Sstevel@tonic-gate * 465*7c478bd9Sstevel@tonic-gate * Imported from rpc.nisd/nis_log_common.c 466*7c478bd9Sstevel@tonic-gate */ 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate nis_name 469*7c478bd9Sstevel@tonic-gate relative_name(s) 470*7c478bd9Sstevel@tonic-gate char *s; /* string with the name in it. */ 471*7c478bd9Sstevel@tonic-gate { 472*7c478bd9Sstevel@tonic-gate char *d; 473*7c478bd9Sstevel@tonic-gate char *buf; 474*7c478bd9Sstevel@tonic-gate int dl, sl; 475*7c478bd9Sstevel@tonic-gate name_pos p; 476*7c478bd9Sstevel@tonic-gate 477*7c478bd9Sstevel@tonic-gate if (s == NULL) 478*7c478bd9Sstevel@tonic-gate return (NULL); 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate d = __nis_rpc_domain(); 481*7c478bd9Sstevel@tonic-gate if (d == NULL) 482*7c478bd9Sstevel@tonic-gate return (NULL); 483*7c478bd9Sstevel@tonic-gate dl = strlen(d); /* _always dot terminated_ */ 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate buf = strdup(s); 486*7c478bd9Sstevel@tonic-gate if (buf == NULL) 487*7c478bd9Sstevel@tonic-gate return (NULL); 488*7c478bd9Sstevel@tonic-gate strcpy(buf, s); /* Make a private copy of 's' */ 489*7c478bd9Sstevel@tonic-gate sl = strlen(buf); 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate if (dl == 1) { /* We're the '.' directory */ 492*7c478bd9Sstevel@tonic-gate buf[sl-1] = '\0'; /* Lose the 'dot' */ 493*7c478bd9Sstevel@tonic-gate return (buf); 494*7c478bd9Sstevel@tonic-gate } 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate p = nis_dir_cmp(buf, d); 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate /* 's' is above 'd' in the tree */ 499*7c478bd9Sstevel@tonic-gate if ((p == HIGHER_NAME) || (p == NOT_SEQUENTIAL) || (p == SAME_NAME)) { 500*7c478bd9Sstevel@tonic-gate free(buf); 501*7c478bd9Sstevel@tonic-gate return (NULL); 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate 504*7c478bd9Sstevel@tonic-gate /* Insert a NUL where the domain name starts in the string */ 505*7c478bd9Sstevel@tonic-gate buf[(sl - dl) - 1] = '\0'; 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate /* Don't return a zero length name */ 508*7c478bd9Sstevel@tonic-gate if (buf[0] == '\0') { 509*7c478bd9Sstevel@tonic-gate free((void *)buf); 510*7c478bd9Sstevel@tonic-gate return (NULL); 511*7c478bd9Sstevel@tonic-gate } 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate return (buf); 514*7c478bd9Sstevel@tonic-gate } 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate /* 517*7c478bd9Sstevel@tonic-gate * Wrapper for internal_table_name() that allocates a large enough 518*7c478bd9Sstevel@tonic-gate * buffer for the internal name. Return value must be freed by caller. 519*7c478bd9Sstevel@tonic-gate * If the input 'name' is NULL, the name of the root directory table 520*7c478bd9Sstevel@tonic-gate * is returned. 521*7c478bd9Sstevel@tonic-gate */ 522*7c478bd9Sstevel@tonic-gate char * 523*7c478bd9Sstevel@tonic-gate internalTableName(char *name) { 524*7c478bd9Sstevel@tonic-gate char *buf, *res; 525*7c478bd9Sstevel@tonic-gate char *myself = "internalTableName"; 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate buf = (char *)am(myself, MAXPATHLEN + NIS_MAXNAMELEN + 1); 528*7c478bd9Sstevel@tonic-gate if (buf == 0) 529*7c478bd9Sstevel@tonic-gate return (0); 530*7c478bd9Sstevel@tonic-gate 531*7c478bd9Sstevel@tonic-gate if (name == 0) { 532*7c478bd9Sstevel@tonic-gate (void) memcpy(buf, ROOTDIRFILE, slen(ROOTDIRFILE)); 533*7c478bd9Sstevel@tonic-gate return (buf); 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate res = internal_table_name(name, buf); 537*7c478bd9Sstevel@tonic-gate if (res != buf) { 538*7c478bd9Sstevel@tonic-gate sfree(buf); 539*7c478bd9Sstevel@tonic-gate buf = 0; 540*7c478bd9Sstevel@tonic-gate } 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate return (buf); 543*7c478bd9Sstevel@tonic-gate } 544*7c478bd9Sstevel@tonic-gate 545*7c478bd9Sstevel@tonic-gate /* 546*7c478bd9Sstevel@tonic-gate * Return the object mapping for the object indicated either by the 547*7c478bd9Sstevel@tonic-gate * internal DB name ('intNameArg'; preferred), or the FQ object name 548*7c478bd9Sstevel@tonic-gate * 'name'. If 'asObj' is non-zero, the caller is interested in the 549*7c478bd9Sstevel@tonic-gate * object mapping proper, not a mapping of table entries. Optionally, 550*7c478bd9Sstevel@tonic-gate * also indicate if the object is mapped from (read) or to (write) LDAP. 551*7c478bd9Sstevel@tonic-gate * 552*7c478bd9Sstevel@tonic-gate * Note that there may be more than one mapping of the appropriate type. 553*7c478bd9Sstevel@tonic-gate * Use the selectTableMapping() function in ldap_map.c to get all 554*7c478bd9Sstevel@tonic-gate * alternatives. However, the function below works as a short-cut if: 555*7c478bd9Sstevel@tonic-gate * 556*7c478bd9Sstevel@tonic-gate * You only want an indication that _a_ mapping of the desired 557*7c478bd9Sstevel@tonic-gate * type exists, or 558*7c478bd9Sstevel@tonic-gate * 559*7c478bd9Sstevel@tonic-gate * You want the non-objectDN information for an object-mapping 560*7c478bd9Sstevel@tonic-gate * proper (i.e., _not_ the mapping for entries in a table). 561*7c478bd9Sstevel@tonic-gate */ 562*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t * 563*7c478bd9Sstevel@tonic-gate getObjMapping(char *name, char *intNameArg, int asObj, 564*7c478bd9Sstevel@tonic-gate int *doRead, int *doWrite) { 565*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t, *x; 566*7c478bd9Sstevel@tonic-gate char *intName; 567*7c478bd9Sstevel@tonic-gate int freeIntName = 0, rd, wr; 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate if (doRead != 0) 570*7c478bd9Sstevel@tonic-gate *doRead = 0; 571*7c478bd9Sstevel@tonic-gate if (doWrite != 0) 572*7c478bd9Sstevel@tonic-gate *doWrite = 0; 573*7c478bd9Sstevel@tonic-gate 574*7c478bd9Sstevel@tonic-gate if (intNameArg == 0) { 575*7c478bd9Sstevel@tonic-gate if (name == 0) 576*7c478bd9Sstevel@tonic-gate return (0); 577*7c478bd9Sstevel@tonic-gate intName = internalTableName(name); 578*7c478bd9Sstevel@tonic-gate if (intName == 0) 579*7c478bd9Sstevel@tonic-gate return (0); 580*7c478bd9Sstevel@tonic-gate freeIntName = 1; 581*7c478bd9Sstevel@tonic-gate } else { 582*7c478bd9Sstevel@tonic-gate intName = intNameArg; 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate t = __nis_find_item_mt(intName, &ldapMappingList, 0, 0); 586*7c478bd9Sstevel@tonic-gate if (t == 0) { 587*7c478bd9Sstevel@tonic-gate if (freeIntName) 588*7c478bd9Sstevel@tonic-gate sfree(intName); 589*7c478bd9Sstevel@tonic-gate return (0); 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate rd = wr = 0; 593*7c478bd9Sstevel@tonic-gate for (x = t; x != 0; x = x->next) { 594*7c478bd9Sstevel@tonic-gate /* 595*7c478bd9Sstevel@tonic-gate * If we're looking for an object mapping, and this 596*7c478bd9Sstevel@tonic-gate * one's for entries in a table, skip it. 597*7c478bd9Sstevel@tonic-gate */ 598*7c478bd9Sstevel@tonic-gate if (asObj && x->objType == NIS_TABLE_OBJ && 599*7c478bd9Sstevel@tonic-gate x->numColumns > 0) 600*7c478bd9Sstevel@tonic-gate continue; 601*7c478bd9Sstevel@tonic-gate /* Check if we should read/write */ 602*7c478bd9Sstevel@tonic-gate if (x->objectDN->read.scope != LDAP_SCOPE_UNKNOWN) 603*7c478bd9Sstevel@tonic-gate rd++; 604*7c478bd9Sstevel@tonic-gate if (x->objectDN->write.scope != LDAP_SCOPE_UNKNOWN) 605*7c478bd9Sstevel@tonic-gate wr++; 606*7c478bd9Sstevel@tonic-gate } 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate if (doRead != 0) 609*7c478bd9Sstevel@tonic-gate *doRead = (rd > 0) ? 1 : 0; 610*7c478bd9Sstevel@tonic-gate if (doWrite != 0) 611*7c478bd9Sstevel@tonic-gate *doWrite = (wr > 0) ? 1 : 0; 612*7c478bd9Sstevel@tonic-gate 613*7c478bd9Sstevel@tonic-gate if (freeIntName) 614*7c478bd9Sstevel@tonic-gate sfree(intName); 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate return (x); 617*7c478bd9Sstevel@tonic-gate } 618