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 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * DESCRIPTION: Contains the map update thread and related code. 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <unistd.h> 34*7c478bd9Sstevel@tonic-gate #include <syslog.h> 35*7c478bd9Sstevel@tonic-gate #include <ndbm.h> 36*7c478bd9Sstevel@tonic-gate #include <thread.h> 37*7c478bd9Sstevel@tonic-gate #include <unistd.h> 38*7c478bd9Sstevel@tonic-gate #include <strings.h> 39*7c478bd9Sstevel@tonic-gate #include "ypsym.h" 40*7c478bd9Sstevel@tonic-gate #include "ypdefs.h" 41*7c478bd9Sstevel@tonic-gate #include "shim.h" 42*7c478bd9Sstevel@tonic-gate #include "yptol.h" 43*7c478bd9Sstevel@tonic-gate #include "../ldap_util.h" 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate /* Enable standard YP code features defined in ypdefs.h */ 46*7c478bd9Sstevel@tonic-gate USE_YP_PREFIX 47*7c478bd9Sstevel@tonic-gate USE_YP_MASTER_NAME 48*7c478bd9Sstevel@tonic-gate USE_YP_LAST_MODIFIED 49*7c478bd9Sstevel@tonic-gate USE_YP_INPUT_FILE 50*7c478bd9Sstevel@tonic-gate USE_YP_OUTPUT_NAME 51*7c478bd9Sstevel@tonic-gate USE_YP_DOMAIN_NAME 52*7c478bd9Sstevel@tonic-gate USE_YP_SECURE 53*7c478bd9Sstevel@tonic-gate USE_YP_INTERDOMAIN 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* 56*7c478bd9Sstevel@tonic-gate * Decs 57*7c478bd9Sstevel@tonic-gate */ 58*7c478bd9Sstevel@tonic-gate suc_code update_from_dit(map_ctrl *, datum *); 59*7c478bd9Sstevel@tonic-gate void * update_thread(void *); 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate /* 62*7c478bd9Sstevel@tonic-gate * Globals 63*7c478bd9Sstevel@tonic-gate */ 64*7c478bd9Sstevel@tonic-gate extern pid_t parent_pid; 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate /* 67*7c478bd9Sstevel@tonic-gate * FUNCTION: update_entry_if_required() 68*7c478bd9Sstevel@tonic-gate * 69*7c478bd9Sstevel@tonic-gate * DESCRIPTION: Determines if an entry is to be updated and if it is does the 70*7c478bd9Sstevel@tonic-gate * update. 71*7c478bd9Sstevel@tonic-gate * 72*7c478bd9Sstevel@tonic-gate * GIVEN : Pointer to the open map ctrl 73*7c478bd9Sstevel@tonic-gate * Pointer to the entry key 74*7c478bd9Sstevel@tonic-gate * 75*7c478bd9Sstevel@tonic-gate * RETURNS : SUCCESS = Entry is in a state to be returned to the client 76*7c478bd9Sstevel@tonic-gate * i.e. either got updated, did not need to be updated or we are 77*7c478bd9Sstevel@tonic-gate * in a mode where it is acceptable to return out of date 78*7c478bd9Sstevel@tonic-gate * information. 79*7c478bd9Sstevel@tonic-gate * FAILURE = Entry need an update but it could not be done. 80*7c478bd9Sstevel@tonic-gate */ 81*7c478bd9Sstevel@tonic-gate suc_code 82*7c478bd9Sstevel@tonic-gate update_entry_if_required(map_ctrl *map, datum *key) 83*7c478bd9Sstevel@tonic-gate { 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate /* Only update individual entries if entire map is */ 86*7c478bd9Sstevel@tonic-gate /* not being updated */ 87*7c478bd9Sstevel@tonic-gate if (is_map_updating(map)) 88*7c478bd9Sstevel@tonic-gate return (SUCCESS); 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate /* 91*7c478bd9Sstevel@tonic-gate * If we are being asked for the order then need to check if 92*7c478bd9Sstevel@tonic-gate * the map is in need of an update. If it is then fake a 93*7c478bd9Sstevel@tonic-gate * recent order. The client will then read the map, using 94*7c478bd9Sstevel@tonic-gate * dbm_firstkey and this will do the update. 95*7c478bd9Sstevel@tonic-gate */ 96*7c478bd9Sstevel@tonic-gate if (0 == strncmp(key->dptr, yp_last_modified, yp_last_modified_sz)) { 97*7c478bd9Sstevel@tonic-gate if (has_map_expired(map)) 98*7c478bd9Sstevel@tonic-gate update_timestamp(map->entries); 99*7c478bd9Sstevel@tonic-gate return (SUCCESS); 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* Never update special keys. Have no TTLs */ 103*7c478bd9Sstevel@tonic-gate if (is_special_key(key)) 104*7c478bd9Sstevel@tonic-gate return (SUCCESS); 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate if (!has_entry_expired(map, key)) 107*7c478bd9Sstevel@tonic-gate /* Didn't need an update */ 108*7c478bd9Sstevel@tonic-gate return (SUCCESS); 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate /* Do the update */ 111*7c478bd9Sstevel@tonic-gate return (update_from_dit(map, key)); 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * FUNCTION: update_from_dit() 116*7c478bd9Sstevel@tonic-gate * 117*7c478bd9Sstevel@tonic-gate * DESCRIPTION: Called to update an entry from the DIT 118*7c478bd9Sstevel@tonic-gate * 119*7c478bd9Sstevel@tonic-gate * INPUTS: Map control structure for an open map 120*7c478bd9Sstevel@tonic-gate * Entry key 121*7c478bd9Sstevel@tonic-gate * 122*7c478bd9Sstevel@tonic-gate * OUTPUTS: SUCCESS = Update complete or we are in a mode where it is 123*7c478bd9Sstevel@tonic-gate * acceptable to return out of date information. 124*7c478bd9Sstevel@tonic-gate * FAILURE = Update failed 125*7c478bd9Sstevel@tonic-gate * 126*7c478bd9Sstevel@tonic-gate */ 127*7c478bd9Sstevel@tonic-gate suc_code 128*7c478bd9Sstevel@tonic-gate update_from_dit(map_ctrl *map, datum *key) 129*7c478bd9Sstevel@tonic-gate { 130*7c478bd9Sstevel@tonic-gate datum dat; 131*7c478bd9Sstevel@tonic-gate int ret; 132*7c478bd9Sstevel@tonic-gate suc_code res; 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate /* 135*7c478bd9Sstevel@tonic-gate * Netgroup maps are a special case we cannot update just one entry so 136*7c478bd9Sstevel@tonic-gate * update the entire map instead. 137*7c478bd9Sstevel@tonic-gate */ 138*7c478bd9Sstevel@tonic-gate if ((0 == strcmp(map->map_name, NETGROUP_BYHOST)) || 139*7c478bd9Sstevel@tonic-gate (0 == strcmp(map->map_name, NETGROUP_BYUSER))) { 140*7c478bd9Sstevel@tonic-gate return (update_map_if_required(map, FALSE)); 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate /* Read entry from the DIT */ 144*7c478bd9Sstevel@tonic-gate ret = read_from_dit(map->map_name, map->domain, key, &dat); 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate /* Check that we got something */ 147*7c478bd9Sstevel@tonic-gate if (NULL == dat.dptr) { 148*7c478bd9Sstevel@tonic-gate if (0 == ret) { 149*7c478bd9Sstevel@tonic-gate /* 150*7c478bd9Sstevel@tonic-gate * In a mode where it is acceptable to return out of 151*7c478bd9Sstevel@tonic-gate * date information. 152*7c478bd9Sstevel@tonic-gate */ 153*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_INFO, 154*7c478bd9Sstevel@tonic-gate "LDAP inaccessible returning old information"); 155*7c478bd9Sstevel@tonic-gate return (SUCCESS); 156*7c478bd9Sstevel@tonic-gate } else { 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * In a mode where it is not acceptable to return out 159*7c478bd9Sstevel@tonic-gate * of date information. 160*7c478bd9Sstevel@tonic-gate * 161*7c478bd9Sstevel@tonic-gate * If the error positviely indicates that there is no 162*7c478bd9Sstevel@tonic-gate * such entry delete it. For errors where object may 163*7c478bd9Sstevel@tonic-gate * still exist in the DIT leave it. 164*7c478bd9Sstevel@tonic-gate */ 165*7c478bd9Sstevel@tonic-gate if (MAP_NO_MATCHING_KEY == ret) { 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * Don't log errors. If the entry was not 168*7c478bd9Sstevel@tonic-gate * already present then no problem. The user 169*7c478bd9Sstevel@tonic-gate * just asked us for a non existant entry. 170*7c478bd9Sstevel@tonic-gate */ 171*7c478bd9Sstevel@tonic-gate dbm_delete(map->entries, *key); 172*7c478bd9Sstevel@tonic-gate dbm_delete(map->ttl, *key); 173*7c478bd9Sstevel@tonic-gate } 174*7c478bd9Sstevel@tonic-gate return (FAILURE); 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate /* Write it to DBM */ 179*7c478bd9Sstevel@tonic-gate res = dbm_store(map->entries, *key, dat, DBM_REPLACE); 180*7c478bd9Sstevel@tonic-gate sfree(dat.dptr); 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate if (SUCCESS != res) 183*7c478bd9Sstevel@tonic-gate return (FAILURE); 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate /* Update TTL */ 186*7c478bd9Sstevel@tonic-gate update_entry_ttl(map, key, TTL_RUNNING); 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate return (SUCCESS); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate /* 192*7c478bd9Sstevel@tonic-gate * FUNCTION: update_map_if_required() 193*7c478bd9Sstevel@tonic-gate * 194*7c478bd9Sstevel@tonic-gate * DESCRIPTION: Called to update an entire map if it is out of date. Map ctrl 195*7c478bd9Sstevel@tonic-gate * must be locked before this is called. This handles checking if 196*7c478bd9Sstevel@tonic-gate * the map is already being updated. It is important that this is 197*7c478bd9Sstevel@tonic-gate * done atomically with obtaining the maps update lock. 198*7c478bd9Sstevel@tonic-gate * 199*7c478bd9Sstevel@tonic-gate * INPUTS: Map control structure for an open map 200*7c478bd9Sstevel@tonic-gate * Flag indication if we should wait for completion 201*7c478bd9Sstevel@tonic-gate * 202*7c478bd9Sstevel@tonic-gate * OUTPUTS: SUCCESS = Map update initiated 203*7c478bd9Sstevel@tonic-gate * FAILURE = Map update not initiated 204*7c478bd9Sstevel@tonic-gate */ 205*7c478bd9Sstevel@tonic-gate suc_code 206*7c478bd9Sstevel@tonic-gate update_map_if_required(map_ctrl *map, bool_t wait) 207*7c478bd9Sstevel@tonic-gate { 208*7c478bd9Sstevel@tonic-gate thread_t tid; 209*7c478bd9Sstevel@tonic-gate map_ctrl *new_map; 210*7c478bd9Sstevel@tonic-gate suc_code res; 211*7c478bd9Sstevel@tonic-gate long flags; 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate if (wait) { 214*7c478bd9Sstevel@tonic-gate /* 215*7c478bd9Sstevel@tonic-gate * Actually get the lock 216*7c478bd9Sstevel@tonic-gate * 217*7c478bd9Sstevel@tonic-gate * May block so unlock map_ctrl while it is done 218*7c478bd9Sstevel@tonic-gate */ 219*7c478bd9Sstevel@tonic-gate unlock_map_ctrl(map); 220*7c478bd9Sstevel@tonic-gate res = lock_map_update(map); 221*7c478bd9Sstevel@tonic-gate lock_map_ctrl(map); 222*7c478bd9Sstevel@tonic-gate if (SUCCESS != res) { 223*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 224*7c478bd9Sstevel@tonic-gate "Could not lock map %s for update", 225*7c478bd9Sstevel@tonic-gate map->map_name); 226*7c478bd9Sstevel@tonic-gate return (FAILURE); 227*7c478bd9Sstevel@tonic-gate } 228*7c478bd9Sstevel@tonic-gate } else { 229*7c478bd9Sstevel@tonic-gate /* If not waiting try to get the lock */ 230*7c478bd9Sstevel@tonic-gate switch (try_lock_map_update(map)) { 231*7c478bd9Sstevel@tonic-gate case 0: 232*7c478bd9Sstevel@tonic-gate /* 233*7c478bd9Sstevel@tonic-gate * We got the lock. Continue to start an update. 234*7c478bd9Sstevel@tonic-gate */ 235*7c478bd9Sstevel@tonic-gate break; 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate case EBUSY: 238*7c478bd9Sstevel@tonic-gate /* 239*7c478bd9Sstevel@tonic-gate * Some one else got the lock. OK they are 240*7c478bd9Sstevel@tonic-gate * doing the update so we can just return. 241*7c478bd9Sstevel@tonic-gate */ 242*7c478bd9Sstevel@tonic-gate return (SUCCESS); 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate default: 245*7c478bd9Sstevel@tonic-gate /* 246*7c478bd9Sstevel@tonic-gate * Some serious problem with lock. 247*7c478bd9Sstevel@tonic-gate */ 248*7c478bd9Sstevel@tonic-gate return (FAILURE); 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate /* 253*7c478bd9Sstevel@tonic-gate * If we get here are holding the update lock. Make a final check that 254*7c478bd9Sstevel@tonic-gate * nobody beat us to the map update while we were getting it. 255*7c478bd9Sstevel@tonic-gate */ 256*7c478bd9Sstevel@tonic-gate if (!has_map_expired(map)) { 257*7c478bd9Sstevel@tonic-gate /* A big waste of time. Somebody else did the update */ 258*7c478bd9Sstevel@tonic-gate unlock_map_update(map); 259*7c478bd9Sstevel@tonic-gate return (SUCCESS); 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate /* 263*7c478bd9Sstevel@tonic-gate * We got the lock and nobody beat us to doing the update. Start our 264*7c478bd9Sstevel@tonic-gate * own update. 265*7c478bd9Sstevel@tonic-gate * 266*7c478bd9Sstevel@tonic-gate * Thread will free the update lock when update is complete. 267*7c478bd9Sstevel@tonic-gate */ 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate /* 271*7c478bd9Sstevel@tonic-gate * Make a copy of the map_ctrl structure so the update thread has an 272*7c478bd9Sstevel@tonic-gate * independent version to work with. Note: Must not be on stack. 273*7c478bd9Sstevel@tonic-gate * 274*7c478bd9Sstevel@tonic-gate * On exit the update thread must free this. 275*7c478bd9Sstevel@tonic-gate */ 276*7c478bd9Sstevel@tonic-gate new_map = dup_map_ctrl(map); 277*7c478bd9Sstevel@tonic-gate if (NULL == new_map) { 278*7c478bd9Sstevel@tonic-gate unlock_map_update(map); 279*7c478bd9Sstevel@tonic-gate return (FAILURE); 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate /* 283*7c478bd9Sstevel@tonic-gate * While thread is running unlock map so other processes can 284*7c478bd9Sstevel@tonic-gate * execute non update related accesses 285*7c478bd9Sstevel@tonic-gate */ 286*7c478bd9Sstevel@tonic-gate unlock_map_ctrl(map); 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate flags = THR_BOUND | THR_NEW_LWP; 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate /* 291*7c478bd9Sstevel@tonic-gate * If we are not going to thr_join then need to create detached. 292*7c478bd9Sstevel@tonic-gate * This prevents a zombie being left when nobody joins us. 293*7c478bd9Sstevel@tonic-gate */ 294*7c478bd9Sstevel@tonic-gate if (!wait && (getpid() == parent_pid)) 295*7c478bd9Sstevel@tonic-gate flags |= THR_DETACHED; 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate /* Kick off update thread */ 298*7c478bd9Sstevel@tonic-gate if (0 != thr_create(NULL, NULL, update_thread, new_map, 299*7c478bd9Sstevel@tonic-gate flags, &tid)) { 300*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 301*7c478bd9Sstevel@tonic-gate "Could not create NIS update thread"); 302*7c478bd9Sstevel@tonic-gate free_map_ctrl(new_map); 303*7c478bd9Sstevel@tonic-gate unlock_map_update(map); 304*7c478bd9Sstevel@tonic-gate if (SUCCESS != lock_map_ctrl(map)) 305*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 306*7c478bd9Sstevel@tonic-gate "Could not acquire update lock for %s", map->map_name); 307*7c478bd9Sstevel@tonic-gate return (FAILURE); 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate if (wait) { 311*7c478bd9Sstevel@tonic-gate /* May block but no problem map_ctrl is already unlocked. */ 312*7c478bd9Sstevel@tonic-gate thr_join(tid, NULL, NULL); 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate /* Re acquire lock */ 316*7c478bd9Sstevel@tonic-gate if (1 != lock_map_ctrl(map)) { 317*7c478bd9Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 318*7c478bd9Sstevel@tonic-gate "Could not re-acquire lock for %s", map->map_name); 319*7c478bd9Sstevel@tonic-gate return (FAILURE); 320*7c478bd9Sstevel@tonic-gate } 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate return (SUCCESS); 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate /* 326*7c478bd9Sstevel@tonic-gate * FUNCTION: update_thread() 327*7c478bd9Sstevel@tonic-gate * 328*7c478bd9Sstevel@tonic-gate * DESCRIPTION: The update thread this is called to update an entire NIS map. 329*7c478bd9Sstevel@tonic-gate * if several NIS maps are found to be out of date several 330*7c478bd9Sstevel@tonic-gate * instances of this may be running at the same time. 331*7c478bd9Sstevel@tonic-gate * 332*7c478bd9Sstevel@tonic-gate * Since we are using a duplicate map_ctrl we do not have to lock 333*7c478bd9Sstevel@tonic-gate * it. If we did would end up using the same mutex as the parent 334*7c478bd9Sstevel@tonic-gate * map ctrl an possibly deadlocking. 335*7c478bd9Sstevel@tonic-gate * 336*7c478bd9Sstevel@tonic-gate * INPUTS: Map handle (because we need access to name and lock) 337*7c478bd9Sstevel@tonic-gate * 338*7c478bd9Sstevel@tonic-gate * OUTPUTS: None exits when finished. 339*7c478bd9Sstevel@tonic-gate */ 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate void * 342*7c478bd9Sstevel@tonic-gate update_thread(void *arg) 343*7c478bd9Sstevel@tonic-gate { 344*7c478bd9Sstevel@tonic-gate void *ret = (void *)-1; 345*7c478bd9Sstevel@tonic-gate map_ctrl *map; 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate /* Cast argument pointer to correct type */ 348*7c478bd9Sstevel@tonic-gate map = (map_ctrl *)arg; 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate /* Actually do the work */ 351*7c478bd9Sstevel@tonic-gate if (SUCCESS == update_map_from_dit(map, FALSE)) 352*7c478bd9Sstevel@tonic-gate ret = 0; 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate /* Update complete or failed */ 355*7c478bd9Sstevel@tonic-gate unlock_map_update(map); 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate /* Free up duplicate copy of the map_ctrl */ 358*7c478bd9Sstevel@tonic-gate free_map_ctrl(map); 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate thr_exit(ret); 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate /* 364*7c478bd9Sstevel@tonic-gate * FUNCTION : is_special_key() 365*7c478bd9Sstevel@tonic-gate * 366*7c478bd9Sstevel@tonic-gate * DESCRIPTION: Works out if a given key is one of the special ones. We just 367*7c478bd9Sstevel@tonic-gate * check for the "YP_" prefix. This is not 100% safe but if 368*7c478bd9Sstevel@tonic-gate * valid keys with a "YP_" prefix exist in the DIT then a lot of 369*7c478bd9Sstevel@tonic-gate * other parts of NIS wont work. 370*7c478bd9Sstevel@tonic-gate */ 371*7c478bd9Sstevel@tonic-gate bool_t 372*7c478bd9Sstevel@tonic-gate is_special_key(datum *key) 373*7c478bd9Sstevel@tonic-gate { 374*7c478bd9Sstevel@tonic-gate if (0 == strncmp(key->dptr, yp_prefix, yp_prefix_sz)) 375*7c478bd9Sstevel@tonic-gate return (TRUE); 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate return (FALSE); 378*7c478bd9Sstevel@tonic-gate } 379