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 (c) 2001 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All Rights Reserved. 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 <stdio.h> 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #include <malloc.h> 32*7c478bd9Sstevel@tonic-gate #include <strings.h> 33*7c478bd9Sstevel@tonic-gate #include <string.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 36*7c478bd9Sstevel@tonic-gate #include <time.h> 37*7c478bd9Sstevel@tonic-gate #include "db_headers.h" 38*7c478bd9Sstevel@tonic-gate #include "db.h" 39*7c478bd9Sstevel@tonic-gate #include "db_mindex.h" 40*7c478bd9Sstevel@tonic-gate #include "db_pickle.h" 41*7c478bd9Sstevel@tonic-gate #include "nisdb_mt.h" 42*7c478bd9Sstevel@tonic-gate #include "nisdb_ldap.h" 43*7c478bd9Sstevel@tonic-gate #include "ldap_nisdbquery.h" 44*7c478bd9Sstevel@tonic-gate #include "ldap_map.h" 45*7c478bd9Sstevel@tonic-gate #include "ldap_ruleval.h" 46*7c478bd9Sstevel@tonic-gate #include "ldap_scheme.h" 47*7c478bd9Sstevel@tonic-gate #include "ldap_parse.h" 48*7c478bd9Sstevel@tonic-gate #include "nis_hashitem.h" 49*7c478bd9Sstevel@tonic-gate #include "nis_servlist.h" 50*7c478bd9Sstevel@tonic-gate #include "ldap_nisplus.h" 51*7c478bd9Sstevel@tonic-gate #include "nis_db.h" 52*7c478bd9Sstevel@tonic-gate #include "ldap_glob.h" 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate /* Pass through configuration information to the table */ 55*7c478bd9Sstevel@tonic-gate bool_t 56*7c478bd9Sstevel@tonic-gate db_mindex::configure(char *tablePath) { 57*7c478bd9Sstevel@tonic-gate if (tablePath == NULL) 58*7c478bd9Sstevel@tonic-gate return (FALSE); 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate if (objPath.ptr != 0) 61*7c478bd9Sstevel@tonic-gate free(objPath.ptr); 62*7c478bd9Sstevel@tonic-gate objPath.ptr = strdup(tablePath); 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate if (table != NULL) { 65*7c478bd9Sstevel@tonic-gate return (table->configure(tablePath)); 66*7c478bd9Sstevel@tonic-gate } else { 67*7c478bd9Sstevel@tonic-gate /* Defer table config until we have a table instance */ 68*7c478bd9Sstevel@tonic-gate return (objPath.ptr != NULL); 69*7c478bd9Sstevel@tonic-gate } 70*7c478bd9Sstevel@tonic-gate } 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate /* 73*7c478bd9Sstevel@tonic-gate * The noWriteThrough flag is used to prevent modifies/updates to LDAP 74*7c478bd9Sstevel@tonic-gate * while we're incorporating log data into the in-memory tables. 75*7c478bd9Sstevel@tonic-gate */ 76*7c478bd9Sstevel@tonic-gate void 77*7c478bd9Sstevel@tonic-gate db_mindex::setNoWriteThrough(void) { 78*7c478bd9Sstevel@tonic-gate ASSERTWHELD(this->mindex); 79*7c478bd9Sstevel@tonic-gate noWriteThrough.flag++; 80*7c478bd9Sstevel@tonic-gate } 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate void 83*7c478bd9Sstevel@tonic-gate db_mindex::clearNoWriteThrough(void) { 84*7c478bd9Sstevel@tonic-gate ASSERTWHELD(this->mindex); 85*7c478bd9Sstevel@tonic-gate if (noWriteThrough.flag > 0) 86*7c478bd9Sstevel@tonic-gate noWriteThrough.flag--; 87*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 88*7c478bd9Sstevel@tonic-gate else 89*7c478bd9Sstevel@tonic-gate abort(); 90*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 91*7c478bd9Sstevel@tonic-gate } 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate /* 94*7c478bd9Sstevel@tonic-gate * The noLDAPquery flag is used to prevent recursive LDAP queries when 95*7c478bd9Sstevel@tonic-gate * satisfy_query() is re-entered as we add an entry from queryLDAP(). 96*7c478bd9Sstevel@tonic-gate */ 97*7c478bd9Sstevel@tonic-gate void 98*7c478bd9Sstevel@tonic-gate db_mindex::setNoLDAPquery(void) { 99*7c478bd9Sstevel@tonic-gate ASSERTWHELD(this->mindex); 100*7c478bd9Sstevel@tonic-gate noLDAPquery.flag++; 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate void 104*7c478bd9Sstevel@tonic-gate db_mindex::clearNoLDAPquery(void) { 105*7c478bd9Sstevel@tonic-gate ASSERTWHELD(this->mindex); 106*7c478bd9Sstevel@tonic-gate if (noLDAPquery.flag > 0) 107*7c478bd9Sstevel@tonic-gate noLDAPquery.flag--; 108*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 109*7c478bd9Sstevel@tonic-gate else 110*7c478bd9Sstevel@tonic-gate abort(); 111*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * The initialLoad flag tells us if an add or remove is done as part of 116*7c478bd9Sstevel@tonic-gate * the initial load of data, in which case we should use the initial TTLs. 117*7c478bd9Sstevel@tonic-gate */ 118*7c478bd9Sstevel@tonic-gate void 119*7c478bd9Sstevel@tonic-gate db_mindex::setInitialLoad(void) { 120*7c478bd9Sstevel@tonic-gate ASSERTWHELD(this->mindex); 121*7c478bd9Sstevel@tonic-gate initialLoad.flag++; 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate void 125*7c478bd9Sstevel@tonic-gate db_mindex::clearInitialLoad(void) { 126*7c478bd9Sstevel@tonic-gate ASSERTWHELD(this->mindex); 127*7c478bd9Sstevel@tonic-gate if (initialLoad.flag > 0) 128*7c478bd9Sstevel@tonic-gate initialLoad.flag--; 129*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 130*7c478bd9Sstevel@tonic-gate else 131*7c478bd9Sstevel@tonic-gate abort(); 132*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate void 136*7c478bd9Sstevel@tonic-gate db_mindex::setDbPtr(void *ptr) { 137*7c478bd9Sstevel@tonic-gate dbptr.ptr = ptr; 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate void * 141*7c478bd9Sstevel@tonic-gate db_mindex::getDbPtr(void) { 142*7c478bd9Sstevel@tonic-gate return (dbptr.ptr); 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate db_table * 146*7c478bd9Sstevel@tonic-gate db_mindex::getTable(void) { 147*7c478bd9Sstevel@tonic-gate return (table); 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate extern void db_free_result(db_result *); 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate zotypes 153*7c478bd9Sstevel@tonic-gate updateMappingObj(__nis_table_mapping_t *t, char **objNameP, 154*7c478bd9Sstevel@tonic-gate bool_t *isMasterP) { 155*7c478bd9Sstevel@tonic-gate zotypes type = NIS_BOGUS_OBJ; 156*7c478bd9Sstevel@tonic-gate char *objName = 0; 157*7c478bd9Sstevel@tonic-gate char *myself = "updateMappingObj"; 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate if (t != 0) 160*7c478bd9Sstevel@tonic-gate objName = t->objName; 161*7c478bd9Sstevel@tonic-gate else if (objNameP != 0) 162*7c478bd9Sstevel@tonic-gate objName = *objNameP; 163*7c478bd9Sstevel@tonic-gate else 164*7c478bd9Sstevel@tonic-gate return (NIS_BOGUS_OBJ); 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate if (objName != 0) { 167*7c478bd9Sstevel@tonic-gate db_status stat; 168*7c478bd9Sstevel@tonic-gate int lstat = LDAP_SUCCESS; 169*7c478bd9Sstevel@tonic-gate nis_object *o = dbFindObject(objName, &stat); 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate /* If not found in the local DB, try LDAP */ 172*7c478bd9Sstevel@tonic-gate if (o == 0) { 173*7c478bd9Sstevel@tonic-gate if (stat != DB_NOTFOUND) { 174*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 175*7c478bd9Sstevel@tonic-gate "%s: DB err %d for \"%s\"", 176*7c478bd9Sstevel@tonic-gate myself, stat, NIL(objName)); 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate o = ldapFindObj(t, objName, &lstat); 179*7c478bd9Sstevel@tonic-gate /* If found, refresh/create the local copy */ 180*7c478bd9Sstevel@tonic-gate if (o != 0) { 181*7c478bd9Sstevel@tonic-gate db_status rstat; 182*7c478bd9Sstevel@tonic-gate rstat = dbRefreshObj(objName, o); 183*7c478bd9Sstevel@tonic-gate if (rstat != DB_SUCCESS) 184*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 185*7c478bd9Sstevel@tonic-gate "%s: DB error %d refreshing \"%s\"", 186*7c478bd9Sstevel@tonic-gate myself, rstat, NIL(objName)); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate if (o != 0) { 191*7c478bd9Sstevel@tonic-gate type = o->zo_data.zo_type; 192*7c478bd9Sstevel@tonic-gate if (objNameP != 0) { 193*7c478bd9Sstevel@tonic-gate *objNameP = sdup(myself, T, objName); 194*7c478bd9Sstevel@tonic-gate if (*objNameP == 0) { 195*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 196*7c478bd9Sstevel@tonic-gate "%s: Unable to copy object name (\"%s\")", 197*7c478bd9Sstevel@tonic-gate myself, NIL(objName)); 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate } 200*7c478bd9Sstevel@tonic-gate if (t != 0) { 201*7c478bd9Sstevel@tonic-gate if (!setMappingObjTypeEtc(t, o)) 202*7c478bd9Sstevel@tonic-gate nis_destroy_object(o); 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate if (isMasterP != 0) 205*7c478bd9Sstevel@tonic-gate *isMasterP = t->isMaster; 206*7c478bd9Sstevel@tonic-gate } else { 207*7c478bd9Sstevel@tonic-gate if (isMasterP != 0) 208*7c478bd9Sstevel@tonic-gate *isMasterP = isMaster(o); 209*7c478bd9Sstevel@tonic-gate nis_destroy_object(o); 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate } else if (lstat != LDAP_SUCCESS) { 212*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 213*7c478bd9Sstevel@tonic-gate "%s: LDAP err %d for \"%s\"", 214*7c478bd9Sstevel@tonic-gate myself, lstat, NIL(objName)); 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate return (type); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate static __nis_table_mapping_t * 222*7c478bd9Sstevel@tonic-gate mappingFromObj(nis_object *obj, int *statP) { 223*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t; 224*7c478bd9Sstevel@tonic-gate __nis_buffer_t b = {0, 0}; 225*7c478bd9Sstevel@tonic-gate char *objPath; 226*7c478bd9Sstevel@tonic-gate char *myself = "mappingFromObj"; 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate if (obj == 0 || obj->zo_data.zo_type == NIS_ENTRY_OBJ) 229*7c478bd9Sstevel@tonic-gate return (0); 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate /* 232*7c478bd9Sstevel@tonic-gate * Convert full object name to the db table path used as 233*7c478bd9Sstevel@tonic-gate * key for the mapping hash list. 234*7c478bd9Sstevel@tonic-gate */ 235*7c478bd9Sstevel@tonic-gate bp2buf(myself, &b, "%s.%s", 236*7c478bd9Sstevel@tonic-gate NIL(obj->zo_name), NIL(obj->zo_domain)); 237*7c478bd9Sstevel@tonic-gate objPath = internalTableName(b.buf); 238*7c478bd9Sstevel@tonic-gate sfree(b.buf); 239*7c478bd9Sstevel@tonic-gate if (slen(objPath) <= 0) { 240*7c478bd9Sstevel@tonic-gate if (statP != 0) 241*7c478bd9Sstevel@tonic-gate *statP = LDAP_OPERATIONS_ERROR; 242*7c478bd9Sstevel@tonic-gate sfree(objPath); 243*7c478bd9Sstevel@tonic-gate return (0); 244*7c478bd9Sstevel@tonic-gate } 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate t = (__nis_table_mapping_t *)__nis_find_item_mt(objPath, 247*7c478bd9Sstevel@tonic-gate &ldapMappingList, 0, 0); 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate sfree(objPath); 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate return (t); 252*7c478bd9Sstevel@tonic-gate } 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate static __nis_table_mapping_t * 255*7c478bd9Sstevel@tonic-gate selectMapping(db_table *table, nis_object *obj, db_query *qin, 256*7c478bd9Sstevel@tonic-gate bool_t wantWrite, bool_t *asObjP, int *statP) { 257*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t; 258*7c478bd9Sstevel@tonic-gate __nis_buffer_t b = {0, 0}; 259*7c478bd9Sstevel@tonic-gate bool_t doLDAP, asObj; 260*7c478bd9Sstevel@tonic-gate int stat = LDAP_SUCCESS; 261*7c478bd9Sstevel@tonic-gate char *objPath = 0, buf[MAXPATHLEN+NIS_MAXNAMELEN+1]; 262*7c478bd9Sstevel@tonic-gate char *myself = "db_mindex::selectMapping"; 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate /* 265*7c478bd9Sstevel@tonic-gate * If 'table' is NULL, we try to find a mapping for 'obj'. 266*7c478bd9Sstevel@tonic-gate * We expect this to happen when our caller wants to write 267*7c478bd9Sstevel@tonic-gate * the object from a directory entry to LDAP. 268*7c478bd9Sstevel@tonic-gate */ 269*7c478bd9Sstevel@tonic-gate if (table == 0) { 270*7c478bd9Sstevel@tonic-gate if (asObjP != 0) 271*7c478bd9Sstevel@tonic-gate *asObjP = TRUE; 272*7c478bd9Sstevel@tonic-gate if (statP != 0) 273*7c478bd9Sstevel@tonic-gate *statP = LDAP_SUCCESS; 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate t = mappingFromObj(obj, statP); 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate if (t == 0) 278*7c478bd9Sstevel@tonic-gate return (0); 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate /* 281*7c478bd9Sstevel@tonic-gate * Should the object type in the mapping be NIS_BOGUS_OBJ, 282*7c478bd9Sstevel@tonic-gate * we need to determine what kind of object this is. 283*7c478bd9Sstevel@tonic-gate */ 284*7c478bd9Sstevel@tonic-gate if (t->objType == NIS_BOGUS_OBJ) { 285*7c478bd9Sstevel@tonic-gate t->objType = updateMappingObj(t, 0, 0); 286*7c478bd9Sstevel@tonic-gate if (t->objType == NIS_BOGUS_OBJ) { 287*7c478bd9Sstevel@tonic-gate if (statP != 0) 288*7c478bd9Sstevel@tonic-gate *statP = LDAP_OPERATIONS_ERROR; 289*7c478bd9Sstevel@tonic-gate return (0); 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate /* 294*7c478bd9Sstevel@tonic-gate * If caller wants a mapping suitable for writing, 295*7c478bd9Sstevel@tonic-gate * check that we're the master for this object. 296*7c478bd9Sstevel@tonic-gate */ 297*7c478bd9Sstevel@tonic-gate if (wantWrite && !t->isMaster) 298*7c478bd9Sstevel@tonic-gate return (0); 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate return (t); 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate /* 304*7c478bd9Sstevel@tonic-gate * If the object type for the mapping is NIS_BOGUS_OBJ, then 305*7c478bd9Sstevel@tonic-gate * we haven't yet been able to determine what kind of object this 306*7c478bd9Sstevel@tonic-gate * is. Try to fix that now. 307*7c478bd9Sstevel@tonic-gate */ 308*7c478bd9Sstevel@tonic-gate if (table->mapping.objType == NIS_BOGUS_OBJ) { 309*7c478bd9Sstevel@tonic-gate table->mapping.objType = updateMappingObj(table->mapping.tm, 310*7c478bd9Sstevel@tonic-gate &table->mapping.objName, 311*7c478bd9Sstevel@tonic-gate &table->mapping.isMaster); 312*7c478bd9Sstevel@tonic-gate table->mapping.expireType = table->mapping.objType; 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate /* 316*7c478bd9Sstevel@tonic-gate * Depending on the object type (table->mapping.objType): 317*7c478bd9Sstevel@tonic-gate * 318*7c478bd9Sstevel@tonic-gate * table Use table->mapping.tm to query LDAP 319*7c478bd9Sstevel@tonic-gate * for entries per 'qin'. 320*7c478bd9Sstevel@tonic-gate * 321*7c478bd9Sstevel@tonic-gate * directory Use 'qin' and table->mapping.objName 322*7c478bd9Sstevel@tonic-gate * to retrieve a mapping entry, and then 323*7c478bd9Sstevel@tonic-gate * query LDAP for the corresponding object. 324*7c478bd9Sstevel@tonic-gate * 'qin' == NULL means reading/writing the 325*7c478bd9Sstevel@tonic-gate * entire directory object, plus the names 326*7c478bd9Sstevel@tonic-gate * of the directory entries. 327*7c478bd9Sstevel@tonic-gate * 328*7c478bd9Sstevel@tonic-gate * bogus Not mapping this object. However, we may 329*7c478bd9Sstevel@tonic-gate * still be mapping the object 'obj'. 330*7c478bd9Sstevel@tonic-gate * 331*7c478bd9Sstevel@tonic-gate * other Shouldn't happen; illegal. 332*7c478bd9Sstevel@tonic-gate */ 333*7c478bd9Sstevel@tonic-gate switch (table->mapping.objType) { 334*7c478bd9Sstevel@tonic-gate case NIS_TABLE_OBJ: 335*7c478bd9Sstevel@tonic-gate t = table->mapping.tm; 336*7c478bd9Sstevel@tonic-gate if (wantWrite) 337*7c478bd9Sstevel@tonic-gate doLDAP = table->mapping.isMaster && 338*7c478bd9Sstevel@tonic-gate table->mapping.toLDAP; 339*7c478bd9Sstevel@tonic-gate else 340*7c478bd9Sstevel@tonic-gate doLDAP = table->mapping.fromLDAP; 341*7c478bd9Sstevel@tonic-gate asObj = FALSE; 342*7c478bd9Sstevel@tonic-gate break; 343*7c478bd9Sstevel@tonic-gate case NIS_DIRECTORY_OBJ: { 344*7c478bd9Sstevel@tonic-gate char *sub = 0; 345*7c478bd9Sstevel@tonic-gate int nqc, len = 0; 346*7c478bd9Sstevel@tonic-gate db_qcomp *qc; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate t = 0; 349*7c478bd9Sstevel@tonic-gate doLDAP = FALSE; 350*7c478bd9Sstevel@tonic-gate asObj = TRUE; 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate /* 353*7c478bd9Sstevel@tonic-gate * We expect the query to have one component, containing 354*7c478bd9Sstevel@tonic-gate * the directory entry name. If there's no query, we want 355*7c478bd9Sstevel@tonic-gate * an enumeration of the entries in the directory. They're 356*7c478bd9Sstevel@tonic-gate * stored with the XDR:ed directory object in LDAP, so 357*7c478bd9Sstevel@tonic-gate * asObj should be TRUE. 358*7c478bd9Sstevel@tonic-gate */ 359*7c478bd9Sstevel@tonic-gate if (qin == 0) { 360*7c478bd9Sstevel@tonic-gate t = table->mapping.tm; 361*7c478bd9Sstevel@tonic-gate if (wantWrite) 362*7c478bd9Sstevel@tonic-gate doLDAP = table->mapping.isMaster && 363*7c478bd9Sstevel@tonic-gate table->mapping.toLDAP; 364*7c478bd9Sstevel@tonic-gate else 365*7c478bd9Sstevel@tonic-gate doLDAP = table->mapping.fromLDAP; 366*7c478bd9Sstevel@tonic-gate asObj = TRUE; 367*7c478bd9Sstevel@tonic-gate break; 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate nqc = qin->size(); 371*7c478bd9Sstevel@tonic-gate if (nqc != 1 || (qc = qin->queryloc()) == 0 || 372*7c478bd9Sstevel@tonic-gate qc[0].index_value == 0) { 373*7c478bd9Sstevel@tonic-gate stat = LDAP_PARAM_ERROR; 374*7c478bd9Sstevel@tonic-gate break; 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate qc[0].index_value->get_value(&sub, &len); 377*7c478bd9Sstevel@tonic-gate if (sub == 0 || len <= 0) { 378*7c478bd9Sstevel@tonic-gate stat = LDAP_PARAM_ERROR; 379*7c478bd9Sstevel@tonic-gate break; 380*7c478bd9Sstevel@tonic-gate } 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate /* Append directory name to dir entry name */ 383*7c478bd9Sstevel@tonic-gate sbc2buf(myself, sub, len, &b); 384*7c478bd9Sstevel@tonic-gate bp2buf(myself, &b, ".%s", table->mapping.objName); 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate /* Convert to the DB internal name */ 387*7c478bd9Sstevel@tonic-gate objPath = internal_table_name(b.buf, buf); 388*7c478bd9Sstevel@tonic-gate sfree(b.buf); 389*7c478bd9Sstevel@tonic-gate if (slen(objPath) <= 0) { 390*7c478bd9Sstevel@tonic-gate stat = LDAP_OPERATIONS_ERROR; 391*7c478bd9Sstevel@tonic-gate break; 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate /* Look for the corresponding table mapping */ 395*7c478bd9Sstevel@tonic-gate t = (__nis_table_mapping_t *)__nis_find_item_mt( 396*7c478bd9Sstevel@tonic-gate objPath, &ldapMappingList, 0, 0); 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate if (t == 0) 399*7c478bd9Sstevel@tonic-gate break; 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate /* Update object mapping information */ 402*7c478bd9Sstevel@tonic-gate if (t->objType == NIS_BOGUS_OBJ) 403*7c478bd9Sstevel@tonic-gate (void) updateMappingObj(t, 0, 0); 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate /* 406*7c478bd9Sstevel@tonic-gate * Should check the objectDN's in 't', but leave that to 407*7c478bd9Sstevel@tonic-gate * underlying functions. 408*7c478bd9Sstevel@tonic-gate */ 409*7c478bd9Sstevel@tonic-gate if (wantWrite) 410*7c478bd9Sstevel@tonic-gate doLDAP = t->isMaster; 411*7c478bd9Sstevel@tonic-gate else 412*7c478bd9Sstevel@tonic-gate doLDAP = TRUE; 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate break; 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate case NIS_BOGUS_OBJ: 417*7c478bd9Sstevel@tonic-gate t = mappingFromObj(obj, statP); 418*7c478bd9Sstevel@tonic-gate doLDAP = TRUE; 419*7c478bd9Sstevel@tonic-gate asObj = TRUE; 420*7c478bd9Sstevel@tonic-gate break; 421*7c478bd9Sstevel@tonic-gate default: 422*7c478bd9Sstevel@tonic-gate t = 0; 423*7c478bd9Sstevel@tonic-gate doLDAP = FALSE; 424*7c478bd9Sstevel@tonic-gate asObj = TRUE; 425*7c478bd9Sstevel@tonic-gate break; 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate if (!doLDAP) 429*7c478bd9Sstevel@tonic-gate t = 0; 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate if (asObjP != 0) 432*7c478bd9Sstevel@tonic-gate *asObjP = asObj; 433*7c478bd9Sstevel@tonic-gate 434*7c478bd9Sstevel@tonic-gate if (statP != 0) 435*7c478bd9Sstevel@tonic-gate *statP = stat; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate return (t); 438*7c478bd9Sstevel@tonic-gate } 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate /* 441*7c478bd9Sstevel@tonic-gate * Replace or remove the table entry identified by 'e'. 'tableName' is 442*7c478bd9Sstevel@tonic-gate * the name of the table (which could be a directory) in which the entry 443*7c478bd9Sstevel@tonic-gate * resides. 'obj' is an un-XDR:ed copy of the object in 'e', optionally 444*7c478bd9Sstevel@tonic-gate * supplied to save re-doing unpacking of the entry object. 'tobj' is 445*7c478bd9Sstevel@tonic-gate * a pointer to the table object; needed for table entries, but not 446*7c478bd9Sstevel@tonic-gate * for directory entries. 447*7c478bd9Sstevel@tonic-gate * 448*7c478bd9Sstevel@tonic-gate * 'ttime' contains the current time, to be supplied for the trans log 449*7c478bd9Sstevel@tonic-gate * entry. 450*7c478bd9Sstevel@tonic-gate * 451*7c478bd9Sstevel@tonic-gate * Returns LDAP_SUCCESS when entry successfully added/modified/deleted, 452*7c478bd9Sstevel@tonic-gate * LDAP_COMPARE_TRUE if an entry to be added/modified was the same as 453*7c478bd9Sstevel@tonic-gate * an already existing one, and a suitable error otherwise. 454*7c478bd9Sstevel@tonic-gate */ 455*7c478bd9Sstevel@tonic-gate int 456*7c478bd9Sstevel@tonic-gate db_mindex::updateTableEntry(entry_object *e, int replace, char *tableName, 457*7c478bd9Sstevel@tonic-gate nis_object *obj, nis_object *tobj, uint32_t ttime, 458*7c478bd9Sstevel@tonic-gate int *xid) { 459*7c478bd9Sstevel@tonic-gate int stat, freeObj = 0; 460*7c478bd9Sstevel@tonic-gate db_index_entry *dbie; 461*7c478bd9Sstevel@tonic-gate long count = 0; 462*7c478bd9Sstevel@tonic-gate bool_t valid = TRUE; 463*7c478bd9Sstevel@tonic-gate db_result *dbres; 464*7c478bd9Sstevel@tonic-gate db_query *qi; 465*7c478bd9Sstevel@tonic-gate nis_object *oldObj = 0; 466*7c478bd9Sstevel@tonic-gate char *myself = "db_mindex::updateTableEntry"; 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate if (table == 0 || e == 0) 469*7c478bd9Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate qi = extract_index_values_from_object(e); 472*7c478bd9Sstevel@tonic-gate if (qi == 0) { 473*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 474*7c478bd9Sstevel@tonic-gate "%s: Out of memory for query index", 475*7c478bd9Sstevel@tonic-gate myself); 476*7c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate dbie = satisfy_query(qi, &count, &valid, FALSE); 480*7c478bd9Sstevel@tonic-gate if (dbie != 0 && (count != 1 || !valid)) { 481*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 482*7c478bd9Sstevel@tonic-gate "%s: count=%d, valid=%s", 483*7c478bd9Sstevel@tonic-gate myself, count, valid ? "TRUE" : "FALSE"); 484*7c478bd9Sstevel@tonic-gate delete qi; 485*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 486*7c478bd9Sstevel@tonic-gate } 487*7c478bd9Sstevel@tonic-gate 488*7c478bd9Sstevel@tonic-gate /* 489*7c478bd9Sstevel@tonic-gate * Need a copy of the old object in order to log a removal 490*7c478bd9Sstevel@tonic-gate * (this is true even if we're modifying an existing entry). 491*7c478bd9Sstevel@tonic-gate */ 492*7c478bd9Sstevel@tonic-gate if (dbie != 0) { 493*7c478bd9Sstevel@tonic-gate oldObj = unmakePseudoEntryObj( 494*7c478bd9Sstevel@tonic-gate table->get_entry(dbie->getlocation()), tobj); 495*7c478bd9Sstevel@tonic-gate if (oldObj == 0) { 496*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 497*7c478bd9Sstevel@tonic-gate "%s: Error getting object from old pseudo-entry for \"%s\" in \"%s\"", 498*7c478bd9Sstevel@tonic-gate myself, NIL(obj->zo_name), 499*7c478bd9Sstevel@tonic-gate NIL(tableName)); 500*7c478bd9Sstevel@tonic-gate delete qi; 501*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate if (replace) { 506*7c478bd9Sstevel@tonic-gate /* Need the object from the entry */ 507*7c478bd9Sstevel@tonic-gate if (dbie != 0 && obj == 0) { 508*7c478bd9Sstevel@tonic-gate obj = unmakePseudoEntryObj(e, tobj); 509*7c478bd9Sstevel@tonic-gate if (obj == 0) { 510*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 511*7c478bd9Sstevel@tonic-gate "%s: Error getting object from pseudo-entry for \"%s\" in \"%s\"", 512*7c478bd9Sstevel@tonic-gate myself, NIL(obj->zo_name), 513*7c478bd9Sstevel@tonic-gate NIL(tableName)); 514*7c478bd9Sstevel@tonic-gate delete qi; 515*7c478bd9Sstevel@tonic-gate nis_destroy_object(oldObj); 516*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 517*7c478bd9Sstevel@tonic-gate } 518*7c478bd9Sstevel@tonic-gate freeObj = 1; 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate /* Is the new object a dup of the old ? */ 522*7c478bd9Sstevel@tonic-gate if (dbie != 0 && sameNisPlusObj(oldObj, obj)) { 523*7c478bd9Sstevel@tonic-gate /* Yes, it's a dup, so just update the timestamp */ 524*7c478bd9Sstevel@tonic-gate table->touchEntry(dbie->getlocation()); 525*7c478bd9Sstevel@tonic-gate delete qi; 526*7c478bd9Sstevel@tonic-gate if (freeObj) 527*7c478bd9Sstevel@tonic-gate nis_destroy_object(obj); 528*7c478bd9Sstevel@tonic-gate nis_destroy_object(oldObj); 529*7c478bd9Sstevel@tonic-gate return (LDAP_COMPARE_TRUE); 530*7c478bd9Sstevel@tonic-gate } else { 531*7c478bd9Sstevel@tonic-gate /* 532*7c478bd9Sstevel@tonic-gate * Not a dup, so go ahead and add it. Provided 533*7c478bd9Sstevel@tonic-gate * that 'qi' isn't NULL (which we've already 534*7c478bd9Sstevel@tonic-gate * checked), DB_ADD(_NOSYNC) does the right 535*7c478bd9Sstevel@tonic-gate * thing even if matching entries already 536*7c478bd9Sstevel@tonic-gate * exist. 537*7c478bd9Sstevel@tonic-gate */ 538*7c478bd9Sstevel@tonic-gate dbres = ((db *)dbptr.ptr)->log_action(DB_ADD_NOSYNC, 539*7c478bd9Sstevel@tonic-gate qi, e); 540*7c478bd9Sstevel@tonic-gate if (dbres == 0) 541*7c478bd9Sstevel@tonic-gate stat = LDAP_OPERATIONS_ERROR; 542*7c478bd9Sstevel@tonic-gate else if (dbres->status == DB_SUCCESS) 543*7c478bd9Sstevel@tonic-gate stat = LDAP_SUCCESS; 544*7c478bd9Sstevel@tonic-gate else 545*7c478bd9Sstevel@tonic-gate stat = LDAP_OPERATIONS_ERROR; 546*7c478bd9Sstevel@tonic-gate db_free_result(dbres); 547*7c478bd9Sstevel@tonic-gate } 548*7c478bd9Sstevel@tonic-gate } else { /* Removing */ 549*7c478bd9Sstevel@tonic-gate /* If the object doesn't exist, we're done */ 550*7c478bd9Sstevel@tonic-gate if (dbie == 0) { 551*7c478bd9Sstevel@tonic-gate delete qi; 552*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 553*7c478bd9Sstevel@tonic-gate } 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate dbres = ((db *)dbptr.ptr)->log_action(DB_REMOVE_NOSYNC, qi, 0); 556*7c478bd9Sstevel@tonic-gate if (dbres == 0) 557*7c478bd9Sstevel@tonic-gate stat = LDAP_OPERATIONS_ERROR; 558*7c478bd9Sstevel@tonic-gate else if (dbres->status == DB_SUCCESS) 559*7c478bd9Sstevel@tonic-gate stat = LDAP_SUCCESS; 560*7c478bd9Sstevel@tonic-gate else 561*7c478bd9Sstevel@tonic-gate stat = LDAP_OPERATIONS_ERROR; 562*7c478bd9Sstevel@tonic-gate db_free_result(dbres); 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate /* Log the operation */ 566*7c478bd9Sstevel@tonic-gate if (stat == LDAP_SUCCESS) { 567*7c478bd9Sstevel@tonic-gate int ret, numAttrs; 568*7c478bd9Sstevel@tonic-gate nis_attr *attr, attrbuf[NIS_MAXCOLUMNS]; 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate /* If we haven't begun the transaction yet, do so now */ 571*7c478bd9Sstevel@tonic-gate if (*xid == 0) { 572*7c478bd9Sstevel@tonic-gate *xid = beginTransaction(); 573*7c478bd9Sstevel@tonic-gate if (*xid == 0) { 574*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 575*7c478bd9Sstevel@tonic-gate "%s: Error starting transaction for \"%s\"", 576*7c478bd9Sstevel@tonic-gate myself, NIL(tableName)); 577*7c478bd9Sstevel@tonic-gate delete qi; 578*7c478bd9Sstevel@tonic-gate if (oldObj != 0) 579*7c478bd9Sstevel@tonic-gate nis_destroy_object(oldObj); 580*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 581*7c478bd9Sstevel@tonic-gate } 582*7c478bd9Sstevel@tonic-gate } 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate if (replace && obj == 0) { 585*7c478bd9Sstevel@tonic-gate obj = unmakePseudoEntryObj(e, tobj); 586*7c478bd9Sstevel@tonic-gate if (obj == 0) { 587*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 588*7c478bd9Sstevel@tonic-gate "%s: Error getting object from pseudo-entry for \"%s\" in \"%s\"", 589*7c478bd9Sstevel@tonic-gate myself, NIL(obj->zo_name), 590*7c478bd9Sstevel@tonic-gate NIL(tableName)); 591*7c478bd9Sstevel@tonic-gate delete qi; 592*7c478bd9Sstevel@tonic-gate if (oldObj != 0) 593*7c478bd9Sstevel@tonic-gate nis_destroy_object(oldObj); 594*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate freeObj = 1; 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate /* 600*7c478bd9Sstevel@tonic-gate * The log stores nis_attr information, so we need to 601*7c478bd9Sstevel@tonic-gate * convert the scheme-query to a nis_attr array. 602*7c478bd9Sstevel@tonic-gate */ 603*7c478bd9Sstevel@tonic-gate attr = schemeQuery2nisAttr(qi, attrbuf, scheme, 604*7c478bd9Sstevel@tonic-gate table->mapping.tm, &numAttrs); 605*7c478bd9Sstevel@tonic-gate if (attr == 0) { 606*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 607*7c478bd9Sstevel@tonic-gate "%s: Error converting index query to nis_attr for \"%s\" in \"%s\"", 608*7c478bd9Sstevel@tonic-gate myself, NIL(obj->zo_name), NIL(tableName)); 609*7c478bd9Sstevel@tonic-gate if (freeObj) 610*7c478bd9Sstevel@tonic-gate nis_destroy_object(obj); 611*7c478bd9Sstevel@tonic-gate if (oldObj != 0) 612*7c478bd9Sstevel@tonic-gate nis_destroy_object(oldObj); 613*7c478bd9Sstevel@tonic-gate delete qi; 614*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 615*7c478bd9Sstevel@tonic-gate } 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate if (replace) { 618*7c478bd9Sstevel@tonic-gate /* 619*7c478bd9Sstevel@tonic-gate * While the DB can handle a modify (replace) 620*7c478bd9Sstevel@tonic-gate * operation, the trans log stores this as a 621*7c478bd9Sstevel@tonic-gate * remove followed by an add (which allows 622*7c478bd9Sstevel@tonic-gate * backing out the change by removing the new 623*7c478bd9Sstevel@tonic-gate * object incarnation, and adding the old one). 624*7c478bd9Sstevel@tonic-gate */ 625*7c478bd9Sstevel@tonic-gate if (oldObj != 0) 626*7c478bd9Sstevel@tonic-gate ret = addUpdate(REM_IBASE, tableName, 627*7c478bd9Sstevel@tonic-gate numAttrs, attr, oldObj, 0, ttime); 628*7c478bd9Sstevel@tonic-gate else 629*7c478bd9Sstevel@tonic-gate ret = 0; 630*7c478bd9Sstevel@tonic-gate if (ret == 0) 631*7c478bd9Sstevel@tonic-gate ret = addUpdate(ADD_IBASE, tableName, 632*7c478bd9Sstevel@tonic-gate numAttrs, attr, obj, 0, ttime); 633*7c478bd9Sstevel@tonic-gate } else { /* Removal */ 634*7c478bd9Sstevel@tonic-gate ret = addUpdate(REM_IBASE, tableName, numAttrs, attr, 635*7c478bd9Sstevel@tonic-gate oldObj, 0, ttime); 636*7c478bd9Sstevel@tonic-gate } 637*7c478bd9Sstevel@tonic-gate if (ret != 0) { 638*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 639*7c478bd9Sstevel@tonic-gate "%s: Error adding trans log entry for \"%s\" in \"%s\"", 640*7c478bd9Sstevel@tonic-gate myself, NIL(obj->zo_name), NIL(tableName)); 641*7c478bd9Sstevel@tonic-gate stat = LDAP_OPERATIONS_ERROR; 642*7c478bd9Sstevel@tonic-gate } 643*7c478bd9Sstevel@tonic-gate } 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate delete qi; 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate if (oldObj != 0) 648*7c478bd9Sstevel@tonic-gate nis_destroy_object(oldObj); 649*7c478bd9Sstevel@tonic-gate if (freeObj) 650*7c478bd9Sstevel@tonic-gate nis_destroy_object(obj); 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate return (stat); 653*7c478bd9Sstevel@tonic-gate } 654*7c478bd9Sstevel@tonic-gate 655*7c478bd9Sstevel@tonic-gate bool_t 656*7c478bd9Sstevel@tonic-gate db_mindex::touchEntry(entry_object *e) { 657*7c478bd9Sstevel@tonic-gate db_query *qi; 658*7c478bd9Sstevel@tonic-gate bool_t ret; 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate if (table == 0 || e == 0) 661*7c478bd9Sstevel@tonic-gate return (FALSE); 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate qi = extract_index_values_from_object(e); 664*7c478bd9Sstevel@tonic-gate if (qi == 0) 665*7c478bd9Sstevel@tonic-gate return (FALSE); 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate ret = touchEntry(qi); 668*7c478bd9Sstevel@tonic-gate 669*7c478bd9Sstevel@tonic-gate delete qi; 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gate return (ret); 672*7c478bd9Sstevel@tonic-gate } 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gate bool_t 675*7c478bd9Sstevel@tonic-gate db_mindex::touchEntry(db_query *q) { 676*7c478bd9Sstevel@tonic-gate db_index_entry *dbie; 677*7c478bd9Sstevel@tonic-gate long count; 678*7c478bd9Sstevel@tonic-gate bool_t valid; 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate dbie = satisfy_query(q, &count, &valid, FALSE); 681*7c478bd9Sstevel@tonic-gate if (dbie != 0 && count == 1 && valid) 682*7c478bd9Sstevel@tonic-gate table->touchEntry(dbie->getlocation()); 683*7c478bd9Sstevel@tonic-gate else 684*7c478bd9Sstevel@tonic-gate return (FALSE); 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate return (TRUE); 687*7c478bd9Sstevel@tonic-gate } 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate /* 690*7c478bd9Sstevel@tonic-gate * Compose an object name from column zero of 'e' and 't->objName', 691*7c478bd9Sstevel@tonic-gate * and return the mapping for that object, if any. Also set '*name' 692*7c478bd9Sstevel@tonic-gate * to point to the dir entry name in 'e'. Note that this is a pointer 693*7c478bd9Sstevel@tonic-gate * to existing data, and shouldn't be freed other than as part of 694*7c478bd9Sstevel@tonic-gate * freeing 'e'. 695*7c478bd9Sstevel@tonic-gate */ 696*7c478bd9Sstevel@tonic-gate static __nis_table_mapping_t * 697*7c478bd9Sstevel@tonic-gate findDirEntryMapping(__nis_table_mapping_t *t, entry_object *e, char **name) { 698*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *x; 699*7c478bd9Sstevel@tonic-gate char *entryName; 700*7c478bd9Sstevel@tonic-gate char *myself = "findDirEntryMapping"; 701*7c478bd9Sstevel@tonic-gate __nis_buffer_t b = {0, 0}; 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate if (e == 0 || e->en_cols.en_cols_len != 2 || 704*7c478bd9Sstevel@tonic-gate e->en_cols.en_cols_val == 0) 705*7c478bd9Sstevel@tonic-gate return (0); 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate entryName = e->en_cols.en_cols_val[1].ec_value.ec_value_val; 708*7c478bd9Sstevel@tonic-gate if (name != 0) 709*7c478bd9Sstevel@tonic-gate *name = entryName; 710*7c478bd9Sstevel@tonic-gate 711*7c478bd9Sstevel@tonic-gate if (t == 0 || entryName == 0 || t->objName == 0) 712*7c478bd9Sstevel@tonic-gate return (0); 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate bp2buf(myself, &b, "%s.%s", entryName, t->objName); 715*7c478bd9Sstevel@tonic-gate if (b.len == 0 || b.buf == 0) 716*7c478bd9Sstevel@tonic-gate return (0); 717*7c478bd9Sstevel@tonic-gate 718*7c478bd9Sstevel@tonic-gate x = (__nis_table_mapping_t *)__nis_find_item_mt(b.buf, 719*7c478bd9Sstevel@tonic-gate &ldapMappingList, 0, 0); 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate sfree(b.buf); 722*7c478bd9Sstevel@tonic-gate 723*7c478bd9Sstevel@tonic-gate return (x); 724*7c478bd9Sstevel@tonic-gate } 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate /* 727*7c478bd9Sstevel@tonic-gate * Query LDAP per the supplied (scheme-) query 'qin'. If 'doAsynch' is 728*7c478bd9Sstevel@tonic-gate * set, and the query is an enumeration (qin == 0), the query will be 729*7c478bd9Sstevel@tonic-gate * performed in a detached thread, and complete asynchronously. In this 730*7c478bd9Sstevel@tonic-gate * case, the return status reflects the setup and launch of the 731*7c478bd9Sstevel@tonic-gate * detached thread; the query will complete asynchronously. 732*7c478bd9Sstevel@tonic-gate * 733*7c478bd9Sstevel@tonic-gate * Returns an appropriate LDAP status code. 734*7c478bd9Sstevel@tonic-gate */ 735*7c478bd9Sstevel@tonic-gate int 736*7c478bd9Sstevel@tonic-gate db_mindex::queryLDAP(db_query *qin, char *dbId, int doAsynch) { 737*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t; 738*7c478bd9Sstevel@tonic-gate int i, na, nq = 0, stat, stat2, numAttrs, ret; 739*7c478bd9Sstevel@tonic-gate int xid = 0; 740*7c478bd9Sstevel@tonic-gate long numEa; 741*7c478bd9Sstevel@tonic-gate bool_t asObj, doEnum; 742*7c478bd9Sstevel@tonic-gate db_query *q; 743*7c478bd9Sstevel@tonic-gate entry_object **ea; 744*7c478bd9Sstevel@tonic-gate nis_attr attr; 745*7c478bd9Sstevel@tonic-gate nis_object *dirObj; 746*7c478bd9Sstevel@tonic-gate db_status dstat; 747*7c478bd9Sstevel@tonic-gate char *myself = "db_mindex::queryLDAP"; 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate if (!useLDAPrespository || table == 0) 750*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 751*7c478bd9Sstevel@tonic-gate 752*7c478bd9Sstevel@tonic-gate /* 753*7c478bd9Sstevel@tonic-gate * Instances from the deferred dictionary shouldn't change, 754*7c478bd9Sstevel@tonic-gate * there's no point in querying LDAP. 755*7c478bd9Sstevel@tonic-gate */ 756*7c478bd9Sstevel@tonic-gate if (table->mapping.isDeferredTable) 757*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate t = selectMapping(table, 0, qin, FALSE, &asObj, &stat); 760*7c478bd9Sstevel@tonic-gate 761*7c478bd9Sstevel@tonic-gate if (t == 0) 762*7c478bd9Sstevel@tonic-gate return (stat); 763*7c478bd9Sstevel@tonic-gate 764*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 765*7c478bd9Sstevel@tonic-gate printf("%s: %s (%s)\n", 766*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName), (asObj ? "object" : "entry")); 767*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate if (qin != NULL) { 770*7c478bd9Sstevel@tonic-gate q = schemeQuery2Query(qin, scheme); 771*7c478bd9Sstevel@tonic-gate if (q == 0) 772*7c478bd9Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 773*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 774*7c478bd9Sstevel@tonic-gate q->print(); 775*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 776*7c478bd9Sstevel@tonic-gate } else { 777*7c478bd9Sstevel@tonic-gate q = 0; 778*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 779*7c478bd9Sstevel@tonic-gate printf("\tenumerating %s%s%s\n", 780*7c478bd9Sstevel@tonic-gate dbId ? dbId : "", dbId ? ":" : "", NIL(t->objName)); 781*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 782*7c478bd9Sstevel@tonic-gate } 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate /* 785*7c478bd9Sstevel@tonic-gate * Do we have any active mappings for this particular query and 786*7c478bd9Sstevel@tonic-gate * dbId ? If not, we're done. 787*7c478bd9Sstevel@tonic-gate * 788*7c478bd9Sstevel@tonic-gate * Note that we don't care about the return value from 789*7c478bd9Sstevel@tonic-gate * selectTableMapping(), just wheter or not there are 790*7c478bd9Sstevel@tonic-gate * any valid mappings. 791*7c478bd9Sstevel@tonic-gate */ 792*7c478bd9Sstevel@tonic-gate i = 0; 793*7c478bd9Sstevel@tonic-gate sfree(selectTableMapping(t, q, 0, asObj, dbId, &i)); 794*7c478bd9Sstevel@tonic-gate if (i <= 0) { 795*7c478bd9Sstevel@tonic-gate freeQuery(q); 796*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 797*7c478bd9Sstevel@tonic-gate } 798*7c478bd9Sstevel@tonic-gate 799*7c478bd9Sstevel@tonic-gate /* Is the object a directory ? */ 800*7c478bd9Sstevel@tonic-gate if (asObj) { 801*7c478bd9Sstevel@tonic-gate nis_object *o; 802*7c478bd9Sstevel@tonic-gate entry_object *e, eo; 803*7c478bd9Sstevel@tonic-gate entry_col ec[2]; 804*7c478bd9Sstevel@tonic-gate int nea; 805*7c478bd9Sstevel@tonic-gate 806*7c478bd9Sstevel@tonic-gate stat = objFromLDAP(t, &o, &ea, &nea); 807*7c478bd9Sstevel@tonic-gate numEa = nea; 808*7c478bd9Sstevel@tonic-gate 809*7c478bd9Sstevel@tonic-gate if (stat == LDAP_NO_SUCH_OBJECT) { 810*7c478bd9Sstevel@tonic-gate /* Positive failure; remove the object */ 811*7c478bd9Sstevel@tonic-gate dstat = dbDeleteObj(t->objName); 812*7c478bd9Sstevel@tonic-gate if (dstat == DB_SUCCESS || dstat == DB_NOTFOUND) { 813*7c478bd9Sstevel@tonic-gate stat = LDAP_SUCCESS; 814*7c478bd9Sstevel@tonic-gate } else { 815*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 816*7c478bd9Sstevel@tonic-gate "%s: DB error %d deleting \"%s\"", 817*7c478bd9Sstevel@tonic-gate myself, dstat, NIL(t->objName)); 818*7c478bd9Sstevel@tonic-gate stat = LDAP_OPERATIONS_ERROR; 819*7c478bd9Sstevel@tonic-gate } 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate freeQuery(q); 822*7c478bd9Sstevel@tonic-gate 823*7c478bd9Sstevel@tonic-gate return (stat); 824*7c478bd9Sstevel@tonic-gate } else if (stat != LDAP_SUCCESS) { 825*7c478bd9Sstevel@tonic-gate freeQuery(q); 826*7c478bd9Sstevel@tonic-gate return (stat); 827*7c478bd9Sstevel@tonic-gate } else if (o == 0) { 828*7c478bd9Sstevel@tonic-gate /* OK; this entry just isn't mapped */ 829*7c478bd9Sstevel@tonic-gate freeQuery(q); 830*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 831*7c478bd9Sstevel@tonic-gate } 832*7c478bd9Sstevel@tonic-gate 833*7c478bd9Sstevel@tonic-gate if (q != 0) { 834*7c478bd9Sstevel@tonic-gate /* 835*7c478bd9Sstevel@tonic-gate * We're updating one particular entry (described 836*7c478bd9Sstevel@tonic-gate * by 't') in the directory 'table->mapping.tm'. 837*7c478bd9Sstevel@tonic-gate */ 838*7c478bd9Sstevel@tonic-gate 839*7c478bd9Sstevel@tonic-gate setOid(o); 840*7c478bd9Sstevel@tonic-gate dstat = dbRefreshObj(t->objName, o); 841*7c478bd9Sstevel@tonic-gate if (dstat == DB_SUCCESS) { 842*7c478bd9Sstevel@tonic-gate stat = LDAP_SUCCESS; 843*7c478bd9Sstevel@tonic-gate } else { 844*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 845*7c478bd9Sstevel@tonic-gate "%s: DB error %d updating \"%s\" in \"%s\"", 846*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName), 847*7c478bd9Sstevel@tonic-gate NIL(table->mapping.tm->objName)); 848*7c478bd9Sstevel@tonic-gate stat = LDAP_OPERATIONS_ERROR; 849*7c478bd9Sstevel@tonic-gate } 850*7c478bd9Sstevel@tonic-gate 851*7c478bd9Sstevel@tonic-gate freeEntryObjArray(ea, numEa); 852*7c478bd9Sstevel@tonic-gate freeQuery(q); 853*7c478bd9Sstevel@tonic-gate nis_destroy_object(o); 854*7c478bd9Sstevel@tonic-gate 855*7c478bd9Sstevel@tonic-gate return (stat); 856*7c478bd9Sstevel@tonic-gate } 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gate dirObj = o; 859*7c478bd9Sstevel@tonic-gate 860*7c478bd9Sstevel@tonic-gate /* 861*7c478bd9Sstevel@tonic-gate * q == 0, so we're enumerating. Update the list of 862*7c478bd9Sstevel@tonic-gate * directory entries. 863*7c478bd9Sstevel@tonic-gate */ 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate /* 866*7c478bd9Sstevel@tonic-gate * Need to disable write-through to LDAP, for which we need 867*7c478bd9Sstevel@tonic-gate * a lock on our db_mindex ('this'); we're also updating the 868*7c478bd9Sstevel@tonic-gate * table, so we need a write lock on that as well. 869*7c478bd9Sstevel@tonic-gate */ 870*7c478bd9Sstevel@tonic-gate WRITELOCKNR(this, stat, "w db_mindex::queryLDAP"); 871*7c478bd9Sstevel@tonic-gate if (stat == 0) { 872*7c478bd9Sstevel@tonic-gate WRITELOCKNR(table, stat2, 873*7c478bd9Sstevel@tonic-gate "table w db_mindex::queryLDAP"); 874*7c478bd9Sstevel@tonic-gate } 875*7c478bd9Sstevel@tonic-gate if (stat != 0 || stat2 != 0) { 876*7c478bd9Sstevel@tonic-gate nis_destroy_object(dirObj); 877*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 878*7c478bd9Sstevel@tonic-gate "%s: lock error %d", myself, 879*7c478bd9Sstevel@tonic-gate stat != 0 ? stat : stat2); 880*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 881*7c478bd9Sstevel@tonic-gate } 882*7c478bd9Sstevel@tonic-gate 883*7c478bd9Sstevel@tonic-gate setNoWriteThrough(); 884*7c478bd9Sstevel@tonic-gate setNoLDAPquery(); 885*7c478bd9Sstevel@tonic-gate table->setEnumMode(0); 886*7c478bd9Sstevel@tonic-gate 887*7c478bd9Sstevel@tonic-gate for (i = 0, na = 0; i < numEa; i++) { 888*7c478bd9Sstevel@tonic-gate int st; 889*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *x; 890*7c478bd9Sstevel@tonic-gate char *name = 0; 891*7c478bd9Sstevel@tonic-gate entry_obj *e; 892*7c478bd9Sstevel@tonic-gate 893*7c478bd9Sstevel@tonic-gate if (ea[i] == 0) 894*7c478bd9Sstevel@tonic-gate continue; 895*7c478bd9Sstevel@tonic-gate 896*7c478bd9Sstevel@tonic-gate /* 897*7c478bd9Sstevel@tonic-gate * We've got a list of dir entries. In the general, 898*7c478bd9Sstevel@tonic-gate * case, some are new, and some already exist. 899*7c478bd9Sstevel@tonic-gate * We definitely want to add the new ones, and to 900*7c478bd9Sstevel@tonic-gate * that end, we need a copy of the object for the 901*7c478bd9Sstevel@tonic-gate * entry. By definition, if an entry is new, we 902*7c478bd9Sstevel@tonic-gate * don't yet have a copy of the object for it, so 903*7c478bd9Sstevel@tonic-gate * it's LDAP or nothing. 904*7c478bd9Sstevel@tonic-gate * 905*7c478bd9Sstevel@tonic-gate * If the entry already exists, try to update the 906*7c478bd9Sstevel@tonic-gate * entry object. In this case, we again only need 907*7c478bd9Sstevel@tonic-gate * to look in LDAP for the object; if there already 908*7c478bd9Sstevel@tonic-gate * is one in the DB, it's in the dir entry which we 909*7c478bd9Sstevel@tonic-gate * want to update. 910*7c478bd9Sstevel@tonic-gate * 911*7c478bd9Sstevel@tonic-gate * So, whether adding or replacing, try to get the 912*7c478bd9Sstevel@tonic-gate * object from LDAP. 913*7c478bd9Sstevel@tonic-gate * 914*7c478bd9Sstevel@tonic-gate * If we can't get a copy of the object, there's not 915*7c478bd9Sstevel@tonic-gate * much point in adding or updating (since a dir 916*7c478bd9Sstevel@tonic-gate * entry just consists of the entry object and name), 917*7c478bd9Sstevel@tonic-gate * so we continue to the next entry. 918*7c478bd9Sstevel@tonic-gate * 919*7c478bd9Sstevel@tonic-gate * However, in that case, we do need to touch the 920*7c478bd9Sstevel@tonic-gate * dir entry; otherwise, it will be removed later 921*7c478bd9Sstevel@tonic-gate * on. 922*7c478bd9Sstevel@tonic-gate */ 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate x = findDirEntryMapping(t, ea[i], &name); 925*7c478bd9Sstevel@tonic-gate o = 0; 926*7c478bd9Sstevel@tonic-gate if (x == 0 || (st = objFromLDAP(x, &o, 0, 0)) != 927*7c478bd9Sstevel@tonic-gate LDAP_SUCCESS) { 928*7c478bd9Sstevel@tonic-gate if (x != 0) 929*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 930*7c478bd9Sstevel@tonic-gate "%s: Unable to obtain object for \"%s\" in \"%s\": %s", 931*7c478bd9Sstevel@tonic-gate myself, NIL(name), NIL(t->objName), 932*7c478bd9Sstevel@tonic-gate ldap_err2string(st)); 933*7c478bd9Sstevel@tonic-gate if (o != 0) 934*7c478bd9Sstevel@tonic-gate nis_destroy_object(o); 935*7c478bd9Sstevel@tonic-gate if (!touchEntry(ea[i])) { 936*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 937*7c478bd9Sstevel@tonic-gate "%s: Inconsistency: LDAP-derived directory \"%s\" " 938*7c478bd9Sstevel@tonic-gate "contains entry \"%s\", which is unknown locally, " 939*7c478bd9Sstevel@tonic-gate "and has no LDAP mapping", 940*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName), 941*7c478bd9Sstevel@tonic-gate NIL(name)); 942*7c478bd9Sstevel@tonic-gate } 943*7c478bd9Sstevel@tonic-gate continue; 944*7c478bd9Sstevel@tonic-gate } 945*7c478bd9Sstevel@tonic-gate 946*7c478bd9Sstevel@tonic-gate if (ea[i]->en_cols.en_cols_len != 2 || 947*7c478bd9Sstevel@tonic-gate ea[i]->en_cols.en_cols_val == 0 || 948*7c478bd9Sstevel@tonic-gate ea[i]->en_cols.en_cols_val[0]. 949*7c478bd9Sstevel@tonic-gate ec_value.ec_value_val != 0 || 950*7c478bd9Sstevel@tonic-gate ea[i]->en_cols.en_cols_val[0]. 951*7c478bd9Sstevel@tonic-gate ec_value.ec_value_len != 0) { 952*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 953*7c478bd9Sstevel@tonic-gate "%s: Illegal entry_obj col 0 for \"%s\" in \"%s\"", 954*7c478bd9Sstevel@tonic-gate myself, NIL(name), NIL(t->objName)); 955*7c478bd9Sstevel@tonic-gate nis_destroy_object(o); 956*7c478bd9Sstevel@tonic-gate touchEntry(ea[i]); 957*7c478bd9Sstevel@tonic-gate continue; 958*7c478bd9Sstevel@tonic-gate } 959*7c478bd9Sstevel@tonic-gate 960*7c478bd9Sstevel@tonic-gate setOid(o); 961*7c478bd9Sstevel@tonic-gate e = makePseudoEntryObj(o, ea[i], 0); 962*7c478bd9Sstevel@tonic-gate if (e == 0) { 963*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 964*7c478bd9Sstevel@tonic-gate "%s: Unable to create pseudo entry object for \"%s\" in \"%s\"", 965*7c478bd9Sstevel@tonic-gate myself, NIL(name), NIL(t->objName)); 966*7c478bd9Sstevel@tonic-gate nis_destroy_object(o); 967*7c478bd9Sstevel@tonic-gate touchEntry(ea[i]); 968*7c478bd9Sstevel@tonic-gate continue; 969*7c478bd9Sstevel@tonic-gate } 970*7c478bd9Sstevel@tonic-gate 971*7c478bd9Sstevel@tonic-gate st = updateTableEntry(e, 1, t->objName, o, 0, 972*7c478bd9Sstevel@tonic-gate o->zo_oid.mtime, &xid); 973*7c478bd9Sstevel@tonic-gate if (st == LDAP_SUCCESS) { 974*7c478bd9Sstevel@tonic-gate na++; 975*7c478bd9Sstevel@tonic-gate } else if (st == LDAP_COMPARE_TRUE) { 976*7c478bd9Sstevel@tonic-gate /* OK, same as existing entry */ 977*7c478bd9Sstevel@tonic-gate st = LDAP_SUCCESS; 978*7c478bd9Sstevel@tonic-gate } else { 979*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 980*7c478bd9Sstevel@tonic-gate "%s: Error updating directory entry for \"%s\" in \"%s\": %s", 981*7c478bd9Sstevel@tonic-gate myself, NIL(name), NIL(t->objName), 982*7c478bd9Sstevel@tonic-gate ldap_err2string(st)); 983*7c478bd9Sstevel@tonic-gate if (stat == LDAP_SUCCESS) 984*7c478bd9Sstevel@tonic-gate stat = st; 985*7c478bd9Sstevel@tonic-gate } 986*7c478bd9Sstevel@tonic-gate 987*7c478bd9Sstevel@tonic-gate /* Free the XDR buffer */ 988*7c478bd9Sstevel@tonic-gate sfree(e->en_cols.en_cols_val[0]. 989*7c478bd9Sstevel@tonic-gate ec_value.ec_value_val); 990*7c478bd9Sstevel@tonic-gate /* Restore ea[i] */ 991*7c478bd9Sstevel@tonic-gate ea[i]->en_cols.en_cols_val[0]. 992*7c478bd9Sstevel@tonic-gate ec_value.ec_value_val = 0; 993*7c478bd9Sstevel@tonic-gate ea[i]->en_cols.en_cols_val[0]. 994*7c478bd9Sstevel@tonic-gate ec_value.ec_value_len = 0; 995*7c478bd9Sstevel@tonic-gate nis_destroy_object(o); 996*7c478bd9Sstevel@tonic-gate } 997*7c478bd9Sstevel@tonic-gate 998*7c478bd9Sstevel@tonic-gate freeEntryObjArray(ea, numEa); 999*7c478bd9Sstevel@tonic-gate 1000*7c478bd9Sstevel@tonic-gate /* Get list of entries to remove */ 1001*7c478bd9Sstevel@tonic-gate ea = table->endEnumMode(&numEa); 1002*7c478bd9Sstevel@tonic-gate if (ea != 0) { 1003*7c478bd9Sstevel@tonic-gate uint32_t nowt = time(0); 1004*7c478bd9Sstevel@tonic-gate 1005*7c478bd9Sstevel@tonic-gate for (i = 0; i < numEa; i++) { 1006*7c478bd9Sstevel@tonic-gate int st; 1007*7c478bd9Sstevel@tonic-gate 1008*7c478bd9Sstevel@tonic-gate if (ea[i] == 0) 1009*7c478bd9Sstevel@tonic-gate continue; 1010*7c478bd9Sstevel@tonic-gate 1011*7c478bd9Sstevel@tonic-gate st = updateTableEntry(ea[i], 0, t->objName, 0, 1012*7c478bd9Sstevel@tonic-gate 0, nowt, &xid); 1013*7c478bd9Sstevel@tonic-gate if (st == LDAP_SUCCESS) { 1014*7c478bd9Sstevel@tonic-gate na++; 1015*7c478bd9Sstevel@tonic-gate } else { 1016*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 1017*7c478bd9Sstevel@tonic-gate "%s: Error removing directory entry for \"%s\": %s", 1018*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName), 1019*7c478bd9Sstevel@tonic-gate ldap_err2string(st)); 1020*7c478bd9Sstevel@tonic-gate if (stat == LDAP_SUCCESS) 1021*7c478bd9Sstevel@tonic-gate stat = st; 1022*7c478bd9Sstevel@tonic-gate } 1023*7c478bd9Sstevel@tonic-gate } 1024*7c478bd9Sstevel@tonic-gate } 1025*7c478bd9Sstevel@tonic-gate 1026*7c478bd9Sstevel@tonic-gate if (stat == LDAP_SUCCESS) { 1027*7c478bd9Sstevel@tonic-gate struct timeval now; 1028*7c478bd9Sstevel@tonic-gate (void) gettimeofday(&now, 0); 1029*7c478bd9Sstevel@tonic-gate table->mapping.enumExpire = now.tv_sec + 1030*7c478bd9Sstevel@tonic-gate table->mapping.ttl; 1031*7c478bd9Sstevel@tonic-gate } 1032*7c478bd9Sstevel@tonic-gate 1033*7c478bd9Sstevel@tonic-gate if (na > 0) 1034*7c478bd9Sstevel@tonic-gate (void) ((db *)dbptr.ptr)->sync_log(); 1035*7c478bd9Sstevel@tonic-gate 1036*7c478bd9Sstevel@tonic-gate if (xid != 0 && na > 0 && stat == LDAP_SUCCESS) { 1037*7c478bd9Sstevel@tonic-gate ret = endTransaction(xid, dirObj); 1038*7c478bd9Sstevel@tonic-gate if (ret != 0) { 1039*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1040*7c478bd9Sstevel@tonic-gate "%s: Error ending transaction for \"%s\"", 1041*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName)); 1042*7c478bd9Sstevel@tonic-gate stat = LDAP_OPERATIONS_ERROR; 1043*7c478bd9Sstevel@tonic-gate } 1044*7c478bd9Sstevel@tonic-gate } else if (xid != 0) { 1045*7c478bd9Sstevel@tonic-gate ret = abort_transaction(xid); 1046*7c478bd9Sstevel@tonic-gate if (ret != 0) { 1047*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1048*7c478bd9Sstevel@tonic-gate "%s: Error aborting transaction for \"%s\"", 1049*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName)); 1050*7c478bd9Sstevel@tonic-gate } 1051*7c478bd9Sstevel@tonic-gate } 1052*7c478bd9Sstevel@tonic-gate nis_destroy_object(dirObj); 1053*7c478bd9Sstevel@tonic-gate 1054*7c478bd9Sstevel@tonic-gate sfree(ea); 1055*7c478bd9Sstevel@tonic-gate 1056*7c478bd9Sstevel@tonic-gate clearNoLDAPquery(); 1057*7c478bd9Sstevel@tonic-gate clearNoWriteThrough(); 1058*7c478bd9Sstevel@tonic-gate 1059*7c478bd9Sstevel@tonic-gate WRITEUNLOCK2(table, this, 1060*7c478bd9Sstevel@tonic-gate stat, stat, 1061*7c478bd9Sstevel@tonic-gate "table wu db_mindex::queryLDAP", 1062*7c478bd9Sstevel@tonic-gate "wu db_mindex::queryLDAP"); 1063*7c478bd9Sstevel@tonic-gate 1064*7c478bd9Sstevel@tonic-gate return (stat); 1065*7c478bd9Sstevel@tonic-gate } 1066*7c478bd9Sstevel@tonic-gate 1067*7c478bd9Sstevel@tonic-gate /* 1068*7c478bd9Sstevel@tonic-gate * In order to ping replicas, if any, we need to find the 1069*7c478bd9Sstevel@tonic-gate * directory containing the table to be updated. If we 1070*7c478bd9Sstevel@tonic-gate * can't find the directory object, we're sunk, so let's 1071*7c478bd9Sstevel@tonic-gate * start with that. 1072*7c478bd9Sstevel@tonic-gate */ 1073*7c478bd9Sstevel@tonic-gate if (t->isMaster) { 1074*7c478bd9Sstevel@tonic-gate dirObj = findObj(t->obj->zo_domain, &dstat, &stat); 1075*7c478bd9Sstevel@tonic-gate if (dirObj == 0) { 1076*7c478bd9Sstevel@tonic-gate if (stat == LDAP_SUCCESS) 1077*7c478bd9Sstevel@tonic-gate stat = LDAP_OPERATIONS_ERROR; 1078*7c478bd9Sstevel@tonic-gate return (stat); 1079*7c478bd9Sstevel@tonic-gate } 1080*7c478bd9Sstevel@tonic-gate } else { 1081*7c478bd9Sstevel@tonic-gate dirObj = 0; 1082*7c478bd9Sstevel@tonic-gate } 1083*7c478bd9Sstevel@tonic-gate 1084*7c478bd9Sstevel@tonic-gate stat = entriesFromLDAP(t, qin, q, dbId, dirObj, doAsynch); 1085*7c478bd9Sstevel@tonic-gate 1086*7c478bd9Sstevel@tonic-gate return (stat); 1087*7c478bd9Sstevel@tonic-gate } 1088*7c478bd9Sstevel@tonic-gate 1089*7c478bd9Sstevel@tonic-gate extern db *tableDB(char *); 1090*7c478bd9Sstevel@tonic-gate 1091*7c478bd9Sstevel@tonic-gate /* 1092*7c478bd9Sstevel@tonic-gate * Remove the LDAP entry/entries corresponding to 'qin'/'obj'. 1093*7c478bd9Sstevel@tonic-gate */ 1094*7c478bd9Sstevel@tonic-gate int 1095*7c478bd9Sstevel@tonic-gate db_mindex::removeLDAP(db_query *qin, nis_object *obj) { 1096*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t; 1097*7c478bd9Sstevel@tonic-gate db_query *q; 1098*7c478bd9Sstevel@tonic-gate bool_t asObj; 1099*7c478bd9Sstevel@tonic-gate int stat; 1100*7c478bd9Sstevel@tonic-gate 1101*7c478bd9Sstevel@tonic-gate if (!useLDAPrespository || table == 0) 1102*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 1103*7c478bd9Sstevel@tonic-gate 1104*7c478bd9Sstevel@tonic-gate /* Instances from the deferred dictionary should not update LDAP */ 1105*7c478bd9Sstevel@tonic-gate if (table->mapping.isDeferredTable) 1106*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 1107*7c478bd9Sstevel@tonic-gate 1108*7c478bd9Sstevel@tonic-gate t = selectMapping(table, 0, qin, TRUE, &asObj, &stat); 1109*7c478bd9Sstevel@tonic-gate if (t == 0 && stat != LDAP_SUCCESS) 1110*7c478bd9Sstevel@tonic-gate return (stat); 1111*7c478bd9Sstevel@tonic-gate 1112*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 1113*7c478bd9Sstevel@tonic-gate if (t != 0) 1114*7c478bd9Sstevel@tonic-gate printf("removeLDAP: %s\n", NIL(t->objName)); 1115*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 1116*7c478bd9Sstevel@tonic-gate 1117*7c478bd9Sstevel@tonic-gate if (qin != NULL) { 1118*7c478bd9Sstevel@tonic-gate if (asObj) { 1119*7c478bd9Sstevel@tonic-gate /* 1120*7c478bd9Sstevel@tonic-gate * selectMapping() gave us the mapping for the 1121*7c478bd9Sstevel@tonic-gate * directory entry. However, if 't' is NULL, this 1122*7c478bd9Sstevel@tonic-gate * could be due to the directory itself not being 1123*7c478bd9Sstevel@tonic-gate * mapped, in which case we must obtain the mapping 1124*7c478bd9Sstevel@tonic-gate * info from 'obj'. 1125*7c478bd9Sstevel@tonic-gate */ 1126*7c478bd9Sstevel@tonic-gate if (t == 0) { 1127*7c478bd9Sstevel@tonic-gate t = selectMapping(0, obj, 0, TRUE, &asObj, 1128*7c478bd9Sstevel@tonic-gate &stat); 1129*7c478bd9Sstevel@tonic-gate if (t == 0 && stat != LDAP_SUCCESS) 1130*7c478bd9Sstevel@tonic-gate return (stat); 1131*7c478bd9Sstevel@tonic-gate } 1132*7c478bd9Sstevel@tonic-gate 1133*7c478bd9Sstevel@tonic-gate if (t != 0) { 1134*7c478bd9Sstevel@tonic-gate stat = deleteLDAPobj(t); 1135*7c478bd9Sstevel@tonic-gate /* 1136*7c478bd9Sstevel@tonic-gate * If we were successful, update the object 1137*7c478bd9Sstevel@tonic-gate * stored with the mapping. 1138*7c478bd9Sstevel@tonic-gate */ 1139*7c478bd9Sstevel@tonic-gate if (stat == LDAP_SUCCESS) 1140*7c478bd9Sstevel@tonic-gate (void) replaceMappingObj(t, 0); 1141*7c478bd9Sstevel@tonic-gate else 1142*7c478bd9Sstevel@tonic-gate return (stat); 1143*7c478bd9Sstevel@tonic-gate } 1144*7c478bd9Sstevel@tonic-gate 1145*7c478bd9Sstevel@tonic-gate /* 1146*7c478bd9Sstevel@tonic-gate * Since it's a directory entry we've removed, we also 1147*7c478bd9Sstevel@tonic-gate * need to update the directory object itself. 1148*7c478bd9Sstevel@tonic-gate */ 1149*7c478bd9Sstevel@tonic-gate stat = storeLDAP(0, 0, 0, 0, 0); 1150*7c478bd9Sstevel@tonic-gate } else { 1151*7c478bd9Sstevel@tonic-gate q = schemeQuery2Query(qin, scheme); 1152*7c478bd9Sstevel@tonic-gate if (q == 0) 1153*7c478bd9Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 1154*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 1155*7c478bd9Sstevel@tonic-gate q->print(); 1156*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 1157*7c478bd9Sstevel@tonic-gate stat = mapToLDAP(t, 1, &q, 0, 0, 0, 0); 1158*7c478bd9Sstevel@tonic-gate freeQuery(q); 1159*7c478bd9Sstevel@tonic-gate } 1160*7c478bd9Sstevel@tonic-gate } else { 1161*7c478bd9Sstevel@tonic-gate /* 1162*7c478bd9Sstevel@tonic-gate * This isn't the way to remove the LDAP entries 1163*7c478bd9Sstevel@tonic-gate * corresponding to the entire table. 1164*7c478bd9Sstevel@tonic-gate */ 1165*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 1166*7c478bd9Sstevel@tonic-gate abort(); 1167*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 1168*7c478bd9Sstevel@tonic-gate stat = LDAP_PARAM_ERROR; 1169*7c478bd9Sstevel@tonic-gate } 1170*7c478bd9Sstevel@tonic-gate 1171*7c478bd9Sstevel@tonic-gate return (stat); 1172*7c478bd9Sstevel@tonic-gate } 1173*7c478bd9Sstevel@tonic-gate 1174*7c478bd9Sstevel@tonic-gate /* 1175*7c478bd9Sstevel@tonic-gate * Helper function for storeLDAP() which handles updates for objects 1176*7c478bd9Sstevel@tonic-gate * other than table entries. 1177*7c478bd9Sstevel@tonic-gate */ 1178*7c478bd9Sstevel@tonic-gate int 1179*7c478bd9Sstevel@tonic-gate db_mindex::storeObjLDAP(__nis_table_mapping_t *t, nis_object *o) { 1180*7c478bd9Sstevel@tonic-gate int stat, assigned = 0; 1181*7c478bd9Sstevel@tonic-gate entry_object **ea; 1182*7c478bd9Sstevel@tonic-gate int numEa, doUnlock = 0; 1183*7c478bd9Sstevel@tonic-gate db *dbase = 0; 1184*7c478bd9Sstevel@tonic-gate db_mindex *dbm = 0; 1185*7c478bd9Sstevel@tonic-gate char *myself = "db_mindex::storeObjLDAP"; 1186*7c478bd9Sstevel@tonic-gate 1187*7c478bd9Sstevel@tonic-gate if (t == 0 || o == 0) 1188*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 1189*7c478bd9Sstevel@tonic-gate 1190*7c478bd9Sstevel@tonic-gate /* 1191*7c478bd9Sstevel@tonic-gate * If the object to be stored is anything other than a 1192*7c478bd9Sstevel@tonic-gate * directory, we can just go ahead and write it to LDAP. 1193*7c478bd9Sstevel@tonic-gate * A directory object, however, also needs a directory 1194*7c478bd9Sstevel@tonic-gate * entry list, so we should to get hold of the db_table 1195*7c478bd9Sstevel@tonic-gate * that goes with the directory. 1196*7c478bd9Sstevel@tonic-gate */ 1197*7c478bd9Sstevel@tonic-gate if (o->zo_data.zo_type == NIS_DIRECTORY_OBJ) { 1198*7c478bd9Sstevel@tonic-gate dbase = tableDB(t->objName); 1199*7c478bd9Sstevel@tonic-gate if (dbase != 0) 1200*7c478bd9Sstevel@tonic-gate dbm = dbase->mindex(); 1201*7c478bd9Sstevel@tonic-gate if (dbase == 0 || dbm == 0 || dbm->table == 0) { 1202*7c478bd9Sstevel@tonic-gate /* By definition, no dir entries */ 1203*7c478bd9Sstevel@tonic-gate ea = 0; 1204*7c478bd9Sstevel@tonic-gate numEa = 0; 1205*7c478bd9Sstevel@tonic-gate dbase = 0; 1206*7c478bd9Sstevel@tonic-gate } else { 1207*7c478bd9Sstevel@tonic-gate entry_object **tea; 1208*7c478bd9Sstevel@tonic-gate long i, ntea; 1209*7c478bd9Sstevel@tonic-gate 1210*7c478bd9Sstevel@tonic-gate /* 1211*7c478bd9Sstevel@tonic-gate * Read-lock the table so that 'tab' 1212*7c478bd9Sstevel@tonic-gate * doesn't change while we're using it. 1213*7c478bd9Sstevel@tonic-gate */ 1214*7c478bd9Sstevel@tonic-gate READLOCK(dbm->table, LDAP_OPERATIONS_ERROR, 1215*7c478bd9Sstevel@tonic-gate "r table db_mindex::storeLDAP"); 1216*7c478bd9Sstevel@tonic-gate doUnlock = 1; 1217*7c478bd9Sstevel@tonic-gate 1218*7c478bd9Sstevel@tonic-gate tea = dbm->table->gettab(); 1219*7c478bd9Sstevel@tonic-gate ntea = dbm->table->getsize(); 1220*7c478bd9Sstevel@tonic-gate 1221*7c478bd9Sstevel@tonic-gate /* 1222*7c478bd9Sstevel@tonic-gate * There may be empty slots in the table 'tab' 1223*7c478bd9Sstevel@tonic-gate * array, so get rid of those. 1224*7c478bd9Sstevel@tonic-gate */ 1225*7c478bd9Sstevel@tonic-gate if (tea != 0 && ntea > 0) { 1226*7c478bd9Sstevel@tonic-gate ea = (entry_object **)am(myself, 1227*7c478bd9Sstevel@tonic-gate ntea * sizeof (ea[0])); 1228*7c478bd9Sstevel@tonic-gate if (ea == 0) { 1229*7c478bd9Sstevel@tonic-gate READUNLOCK(dbm->table, LDAP_NO_MEMORY, 1230*7c478bd9Sstevel@tonic-gate "ru table db_mindex::storeLDAP"); 1231*7c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 1232*7c478bd9Sstevel@tonic-gate } 1233*7c478bd9Sstevel@tonic-gate for (i = 0, numEa = 0; i < ntea; i++) { 1234*7c478bd9Sstevel@tonic-gate if (tea[i] != 0) { 1235*7c478bd9Sstevel@tonic-gate ea[numEa] = tea[i]; 1236*7c478bd9Sstevel@tonic-gate numEa++; 1237*7c478bd9Sstevel@tonic-gate } 1238*7c478bd9Sstevel@tonic-gate } 1239*7c478bd9Sstevel@tonic-gate if (numEa == 0) { 1240*7c478bd9Sstevel@tonic-gate /* No non-empty slots */ 1241*7c478bd9Sstevel@tonic-gate sfree(ea); 1242*7c478bd9Sstevel@tonic-gate ea = 0; 1243*7c478bd9Sstevel@tonic-gate READUNLOCK(dbm->table, 1244*7c478bd9Sstevel@tonic-gate LDAP_OPERATIONS_ERROR, 1245*7c478bd9Sstevel@tonic-gate "ru table db_mindex::storeLDAP"); 1246*7c478bd9Sstevel@tonic-gate doUnlock = 0; 1247*7c478bd9Sstevel@tonic-gate } 1248*7c478bd9Sstevel@tonic-gate } else { 1249*7c478bd9Sstevel@tonic-gate ea = 0; 1250*7c478bd9Sstevel@tonic-gate numEa = 0; 1251*7c478bd9Sstevel@tonic-gate READUNLOCK(dbm->table, 1252*7c478bd9Sstevel@tonic-gate LDAP_OPERATIONS_ERROR, 1253*7c478bd9Sstevel@tonic-gate "ru table db_mindex::storeLDAP"); 1254*7c478bd9Sstevel@tonic-gate doUnlock = 0; 1255*7c478bd9Sstevel@tonic-gate } 1256*7c478bd9Sstevel@tonic-gate } 1257*7c478bd9Sstevel@tonic-gate } else { 1258*7c478bd9Sstevel@tonic-gate ea = 0; 1259*7c478bd9Sstevel@tonic-gate numEa = 0; 1260*7c478bd9Sstevel@tonic-gate } 1261*7c478bd9Sstevel@tonic-gate 1262*7c478bd9Sstevel@tonic-gate stat = objToLDAP(t, o, ea, numEa); 1263*7c478bd9Sstevel@tonic-gate 1264*7c478bd9Sstevel@tonic-gate if (ea != 0) 1265*7c478bd9Sstevel@tonic-gate sfree(ea); 1266*7c478bd9Sstevel@tonic-gate if (doUnlock) { 1267*7c478bd9Sstevel@tonic-gate READUNLOCK(dbm->table, stat, 1268*7c478bd9Sstevel@tonic-gate "ru table db_mindex::storeLDAP"); 1269*7c478bd9Sstevel@tonic-gate } 1270*7c478bd9Sstevel@tonic-gate 1271*7c478bd9Sstevel@tonic-gate return (stat); 1272*7c478bd9Sstevel@tonic-gate } 1273*7c478bd9Sstevel@tonic-gate 1274*7c478bd9Sstevel@tonic-gate 1275*7c478bd9Sstevel@tonic-gate /* 1276*7c478bd9Sstevel@tonic-gate * Store data specified by the index-query 'qin' to LDAP. If 'obj' is 1277*7c478bd9Sstevel@tonic-gate * non-null, it's a pointer to the pseudo-entry object corresponding to 1278*7c478bd9Sstevel@tonic-gate * 'qin'. As a short-cut/convenience, the caller can instead supply 1279*7c478bd9Sstevel@tonic-gate * the actual nis_object 'o'; if 'o' is NULL, it's derived from 'obj'. 1280*7c478bd9Sstevel@tonic-gate * 1281*7c478bd9Sstevel@tonic-gate * 'oldObj' is used for table entries if the store operation is 1282*7c478bd9Sstevel@tonic-gate * an update, and the corresponding NIS+ operation was a delete followed 1283*7c478bd9Sstevel@tonic-gate * by an add. In this case, oldObj contains the pre-delete incarnation of 1284*7c478bd9Sstevel@tonic-gate * the entry object to be modified. 1285*7c478bd9Sstevel@tonic-gate * 1286*7c478bd9Sstevel@tonic-gate * The 'dbId' string is used to select one dbId for mapping chains 1287*7c478bd9Sstevel@tonic-gate * that contain more than one. 1288*7c478bd9Sstevel@tonic-gate * 1289*7c478bd9Sstevel@tonic-gate * Returns an LDAP status code. 1290*7c478bd9Sstevel@tonic-gate */ 1291*7c478bd9Sstevel@tonic-gate int 1292*7c478bd9Sstevel@tonic-gate db_mindex::storeLDAP(db_query *qin, entry_object *obj, nis_object *o, 1293*7c478bd9Sstevel@tonic-gate entry_obj *oldObj, char *dbId) { 1294*7c478bd9Sstevel@tonic-gate __nis_table_mapping_t *t; 1295*7c478bd9Sstevel@tonic-gate bool_t asObj; 1296*7c478bd9Sstevel@tonic-gate db_query *q, *qo, **qa; 1297*7c478bd9Sstevel@tonic-gate __nis_rule_value_t *rv = 0; 1298*7c478bd9Sstevel@tonic-gate int stat; 1299*7c478bd9Sstevel@tonic-gate char *myself = "db_mindex::storeLDAP"; 1300*7c478bd9Sstevel@tonic-gate 1301*7c478bd9Sstevel@tonic-gate if (!useLDAPrespository || table == 0) 1302*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 1303*7c478bd9Sstevel@tonic-gate 1304*7c478bd9Sstevel@tonic-gate /* Instances from the deferred dictionary should not update LDAP */ 1305*7c478bd9Sstevel@tonic-gate if (table->mapping.isDeferredTable) 1306*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 1307*7c478bd9Sstevel@tonic-gate 1308*7c478bd9Sstevel@tonic-gate t = selectMapping(table, 0, qin, TRUE, &asObj, &stat); 1309*7c478bd9Sstevel@tonic-gate if (t == 0 && stat != LDAP_SUCCESS) 1310*7c478bd9Sstevel@tonic-gate return (stat); 1311*7c478bd9Sstevel@tonic-gate 1312*7c478bd9Sstevel@tonic-gate #ifdef NISDB_LDAP_DEBUG 1313*7c478bd9Sstevel@tonic-gate if (t != 0) 1314*7c478bd9Sstevel@tonic-gate printf("storeLDAP: %s%s%s\n", 1315*7c478bd9Sstevel@tonic-gate dbId ? dbId : "", dbId ? ":" : "", NIL(t->objName)); 1316*7c478bd9Sstevel@tonic-gate #endif /* NISDB_LDAP_DEBUG */ 1317*7c478bd9Sstevel@tonic-gate 1318*7c478bd9Sstevel@tonic-gate /* 1319*7c478bd9Sstevel@tonic-gate * selectMapping() didn't have the object to look at, so we 1320*7c478bd9Sstevel@tonic-gate * must check if this is a directory entry or not. 1321*7c478bd9Sstevel@tonic-gate */ 1322*7c478bd9Sstevel@tonic-gate if (asObj) { 1323*7c478bd9Sstevel@tonic-gate if (o != 0) { 1324*7c478bd9Sstevel@tonic-gate if (o->zo_data.zo_type == NIS_ENTRY_OBJ) 1325*7c478bd9Sstevel@tonic-gate asObj = FALSE; 1326*7c478bd9Sstevel@tonic-gate } else if (obj != 0) { 1327*7c478bd9Sstevel@tonic-gate if (obj->en_type == 0 || 1328*7c478bd9Sstevel@tonic-gate strcmp(obj->en_type, "IN_DIRECTORY") != 0) 1329*7c478bd9Sstevel@tonic-gate asObj = FALSE; 1330*7c478bd9Sstevel@tonic-gate } 1331*7c478bd9Sstevel@tonic-gate } 1332*7c478bd9Sstevel@tonic-gate 1333*7c478bd9Sstevel@tonic-gate if (asObj) { 1334*7c478bd9Sstevel@tonic-gate bool_t freeO = FALSE; 1335*7c478bd9Sstevel@tonic-gate 1336*7c478bd9Sstevel@tonic-gate /* 1337*7c478bd9Sstevel@tonic-gate * If we don't have a mapping, that's probably because 1338*7c478bd9Sstevel@tonic-gate * the directory (represented by 'this') isn't mapped. 1339*7c478bd9Sstevel@tonic-gate * Try to get a mapping from 'o' or 'obj'. 1340*7c478bd9Sstevel@tonic-gate */ 1341*7c478bd9Sstevel@tonic-gate if (t == 0) { 1342*7c478bd9Sstevel@tonic-gate if (o == 0 && obj != 0) { 1343*7c478bd9Sstevel@tonic-gate o = unmakePseudoEntryObj(obj, 0); 1344*7c478bd9Sstevel@tonic-gate if (o == 0) 1345*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 1346*7c478bd9Sstevel@tonic-gate freeO = TRUE; 1347*7c478bd9Sstevel@tonic-gate } 1348*7c478bd9Sstevel@tonic-gate if (o != 0) { 1349*7c478bd9Sstevel@tonic-gate t = selectMapping(0, o, 0, TRUE, &asObj, &stat); 1350*7c478bd9Sstevel@tonic-gate if (t == 0) { 1351*7c478bd9Sstevel@tonic-gate if (freeO) 1352*7c478bd9Sstevel@tonic-gate nis_destroy_object(o); 1353*7c478bd9Sstevel@tonic-gate return (stat); 1354*7c478bd9Sstevel@tonic-gate } 1355*7c478bd9Sstevel@tonic-gate } 1356*7c478bd9Sstevel@tonic-gate } 1357*7c478bd9Sstevel@tonic-gate 1358*7c478bd9Sstevel@tonic-gate /* 1359*7c478bd9Sstevel@tonic-gate * If we found a mapping for the 'table' in this db_mindex, 1360*7c478bd9Sstevel@tonic-gate * store the object. 1361*7c478bd9Sstevel@tonic-gate */ 1362*7c478bd9Sstevel@tonic-gate if (t != 0) { 1363*7c478bd9Sstevel@tonic-gate if (o == 0) { 1364*7c478bd9Sstevel@tonic-gate if (obj != 0) { 1365*7c478bd9Sstevel@tonic-gate o = unmakePseudoEntryObj(obj, 0); 1366*7c478bd9Sstevel@tonic-gate freeO = TRUE; 1367*7c478bd9Sstevel@tonic-gate } else { 1368*7c478bd9Sstevel@tonic-gate db_status dstat; 1369*7c478bd9Sstevel@tonic-gate 1370*7c478bd9Sstevel@tonic-gate o = dbFindObject(t->objName, &dstat); 1371*7c478bd9Sstevel@tonic-gate if (o == 0) 1372*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1373*7c478bd9Sstevel@tonic-gate "%s: DB error %d finding \"%s\"", 1374*7c478bd9Sstevel@tonic-gate myself, 1375*7c478bd9Sstevel@tonic-gate NIL(t->objName)); 1376*7c478bd9Sstevel@tonic-gate freeO = TRUE; 1377*7c478bd9Sstevel@tonic-gate } 1378*7c478bd9Sstevel@tonic-gate } 1379*7c478bd9Sstevel@tonic-gate if (o == 0) 1380*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 1381*7c478bd9Sstevel@tonic-gate 1382*7c478bd9Sstevel@tonic-gate stat = storeObjLDAP(t, o); 1383*7c478bd9Sstevel@tonic-gate 1384*7c478bd9Sstevel@tonic-gate /* 1385*7c478bd9Sstevel@tonic-gate * Store the object with the mapping. If 'o' was 1386*7c478bd9Sstevel@tonic-gate * supplied by the caller, we first need to make 1387*7c478bd9Sstevel@tonic-gate * a copy. 1388*7c478bd9Sstevel@tonic-gate */ 1389*7c478bd9Sstevel@tonic-gate if (!freeO) { 1390*7c478bd9Sstevel@tonic-gate o = nis_clone_object(o, 0); 1391*7c478bd9Sstevel@tonic-gate if (o == 0) 1392*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 1393*7c478bd9Sstevel@tonic-gate "%s: Unable to refresh mapping object for \"%s\"", 1394*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName)); 1395*7c478bd9Sstevel@tonic-gate } 1396*7c478bd9Sstevel@tonic-gate if (o != 0) { 1397*7c478bd9Sstevel@tonic-gate if (!replaceMappingObj(t, o)) 1398*7c478bd9Sstevel@tonic-gate nis_destroy_object(o); 1399*7c478bd9Sstevel@tonic-gate } 1400*7c478bd9Sstevel@tonic-gate 1401*7c478bd9Sstevel@tonic-gate /* 1402*7c478bd9Sstevel@tonic-gate * Object now either destroyed or stored in 't'. 1403*7c478bd9Sstevel@tonic-gate * Set pointer to NULL in order to avoid freeing 1404*7c478bd9Sstevel@tonic-gate * it below. 1405*7c478bd9Sstevel@tonic-gate */ 1406*7c478bd9Sstevel@tonic-gate o = 0; 1407*7c478bd9Sstevel@tonic-gate 1408*7c478bd9Sstevel@tonic-gate if (stat != LDAP_SUCCESS) 1409*7c478bd9Sstevel@tonic-gate return (stat); 1410*7c478bd9Sstevel@tonic-gate } 1411*7c478bd9Sstevel@tonic-gate 1412*7c478bd9Sstevel@tonic-gate if (freeO && o != 0) { 1413*7c478bd9Sstevel@tonic-gate nis_destroy_object(o); 1414*7c478bd9Sstevel@tonic-gate o = 0; 1415*7c478bd9Sstevel@tonic-gate } 1416*7c478bd9Sstevel@tonic-gate 1417*7c478bd9Sstevel@tonic-gate /* 1418*7c478bd9Sstevel@tonic-gate * If the entry object 'obj' has the type "IN_DIRECTORY", 1419*7c478bd9Sstevel@tonic-gate * then it's a directory entry, and we should check if 1420*7c478bd9Sstevel@tonic-gate * the directory is mapped to LDAP, and update the dir 1421*7c478bd9Sstevel@tonic-gate * entry list accordingly. 1422*7c478bd9Sstevel@tonic-gate */ 1423*7c478bd9Sstevel@tonic-gate if (obj == 0 || obj->en_type == 0 || 1424*7c478bd9Sstevel@tonic-gate strcmp(obj->en_type, "IN_DIRECTORY") != 0) 1425*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 1426*7c478bd9Sstevel@tonic-gate 1427*7c478bd9Sstevel@tonic-gate /* Does it have a mapping ? */ 1428*7c478bd9Sstevel@tonic-gate t = selectMapping(table, 0, 0, TRUE, &asObj, &stat); 1429*7c478bd9Sstevel@tonic-gate if (t == 0) 1430*7c478bd9Sstevel@tonic-gate return (stat); 1431*7c478bd9Sstevel@tonic-gate 1432*7c478bd9Sstevel@tonic-gate stat = storeObjLDAP(t, t->obj); 1433*7c478bd9Sstevel@tonic-gate 1434*7c478bd9Sstevel@tonic-gate return (stat); 1435*7c478bd9Sstevel@tonic-gate } 1436*7c478bd9Sstevel@tonic-gate 1437*7c478bd9Sstevel@tonic-gate /* Store table entries. If we don't have a mapping, we're done. */ 1438*7c478bd9Sstevel@tonic-gate if (t == 0) 1439*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 1440*7c478bd9Sstevel@tonic-gate 1441*7c478bd9Sstevel@tonic-gate if (qin != NULL && obj != NULL) { 1442*7c478bd9Sstevel@tonic-gate db_index_entry *dbie; 1443*7c478bd9Sstevel@tonic-gate int i, size, nq = 0; 1444*7c478bd9Sstevel@tonic-gate long l, count; 1445*7c478bd9Sstevel@tonic-gate bool_t valid; 1446*7c478bd9Sstevel@tonic-gate db_query qbuf, **qold; 1447*7c478bd9Sstevel@tonic-gate 1448*7c478bd9Sstevel@tonic-gate rv = (__nis_rule_value_t *)am(myself, sizeof (*rv)); 1449*7c478bd9Sstevel@tonic-gate qa = (db_query **)am(myself, sizeof (qa[0])); 1450*7c478bd9Sstevel@tonic-gate if (oldObj != 0) { 1451*7c478bd9Sstevel@tonic-gate /* 1452*7c478bd9Sstevel@tonic-gate * Note that only qold[0] is a unique query pointer. 1453*7c478bd9Sstevel@tonic-gate * All the other qold[i]'s are copies of qa[i]. 1454*7c478bd9Sstevel@tonic-gate * Hence, we only free qold[0], as well as qold 1455*7c478bd9Sstevel@tonic-gate * itself. 1456*7c478bd9Sstevel@tonic-gate */ 1457*7c478bd9Sstevel@tonic-gate qold = (db_query **)am(myself, sizeof (qold[0])); 1458*7c478bd9Sstevel@tonic-gate } else { 1459*7c478bd9Sstevel@tonic-gate qold = 0; 1460*7c478bd9Sstevel@tonic-gate } 1461*7c478bd9Sstevel@tonic-gate if (rv == 0 || qa == 0 || (oldObj != 0 && qold == 0)) { 1462*7c478bd9Sstevel@tonic-gate sfree(rv); 1463*7c478bd9Sstevel@tonic-gate sfree(qa); 1464*7c478bd9Sstevel@tonic-gate sfree(qold); 1465*7c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 1466*7c478bd9Sstevel@tonic-gate } 1467*7c478bd9Sstevel@tonic-gate 1468*7c478bd9Sstevel@tonic-gate q = schemeQuery2Query(qin, scheme); 1469*7c478bd9Sstevel@tonic-gate if (q == 0) { 1470*7c478bd9Sstevel@tonic-gate sfree(rv); 1471*7c478bd9Sstevel@tonic-gate sfree(qa); 1472*7c478bd9Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 1473*7c478bd9Sstevel@tonic-gate } 1474*7c478bd9Sstevel@tonic-gate 1475*7c478bd9Sstevel@tonic-gate qa[0] = pseudoEntryObj2Query(obj, t->obj, &rv[0]); 1476*7c478bd9Sstevel@tonic-gate if (qa[0] == 0) { 1477*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1478*7c478bd9Sstevel@tonic-gate "%s: Unable to obtain query representation of new entry object for \"%s\"", 1479*7c478bd9Sstevel@tonic-gate myself, NIL(t->dbId)); 1480*7c478bd9Sstevel@tonic-gate freeQuery(q); 1481*7c478bd9Sstevel@tonic-gate sfree(rv); 1482*7c478bd9Sstevel@tonic-gate sfree(qa); 1483*7c478bd9Sstevel@tonic-gate sfree(qold); 1484*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 1485*7c478bd9Sstevel@tonic-gate } 1486*7c478bd9Sstevel@tonic-gate if (oldObj != 0) { 1487*7c478bd9Sstevel@tonic-gate qold[0] = pseudoEntryObj2Query(oldObj, t->obj, 0); 1488*7c478bd9Sstevel@tonic-gate if (qold[0] == 0) { 1489*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 1490*7c478bd9Sstevel@tonic-gate "%s: Unable to obtain query representation of old entry object for \"%s\"", 1491*7c478bd9Sstevel@tonic-gate myself, NIL(t->dbId)); 1492*7c478bd9Sstevel@tonic-gate freeQueries(qa, 1); 1493*7c478bd9Sstevel@tonic-gate freeQuery(q); 1494*7c478bd9Sstevel@tonic-gate sfree(rv); 1495*7c478bd9Sstevel@tonic-gate sfree(qa); 1496*7c478bd9Sstevel@tonic-gate sfree(qold); 1497*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 1498*7c478bd9Sstevel@tonic-gate } 1499*7c478bd9Sstevel@tonic-gate } 1500*7c478bd9Sstevel@tonic-gate 1501*7c478bd9Sstevel@tonic-gate nq++; 1502*7c478bd9Sstevel@tonic-gate 1503*7c478bd9Sstevel@tonic-gate /* 1504*7c478bd9Sstevel@tonic-gate * In order to support many-to-one NIS+ to LDAP mapping, 1505*7c478bd9Sstevel@tonic-gate * we need to find all possible matches in the NIS+ DB, 1506*7c478bd9Sstevel@tonic-gate * and then merge to produce a single update. mapToLDAP() 1507*7c478bd9Sstevel@tonic-gate * takes care of the merging, so our job is to collect 1508*7c478bd9Sstevel@tonic-gate * the matches. Worst case is that we need to search 1509*7c478bd9Sstevel@tonic-gate * individually for each component in 'qin', so that's 1510*7c478bd9Sstevel@tonic-gate * what we'll do. 1511*7c478bd9Sstevel@tonic-gate * 1512*7c478bd9Sstevel@tonic-gate * mapToLDAP() has a mode that only performs an update 1513*7c478bd9Sstevel@tonic-gate * for the first DN, and that's what we want. In order 1514*7c478bd9Sstevel@tonic-gate * to make sure that it's the correct DN, we leave the 1515*7c478bd9Sstevel@tonic-gate * original query as the first one passed to mapToLDAP(). 1516*7c478bd9Sstevel@tonic-gate */ 1517*7c478bd9Sstevel@tonic-gate 1518*7c478bd9Sstevel@tonic-gate size = qin->size(); 1519*7c478bd9Sstevel@tonic-gate 1520*7c478bd9Sstevel@tonic-gate /* For each component of 'qin' */ 1521*7c478bd9Sstevel@tonic-gate for (i = 0; i < size; i++) { 1522*7c478bd9Sstevel@tonic-gate db_query *qc, **qat, **qoldt; 1523*7c478bd9Sstevel@tonic-gate long j; 1524*7c478bd9Sstevel@tonic-gate __nis_rule_value_t *rvt; 1525*7c478bd9Sstevel@tonic-gate 1526*7c478bd9Sstevel@tonic-gate qc = queryFromComponent(qin, i, &qbuf); 1527*7c478bd9Sstevel@tonic-gate if (qc == 0) 1528*7c478bd9Sstevel@tonic-gate continue; 1529*7c478bd9Sstevel@tonic-gate 1530*7c478bd9Sstevel@tonic-gate dbie = satisfy_query_dbonly(qc, &count, FALSE, &valid); 1531*7c478bd9Sstevel@tonic-gate if (dbie == 0 || !valid || count <= 0) 1532*7c478bd9Sstevel@tonic-gate continue; 1533*7c478bd9Sstevel@tonic-gate 1534*7c478bd9Sstevel@tonic-gate rvt = (__nis_rule_value_t *)realloc(rv, 1535*7c478bd9Sstevel@tonic-gate (nq+count) * sizeof (rv[0])); 1536*7c478bd9Sstevel@tonic-gate qat = (db_query **)realloc(qa, 1537*7c478bd9Sstevel@tonic-gate (nq+count) * sizeof (qa[0])); 1538*7c478bd9Sstevel@tonic-gate if (qold != 0) 1539*7c478bd9Sstevel@tonic-gate qoldt = (db_query **)realloc(qold, 1540*7c478bd9Sstevel@tonic-gate (nq+count) * sizeof (qold[0])); 1541*7c478bd9Sstevel@tonic-gate if (rvt == 0 || qat == 0 || (qold != 0 && qoldt == 0)) { 1542*7c478bd9Sstevel@tonic-gate if (qat == 0) 1543*7c478bd9Sstevel@tonic-gate freeQueries(qa, nq); 1544*7c478bd9Sstevel@tonic-gate else 1545*7c478bd9Sstevel@tonic-gate freeQueries(qat, nq); 1546*7c478bd9Sstevel@tonic-gate if (rvt == 0) 1547*7c478bd9Sstevel@tonic-gate freeRuleValue(rv, nq); 1548*7c478bd9Sstevel@tonic-gate else 1549*7c478bd9Sstevel@tonic-gate freeRuleValue(rvt, nq); 1550*7c478bd9Sstevel@tonic-gate if (qold != 0) { 1551*7c478bd9Sstevel@tonic-gate if (qoldt == 0) 1552*7c478bd9Sstevel@tonic-gate freeQueries(qold, 1); 1553*7c478bd9Sstevel@tonic-gate else 1554*7c478bd9Sstevel@tonic-gate freeQueries(qoldt, 1); 1555*7c478bd9Sstevel@tonic-gate } 1556*7c478bd9Sstevel@tonic-gate freeQuery(q); 1557*7c478bd9Sstevel@tonic-gate (void) memset(&qbuf, 0, sizeof (qbuf)); 1558*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOMEM, LOG_ERR, 1559*7c478bd9Sstevel@tonic-gate "%s: realloc(%d) failed", 1560*7c478bd9Sstevel@tonic-gate myself, (nq+count) * sizeof (void *)); 1561*7c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 1562*7c478bd9Sstevel@tonic-gate } 1563*7c478bd9Sstevel@tonic-gate 1564*7c478bd9Sstevel@tonic-gate rv = rvt; 1565*7c478bd9Sstevel@tonic-gate qa = qat; 1566*7c478bd9Sstevel@tonic-gate 1567*7c478bd9Sstevel@tonic-gate (void) memset(&rv[nq], 0, count * sizeof (rv[0])); 1568*7c478bd9Sstevel@tonic-gate (void) memset(&qa[nq], 0, count * sizeof (qa[0])); 1569*7c478bd9Sstevel@tonic-gate if (qold != 0) { 1570*7c478bd9Sstevel@tonic-gate qold = qoldt; 1571*7c478bd9Sstevel@tonic-gate (void) memset(&qold[nq], 0, 1572*7c478bd9Sstevel@tonic-gate count * sizeof (qold[0])); 1573*7c478bd9Sstevel@tonic-gate } 1574*7c478bd9Sstevel@tonic-gate 1575*7c478bd9Sstevel@tonic-gate for (j = 0; j < count; j++) { 1576*7c478bd9Sstevel@tonic-gate qa[nq] = pseudoEntryObj2Query( 1577*7c478bd9Sstevel@tonic-gate table->get_entry(dbie->getlocation()), 1578*7c478bd9Sstevel@tonic-gate t->obj, &rv[nq]); 1579*7c478bd9Sstevel@tonic-gate if (qa[nq] == 0) { 1580*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 1581*7c478bd9Sstevel@tonic-gate "%s: Could not create query from entry obj for \"%s\"", 1582*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName)); 1583*7c478bd9Sstevel@tonic-gate freeQueries(qa, nq); 1584*7c478bd9Sstevel@tonic-gate freeQueries(qold, 1); 1585*7c478bd9Sstevel@tonic-gate freeRuleValue(rv, nq); 1586*7c478bd9Sstevel@tonic-gate freeQuery(q); 1587*7c478bd9Sstevel@tonic-gate (void) memset(&qbuf, 0, sizeof (qbuf)); 1588*7c478bd9Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 1589*7c478bd9Sstevel@tonic-gate } 1590*7c478bd9Sstevel@tonic-gate if (qold != 0) 1591*7c478bd9Sstevel@tonic-gate qold[nq] = qa[nq]; 1592*7c478bd9Sstevel@tonic-gate nq++; 1593*7c478bd9Sstevel@tonic-gate dbie = dbie->getnextresult(); 1594*7c478bd9Sstevel@tonic-gate if (dbie == 0) 1595*7c478bd9Sstevel@tonic-gate break; 1596*7c478bd9Sstevel@tonic-gate } 1597*7c478bd9Sstevel@tonic-gate } 1598*7c478bd9Sstevel@tonic-gate 1599*7c478bd9Sstevel@tonic-gate stat = mapToLDAP(t, nq, (qold != 0 ? qold : qa), qa, rv, 1, 1600*7c478bd9Sstevel@tonic-gate dbId); 1601*7c478bd9Sstevel@tonic-gate 1602*7c478bd9Sstevel@tonic-gate freeQueries(qa, nq); 1603*7c478bd9Sstevel@tonic-gate freeRuleValue(rv, nq); 1604*7c478bd9Sstevel@tonic-gate freeQuery(q); 1605*7c478bd9Sstevel@tonic-gate freeQueries(qold, 1); 1606*7c478bd9Sstevel@tonic-gate (void) memset(&qbuf, 0, sizeof (qbuf)); 1607*7c478bd9Sstevel@tonic-gate 1608*7c478bd9Sstevel@tonic-gate } else if (qin == 0 && obj == 0 && t->objType == NIS_TABLE_OBJ) { 1609*7c478bd9Sstevel@tonic-gate long i, j, ntab; 1610*7c478bd9Sstevel@tonic-gate entry_object **tab; 1611*7c478bd9Sstevel@tonic-gate 1612*7c478bd9Sstevel@tonic-gate READLOCK(table, LDAP_OPERATIONS_ERROR, 1613*7c478bd9Sstevel@tonic-gate "r table db_mindex::storeLDAP"); 1614*7c478bd9Sstevel@tonic-gate 1615*7c478bd9Sstevel@tonic-gate tab = table->gettab(); 1616*7c478bd9Sstevel@tonic-gate ntab = table->getsize(); 1617*7c478bd9Sstevel@tonic-gate if (tab == 0 || ntab <= 0) { 1618*7c478bd9Sstevel@tonic-gate READUNLOCK(table, LDAP_OPERATIONS_ERROR, 1619*7c478bd9Sstevel@tonic-gate "ru table db_mindex::storeLDAP"); 1620*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 1621*7c478bd9Sstevel@tonic-gate } 1622*7c478bd9Sstevel@tonic-gate 1623*7c478bd9Sstevel@tonic-gate qa = (db_query **)am(myself, ntab * sizeof (qa[0])); 1624*7c478bd9Sstevel@tonic-gate rv = (__nis_rule_value_t *)am(myself, ntab * sizeof (rv[0])); 1625*7c478bd9Sstevel@tonic-gate if (qa == 0 || rv == 0) { 1626*7c478bd9Sstevel@tonic-gate sfree(qa); 1627*7c478bd9Sstevel@tonic-gate sfree(rv); 1628*7c478bd9Sstevel@tonic-gate READUNLOCK(table, LDAP_OPERATIONS_ERROR, 1629*7c478bd9Sstevel@tonic-gate "ru table db_mindex::storeLDAP"); 1630*7c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 1631*7c478bd9Sstevel@tonic-gate } 1632*7c478bd9Sstevel@tonic-gate 1633*7c478bd9Sstevel@tonic-gate for (i = 0; i < ntab; i++) { 1634*7c478bd9Sstevel@tonic-gate if (tab[i] == 0) 1635*7c478bd9Sstevel@tonic-gate continue; 1636*7c478bd9Sstevel@tonic-gate 1637*7c478bd9Sstevel@tonic-gate qa[i] = pseudoEntryObj2Query(tab[i], t->obj, &rv[i]); 1638*7c478bd9Sstevel@tonic-gate if (qa[i] == 0) { 1639*7c478bd9Sstevel@tonic-gate freeQueries(qa, i); 1640*7c478bd9Sstevel@tonic-gate freeRuleValue(rv, i); 1641*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 1642*7c478bd9Sstevel@tonic-gate "%s: Could not create query from entry for \"%s\"", 1643*7c478bd9Sstevel@tonic-gate myself, NIL(t->objName)); 1644*7c478bd9Sstevel@tonic-gate READUNLOCK(table, LDAP_OPERATIONS_ERROR, 1645*7c478bd9Sstevel@tonic-gate "ru table db_mindex::storeLDAP"); 1646*7c478bd9Sstevel@tonic-gate return (LDAP_OPERATIONS_ERROR); 1647*7c478bd9Sstevel@tonic-gate } 1648*7c478bd9Sstevel@tonic-gate } 1649*7c478bd9Sstevel@tonic-gate 1650*7c478bd9Sstevel@tonic-gate stat = mapToLDAP(t, ntab, qa, qa, rv, 0, dbId); 1651*7c478bd9Sstevel@tonic-gate 1652*7c478bd9Sstevel@tonic-gate freeQueries(qa, ntab); 1653*7c478bd9Sstevel@tonic-gate freeRuleValue(rv, ntab); 1654*7c478bd9Sstevel@tonic-gate 1655*7c478bd9Sstevel@tonic-gate if (stat == LDAP_SUCCESS) { 1656*7c478bd9Sstevel@tonic-gate struct timeval now; 1657*7c478bd9Sstevel@tonic-gate int lstat, lck = 1; 1658*7c478bd9Sstevel@tonic-gate /* 1659*7c478bd9Sstevel@tonic-gate * Since we've just successfully uploaded everthing 1660*7c478bd9Sstevel@tonic-gate * in this table, we now consider our local copy 1661*7c478bd9Sstevel@tonic-gate * up-to-date as well. 1662*7c478bd9Sstevel@tonic-gate */ 1663*7c478bd9Sstevel@tonic-gate 1664*7c478bd9Sstevel@tonic-gate (void) gettimeofday(&now, 0); 1665*7c478bd9Sstevel@tonic-gate WRITELOCKNR(table, lstat, 1666*7c478bd9Sstevel@tonic-gate "w table db_mindex::storeLDAP"); 1667*7c478bd9Sstevel@tonic-gate if (lstat == 0) { 1668*7c478bd9Sstevel@tonic-gate table->mapping.enumExpire = now.tv_sec + 1669*7c478bd9Sstevel@tonic-gate table->mapping.ttl; 1670*7c478bd9Sstevel@tonic-gate lck = 0; 1671*7c478bd9Sstevel@tonic-gate WRITEUNLOCKNR(table, lstat, 1672*7c478bd9Sstevel@tonic-gate "wu table db_mindex::storeLDAP"); 1673*7c478bd9Sstevel@tonic-gate } 1674*7c478bd9Sstevel@tonic-gate if (lstat != 0) { 1675*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 1676*7c478bd9Sstevel@tonic-gate "%s: %sock error %d for \"%s\"%s", 1677*7c478bd9Sstevel@tonic-gate myself, lck?"L":"Unl", lstat, 1678*7c478bd9Sstevel@tonic-gate NIL(t->objName), 1679*7c478bd9Sstevel@tonic-gate lck ? 1680*7c478bd9Sstevel@tonic-gate "; unable to update enumeration expiration": 1681*7c478bd9Sstevel@tonic-gate ""); 1682*7c478bd9Sstevel@tonic-gate } 1683*7c478bd9Sstevel@tonic-gate } 1684*7c478bd9Sstevel@tonic-gate 1685*7c478bd9Sstevel@tonic-gate READUNLOCK(table, stat, 1686*7c478bd9Sstevel@tonic-gate "ru table db_mindex::storeLDAP"); 1687*7c478bd9Sstevel@tonic-gate } 1688*7c478bd9Sstevel@tonic-gate 1689*7c478bd9Sstevel@tonic-gate return (stat); 1690*7c478bd9Sstevel@tonic-gate } 1691