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