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 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <assert.h> 30*7c478bd9Sstevel@tonic-gate #include <errno.h> 31*7c478bd9Sstevel@tonic-gate #include <memory.h> 32*7c478bd9Sstevel@tonic-gate #include <signal.h> 33*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 34*7c478bd9Sstevel@tonic-gate #include <stdio.h> 35*7c478bd9Sstevel@tonic-gate #include <string.h> 36*7c478bd9Sstevel@tonic-gate #include <libintl.h> 37*7c478bd9Sstevel@tonic-gate #include <syslog.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/door.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/wait.h> 43*7c478bd9Sstevel@tonic-gate #include <synch.h> 44*7c478bd9Sstevel@tonic-gate #include <pthread.h> 45*7c478bd9Sstevel@tonic-gate #include <unistd.h> 46*7c478bd9Sstevel@tonic-gate #include <lber.h> 47*7c478bd9Sstevel@tonic-gate #include <ldap.h> 48*7c478bd9Sstevel@tonic-gate #include <ctype.h> /* tolower */ 49*7c478bd9Sstevel@tonic-gate #include "cachemgr.h" 50*7c478bd9Sstevel@tonic-gate #include "solaris-priv.h" 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate static rwlock_t ldap_lock = DEFAULTRWLOCK; 53*7c478bd9Sstevel@tonic-gate static int sighup_update = FALSE; 54*7c478bd9Sstevel@tonic-gate extern admin_t current_admin; 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* variables used for SIGHUP wakeup on sleep */ 57*7c478bd9Sstevel@tonic-gate static mutex_t sighuplock; 58*7c478bd9Sstevel@tonic-gate static cond_t cond; 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate /* refresh time statistics */ 61*7c478bd9Sstevel@tonic-gate static time_t prev_refresh_time = 0; 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate /* variables used for signaling parent process */ 64*7c478bd9Sstevel@tonic-gate static mutex_t sig_mutex; 65*7c478bd9Sstevel@tonic-gate static int signal_done = FALSE; 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* TCP connection timeout (in milliseconds) */ 68*7c478bd9Sstevel@tonic-gate static int tcptimeout = NS_DEFAULT_BIND_TIMEOUT * 1000; 69*7c478bd9Sstevel@tonic-gate /* search timeout (in seconds) */ 70*7c478bd9Sstevel@tonic-gate static int search_timeout = NS_DEFAULT_SEARCH_TIMEOUT; 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate #ifdef SLP 73*7c478bd9Sstevel@tonic-gate extern int use_slp; 74*7c478bd9Sstevel@tonic-gate #endif /* SLP */ 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate /* nis domain information */ 77*7c478bd9Sstevel@tonic-gate #define _NIS_FILTER "objectclass=nisDomainObject" 78*7c478bd9Sstevel@tonic-gate #define _NIS_DOMAIN "nisdomain" 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate #define CACHESLEEPTIME 600 81*7c478bd9Sstevel@tonic-gate /* 82*7c478bd9Sstevel@tonic-gate * server list refresh delay when in "no server" mode 83*7c478bd9Sstevel@tonic-gate * (1 second) 84*7c478bd9Sstevel@tonic-gate */ 85*7c478bd9Sstevel@tonic-gate #define REFRESH_DELAY_WHEN_NO_SERVER 1 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate typedef enum { 88*7c478bd9Sstevel@tonic-gate INFO_OP_CREATE = 0, 89*7c478bd9Sstevel@tonic-gate INFO_OP_DELETE = 1, 90*7c478bd9Sstevel@tonic-gate INFO_OP_REFRESH = 2, 91*7c478bd9Sstevel@tonic-gate INFO_OP_REFRESH_WAIT = 3, 92*7c478bd9Sstevel@tonic-gate INFO_OP_GETSERVER = 4, 93*7c478bd9Sstevel@tonic-gate INFO_OP_GETSTAT = 5 94*7c478bd9Sstevel@tonic-gate } info_op_t; 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate typedef enum { 97*7c478bd9Sstevel@tonic-gate INFO_RW_UNKNOWN = 0, 98*7c478bd9Sstevel@tonic-gate INFO_RW_READONLY = 1, 99*7c478bd9Sstevel@tonic-gate INFO_RW_WRITEABLE = 2 100*7c478bd9Sstevel@tonic-gate } info_rw_t; 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate typedef enum { 103*7c478bd9Sstevel@tonic-gate INFO_SERVER_JUST_INITED = -1, 104*7c478bd9Sstevel@tonic-gate INFO_SERVER_UNKNOWN = 0, 105*7c478bd9Sstevel@tonic-gate INFO_SERVER_CONNECTING = 1, 106*7c478bd9Sstevel@tonic-gate INFO_SERVER_UP = 2, 107*7c478bd9Sstevel@tonic-gate INFO_SERVER_ERROR = 3, 108*7c478bd9Sstevel@tonic-gate INFO_SERVER_REMOVED = 4 109*7c478bd9Sstevel@tonic-gate } info_server_t; 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate typedef enum { 112*7c478bd9Sstevel@tonic-gate INFO_STATUS_UNKNOWN = 0, 113*7c478bd9Sstevel@tonic-gate INFO_STATUS_ERROR = 1, 114*7c478bd9Sstevel@tonic-gate INFO_STATUS_NEW = 2, 115*7c478bd9Sstevel@tonic-gate INFO_STATUS_OLD = 3 116*7c478bd9Sstevel@tonic-gate } info_status_t; 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate typedef enum { 119*7c478bd9Sstevel@tonic-gate CACHE_OP_CREATE = 0, 120*7c478bd9Sstevel@tonic-gate CACHE_OP_DELETE = 1, 121*7c478bd9Sstevel@tonic-gate CACHE_OP_FIND = 2, 122*7c478bd9Sstevel@tonic-gate CACHE_OP_ADD = 3, 123*7c478bd9Sstevel@tonic-gate CACHE_OP_GETSTAT = 4 124*7c478bd9Sstevel@tonic-gate } cache_op_t; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate typedef enum { 127*7c478bd9Sstevel@tonic-gate CACHE_MAP_UNKNOWN = 0, 128*7c478bd9Sstevel@tonic-gate CACHE_MAP_DN2DOMAIN = 1 129*7c478bd9Sstevel@tonic-gate } cache_type_t; 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate typedef struct server_info_ext { 132*7c478bd9Sstevel@tonic-gate char *addr; 133*7c478bd9Sstevel@tonic-gate char *rootDSE_data; 134*7c478bd9Sstevel@tonic-gate char *errormsg; 135*7c478bd9Sstevel@tonic-gate info_rw_t type; 136*7c478bd9Sstevel@tonic-gate info_server_t server_status; 137*7c478bd9Sstevel@tonic-gate info_server_t prev_server_status; 138*7c478bd9Sstevel@tonic-gate info_status_t info_status; 139*7c478bd9Sstevel@tonic-gate } server_info_ext_t; 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate typedef struct server_info { 142*7c478bd9Sstevel@tonic-gate struct server_info *next; 143*7c478bd9Sstevel@tonic-gate mutex_t mutex[2]; /* 0: current copy lock */ 144*7c478bd9Sstevel@tonic-gate /* 1: update copy lock */ 145*7c478bd9Sstevel@tonic-gate server_info_ext_t sinfo[2]; /* 0: current, 1: update copy */ 146*7c478bd9Sstevel@tonic-gate } server_info_t; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate typedef struct cache_hash { 149*7c478bd9Sstevel@tonic-gate cache_type_t type; 150*7c478bd9Sstevel@tonic-gate char *from; 151*7c478bd9Sstevel@tonic-gate char *to; 152*7c478bd9Sstevel@tonic-gate struct cache_hash *next; 153*7c478bd9Sstevel@tonic-gate } cache_hash_t; 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate static int getldap_destroy_serverInfo(server_info_t *head); 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * Load configuration 159*7c478bd9Sstevel@tonic-gate * The code was in signal handler getldap_revalidate 160*7c478bd9Sstevel@tonic-gate * It's moved out of the handler because it could cause deadlock 161*7c478bd9Sstevel@tonic-gate * return: 1 SUCCESS 162*7c478bd9Sstevel@tonic-gate * 0 FAIL 163*7c478bd9Sstevel@tonic-gate */ 164*7c478bd9Sstevel@tonic-gate static int 165*7c478bd9Sstevel@tonic-gate load_config() { 166*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *error; 167*7c478bd9Sstevel@tonic-gate int rc = 1; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_setServer(TRUE); 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ldap_lock); 172*7c478bd9Sstevel@tonic-gate if ((error = __ns_ldap_LoadConfiguration()) != NULL) { 173*7c478bd9Sstevel@tonic-gate logit("Error: Unable to read '%s': %s\n", 174*7c478bd9Sstevel@tonic-gate NSCONFIGFILE, error->message); 175*7c478bd9Sstevel@tonic-gate __ns_ldap_freeError(&error); 176*7c478bd9Sstevel@tonic-gate rc = 0; /* FAIL */ 177*7c478bd9Sstevel@tonic-gate } else 178*7c478bd9Sstevel@tonic-gate sighup_update = TRUE; 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate return (rc); 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate /* 186*7c478bd9Sstevel@tonic-gate * Calculate a hash for a string 187*7c478bd9Sstevel@tonic-gate * Based on elf_hash algorithm, hash is case insensitive 188*7c478bd9Sstevel@tonic-gate * Uses tolower instead of _tolower because of I18N 189*7c478bd9Sstevel@tonic-gate */ 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate static unsigned long 192*7c478bd9Sstevel@tonic-gate getldap_hash(const char *str) 193*7c478bd9Sstevel@tonic-gate { 194*7c478bd9Sstevel@tonic-gate unsigned int hval = 0; 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate while (*str) { 197*7c478bd9Sstevel@tonic-gate unsigned int g; 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate hval = (hval << 4) + tolower(*str++); 200*7c478bd9Sstevel@tonic-gate if ((g = (hval & 0xf0000000)) != 0) 201*7c478bd9Sstevel@tonic-gate hval ^= g >> 24; 202*7c478bd9Sstevel@tonic-gate hval &= ~g; 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate return ((unsigned long)hval); 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate /* 208*7c478bd9Sstevel@tonic-gate * Remove a hash table entry. 209*7c478bd9Sstevel@tonic-gate * This function expects a lock in place when called. 210*7c478bd9Sstevel@tonic-gate */ 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate static cache_hash_t * 213*7c478bd9Sstevel@tonic-gate getldap_free_hash(cache_hash_t *p) 214*7c478bd9Sstevel@tonic-gate { 215*7c478bd9Sstevel@tonic-gate cache_hash_t *next; 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate p->type = CACHE_MAP_UNKNOWN; 218*7c478bd9Sstevel@tonic-gate if (p->from) 219*7c478bd9Sstevel@tonic-gate free(p->from); 220*7c478bd9Sstevel@tonic-gate if (p->to) 221*7c478bd9Sstevel@tonic-gate free(p->to); 222*7c478bd9Sstevel@tonic-gate next = p->next; 223*7c478bd9Sstevel@tonic-gate p->next = NULL; 224*7c478bd9Sstevel@tonic-gate free(p); 225*7c478bd9Sstevel@tonic-gate return (next); 226*7c478bd9Sstevel@tonic-gate } 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate /* 229*7c478bd9Sstevel@tonic-gate * Scan a hash table hit for a matching hash entry. 230*7c478bd9Sstevel@tonic-gate * This function expects a lock in place when called. 231*7c478bd9Sstevel@tonic-gate */ 232*7c478bd9Sstevel@tonic-gate static cache_hash_t * 233*7c478bd9Sstevel@tonic-gate getldap_scan_hash(cache_type_t type, char *from, 234*7c478bd9Sstevel@tonic-gate cache_hash_t *idx) 235*7c478bd9Sstevel@tonic-gate { 236*7c478bd9Sstevel@tonic-gate while (idx) { 237*7c478bd9Sstevel@tonic-gate if (idx->type == type && 238*7c478bd9Sstevel@tonic-gate strcasecmp(from, idx->from) == 0) { 239*7c478bd9Sstevel@tonic-gate return (idx); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate idx = idx->next; 242*7c478bd9Sstevel@tonic-gate } 243*7c478bd9Sstevel@tonic-gate return ((cache_hash_t *)NULL); 244*7c478bd9Sstevel@tonic-gate } 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate /* 247*7c478bd9Sstevel@tonic-gate * Format and return the cache data statistics 248*7c478bd9Sstevel@tonic-gate */ 249*7c478bd9Sstevel@tonic-gate static int 250*7c478bd9Sstevel@tonic-gate getldap_get_cacheData_stat(int max, int current, char **output) 251*7c478bd9Sstevel@tonic-gate { 252*7c478bd9Sstevel@tonic-gate #define C_HEADER0 "Cache data information: " 253*7c478bd9Sstevel@tonic-gate #define C_HEADER1 " Maximum cache entries: " 254*7c478bd9Sstevel@tonic-gate #define C_HEADER2 " Number of cache entries: " 255*7c478bd9Sstevel@tonic-gate int hdr0_len = strlen(gettext(C_HEADER0)); 256*7c478bd9Sstevel@tonic-gate int hdr1_len = strlen(gettext(C_HEADER1)); 257*7c478bd9Sstevel@tonic-gate int hdr2_len = strlen(gettext(C_HEADER2)); 258*7c478bd9Sstevel@tonic-gate int len; 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 261*7c478bd9Sstevel@tonic-gate logit("getldap_get_cacheData_stat()...\n"); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate *output = NULL; 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate len = hdr0_len + hdr1_len + hdr2_len + 267*7c478bd9Sstevel@tonic-gate 3 * strlen(DOORLINESEP) + 21; 268*7c478bd9Sstevel@tonic-gate *output = malloc(len); 269*7c478bd9Sstevel@tonic-gate if (*output == NULL) 270*7c478bd9Sstevel@tonic-gate return (-1); 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate (void) snprintf(*output, len, "%s%s%s%10d%s%s%10d%s", 273*7c478bd9Sstevel@tonic-gate gettext(C_HEADER0), DOORLINESEP, 274*7c478bd9Sstevel@tonic-gate gettext(C_HEADER1), max, DOORLINESEP, 275*7c478bd9Sstevel@tonic-gate gettext(C_HEADER2), current, DOORLINESEP); 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate static int 281*7c478bd9Sstevel@tonic-gate getldap_cache_op(cache_op_t op, cache_type_t type, 282*7c478bd9Sstevel@tonic-gate char *from, char **to) 283*7c478bd9Sstevel@tonic-gate { 284*7c478bd9Sstevel@tonic-gate #define CACHE_HASH_MAX 257 285*7c478bd9Sstevel@tonic-gate #define CACHE_HASH_MAX_ENTRY 256 286*7c478bd9Sstevel@tonic-gate static cache_hash_t *hashTbl[CACHE_HASH_MAX]; 287*7c478bd9Sstevel@tonic-gate cache_hash_t *next, *idx, *newp; 288*7c478bd9Sstevel@tonic-gate unsigned long hash; 289*7c478bd9Sstevel@tonic-gate static rwlock_t cache_lock = DEFAULTRWLOCK; 290*7c478bd9Sstevel@tonic-gate int i; 291*7c478bd9Sstevel@tonic-gate static entry_num = 0; 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 294*7c478bd9Sstevel@tonic-gate logit("getldap_cache_op()...\n"); 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate switch (op) { 297*7c478bd9Sstevel@tonic-gate case CACHE_OP_CREATE: 298*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 299*7c478bd9Sstevel@tonic-gate logit("operation is CACHE_OP_CREATE...\n"); 300*7c478bd9Sstevel@tonic-gate } 301*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&cache_lock); 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate for (i = 0; i < CACHE_HASH_MAX; i++) { 304*7c478bd9Sstevel@tonic-gate hashTbl[i] = NULL; 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate entry_num = 0; 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&cache_lock); 309*7c478bd9Sstevel@tonic-gate break; 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate case CACHE_OP_DELETE: 312*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 313*7c478bd9Sstevel@tonic-gate logit("operation is CACHE_OP_DELETE...\n"); 314*7c478bd9Sstevel@tonic-gate } 315*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&cache_lock); 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate for (i = 0; i < CACHE_HASH_MAX; i++) { 318*7c478bd9Sstevel@tonic-gate next = hashTbl[i]; 319*7c478bd9Sstevel@tonic-gate while (next != NULL) { 320*7c478bd9Sstevel@tonic-gate next = getldap_free_hash(next); 321*7c478bd9Sstevel@tonic-gate } 322*7c478bd9Sstevel@tonic-gate hashTbl[i] = NULL; 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate entry_num = 0; 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&cache_lock); 327*7c478bd9Sstevel@tonic-gate break; 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate case CACHE_OP_ADD: 330*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 331*7c478bd9Sstevel@tonic-gate logit("operation is CACHE_OP_ADD...\n"); 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate if (from == NULL || to == NULL || *to == NULL) 334*7c478bd9Sstevel@tonic-gate return (-1); 335*7c478bd9Sstevel@tonic-gate hash = getldap_hash(from) % CACHE_HASH_MAX; 336*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&cache_lock); 337*7c478bd9Sstevel@tonic-gate idx = hashTbl[hash]; 338*7c478bd9Sstevel@tonic-gate /* 339*7c478bd9Sstevel@tonic-gate * replace old "to" value with new one 340*7c478bd9Sstevel@tonic-gate * if an entry with same "from" 341*7c478bd9Sstevel@tonic-gate * already exists 342*7c478bd9Sstevel@tonic-gate */ 343*7c478bd9Sstevel@tonic-gate if (idx) { 344*7c478bd9Sstevel@tonic-gate newp = getldap_scan_hash(type, from, idx); 345*7c478bd9Sstevel@tonic-gate if (newp) { 346*7c478bd9Sstevel@tonic-gate free(newp->to); 347*7c478bd9Sstevel@tonic-gate newp->to = strdup(*to); 348*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&cache_lock); 349*7c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate if (entry_num > CACHE_HASH_MAX_ENTRY) { 354*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&cache_lock); 355*7c478bd9Sstevel@tonic-gate return (-1); 356*7c478bd9Sstevel@tonic-gate } 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate newp = (cache_hash_t *)malloc(sizeof (cache_hash_t)); 359*7c478bd9Sstevel@tonic-gate if (newp == NULL) { 360*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&cache_lock); 361*7c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate newp->type = type; 364*7c478bd9Sstevel@tonic-gate newp->from = strdup(from); 365*7c478bd9Sstevel@tonic-gate newp->to = strdup(*to); 366*7c478bd9Sstevel@tonic-gate newp->next = idx; 367*7c478bd9Sstevel@tonic-gate hashTbl[hash] = newp; 368*7c478bd9Sstevel@tonic-gate entry_num++; 369*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&cache_lock); 370*7c478bd9Sstevel@tonic-gate break; 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate case CACHE_OP_FIND: 373*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 374*7c478bd9Sstevel@tonic-gate logit("operation is CACHE_OP_FIND...\n"); 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate if (from == NULL || to == NULL) 377*7c478bd9Sstevel@tonic-gate return (-1); 378*7c478bd9Sstevel@tonic-gate *to = NULL; 379*7c478bd9Sstevel@tonic-gate hash = getldap_hash(from) % CACHE_HASH_MAX; 380*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&cache_lock); 381*7c478bd9Sstevel@tonic-gate idx = hashTbl[hash]; 382*7c478bd9Sstevel@tonic-gate idx = getldap_scan_hash(type, from, idx); 383*7c478bd9Sstevel@tonic-gate if (idx) 384*7c478bd9Sstevel@tonic-gate *to = strdup(idx->to); 385*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&cache_lock); 386*7c478bd9Sstevel@tonic-gate if (idx == NULL) 387*7c478bd9Sstevel@tonic-gate return (-1); 388*7c478bd9Sstevel@tonic-gate break; 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate case CACHE_OP_GETSTAT: 391*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 392*7c478bd9Sstevel@tonic-gate logit("operation is CACHE_OP_GETSTAT...\n"); 393*7c478bd9Sstevel@tonic-gate } 394*7c478bd9Sstevel@tonic-gate if (to == NULL) 395*7c478bd9Sstevel@tonic-gate return (-1); 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate return (getldap_get_cacheData_stat(CACHE_HASH_MAX_ENTRY, 398*7c478bd9Sstevel@tonic-gate entry_num, to)); 399*7c478bd9Sstevel@tonic-gate break; 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate default: 402*7c478bd9Sstevel@tonic-gate logit("getldap_cache_op(): " 403*7c478bd9Sstevel@tonic-gate "invalid operation code (%d).\n", op); 404*7c478bd9Sstevel@tonic-gate return (-1); 405*7c478bd9Sstevel@tonic-gate break; 406*7c478bd9Sstevel@tonic-gate } 407*7c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 408*7c478bd9Sstevel@tonic-gate } 409*7c478bd9Sstevel@tonic-gate /* 410*7c478bd9Sstevel@tonic-gate * Function: sync_current_with_update_copy 411*7c478bd9Sstevel@tonic-gate * 412*7c478bd9Sstevel@tonic-gate * This function syncs up the 2 sinfo copies in info. 413*7c478bd9Sstevel@tonic-gate * 414*7c478bd9Sstevel@tonic-gate * The 2 copies are identical most of time. 415*7c478bd9Sstevel@tonic-gate * The update copy(sinfo[1]) could be different when 416*7c478bd9Sstevel@tonic-gate * getldap_serverInfo_refresh thread is refreshing the server list 417*7c478bd9Sstevel@tonic-gate * and calls getldap_get_rootDSE to update info. getldap_get_rootDSE 418*7c478bd9Sstevel@tonic-gate * calls sync_current_with_update_copy to sync up 2 copies before thr_exit. 419*7c478bd9Sstevel@tonic-gate * The calling sequence is 420*7c478bd9Sstevel@tonic-gate * getldap_serverInfo_refresh-> 421*7c478bd9Sstevel@tonic-gate * getldap_get_serverInfo_op(INFO_OP_CREATE,...)-> 422*7c478bd9Sstevel@tonic-gate * getldap_set_serverInfo-> 423*7c478bd9Sstevel@tonic-gate * getldap_get_rootDSE 424*7c478bd9Sstevel@tonic-gate * 425*7c478bd9Sstevel@tonic-gate * The original server_info_t has one copy of server info. When libsldap 426*7c478bd9Sstevel@tonic-gate * makes door call GETLDAPSERVER to get the server info and getldap_get_rootDSE 427*7c478bd9Sstevel@tonic-gate * is updating the server info, it would hit a unprotected window in 428*7c478bd9Sstevel@tonic-gate * getldap_rootDSE. The door call will not get server info and libsldap 429*7c478bd9Sstevel@tonic-gate * fails at making ldap connection. 430*7c478bd9Sstevel@tonic-gate * 431*7c478bd9Sstevel@tonic-gate * The new server_info_t provides GETLDAPSERVER thread with a current 432*7c478bd9Sstevel@tonic-gate * copy(sinfo[0]). getldap_get_rootDSE only works on the update copy(sinfo[1]) 433*7c478bd9Sstevel@tonic-gate * and syncs up 2 copies before thr_exit. This will close the window in 434*7c478bd9Sstevel@tonic-gate * getldap_get_rootDSE. 435*7c478bd9Sstevel@tonic-gate * 436*7c478bd9Sstevel@tonic-gate */ 437*7c478bd9Sstevel@tonic-gate static void 438*7c478bd9Sstevel@tonic-gate sync_current_with_update_copy(server_info_t *info) 439*7c478bd9Sstevel@tonic-gate { 440*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 441*7c478bd9Sstevel@tonic-gate logit("sync_current_with_update_copy()...\n"); 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info->mutex[1]); 445*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info->mutex[0]); 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate /* free memory in current copy first */ 448*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].addr) 449*7c478bd9Sstevel@tonic-gate free(info->sinfo[0].addr); 450*7c478bd9Sstevel@tonic-gate info->sinfo[0].addr = NULL; 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].rootDSE_data) 453*7c478bd9Sstevel@tonic-gate free(info->sinfo[0].rootDSE_data); 454*7c478bd9Sstevel@tonic-gate info->sinfo[0].rootDSE_data = NULL; 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].errormsg) 457*7c478bd9Sstevel@tonic-gate free(info->sinfo[0].errormsg); 458*7c478bd9Sstevel@tonic-gate info->sinfo[0].errormsg = NULL; 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate /* 461*7c478bd9Sstevel@tonic-gate * make current and update copy identical 462*7c478bd9Sstevel@tonic-gate */ 463*7c478bd9Sstevel@tonic-gate info->sinfo[0] = info->sinfo[1]; 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate /* 466*7c478bd9Sstevel@tonic-gate * getldap_get_server_stat() reads the update copy sinfo[1] 467*7c478bd9Sstevel@tonic-gate * so it can't be freed or nullified yet at this point. 468*7c478bd9Sstevel@tonic-gate * 469*7c478bd9Sstevel@tonic-gate * The sinfo[0] and sinfo[1] have identical string pointers. 470*7c478bd9Sstevel@tonic-gate * strdup the strings to avoid the double free problem. 471*7c478bd9Sstevel@tonic-gate * The strings of sinfo[1] are freed in 472*7c478bd9Sstevel@tonic-gate * getldap_get_rootDSE() and the strings of sinfo[0] 473*7c478bd9Sstevel@tonic-gate * are freed earlier in this function. If the pointers are the 474*7c478bd9Sstevel@tonic-gate * same, they will be freed twice. 475*7c478bd9Sstevel@tonic-gate */ 476*7c478bd9Sstevel@tonic-gate if (info->sinfo[1].addr) 477*7c478bd9Sstevel@tonic-gate info->sinfo[0].addr = strdup(info->sinfo[1].addr); 478*7c478bd9Sstevel@tonic-gate if (info->sinfo[1].rootDSE_data) 479*7c478bd9Sstevel@tonic-gate info->sinfo[0].rootDSE_data = 480*7c478bd9Sstevel@tonic-gate strdup(info->sinfo[1].rootDSE_data); 481*7c478bd9Sstevel@tonic-gate if (info->sinfo[1].errormsg) 482*7c478bd9Sstevel@tonic-gate info->sinfo[0].errormsg = strdup(info->sinfo[1].errormsg); 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[0]); 485*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[1]); 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate 489*7c478bd9Sstevel@tonic-gate static void * 490*7c478bd9Sstevel@tonic-gate getldap_get_rootDSE(void *arg) 491*7c478bd9Sstevel@tonic-gate { 492*7c478bd9Sstevel@tonic-gate server_info_t *serverInfo = (server_info_t *)arg; 493*7c478bd9Sstevel@tonic-gate int ldapVersion = LDAP_VERSION3; 494*7c478bd9Sstevel@tonic-gate LDAP *ld; 495*7c478bd9Sstevel@tonic-gate LDAPMessage *resultMsg = NULL; 496*7c478bd9Sstevel@tonic-gate LDAPMessage *e; 497*7c478bd9Sstevel@tonic-gate BerElement *ber; 498*7c478bd9Sstevel@tonic-gate char errmsg[MAXERROR]; 499*7c478bd9Sstevel@tonic-gate char *rootDSE; 500*7c478bd9Sstevel@tonic-gate char *attrs[3]; 501*7c478bd9Sstevel@tonic-gate char *a; 502*7c478bd9Sstevel@tonic-gate char **vals; 503*7c478bd9Sstevel@tonic-gate int ldaperrno = 0; 504*7c478bd9Sstevel@tonic-gate int rc = 0, exitrc = NS_LDAP_SUCCESS; 505*7c478bd9Sstevel@tonic-gate int i = 0, len = 0; 506*7c478bd9Sstevel@tonic-gate pid_t ppid; 507*7c478bd9Sstevel@tonic-gate struct timeval tv; 508*7c478bd9Sstevel@tonic-gate int server_found = 0; 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 511*7c478bd9Sstevel@tonic-gate logit("getldap_get_rootDSE()....\n"); 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate /* initialize the server info element */ 515*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&serverInfo->mutex[1]); 516*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].type = INFO_RW_UNKNOWN; 517*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].info_status 518*7c478bd9Sstevel@tonic-gate = INFO_STATUS_UNKNOWN; 519*7c478bd9Sstevel@tonic-gate /* 520*7c478bd9Sstevel@tonic-gate * When the sever list is refreshed over and over, 521*7c478bd9Sstevel@tonic-gate * this function is called each time it is refreshed. 522*7c478bd9Sstevel@tonic-gate * The previous server status of the update copy(sinfo[1]) 523*7c478bd9Sstevel@tonic-gate * is the status of the current copy 524*7c478bd9Sstevel@tonic-gate */ 525*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&serverInfo->mutex[0]); 526*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].prev_server_status = 527*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[0].server_status; 528*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&serverInfo->mutex[0]); 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].server_status = 531*7c478bd9Sstevel@tonic-gate INFO_SERVER_UNKNOWN; 532*7c478bd9Sstevel@tonic-gate if (serverInfo->sinfo[1].rootDSE_data) 533*7c478bd9Sstevel@tonic-gate free(serverInfo->sinfo[1].rootDSE_data); 534*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].rootDSE_data = NULL; 535*7c478bd9Sstevel@tonic-gate if (serverInfo->sinfo[1].errormsg) 536*7c478bd9Sstevel@tonic-gate free(serverInfo->sinfo[1].errormsg); 537*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].errormsg = NULL; 538*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&serverInfo->mutex[1]); 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate if ((ld = ldap_init(serverInfo->sinfo[1].addr, 541*7c478bd9Sstevel@tonic-gate LDAP_PORT)) == NULL || 542*7c478bd9Sstevel@tonic-gate /* SKIP ldap data base to prevent recursion */ 543*7c478bd9Sstevel@tonic-gate /* in gethostbyname when resolving hostname */ 544*7c478bd9Sstevel@tonic-gate 0 != ldap_set_option(ld, LDAP_X_OPT_DNS_SKIPDB, "ldap")) { 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&serverInfo->mutex[1]); 547*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].server_status = 548*7c478bd9Sstevel@tonic-gate INFO_SERVER_ERROR; 549*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].info_status = 550*7c478bd9Sstevel@tonic-gate INFO_STATUS_ERROR; 551*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].errormsg = 552*7c478bd9Sstevel@tonic-gate strdup(gettext("ldap_init failed")); 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 555*7c478bd9Sstevel@tonic-gate logit("getldap_get_rootDSE: %s.\n", 556*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].errormsg); 557*7c478bd9Sstevel@tonic-gate } 558*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&serverInfo->mutex[1]); 559*7c478bd9Sstevel@tonic-gate /* 560*7c478bd9Sstevel@tonic-gate * sync sinfo copies in the serverInfo. 561*7c478bd9Sstevel@tonic-gate * protected by mutex 562*7c478bd9Sstevel@tonic-gate */ 563*7c478bd9Sstevel@tonic-gate sync_current_with_update_copy(serverInfo); 564*7c478bd9Sstevel@tonic-gate thr_exit((void *) -1); 565*7c478bd9Sstevel@tonic-gate } 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate ldap_set_option(ld, 568*7c478bd9Sstevel@tonic-gate LDAP_OPT_PROTOCOL_VERSION, &ldapVersion); 569*7c478bd9Sstevel@tonic-gate ldap_set_option(ld, 570*7c478bd9Sstevel@tonic-gate LDAP_X_OPT_CONNECT_TIMEOUT, &tcptimeout); 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate /* currently, only interested in two attributes */ 573*7c478bd9Sstevel@tonic-gate attrs[0] = "supportedControl"; 574*7c478bd9Sstevel@tonic-gate attrs[1] = "supportedsaslmechanisms"; 575*7c478bd9Sstevel@tonic-gate attrs[2] = NULL; 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&serverInfo->mutex[1]); 578*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].server_status = INFO_SERVER_CONNECTING; 579*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&serverInfo->mutex[1]); 580*7c478bd9Sstevel@tonic-gate 581*7c478bd9Sstevel@tonic-gate tv.tv_sec = search_timeout; 582*7c478bd9Sstevel@tonic-gate tv.tv_usec = 0; 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate rc = ldap_search_ext_s(ld, "", LDAP_SCOPE_BASE, 585*7c478bd9Sstevel@tonic-gate "(objectclass=*)", 586*7c478bd9Sstevel@tonic-gate attrs, 0, NULL, NULL, &tv, 0, &resultMsg); 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate switch (rc) { 589*7c478bd9Sstevel@tonic-gate /* If successful, the root DSE was found. */ 590*7c478bd9Sstevel@tonic-gate case LDAP_SUCCESS: 591*7c478bd9Sstevel@tonic-gate break; 592*7c478bd9Sstevel@tonic-gate /* 593*7c478bd9Sstevel@tonic-gate * If the root DSE was not found, the server does 594*7c478bd9Sstevel@tonic-gate * not comply with the LDAP v3 protocol. 595*7c478bd9Sstevel@tonic-gate */ 596*7c478bd9Sstevel@tonic-gate default: 597*7c478bd9Sstevel@tonic-gate ldap_get_option(ld, 598*7c478bd9Sstevel@tonic-gate LDAP_OPT_ERROR_NUMBER, &ldaperrno); 599*7c478bd9Sstevel@tonic-gate (void) snprintf(errmsg, sizeof (errmsg), 600*7c478bd9Sstevel@tonic-gate gettext(ldap_err2string(ldaperrno))); 601*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 602*7c478bd9Sstevel@tonic-gate logit("getldap_get_rootDSE: Root DSE not found." 603*7c478bd9Sstevel@tonic-gate " %s is not an LDAPv3 server (%s).\n", 604*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].addr, errmsg); 605*7c478bd9Sstevel@tonic-gate } 606*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&serverInfo->mutex[1]); 607*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].errormsg 608*7c478bd9Sstevel@tonic-gate = strdup(errmsg); 609*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].info_status 610*7c478bd9Sstevel@tonic-gate = INFO_STATUS_ERROR; 611*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].server_status 612*7c478bd9Sstevel@tonic-gate = INFO_SERVER_ERROR; 613*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&serverInfo->mutex[1]); 614*7c478bd9Sstevel@tonic-gate if (resultMsg) 615*7c478bd9Sstevel@tonic-gate ldap_msgfree(resultMsg); 616*7c478bd9Sstevel@tonic-gate ldap_unbind(ld); 617*7c478bd9Sstevel@tonic-gate /* 618*7c478bd9Sstevel@tonic-gate * sync sinfo copies in the serverInfo. 619*7c478bd9Sstevel@tonic-gate * protected by mutex 620*7c478bd9Sstevel@tonic-gate */ 621*7c478bd9Sstevel@tonic-gate sync_current_with_update_copy(serverInfo); 622*7c478bd9Sstevel@tonic-gate thr_exit((void *) -1); 623*7c478bd9Sstevel@tonic-gate break; 624*7c478bd9Sstevel@tonic-gate } 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate if ((e = ldap_first_entry(ld, resultMsg)) != NULL) { 628*7c478bd9Sstevel@tonic-gate /* calculate length of root DSE data */ 629*7c478bd9Sstevel@tonic-gate for (a = ldap_first_attribute(ld, e, &ber); 630*7c478bd9Sstevel@tonic-gate a != NULL; 631*7c478bd9Sstevel@tonic-gate a = ldap_next_attribute(ld, e, ber)) { 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate if ((vals = ldap_get_values(ld, e, a)) != NULL) { 634*7c478bd9Sstevel@tonic-gate for (i = 0; vals[i] != NULL; i++) { 635*7c478bd9Sstevel@tonic-gate len += strlen(a) + 636*7c478bd9Sstevel@tonic-gate strlen(vals[i]) + 637*7c478bd9Sstevel@tonic-gate strlen(DOORLINESEP) +1; 638*7c478bd9Sstevel@tonic-gate } 639*7c478bd9Sstevel@tonic-gate ldap_value_free(vals); 640*7c478bd9Sstevel@tonic-gate } 641*7c478bd9Sstevel@tonic-gate ldap_memfree(a); 642*7c478bd9Sstevel@tonic-gate } 643*7c478bd9Sstevel@tonic-gate if (ber != NULL) 644*7c478bd9Sstevel@tonic-gate ber_free(ber, 0); 645*7c478bd9Sstevel@tonic-gate /* copy root DSE data */ 646*7c478bd9Sstevel@tonic-gate if (len) { 647*7c478bd9Sstevel@tonic-gate /* add 1 for the last '\0' */ 648*7c478bd9Sstevel@tonic-gate rootDSE = (char *)malloc(len + 1); 649*7c478bd9Sstevel@tonic-gate if (rootDSE != NULL) { 650*7c478bd9Sstevel@tonic-gate /* make it an empty string first */ 651*7c478bd9Sstevel@tonic-gate *rootDSE = '\0'; 652*7c478bd9Sstevel@tonic-gate for (a = ldap_first_attribute(ld, e, &ber); 653*7c478bd9Sstevel@tonic-gate a != NULL; 654*7c478bd9Sstevel@tonic-gate a = ldap_next_attribute( 655*7c478bd9Sstevel@tonic-gate ld, e, ber)) { 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate if ((vals = ldap_get_values( 658*7c478bd9Sstevel@tonic-gate ld, e, a)) != NULL) { 659*7c478bd9Sstevel@tonic-gate for (i = 0; vals[i] != NULL; 660*7c478bd9Sstevel@tonic-gate i++) { 661*7c478bd9Sstevel@tonic-gate int len; 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate len = strlen(a) + 664*7c478bd9Sstevel@tonic-gate strlen(vals[i]) + 665*7c478bd9Sstevel@tonic-gate strlen(DOORLINESEP) + 2; 666*7c478bd9Sstevel@tonic-gate (void) snprintf( 667*7c478bd9Sstevel@tonic-gate rootDSE + 668*7c478bd9Sstevel@tonic-gate strlen(rootDSE), 669*7c478bd9Sstevel@tonic-gate len, "%s=%s%s", 670*7c478bd9Sstevel@tonic-gate a, vals[i], 671*7c478bd9Sstevel@tonic-gate DOORLINESEP); 672*7c478bd9Sstevel@tonic-gate } 673*7c478bd9Sstevel@tonic-gate ldap_value_free(vals); 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate ldap_memfree(a); 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate if (ber != NULL) 678*7c478bd9Sstevel@tonic-gate ber_free(ber, 0); 679*7c478bd9Sstevel@tonic-gate } else 680*7c478bd9Sstevel@tonic-gate len = 0; 681*7c478bd9Sstevel@tonic-gate } 682*7c478bd9Sstevel@tonic-gate } 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate /* error, if no root DSE data */ 685*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&serverInfo->mutex[1]); 686*7c478bd9Sstevel@tonic-gate if (len == 0) { 687*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].errormsg = 688*7c478bd9Sstevel@tonic-gate strdup(gettext("No root DSE data returned.")); 689*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 690*7c478bd9Sstevel@tonic-gate logit("getldap_get_rootDSE: %s.\n", 691*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].errormsg); 692*7c478bd9Sstevel@tonic-gate } 693*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].type 694*7c478bd9Sstevel@tonic-gate = INFO_RW_UNKNOWN; 695*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].info_status 696*7c478bd9Sstevel@tonic-gate = INFO_STATUS_ERROR; 697*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].server_status = INFO_SERVER_ERROR; 698*7c478bd9Sstevel@tonic-gate exitrc = -1; 699*7c478bd9Sstevel@tonic-gate } else { 700*7c478bd9Sstevel@tonic-gate /* assume writeable, i.e., can do modify */ 701*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].type = INFO_RW_WRITEABLE; 702*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].server_status 703*7c478bd9Sstevel@tonic-gate = INFO_SERVER_UP; 704*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].info_status = INFO_STATUS_NEW; 705*7c478bd9Sstevel@tonic-gate /* remove the last DOORLINESEP */ 706*7c478bd9Sstevel@tonic-gate *(rootDSE+strlen(rootDSE)-1) = '\0'; 707*7c478bd9Sstevel@tonic-gate serverInfo->sinfo[1].rootDSE_data = rootDSE; 708*7c478bd9Sstevel@tonic-gate 709*7c478bd9Sstevel@tonic-gate server_found = 1; 710*7c478bd9Sstevel@tonic-gate 711*7c478bd9Sstevel@tonic-gate exitrc = NS_LDAP_SUCCESS; 712*7c478bd9Sstevel@tonic-gate } 713*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&serverInfo->mutex[1]); 714*7c478bd9Sstevel@tonic-gate 715*7c478bd9Sstevel@tonic-gate if (resultMsg) 716*7c478bd9Sstevel@tonic-gate ldap_msgfree(resultMsg); 717*7c478bd9Sstevel@tonic-gate ldap_unbind(ld); 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate /* 720*7c478bd9Sstevel@tonic-gate * sync sinfo copies in the serverInfo. 721*7c478bd9Sstevel@tonic-gate * protected by mutex 722*7c478bd9Sstevel@tonic-gate */ 723*7c478bd9Sstevel@tonic-gate sync_current_with_update_copy(serverInfo); 724*7c478bd9Sstevel@tonic-gate /* 725*7c478bd9Sstevel@tonic-gate * signal that the ldap_cachemgr parent process 726*7c478bd9Sstevel@tonic-gate * should exit now, if it is still waiting 727*7c478bd9Sstevel@tonic-gate */ 728*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&sig_mutex); 729*7c478bd9Sstevel@tonic-gate if (signal_done == FALSE && server_found) { 730*7c478bd9Sstevel@tonic-gate ppid = getppid(); 731*7c478bd9Sstevel@tonic-gate (void) kill(ppid, SIGUSR1); 732*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 733*7c478bd9Sstevel@tonic-gate logit("getldap_get_rootDSE(): " 734*7c478bd9Sstevel@tonic-gate "SIGUSR1 signal sent to " 735*7c478bd9Sstevel@tonic-gate "parent process(%ld).\n", ppid); 736*7c478bd9Sstevel@tonic-gate } 737*7c478bd9Sstevel@tonic-gate signal_done = TRUE; 738*7c478bd9Sstevel@tonic-gate } 739*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&sig_mutex); 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate thr_exit((void *) exitrc); 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate return ((void *) NULL); 744*7c478bd9Sstevel@tonic-gate } 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate static int 747*7c478bd9Sstevel@tonic-gate getldap_init_serverInfo(server_info_t **head) 748*7c478bd9Sstevel@tonic-gate { 749*7c478bd9Sstevel@tonic-gate char **servers = NULL; 750*7c478bd9Sstevel@tonic-gate int rc = 0, i, exitrc = NS_LDAP_SUCCESS; 751*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *errorp = NULL; 752*7c478bd9Sstevel@tonic-gate server_info_t *info, *tail = NULL; 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate *head = NULL; 755*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 756*7c478bd9Sstevel@tonic-gate logit("getldap_init_serverInfo()...\n"); 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate rc = __s_api_getServers(&servers, &errorp); 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 761*7c478bd9Sstevel@tonic-gate logit("getldap_init_serverInfo: " 762*7c478bd9Sstevel@tonic-gate "__s_api_getServers failed.\n"); 763*7c478bd9Sstevel@tonic-gate if (errorp) 764*7c478bd9Sstevel@tonic-gate __ns_ldap_freeError(&errorp); 765*7c478bd9Sstevel@tonic-gate return (-1); 766*7c478bd9Sstevel@tonic-gate } 767*7c478bd9Sstevel@tonic-gate for (i = 0; servers[i] != NULL; i++) { 768*7c478bd9Sstevel@tonic-gate info = (server_info_t *)calloc(1, sizeof (server_info_t)); 769*7c478bd9Sstevel@tonic-gate if (info == NULL) { 770*7c478bd9Sstevel@tonic-gate logit("getldap_init_serverInfo: " 771*7c478bd9Sstevel@tonic-gate "not enough memory.\n"); 772*7c478bd9Sstevel@tonic-gate exitrc = NS_LDAP_MEMORY; 773*7c478bd9Sstevel@tonic-gate break; 774*7c478bd9Sstevel@tonic-gate } 775*7c478bd9Sstevel@tonic-gate if (i == 0) { 776*7c478bd9Sstevel@tonic-gate *head = info; 777*7c478bd9Sstevel@tonic-gate tail = info; 778*7c478bd9Sstevel@tonic-gate } else { 779*7c478bd9Sstevel@tonic-gate tail->next = info; 780*7c478bd9Sstevel@tonic-gate tail = info; 781*7c478bd9Sstevel@tonic-gate } 782*7c478bd9Sstevel@tonic-gate 783*7c478bd9Sstevel@tonic-gate info->sinfo[0].addr = strdup(servers[i]); 784*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].addr == NULL) { 785*7c478bd9Sstevel@tonic-gate logit("getldap_init_serverInfo: " 786*7c478bd9Sstevel@tonic-gate "not enough memory.\n"); 787*7c478bd9Sstevel@tonic-gate exitrc = NS_LDAP_MEMORY; 788*7c478bd9Sstevel@tonic-gate break; 789*7c478bd9Sstevel@tonic-gate } 790*7c478bd9Sstevel@tonic-gate info->sinfo[1].addr = strdup(servers[i]); 791*7c478bd9Sstevel@tonic-gate if (info->sinfo[1].addr == NULL) { 792*7c478bd9Sstevel@tonic-gate logit("getldap_init_serverInfo: " 793*7c478bd9Sstevel@tonic-gate "not enough memory.\n"); 794*7c478bd9Sstevel@tonic-gate exitrc = NS_LDAP_MEMORY; 795*7c478bd9Sstevel@tonic-gate break; 796*7c478bd9Sstevel@tonic-gate } 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate info->sinfo[0].type = INFO_RW_UNKNOWN; 799*7c478bd9Sstevel@tonic-gate info->sinfo[1].type = INFO_RW_UNKNOWN; 800*7c478bd9Sstevel@tonic-gate info->sinfo[0].info_status = INFO_STATUS_UNKNOWN; 801*7c478bd9Sstevel@tonic-gate info->sinfo[1].info_status = INFO_STATUS_UNKNOWN; 802*7c478bd9Sstevel@tonic-gate info->sinfo[0].server_status = INFO_SERVER_UNKNOWN; 803*7c478bd9Sstevel@tonic-gate info->sinfo[1].server_status = INFO_SERVER_UNKNOWN; 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate /* 806*7c478bd9Sstevel@tonic-gate * Assume at startup or after the configuration 807*7c478bd9Sstevel@tonic-gate * profile is refreshed, all servers are good. 808*7c478bd9Sstevel@tonic-gate */ 809*7c478bd9Sstevel@tonic-gate info->sinfo[0].prev_server_status = 810*7c478bd9Sstevel@tonic-gate INFO_SERVER_UP; 811*7c478bd9Sstevel@tonic-gate info->sinfo[1].prev_server_status = 812*7c478bd9Sstevel@tonic-gate INFO_SERVER_UP; 813*7c478bd9Sstevel@tonic-gate info->sinfo[0].rootDSE_data = NULL; 814*7c478bd9Sstevel@tonic-gate info->sinfo[1].rootDSE_data = NULL; 815*7c478bd9Sstevel@tonic-gate info->sinfo[0].errormsg = NULL; 816*7c478bd9Sstevel@tonic-gate info->sinfo[1].errormsg = NULL; 817*7c478bd9Sstevel@tonic-gate info->next = NULL; 818*7c478bd9Sstevel@tonic-gate } 819*7c478bd9Sstevel@tonic-gate __s_api_free2dArray(servers); 820*7c478bd9Sstevel@tonic-gate if (exitrc != NS_LDAP_SUCCESS) { 821*7c478bd9Sstevel@tonic-gate if (head && *head) { 822*7c478bd9Sstevel@tonic-gate (void) getldap_destroy_serverInfo(*head); 823*7c478bd9Sstevel@tonic-gate *head = NULL; 824*7c478bd9Sstevel@tonic-gate } 825*7c478bd9Sstevel@tonic-gate } 826*7c478bd9Sstevel@tonic-gate return (exitrc); 827*7c478bd9Sstevel@tonic-gate } 828*7c478bd9Sstevel@tonic-gate 829*7c478bd9Sstevel@tonic-gate static int 830*7c478bd9Sstevel@tonic-gate getldap_destroy_serverInfo(server_info_t *head) 831*7c478bd9Sstevel@tonic-gate { 832*7c478bd9Sstevel@tonic-gate server_info_t *info, *next; 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 835*7c478bd9Sstevel@tonic-gate logit("getldap_destroy_serverInfo()...\n"); 836*7c478bd9Sstevel@tonic-gate } 837*7c478bd9Sstevel@tonic-gate 838*7c478bd9Sstevel@tonic-gate if (head == NULL) { 839*7c478bd9Sstevel@tonic-gate logit("getldap_destroy_serverInfo: " 840*7c478bd9Sstevel@tonic-gate "invalid serverInfo list.\n"); 841*7c478bd9Sstevel@tonic-gate return (-1); 842*7c478bd9Sstevel@tonic-gate } 843*7c478bd9Sstevel@tonic-gate 844*7c478bd9Sstevel@tonic-gate for (info = head; info; info = next) { 845*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].addr) 846*7c478bd9Sstevel@tonic-gate free(info->sinfo[0].addr); 847*7c478bd9Sstevel@tonic-gate if (info->sinfo[1].addr) 848*7c478bd9Sstevel@tonic-gate free(info->sinfo[1].addr); 849*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].rootDSE_data) 850*7c478bd9Sstevel@tonic-gate free(info->sinfo[0].rootDSE_data); 851*7c478bd9Sstevel@tonic-gate if (info->sinfo[1].rootDSE_data) 852*7c478bd9Sstevel@tonic-gate free(info->sinfo[1].rootDSE_data); 853*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].errormsg) 854*7c478bd9Sstevel@tonic-gate free(info->sinfo[0].errormsg); 855*7c478bd9Sstevel@tonic-gate if (info->sinfo[1].errormsg) 856*7c478bd9Sstevel@tonic-gate free(info->sinfo[1].errormsg); 857*7c478bd9Sstevel@tonic-gate next = info->next; 858*7c478bd9Sstevel@tonic-gate free(info); 859*7c478bd9Sstevel@tonic-gate } 860*7c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 861*7c478bd9Sstevel@tonic-gate } 862*7c478bd9Sstevel@tonic-gate 863*7c478bd9Sstevel@tonic-gate static int 864*7c478bd9Sstevel@tonic-gate getldap_set_serverInfo(server_info_t *head, 865*7c478bd9Sstevel@tonic-gate int reset_bindtime) 866*7c478bd9Sstevel@tonic-gate { 867*7c478bd9Sstevel@tonic-gate server_info_t *info; 868*7c478bd9Sstevel@tonic-gate int atleast1 = 0; 869*7c478bd9Sstevel@tonic-gate thread_t *tid; 870*7c478bd9Sstevel@tonic-gate int num_threads = 0, i, j; 871*7c478bd9Sstevel@tonic-gate void *status; 872*7c478bd9Sstevel@tonic-gate void **paramVal = NULL; 873*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 876*7c478bd9Sstevel@tonic-gate logit("getldap_set_serverInfo()...\n"); 877*7c478bd9Sstevel@tonic-gate } 878*7c478bd9Sstevel@tonic-gate 879*7c478bd9Sstevel@tonic-gate if (head == NULL) { 880*7c478bd9Sstevel@tonic-gate logit("getldap_set_serverInfo: " 881*7c478bd9Sstevel@tonic-gate "invalid serverInfo list.\n"); 882*7c478bd9Sstevel@tonic-gate return (-1); 883*7c478bd9Sstevel@tonic-gate } 884*7c478bd9Sstevel@tonic-gate 885*7c478bd9Sstevel@tonic-gate /* Get the bind timeout value */ 886*7c478bd9Sstevel@tonic-gate if (reset_bindtime == 1) { 887*7c478bd9Sstevel@tonic-gate tcptimeout = NS_DEFAULT_BIND_TIMEOUT * 1000; 888*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_getParam(NS_LDAP_BIND_TIME_P, 889*7c478bd9Sstevel@tonic-gate ¶mVal, &error); 890*7c478bd9Sstevel@tonic-gate if (paramVal != NULL && *paramVal != NULL) { 891*7c478bd9Sstevel@tonic-gate /* convert to milliseconds */ 892*7c478bd9Sstevel@tonic-gate tcptimeout = **((int **)paramVal); 893*7c478bd9Sstevel@tonic-gate tcptimeout *= 1000; 894*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶mVal); 895*7c478bd9Sstevel@tonic-gate } 896*7c478bd9Sstevel@tonic-gate if (error) 897*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 898*7c478bd9Sstevel@tonic-gate 899*7c478bd9Sstevel@tonic-gate /* get search timeout value */ 900*7c478bd9Sstevel@tonic-gate search_timeout = NS_DEFAULT_SEARCH_TIMEOUT; 901*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_getParam(NS_LDAP_SEARCH_TIME_P, 902*7c478bd9Sstevel@tonic-gate ¶mVal, &error); 903*7c478bd9Sstevel@tonic-gate if (paramVal != NULL && *paramVal != NULL) { 904*7c478bd9Sstevel@tonic-gate search_timeout = **((int **)paramVal); 905*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶mVal); 906*7c478bd9Sstevel@tonic-gate } 907*7c478bd9Sstevel@tonic-gate if (error) 908*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 909*7c478bd9Sstevel@tonic-gate 910*7c478bd9Sstevel@tonic-gate } 911*7c478bd9Sstevel@tonic-gate 912*7c478bd9Sstevel@tonic-gate for (info = head; info; info = info->next) 913*7c478bd9Sstevel@tonic-gate num_threads++; 914*7c478bd9Sstevel@tonic-gate 915*7c478bd9Sstevel@tonic-gate if (num_threads == 0) { 916*7c478bd9Sstevel@tonic-gate logit("getldap_set_serverInfo: " 917*7c478bd9Sstevel@tonic-gate "empty serverInfo list.\n"); 918*7c478bd9Sstevel@tonic-gate return (-1); 919*7c478bd9Sstevel@tonic-gate } 920*7c478bd9Sstevel@tonic-gate 921*7c478bd9Sstevel@tonic-gate tid = (thread_t *) calloc(1, sizeof (thread_t) * num_threads); 922*7c478bd9Sstevel@tonic-gate if (tid == NULL) { 923*7c478bd9Sstevel@tonic-gate logit("getldap_set_serverInfo: " 924*7c478bd9Sstevel@tonic-gate "No memory to create thread ID list.\n"); 925*7c478bd9Sstevel@tonic-gate return (-1); 926*7c478bd9Sstevel@tonic-gate } 927*7c478bd9Sstevel@tonic-gate 928*7c478bd9Sstevel@tonic-gate for (info = head, i = 0; info; info = info->next, i++) { 929*7c478bd9Sstevel@tonic-gate if (thr_create(NULL, 0, 930*7c478bd9Sstevel@tonic-gate (void *(*)(void*))getldap_get_rootDSE, 931*7c478bd9Sstevel@tonic-gate (void *)info, 0, &tid[i])) { 932*7c478bd9Sstevel@tonic-gate logit("getldap_set_serverInfo: " 933*7c478bd9Sstevel@tonic-gate "can not create thread %d.\n", i + 1); 934*7c478bd9Sstevel@tonic-gate for (j = 0; j < i; j++) 935*7c478bd9Sstevel@tonic-gate (void) thr_join(tid[j], NULL, NULL); 936*7c478bd9Sstevel@tonic-gate free(tid); 937*7c478bd9Sstevel@tonic-gate return (-1); 938*7c478bd9Sstevel@tonic-gate } 939*7c478bd9Sstevel@tonic-gate } 940*7c478bd9Sstevel@tonic-gate 941*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_threads; i++) { 942*7c478bd9Sstevel@tonic-gate if (thr_join(tid[i], NULL, &status) == 0) { 943*7c478bd9Sstevel@tonic-gate if ((int)status == NS_LDAP_SUCCESS) 944*7c478bd9Sstevel@tonic-gate atleast1 = 1; 945*7c478bd9Sstevel@tonic-gate } 946*7c478bd9Sstevel@tonic-gate } 947*7c478bd9Sstevel@tonic-gate 948*7c478bd9Sstevel@tonic-gate free(tid); 949*7c478bd9Sstevel@tonic-gate 950*7c478bd9Sstevel@tonic-gate if (atleast1) 951*7c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 952*7c478bd9Sstevel@tonic-gate else 953*7c478bd9Sstevel@tonic-gate return (-1); 954*7c478bd9Sstevel@tonic-gate } 955*7c478bd9Sstevel@tonic-gate 956*7c478bd9Sstevel@tonic-gate /* 957*7c478bd9Sstevel@tonic-gate * getldap_get_serverInfo processes the GETLDAPSERVER door request passed 958*7c478bd9Sstevel@tonic-gate * to this function from getldap_serverInfo_op(). 959*7c478bd9Sstevel@tonic-gate * input: 960*7c478bd9Sstevel@tonic-gate * a buffer containing an empty string (e.g., input[0]='\0';) or a string 961*7c478bd9Sstevel@tonic-gate * as the "input" in printf(input, "%s%s%s", req, DOORLINESEP, addr); 962*7c478bd9Sstevel@tonic-gate * where addr is the address of a server and 963*7c478bd9Sstevel@tonic-gate * req is one of the following: 964*7c478bd9Sstevel@tonic-gate * NS_CACHE_NEW: send a new server address, addr is ignored. 965*7c478bd9Sstevel@tonic-gate * NS_CACHE_NORESP: send the next one, remove addr from list. 966*7c478bd9Sstevel@tonic-gate * NS_CACHE_NEXT: send the next one, keep addr on list. 967*7c478bd9Sstevel@tonic-gate * NS_CACHE_WRITE: send a non-replica server, if possible, if not, same 968*7c478bd9Sstevel@tonic-gate * as NS_CACHE_NEXT. 969*7c478bd9Sstevel@tonic-gate * output: 970*7c478bd9Sstevel@tonic-gate * a buffer containing server info in the following format: 971*7c478bd9Sstevel@tonic-gate * serveraddress DOORLINESEP [ attr=value [DOORLINESEP attr=value ]...] 972*7c478bd9Sstevel@tonic-gate * for example: ( here | used as DOORLINESEP for visual purposes) 973*7c478bd9Sstevel@tonic-gate * 1.2.3.4|supportedControl=1.1.1.1|supportedSASLmechanisms=EXTERNAL 974*7c478bd9Sstevel@tonic-gate * NOTE: caller should free this buffer when done using it 975*7c478bd9Sstevel@tonic-gate */ 976*7c478bd9Sstevel@tonic-gate static int 977*7c478bd9Sstevel@tonic-gate getldap_get_serverInfo(server_info_t *head, char *input, 978*7c478bd9Sstevel@tonic-gate char **output, int *svr_removed) 979*7c478bd9Sstevel@tonic-gate { 980*7c478bd9Sstevel@tonic-gate server_info_t *info = NULL; 981*7c478bd9Sstevel@tonic-gate server_info_t *server = NULL; 982*7c478bd9Sstevel@tonic-gate char *addr = NULL; 983*7c478bd9Sstevel@tonic-gate char *req = NULL; 984*7c478bd9Sstevel@tonic-gate char req_new[] = NS_CACHE_NEW; 985*7c478bd9Sstevel@tonic-gate int matched = FALSE, len; 986*7c478bd9Sstevel@tonic-gate 987*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 988*7c478bd9Sstevel@tonic-gate logit("getldap_get_serverInfo()...\n"); 989*7c478bd9Sstevel@tonic-gate } 990*7c478bd9Sstevel@tonic-gate 991*7c478bd9Sstevel@tonic-gate if (input == NULL || output == NULL) { 992*7c478bd9Sstevel@tonic-gate logit("getldap_get_serverInfo: " 993*7c478bd9Sstevel@tonic-gate "No input or output buffer.\n"); 994*7c478bd9Sstevel@tonic-gate return (-1); 995*7c478bd9Sstevel@tonic-gate } 996*7c478bd9Sstevel@tonic-gate 997*7c478bd9Sstevel@tonic-gate *output = NULL; 998*7c478bd9Sstevel@tonic-gate *svr_removed = FALSE; 999*7c478bd9Sstevel@tonic-gate 1000*7c478bd9Sstevel@tonic-gate if (head == NULL) { 1001*7c478bd9Sstevel@tonic-gate logit("getldap_get_serverInfo: " 1002*7c478bd9Sstevel@tonic-gate "invalid serverInfo list.\n"); 1003*7c478bd9Sstevel@tonic-gate return (-1); 1004*7c478bd9Sstevel@tonic-gate } 1005*7c478bd9Sstevel@tonic-gate /* 1006*7c478bd9Sstevel@tonic-gate * parse the input string to get req and addr, 1007*7c478bd9Sstevel@tonic-gate * if input is empty, i.e., input[0] == '\0', 1008*7c478bd9Sstevel@tonic-gate * treat it as an NS_CACHE_NEW request 1009*7c478bd9Sstevel@tonic-gate */ 1010*7c478bd9Sstevel@tonic-gate req = req_new; 1011*7c478bd9Sstevel@tonic-gate if (input[0] != '\0') { 1012*7c478bd9Sstevel@tonic-gate req = input; 1013*7c478bd9Sstevel@tonic-gate input[strlen(NS_CACHE_NEW)] = '\0'; 1014*7c478bd9Sstevel@tonic-gate addr = input + strlen(DOORLINESEP) + strlen(NS_CACHE_NEW); 1015*7c478bd9Sstevel@tonic-gate } 1016*7c478bd9Sstevel@tonic-gate /* 1017*7c478bd9Sstevel@tonic-gate * if NS_CACHE_NEW, 1018*7c478bd9Sstevel@tonic-gate * or the server info is new, 1019*7c478bd9Sstevel@tonic-gate * starts from the 1020*7c478bd9Sstevel@tonic-gate * beginning of the list 1021*7c478bd9Sstevel@tonic-gate */ 1022*7c478bd9Sstevel@tonic-gate if ((strcmp(req, NS_CACHE_NEW) == 0) || 1023*7c478bd9Sstevel@tonic-gate (head->sinfo[0].info_status == INFO_STATUS_NEW)) 1024*7c478bd9Sstevel@tonic-gate matched = TRUE; 1025*7c478bd9Sstevel@tonic-gate for (info = head; info; info = info->next) { 1026*7c478bd9Sstevel@tonic-gate /* 1027*7c478bd9Sstevel@tonic-gate * make sure the server info stays the same 1028*7c478bd9Sstevel@tonic-gate * while the data is being processed 1029*7c478bd9Sstevel@tonic-gate */ 1030*7c478bd9Sstevel@tonic-gate 1031*7c478bd9Sstevel@tonic-gate /* 1032*7c478bd9Sstevel@tonic-gate * This function is called to get server info list 1033*7c478bd9Sstevel@tonic-gate * and pass it back to door call clients. 1034*7c478bd9Sstevel@tonic-gate * Access the current copy (sinfo[0]) to get such 1035*7c478bd9Sstevel@tonic-gate * information 1036*7c478bd9Sstevel@tonic-gate */ 1037*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info->mutex[0]); 1038*7c478bd9Sstevel@tonic-gate 1039*7c478bd9Sstevel@tonic-gate if (matched == FALSE && 1040*7c478bd9Sstevel@tonic-gate strcmp(info->sinfo[0].addr, addr) == 0) { 1041*7c478bd9Sstevel@tonic-gate matched = TRUE; 1042*7c478bd9Sstevel@tonic-gate if (strcmp(req, NS_CACHE_NORESP) == 0) { 1043*7c478bd9Sstevel@tonic-gate 1044*7c478bd9Sstevel@tonic-gate /* 1045*7c478bd9Sstevel@tonic-gate * if the server has already been removed, 1046*7c478bd9Sstevel@tonic-gate * don't bother 1047*7c478bd9Sstevel@tonic-gate */ 1048*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].server_status == 1049*7c478bd9Sstevel@tonic-gate INFO_SERVER_REMOVED) { 1050*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[0]); 1051*7c478bd9Sstevel@tonic-gate continue; 1052*7c478bd9Sstevel@tonic-gate } 1053*7c478bd9Sstevel@tonic-gate 1054*7c478bd9Sstevel@tonic-gate /* 1055*7c478bd9Sstevel@tonic-gate * if the information is new, 1056*7c478bd9Sstevel@tonic-gate * give this server one more chance 1057*7c478bd9Sstevel@tonic-gate */ 1058*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].info_status == 1059*7c478bd9Sstevel@tonic-gate INFO_STATUS_NEW && 1060*7c478bd9Sstevel@tonic-gate info->sinfo[0].server_status == 1061*7c478bd9Sstevel@tonic-gate INFO_SERVER_UP) { 1062*7c478bd9Sstevel@tonic-gate server = info; 1063*7c478bd9Sstevel@tonic-gate break; 1064*7c478bd9Sstevel@tonic-gate } else { 1065*7c478bd9Sstevel@tonic-gate /* 1066*7c478bd9Sstevel@tonic-gate * it is recommended that 1067*7c478bd9Sstevel@tonic-gate * before removing the 1068*7c478bd9Sstevel@tonic-gate * server from the list, 1069*7c478bd9Sstevel@tonic-gate * the server should be 1070*7c478bd9Sstevel@tonic-gate * contacted one more time 1071*7c478bd9Sstevel@tonic-gate * to make sure that it is 1072*7c478bd9Sstevel@tonic-gate * really unavailable. 1073*7c478bd9Sstevel@tonic-gate * For now, just trust the client 1074*7c478bd9Sstevel@tonic-gate * (i.e., the sldap library) 1075*7c478bd9Sstevel@tonic-gate * that it knows what it is 1076*7c478bd9Sstevel@tonic-gate * doing and would not try 1077*7c478bd9Sstevel@tonic-gate * to mess up the server 1078*7c478bd9Sstevel@tonic-gate * list. 1079*7c478bd9Sstevel@tonic-gate */ 1080*7c478bd9Sstevel@tonic-gate info->sinfo[0].prev_server_status = 1081*7c478bd9Sstevel@tonic-gate info->sinfo[0].server_status; 1082*7c478bd9Sstevel@tonic-gate info->sinfo[0].server_status = 1083*7c478bd9Sstevel@tonic-gate INFO_SERVER_REMOVED; 1084*7c478bd9Sstevel@tonic-gate /* 1085*7c478bd9Sstevel@tonic-gate * make sure this will be seen 1086*7c478bd9Sstevel@tonic-gate * if a user query the server 1087*7c478bd9Sstevel@tonic-gate * status via the ldap_cachemgr's 1088*7c478bd9Sstevel@tonic-gate * -g option 1089*7c478bd9Sstevel@tonic-gate */ 1090*7c478bd9Sstevel@tonic-gate info->sinfo[1].server_status = 1091*7c478bd9Sstevel@tonic-gate INFO_SERVER_REMOVED; 1092*7c478bd9Sstevel@tonic-gate *svr_removed = TRUE; 1093*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[0]); 1094*7c478bd9Sstevel@tonic-gate continue; 1095*7c478bd9Sstevel@tonic-gate } 1096*7c478bd9Sstevel@tonic-gate } else { 1097*7c478bd9Sstevel@tonic-gate /* 1098*7c478bd9Sstevel@tonic-gate * req == NS_CACHE_NEXT or NS_CACHE_WRITE 1099*7c478bd9Sstevel@tonic-gate */ 1100*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[0]); 1101*7c478bd9Sstevel@tonic-gate continue; 1102*7c478bd9Sstevel@tonic-gate } 1103*7c478bd9Sstevel@tonic-gate } 1104*7c478bd9Sstevel@tonic-gate 1105*7c478bd9Sstevel@tonic-gate if (matched) { 1106*7c478bd9Sstevel@tonic-gate if (strcmp(req, NS_CACHE_WRITE) == 0) { 1107*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].type == 1108*7c478bd9Sstevel@tonic-gate INFO_RW_WRITEABLE && 1109*7c478bd9Sstevel@tonic-gate info->sinfo[0].server_status == 1110*7c478bd9Sstevel@tonic-gate INFO_SERVER_UP) { 1111*7c478bd9Sstevel@tonic-gate server = info; 1112*7c478bd9Sstevel@tonic-gate break; 1113*7c478bd9Sstevel@tonic-gate } 1114*7c478bd9Sstevel@tonic-gate } else if (info->sinfo[0].server_status == 1115*7c478bd9Sstevel@tonic-gate INFO_SERVER_UP) { 1116*7c478bd9Sstevel@tonic-gate server = info; 1117*7c478bd9Sstevel@tonic-gate break; 1118*7c478bd9Sstevel@tonic-gate } 1119*7c478bd9Sstevel@tonic-gate } 1120*7c478bd9Sstevel@tonic-gate 1121*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[0]); 1122*7c478bd9Sstevel@tonic-gate } 1123*7c478bd9Sstevel@tonic-gate 1124*7c478bd9Sstevel@tonic-gate if (server) { 1125*7c478bd9Sstevel@tonic-gate len = strlen(server->sinfo[0].addr) + 1126*7c478bd9Sstevel@tonic-gate strlen(server->sinfo[0].rootDSE_data) + 1127*7c478bd9Sstevel@tonic-gate strlen(DOORLINESEP) + 1; 1128*7c478bd9Sstevel@tonic-gate *output = (char *)malloc(len); 1129*7c478bd9Sstevel@tonic-gate if (*output == NULL) { 1130*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[0]); 1131*7c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 1132*7c478bd9Sstevel@tonic-gate } 1133*7c478bd9Sstevel@tonic-gate (void) snprintf(*output, len, "%s%s%s", 1134*7c478bd9Sstevel@tonic-gate server->sinfo[0].addr, DOORLINESEP, 1135*7c478bd9Sstevel@tonic-gate server->sinfo[0].rootDSE_data); 1136*7c478bd9Sstevel@tonic-gate server->sinfo[0].info_status = INFO_STATUS_OLD; 1137*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[0]); 1138*7c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 1139*7c478bd9Sstevel@tonic-gate } 1140*7c478bd9Sstevel@tonic-gate else 1141*7c478bd9Sstevel@tonic-gate return (-99); 1142*7c478bd9Sstevel@tonic-gate } 1143*7c478bd9Sstevel@tonic-gate 1144*7c478bd9Sstevel@tonic-gate /* 1145*7c478bd9Sstevel@tonic-gate * Format previous and next refresh time 1146*7c478bd9Sstevel@tonic-gate */ 1147*7c478bd9Sstevel@tonic-gate static int 1148*7c478bd9Sstevel@tonic-gate getldap_format_refresh_time(char **output, time_t *prev, time_t *next) 1149*7c478bd9Sstevel@tonic-gate { 1150*7c478bd9Sstevel@tonic-gate #define TIME_FORMAT "%Y/%m/%d %H:%M:%S" 1151*7c478bd9Sstevel@tonic-gate #define TIME_HEADER1 " Previous refresh time: " 1152*7c478bd9Sstevel@tonic-gate #define TIME_HEADER2 " Next refresh time: " 1153*7c478bd9Sstevel@tonic-gate int hdr1_len = strlen(gettext(TIME_HEADER1)); 1154*7c478bd9Sstevel@tonic-gate int hdr2_len = strlen(gettext(TIME_HEADER2)); 1155*7c478bd9Sstevel@tonic-gate struct tm tm; 1156*7c478bd9Sstevel@tonic-gate char nbuf[256]; 1157*7c478bd9Sstevel@tonic-gate char pbuf[256]; 1158*7c478bd9Sstevel@tonic-gate int len; 1159*7c478bd9Sstevel@tonic-gate 1160*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 1161*7c478bd9Sstevel@tonic-gate logit("getldap_format_refresh_time()...\n"); 1162*7c478bd9Sstevel@tonic-gate } 1163*7c478bd9Sstevel@tonic-gate 1164*7c478bd9Sstevel@tonic-gate *output = NULL; 1165*7c478bd9Sstevel@tonic-gate 1166*7c478bd9Sstevel@tonic-gate /* format the time of previous refresh */ 1167*7c478bd9Sstevel@tonic-gate if (*prev != 0) { 1168*7c478bd9Sstevel@tonic-gate (void) localtime_r(prev, &tm); 1169*7c478bd9Sstevel@tonic-gate (void) strftime(pbuf, sizeof (pbuf) - 1, TIME_FORMAT, &tm); 1170*7c478bd9Sstevel@tonic-gate } else { 1171*7c478bd9Sstevel@tonic-gate (void) strcpy(pbuf, gettext("NOT DONE")); 1172*7c478bd9Sstevel@tonic-gate } 1173*7c478bd9Sstevel@tonic-gate 1174*7c478bd9Sstevel@tonic-gate /* format the time of next refresh */ 1175*7c478bd9Sstevel@tonic-gate if (*next != 0) { 1176*7c478bd9Sstevel@tonic-gate (void) localtime_r(next, &tm); 1177*7c478bd9Sstevel@tonic-gate (void) strftime(nbuf, sizeof (nbuf) - 1, TIME_FORMAT, &tm); 1178*7c478bd9Sstevel@tonic-gate } else { 1179*7c478bd9Sstevel@tonic-gate (void) strcpy(nbuf, gettext("NOT SET")); 1180*7c478bd9Sstevel@tonic-gate } 1181*7c478bd9Sstevel@tonic-gate 1182*7c478bd9Sstevel@tonic-gate len = hdr1_len + hdr2_len + strlen(nbuf) + 1183*7c478bd9Sstevel@tonic-gate strlen(pbuf) + 2 * strlen(DOORLINESEP) + 1; 1184*7c478bd9Sstevel@tonic-gate 1185*7c478bd9Sstevel@tonic-gate *output = malloc(len); 1186*7c478bd9Sstevel@tonic-gate if (*output == NULL) 1187*7c478bd9Sstevel@tonic-gate return (-1); 1188*7c478bd9Sstevel@tonic-gate 1189*7c478bd9Sstevel@tonic-gate (void) snprintf(*output, len, "%s%s%s%s%s%s", 1190*7c478bd9Sstevel@tonic-gate gettext(TIME_HEADER1), pbuf, DOORLINESEP, 1191*7c478bd9Sstevel@tonic-gate gettext(TIME_HEADER2), nbuf, DOORLINESEP); 1192*7c478bd9Sstevel@tonic-gate 1193*7c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 1194*7c478bd9Sstevel@tonic-gate } 1195*7c478bd9Sstevel@tonic-gate 1196*7c478bd9Sstevel@tonic-gate /* 1197*7c478bd9Sstevel@tonic-gate * getldap_get_server_stat processes the GETSTAT request passed 1198*7c478bd9Sstevel@tonic-gate * to this function from getldap_serverInfo_op(). 1199*7c478bd9Sstevel@tonic-gate * output: 1200*7c478bd9Sstevel@tonic-gate * a buffer containing info for all the servers. 1201*7c478bd9Sstevel@tonic-gate * For each server, the data is in the following format: 1202*7c478bd9Sstevel@tonic-gate * server: server address or name, status: unknown|up|down|removed DOORLINESEP 1203*7c478bd9Sstevel@tonic-gate * for example: ( here | used as DOORLINESEP for visual purposes) 1204*7c478bd9Sstevel@tonic-gate * server: 1.2.3.4, status: down|server: 2.2.2.2, status: up| 1205*7c478bd9Sstevel@tonic-gate * NOTE: caller should free this buffer when done using it 1206*7c478bd9Sstevel@tonic-gate */ 1207*7c478bd9Sstevel@tonic-gate static int 1208*7c478bd9Sstevel@tonic-gate getldap_get_server_stat(server_info_t *head, char **output, 1209*7c478bd9Sstevel@tonic-gate time_t *prev, time_t *next) 1210*7c478bd9Sstevel@tonic-gate { 1211*7c478bd9Sstevel@tonic-gate #define S_HEADER "Server information: " 1212*7c478bd9Sstevel@tonic-gate #define S_FORMAT " server: %s, status: %s%s" 1213*7c478bd9Sstevel@tonic-gate #define S_ERROR " error message: %s%s" 1214*7c478bd9Sstevel@tonic-gate server_info_t *info = NULL; 1215*7c478bd9Sstevel@tonic-gate int header_len = strlen(gettext(S_HEADER)); 1216*7c478bd9Sstevel@tonic-gate int format_len = strlen(gettext(S_FORMAT)); 1217*7c478bd9Sstevel@tonic-gate int error_len = strlen(gettext(S_ERROR)); 1218*7c478bd9Sstevel@tonic-gate int len = header_len + strlen(DOORLINESEP); 1219*7c478bd9Sstevel@tonic-gate int len1 = 0; 1220*7c478bd9Sstevel@tonic-gate char *status, *output1 = NULL, *tmpptr; 1221*7c478bd9Sstevel@tonic-gate 1222*7c478bd9Sstevel@tonic-gate *output = NULL; 1223*7c478bd9Sstevel@tonic-gate 1224*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 1225*7c478bd9Sstevel@tonic-gate logit("getldap_get_server_stat()...\n"); 1226*7c478bd9Sstevel@tonic-gate } 1227*7c478bd9Sstevel@tonic-gate 1228*7c478bd9Sstevel@tonic-gate if (head == NULL) { 1229*7c478bd9Sstevel@tonic-gate logit("getldap_get_server_stat: " 1230*7c478bd9Sstevel@tonic-gate "invalid serverInfo list.\n"); 1231*7c478bd9Sstevel@tonic-gate return (-1); 1232*7c478bd9Sstevel@tonic-gate } 1233*7c478bd9Sstevel@tonic-gate 1234*7c478bd9Sstevel@tonic-gate /* format previous and next refresh time */ 1235*7c478bd9Sstevel@tonic-gate (void) getldap_format_refresh_time(&output1, prev, next); 1236*7c478bd9Sstevel@tonic-gate if (output1 == NULL) 1237*7c478bd9Sstevel@tonic-gate return (-1); 1238*7c478bd9Sstevel@tonic-gate len += strlen(output1); 1239*7c478bd9Sstevel@tonic-gate len1 = len + strlen(DOORLINESEP) + 1; 1240*7c478bd9Sstevel@tonic-gate 1241*7c478bd9Sstevel@tonic-gate *output = (char *)calloc(1, len1); 1242*7c478bd9Sstevel@tonic-gate if (*output == NULL) { 1243*7c478bd9Sstevel@tonic-gate free(output1); 1244*7c478bd9Sstevel@tonic-gate return (-1); 1245*7c478bd9Sstevel@tonic-gate } 1246*7c478bd9Sstevel@tonic-gate 1247*7c478bd9Sstevel@tonic-gate /* insert header string and refresh time info */ 1248*7c478bd9Sstevel@tonic-gate (void) snprintf(*output, len1, "%s%s%s", 1249*7c478bd9Sstevel@tonic-gate gettext(S_HEADER), DOORLINESEP, output1); 1250*7c478bd9Sstevel@tonic-gate 1251*7c478bd9Sstevel@tonic-gate for (info = head; info; info = info->next) { 1252*7c478bd9Sstevel@tonic-gate 1253*7c478bd9Sstevel@tonic-gate /* 1254*7c478bd9Sstevel@tonic-gate * make sure the server info stays the same 1255*7c478bd9Sstevel@tonic-gate * while the data is being processed 1256*7c478bd9Sstevel@tonic-gate */ 1257*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info->mutex[1]); 1258*7c478bd9Sstevel@tonic-gate 1259*7c478bd9Sstevel@tonic-gate /* 1260*7c478bd9Sstevel@tonic-gate * When the updating process is under way(getldap_get_rootDSE) 1261*7c478bd9Sstevel@tonic-gate * the update copy(sinfo[1] is the latest copy. 1262*7c478bd9Sstevel@tonic-gate * When the updating process 1263*7c478bd9Sstevel@tonic-gate * is done, the current copy (sinfo[0]) has the latest status, 1264*7c478bd9Sstevel@tonic-gate * which is still identical to the update copy. 1265*7c478bd9Sstevel@tonic-gate * So update copy has the latest status. 1266*7c478bd9Sstevel@tonic-gate * Use the update copy(sinfo[1]) to show status 1267*7c478bd9Sstevel@tonic-gate * (ldap_cachemgr -g). 1268*7c478bd9Sstevel@tonic-gate * 1269*7c478bd9Sstevel@tonic-gate */ 1270*7c478bd9Sstevel@tonic-gate 1271*7c478bd9Sstevel@tonic-gate switch (info->sinfo[1].server_status) { 1272*7c478bd9Sstevel@tonic-gate case INFO_SERVER_UNKNOWN: 1273*7c478bd9Sstevel@tonic-gate status = gettext("UNKNOWN"); 1274*7c478bd9Sstevel@tonic-gate break; 1275*7c478bd9Sstevel@tonic-gate case INFO_SERVER_CONNECTING: 1276*7c478bd9Sstevel@tonic-gate status = gettext("CONNECTING"); 1277*7c478bd9Sstevel@tonic-gate break; 1278*7c478bd9Sstevel@tonic-gate case INFO_SERVER_UP: 1279*7c478bd9Sstevel@tonic-gate status = gettext("UP"); 1280*7c478bd9Sstevel@tonic-gate break; 1281*7c478bd9Sstevel@tonic-gate case INFO_SERVER_ERROR: 1282*7c478bd9Sstevel@tonic-gate status = gettext("ERROR"); 1283*7c478bd9Sstevel@tonic-gate break; 1284*7c478bd9Sstevel@tonic-gate case INFO_SERVER_REMOVED: 1285*7c478bd9Sstevel@tonic-gate status = gettext("REMOVED"); 1286*7c478bd9Sstevel@tonic-gate break; 1287*7c478bd9Sstevel@tonic-gate } 1288*7c478bd9Sstevel@tonic-gate 1289*7c478bd9Sstevel@tonic-gate len += format_len + strlen(status) + 1290*7c478bd9Sstevel@tonic-gate strlen(info->sinfo[1].addr) + 1291*7c478bd9Sstevel@tonic-gate strlen(DOORLINESEP); 1292*7c478bd9Sstevel@tonic-gate if (info->sinfo[1].errormsg != NULL) 1293*7c478bd9Sstevel@tonic-gate len += error_len + 1294*7c478bd9Sstevel@tonic-gate strlen(info->sinfo[1].errormsg) + 1295*7c478bd9Sstevel@tonic-gate strlen(DOORLINESEP); 1296*7c478bd9Sstevel@tonic-gate 1297*7c478bd9Sstevel@tonic-gate tmpptr = (char *)realloc(*output, len); 1298*7c478bd9Sstevel@tonic-gate if (tmpptr == NULL) { 1299*7c478bd9Sstevel@tonic-gate free(output1); 1300*7c478bd9Sstevel@tonic-gate free(*output); 1301*7c478bd9Sstevel@tonic-gate *output = NULL; 1302*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[1]); 1303*7c478bd9Sstevel@tonic-gate return (-1); 1304*7c478bd9Sstevel@tonic-gate } else 1305*7c478bd9Sstevel@tonic-gate *output = tmpptr; 1306*7c478bd9Sstevel@tonic-gate 1307*7c478bd9Sstevel@tonic-gate /* insert server IP addr or name and status */ 1308*7c478bd9Sstevel@tonic-gate len1 = len - strlen(*output); 1309*7c478bd9Sstevel@tonic-gate (void) snprintf(*output + strlen(*output), len1, 1310*7c478bd9Sstevel@tonic-gate gettext(S_FORMAT), info->sinfo[1].addr, 1311*7c478bd9Sstevel@tonic-gate status, DOORLINESEP); 1312*7c478bd9Sstevel@tonic-gate /* insert error message if any */ 1313*7c478bd9Sstevel@tonic-gate len1 = len - strlen(*output); 1314*7c478bd9Sstevel@tonic-gate if (info->sinfo[1].errormsg != NULL) 1315*7c478bd9Sstevel@tonic-gate (void) snprintf(*output + strlen(*output), len1, 1316*7c478bd9Sstevel@tonic-gate gettext(S_ERROR), 1317*7c478bd9Sstevel@tonic-gate info->sinfo[1].errormsg, 1318*7c478bd9Sstevel@tonic-gate DOORLINESEP); 1319*7c478bd9Sstevel@tonic-gate 1320*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[1]); 1321*7c478bd9Sstevel@tonic-gate 1322*7c478bd9Sstevel@tonic-gate } 1323*7c478bd9Sstevel@tonic-gate 1324*7c478bd9Sstevel@tonic-gate free(output1); 1325*7c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 1326*7c478bd9Sstevel@tonic-gate } 1327*7c478bd9Sstevel@tonic-gate 1328*7c478bd9Sstevel@tonic-gate /* 1329*7c478bd9Sstevel@tonic-gate * Format and return the refresh time statistics 1330*7c478bd9Sstevel@tonic-gate */ 1331*7c478bd9Sstevel@tonic-gate static int 1332*7c478bd9Sstevel@tonic-gate getldap_get_refresh_stat(char **output) 1333*7c478bd9Sstevel@tonic-gate { 1334*7c478bd9Sstevel@tonic-gate #define R_HEADER0 "Configuration refresh information: " 1335*7c478bd9Sstevel@tonic-gate #define R_HEADER1 " Configured to NO REFRESH." 1336*7c478bd9Sstevel@tonic-gate int hdr0_len = strlen(gettext(R_HEADER0)); 1337*7c478bd9Sstevel@tonic-gate int hdr1_len = strlen(gettext(R_HEADER1)); 1338*7c478bd9Sstevel@tonic-gate int cache_ttl = -1, len = 0; 1339*7c478bd9Sstevel@tonic-gate time_t expire = 0; 1340*7c478bd9Sstevel@tonic-gate void **paramVal = NULL; 1341*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *errorp = NULL; 1342*7c478bd9Sstevel@tonic-gate char *output1 = NULL; 1343*7c478bd9Sstevel@tonic-gate 1344*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 1345*7c478bd9Sstevel@tonic-gate logit("getldap_get_refresh_stat()...\n"); 1346*7c478bd9Sstevel@tonic-gate } 1347*7c478bd9Sstevel@tonic-gate 1348*7c478bd9Sstevel@tonic-gate *output = NULL; 1349*7c478bd9Sstevel@tonic-gate 1350*7c478bd9Sstevel@tonic-gate /* get configured cache TTL */ 1351*7c478bd9Sstevel@tonic-gate if ((__ns_ldap_getParam(NS_LDAP_CACHETTL_P, 1352*7c478bd9Sstevel@tonic-gate ¶mVal, &errorp) == NS_LDAP_SUCCESS) && 1353*7c478bd9Sstevel@tonic-gate paramVal != NULL && 1354*7c478bd9Sstevel@tonic-gate (char *)*paramVal != NULL) { 1355*7c478bd9Sstevel@tonic-gate cache_ttl = atol((char *)*paramVal); 1356*7c478bd9Sstevel@tonic-gate } else { 1357*7c478bd9Sstevel@tonic-gate if (errorp) 1358*7c478bd9Sstevel@tonic-gate __ns_ldap_freeError(&errorp); 1359*7c478bd9Sstevel@tonic-gate } 1360*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶mVal); 1361*7c478bd9Sstevel@tonic-gate 1362*7c478bd9Sstevel@tonic-gate /* cound not get cache TTL */ 1363*7c478bd9Sstevel@tonic-gate if (cache_ttl == -1) 1364*7c478bd9Sstevel@tonic-gate return (-1); 1365*7c478bd9Sstevel@tonic-gate 1366*7c478bd9Sstevel@tonic-gate if (cache_ttl == 0) { 1367*7c478bd9Sstevel@tonic-gate len = hdr0_len + hdr1_len + 1368*7c478bd9Sstevel@tonic-gate 2 * strlen(DOORLINESEP) + 1; 1369*7c478bd9Sstevel@tonic-gate *output = malloc(len); 1370*7c478bd9Sstevel@tonic-gate if (*output == NULL) 1371*7c478bd9Sstevel@tonic-gate return (-1); 1372*7c478bd9Sstevel@tonic-gate (void) snprintf(*output, len, "%s%s%s%s", 1373*7c478bd9Sstevel@tonic-gate gettext(R_HEADER0), DOORLINESEP, 1374*7c478bd9Sstevel@tonic-gate gettext(R_HEADER1), DOORLINESEP); 1375*7c478bd9Sstevel@tonic-gate } else { 1376*7c478bd9Sstevel@tonic-gate 1377*7c478bd9Sstevel@tonic-gate /* get configuration expiration time */ 1378*7c478bd9Sstevel@tonic-gate if ((__ns_ldap_getParam(NS_LDAP_EXP_P, 1379*7c478bd9Sstevel@tonic-gate ¶mVal, &errorp) == NS_LDAP_SUCCESS) && 1380*7c478bd9Sstevel@tonic-gate paramVal != NULL && 1381*7c478bd9Sstevel@tonic-gate (char *)*paramVal != NULL) { 1382*7c478bd9Sstevel@tonic-gate expire = (time_t)atol((char *)*paramVal); 1383*7c478bd9Sstevel@tonic-gate } else { 1384*7c478bd9Sstevel@tonic-gate if (errorp) 1385*7c478bd9Sstevel@tonic-gate __ns_ldap_freeError(&errorp); 1386*7c478bd9Sstevel@tonic-gate } 1387*7c478bd9Sstevel@tonic-gate 1388*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶mVal); 1389*7c478bd9Sstevel@tonic-gate 1390*7c478bd9Sstevel@tonic-gate /* cound not get expiration time */ 1391*7c478bd9Sstevel@tonic-gate if (expire == -1) 1392*7c478bd9Sstevel@tonic-gate return (-1); 1393*7c478bd9Sstevel@tonic-gate 1394*7c478bd9Sstevel@tonic-gate /* format previous and next refresh time */ 1395*7c478bd9Sstevel@tonic-gate (void) getldap_format_refresh_time(&output1, 1396*7c478bd9Sstevel@tonic-gate &prev_refresh_time, &expire); 1397*7c478bd9Sstevel@tonic-gate if (output1 == NULL) 1398*7c478bd9Sstevel@tonic-gate return (-1); 1399*7c478bd9Sstevel@tonic-gate 1400*7c478bd9Sstevel@tonic-gate len = hdr0_len + strlen(output1) + 1401*7c478bd9Sstevel@tonic-gate 2 * strlen(DOORLINESEP) + 1; 1402*7c478bd9Sstevel@tonic-gate *output = malloc(len); 1403*7c478bd9Sstevel@tonic-gate if (*output == NULL) { 1404*7c478bd9Sstevel@tonic-gate free(output1); 1405*7c478bd9Sstevel@tonic-gate return (-1); 1406*7c478bd9Sstevel@tonic-gate } 1407*7c478bd9Sstevel@tonic-gate (void) snprintf(*output, len, "%s%s%s%s", 1408*7c478bd9Sstevel@tonic-gate gettext(R_HEADER0), DOORLINESEP, 1409*7c478bd9Sstevel@tonic-gate output1, DOORLINESEP); 1410*7c478bd9Sstevel@tonic-gate free(output1); 1411*7c478bd9Sstevel@tonic-gate } 1412*7c478bd9Sstevel@tonic-gate 1413*7c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 1414*7c478bd9Sstevel@tonic-gate } 1415*7c478bd9Sstevel@tonic-gate 1416*7c478bd9Sstevel@tonic-gate static int 1417*7c478bd9Sstevel@tonic-gate getldap_get_cacheTTL() 1418*7c478bd9Sstevel@tonic-gate { 1419*7c478bd9Sstevel@tonic-gate void **paramVal = NULL; 1420*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *error; 1421*7c478bd9Sstevel@tonic-gate int rc = 0, cachettl; 1422*7c478bd9Sstevel@tonic-gate 1423*7c478bd9Sstevel@tonic-gate 1424*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 1425*7c478bd9Sstevel@tonic-gate logit("getldap_get_cacheTTL()....\n"); 1426*7c478bd9Sstevel@tonic-gate } 1427*7c478bd9Sstevel@tonic-gate 1428*7c478bd9Sstevel@tonic-gate if ((rc = __ns_ldap_getParam(NS_LDAP_CACHETTL_P, 1429*7c478bd9Sstevel@tonic-gate ¶mVal, &error)) != NS_LDAP_SUCCESS) { 1430*7c478bd9Sstevel@tonic-gate if (error != NULL && error->message != NULL) 1431*7c478bd9Sstevel@tonic-gate logit("Error: Unable to get configuration " 1432*7c478bd9Sstevel@tonic-gate "refresh TTL: %s\n", 1433*7c478bd9Sstevel@tonic-gate error->message); 1434*7c478bd9Sstevel@tonic-gate else { 1435*7c478bd9Sstevel@tonic-gate char *tmp; 1436*7c478bd9Sstevel@tonic-gate 1437*7c478bd9Sstevel@tonic-gate __ns_ldap_err2str(rc, &tmp); 1438*7c478bd9Sstevel@tonic-gate logit("Error: Unable to get configuration " 1439*7c478bd9Sstevel@tonic-gate "refresh TTL: %s\n", tmp); 1440*7c478bd9Sstevel@tonic-gate } 1441*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶mVal); 1442*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 1443*7c478bd9Sstevel@tonic-gate return (-1); 1444*7c478bd9Sstevel@tonic-gate } 1445*7c478bd9Sstevel@tonic-gate if (paramVal == NULL || (char *)*paramVal == NULL) 1446*7c478bd9Sstevel@tonic-gate return (-1); 1447*7c478bd9Sstevel@tonic-gate cachettl = atol((char *)*paramVal); 1448*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶mVal); 1449*7c478bd9Sstevel@tonic-gate return (cachettl); 1450*7c478bd9Sstevel@tonic-gate } 1451*7c478bd9Sstevel@tonic-gate 1452*7c478bd9Sstevel@tonic-gate 1453*7c478bd9Sstevel@tonic-gate /* 1454*7c478bd9Sstevel@tonic-gate * This function implements the adaptive server list refresh 1455*7c478bd9Sstevel@tonic-gate * algorithm used by ldap_cachemgr. The idea is to have the 1456*7c478bd9Sstevel@tonic-gate * refresh TTL adjust itself between maximum and minimum 1457*7c478bd9Sstevel@tonic-gate * values. If the server list has been walked three times 1458*7c478bd9Sstevel@tonic-gate * in a row without errors, the TTL will be doubled. This will 1459*7c478bd9Sstevel@tonic-gate * be done repeatedly until the maximum value is reached 1460*7c478bd9Sstevel@tonic-gate * or passed. If passed, the maximum value will be used. 1461*7c478bd9Sstevel@tonic-gate * If any time a server is found to be down/bad, either 1462*7c478bd9Sstevel@tonic-gate * after another server list walk or informed by libsldap via 1463*7c478bd9Sstevel@tonic-gate * the GETLDAPSERVER door calls, the TTL will be set to half 1464*7c478bd9Sstevel@tonic-gate * of its value, again repeatedly, but no less than the minimum 1465*7c478bd9Sstevel@tonic-gate * value. Also, at any time, if all the servers on the list 1466*7c478bd9Sstevel@tonic-gate * are found to be down/bad, the TTL will be set to minimum, 1467*7c478bd9Sstevel@tonic-gate * so that a "no-server" refresh loop should be entered to try 1468*7c478bd9Sstevel@tonic-gate * to find a good server as soon as possible. The caller 1469*7c478bd9Sstevel@tonic-gate * could check the no_gd_server flag for this situation. 1470*7c478bd9Sstevel@tonic-gate * The maximum and minimum values are initialized when the input 1471*7c478bd9Sstevel@tonic-gate * refresh_ttl is set to zero, this should occur during 1472*7c478bd9Sstevel@tonic-gate * ldap_cachemgr startup or every time the server list is 1473*7c478bd9Sstevel@tonic-gate * recreated after the configuration profile is refreshed 1474*7c478bd9Sstevel@tonic-gate * from an LDAP server. The maximum is set to the value of 1475*7c478bd9Sstevel@tonic-gate * the NS_LDAP_CACHETTL parameter (configuration profile 1476*7c478bd9Sstevel@tonic-gate * refresh TTL), but if it is zero (never refreshed) or can 1477*7c478bd9Sstevel@tonic-gate * not be retrieved, the maximum is set to the macro 1478*7c478bd9Sstevel@tonic-gate * REFRESHTTL_MAX (12 hours) defined below. The minimum is 1479*7c478bd9Sstevel@tonic-gate * set to REFRESHTTL_MIN, which is the TCP connection timeout 1480*7c478bd9Sstevel@tonic-gate * (tcptimeout) set via the LDAP API ldap_set_option() 1481*7c478bd9Sstevel@tonic-gate * with the new LDAP_X_OPT_CONNECT_TIMEOUT option plus 10 seconds. 1482*7c478bd9Sstevel@tonic-gate * This accounts for the maximum possible timeout value for an 1483*7c478bd9Sstevel@tonic-gate * LDAP TCP connect call.The first refresh TTL, initial value of 1484*7c478bd9Sstevel@tonic-gate * refresh_ttl, will be set to the smaller of the two, 1485*7c478bd9Sstevel@tonic-gate * REFRESHTTL_REGULAR (10 minutes) or (REFRESHTTL_MAX + REFRESHTTL_MIN)/2. 1486*7c478bd9Sstevel@tonic-gate * The idea is to have a low starting value and have the value 1487*7c478bd9Sstevel@tonic-gate * stay low if the network/server is unstable, but eventually 1488*7c478bd9Sstevel@tonic-gate * the value will move up to maximum and stay there if the 1489*7c478bd9Sstevel@tonic-gate * network/server is stable. 1490*7c478bd9Sstevel@tonic-gate */ 1491*7c478bd9Sstevel@tonic-gate static int 1492*7c478bd9Sstevel@tonic-gate getldap_set_refresh_ttl(server_info_t *head, int *refresh_ttl, 1493*7c478bd9Sstevel@tonic-gate int *no_gd_server) 1494*7c478bd9Sstevel@tonic-gate { 1495*7c478bd9Sstevel@tonic-gate #define REFRESHTTL_REGULAR 600 1496*7c478bd9Sstevel@tonic-gate #define REFRESHTTL_MAX 43200 1497*7c478bd9Sstevel@tonic-gate /* tcptimeout is in milliseconds */ 1498*7c478bd9Sstevel@tonic-gate #define REFRESHTTL_MIN (tcptimeout/1000) + 10 1499*7c478bd9Sstevel@tonic-gate #define UP_REFRESH_TTL_NUM 2 1500*7c478bd9Sstevel@tonic-gate 1501*7c478bd9Sstevel@tonic-gate static mutex_t refresh_mutex; 1502*7c478bd9Sstevel@tonic-gate static int refresh_ttl_max = 0; 1503*7c478bd9Sstevel@tonic-gate static int refresh_ttl_min = 0; 1504*7c478bd9Sstevel@tonic-gate static int num_walked_ok = 0; 1505*7c478bd9Sstevel@tonic-gate int num_servers = 0; 1506*7c478bd9Sstevel@tonic-gate int num_good_servers = 0; 1507*7c478bd9Sstevel@tonic-gate int num_prev_good_servers = 0; 1508*7c478bd9Sstevel@tonic-gate server_info_t *info; 1509*7c478bd9Sstevel@tonic-gate 1510*7c478bd9Sstevel@tonic-gate /* allow one thread at a time */ 1511*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&refresh_mutex); 1512*7c478bd9Sstevel@tonic-gate 1513*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 1514*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl()...\n"); 1515*7c478bd9Sstevel@tonic-gate } 1516*7c478bd9Sstevel@tonic-gate 1517*7c478bd9Sstevel@tonic-gate if (!head || !refresh_ttl || !no_gd_server) { 1518*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl: head is " 1519*7c478bd9Sstevel@tonic-gate "NULL or refresh_ttl is NULL or " 1520*7c478bd9Sstevel@tonic-gate "no_gd_server is NULL"); 1521*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&refresh_mutex); 1522*7c478bd9Sstevel@tonic-gate return (-1); 1523*7c478bd9Sstevel@tonic-gate } 1524*7c478bd9Sstevel@tonic-gate *no_gd_server = FALSE; 1525*7c478bd9Sstevel@tonic-gate 1526*7c478bd9Sstevel@tonic-gate /* 1527*7c478bd9Sstevel@tonic-gate * init max. min. TTLs if first time through or a fresh one 1528*7c478bd9Sstevel@tonic-gate */ 1529*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_SERVER_LIST_REFRESH) { 1530*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl:(1) refresh ttl is %d " 1531*7c478bd9Sstevel@tonic-gate "seconds\n", *refresh_ttl); 1532*7c478bd9Sstevel@tonic-gate } 1533*7c478bd9Sstevel@tonic-gate if (*refresh_ttl == 0) { 1534*7c478bd9Sstevel@tonic-gate num_walked_ok = 0; 1535*7c478bd9Sstevel@tonic-gate /* 1536*7c478bd9Sstevel@tonic-gate * init cache manager server list TTL: 1537*7c478bd9Sstevel@tonic-gate * 1538*7c478bd9Sstevel@tonic-gate * init the min. TTL to 1539*7c478bd9Sstevel@tonic-gate * REFRESHTTL_MIN ( 2*(TCP MSL) + 10 seconds) 1540*7c478bd9Sstevel@tonic-gate */ 1541*7c478bd9Sstevel@tonic-gate refresh_ttl_min = REFRESHTTL_MIN; 1542*7c478bd9Sstevel@tonic-gate 1543*7c478bd9Sstevel@tonic-gate /* 1544*7c478bd9Sstevel@tonic-gate * try to set the max. TTL to 1545*7c478bd9Sstevel@tonic-gate * configuration refresh TTL (NS_LDAP_CACHETTL), 1546*7c478bd9Sstevel@tonic-gate * if error (-1), or never refreshed (0), 1547*7c478bd9Sstevel@tonic-gate * set it to REFRESHTTL_MAX (12 hours) 1548*7c478bd9Sstevel@tonic-gate */ 1549*7c478bd9Sstevel@tonic-gate refresh_ttl_max = getldap_get_cacheTTL(); 1550*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_SERVER_LIST_REFRESH) { 1551*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl:(2) refresh ttl is %d " 1552*7c478bd9Sstevel@tonic-gate "seconds\n", *refresh_ttl); 1553*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl:(2) max ttl is %d, " 1554*7c478bd9Sstevel@tonic-gate "min ttl is %d seconds\n", 1555*7c478bd9Sstevel@tonic-gate refresh_ttl_max, refresh_ttl_min); 1556*7c478bd9Sstevel@tonic-gate } 1557*7c478bd9Sstevel@tonic-gate if (refresh_ttl_max <= 0) 1558*7c478bd9Sstevel@tonic-gate refresh_ttl_max = REFRESHTTL_MAX; 1559*7c478bd9Sstevel@tonic-gate else if (refresh_ttl_max < refresh_ttl_min) 1560*7c478bd9Sstevel@tonic-gate refresh_ttl_max = refresh_ttl_min; 1561*7c478bd9Sstevel@tonic-gate 1562*7c478bd9Sstevel@tonic-gate /* 1563*7c478bd9Sstevel@tonic-gate * init the first TTL to the smaller of the two: 1564*7c478bd9Sstevel@tonic-gate * REFRESHTTL_REGULAR ( 10 minutes), 1565*7c478bd9Sstevel@tonic-gate * (refresh_ttl_max + refresh_ttl_min)/2 1566*7c478bd9Sstevel@tonic-gate */ 1567*7c478bd9Sstevel@tonic-gate *refresh_ttl = REFRESHTTL_REGULAR; 1568*7c478bd9Sstevel@tonic-gate if (*refresh_ttl > (refresh_ttl_max + refresh_ttl_min) / 2) 1569*7c478bd9Sstevel@tonic-gate *refresh_ttl = (refresh_ttl_max + refresh_ttl_min) / 2; 1570*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_SERVER_LIST_REFRESH) { 1571*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl:(3) refresh ttl is %d " 1572*7c478bd9Sstevel@tonic-gate "seconds\n", *refresh_ttl); 1573*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl:(3) max ttl is %d, " 1574*7c478bd9Sstevel@tonic-gate "min ttl is %d seconds\n", 1575*7c478bd9Sstevel@tonic-gate refresh_ttl_max, refresh_ttl_min); 1576*7c478bd9Sstevel@tonic-gate } 1577*7c478bd9Sstevel@tonic-gate } 1578*7c478bd9Sstevel@tonic-gate 1579*7c478bd9Sstevel@tonic-gate /* 1580*7c478bd9Sstevel@tonic-gate * get the servers statistics: 1581*7c478bd9Sstevel@tonic-gate * number of servers on list 1582*7c478bd9Sstevel@tonic-gate * number of good servers on list 1583*7c478bd9Sstevel@tonic-gate * number of pevious good servers on list 1584*7c478bd9Sstevel@tonic-gate */ 1585*7c478bd9Sstevel@tonic-gate for (info = head; info; info = info->next) { 1586*7c478bd9Sstevel@tonic-gate num_servers++; 1587*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info->mutex[0]); 1588*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].server_status == INFO_SERVER_UP) 1589*7c478bd9Sstevel@tonic-gate num_good_servers++; 1590*7c478bd9Sstevel@tonic-gate /* 1591*7c478bd9Sstevel@tonic-gate * Server's previous status could be UNKNOWN 1592*7c478bd9Sstevel@tonic-gate * only between the very first and second 1593*7c478bd9Sstevel@tonic-gate * refresh. Treat that UNKNOWN status as up 1594*7c478bd9Sstevel@tonic-gate */ 1595*7c478bd9Sstevel@tonic-gate if (info->sinfo[0].prev_server_status 1596*7c478bd9Sstevel@tonic-gate == INFO_SERVER_UP || 1597*7c478bd9Sstevel@tonic-gate info->sinfo[0].prev_server_status 1598*7c478bd9Sstevel@tonic-gate == INFO_SERVER_UNKNOWN) 1599*7c478bd9Sstevel@tonic-gate num_prev_good_servers++; 1600*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info->mutex[0]); 1601*7c478bd9Sstevel@tonic-gate } 1602*7c478bd9Sstevel@tonic-gate 1603*7c478bd9Sstevel@tonic-gate /* 1604*7c478bd9Sstevel@tonic-gate * if the server list is walked three times in a row 1605*7c478bd9Sstevel@tonic-gate * without problems, double the refresh TTL but no more 1606*7c478bd9Sstevel@tonic-gate * than the max. refresh TTL 1607*7c478bd9Sstevel@tonic-gate */ 1608*7c478bd9Sstevel@tonic-gate if (num_good_servers == num_servers) { 1609*7c478bd9Sstevel@tonic-gate num_walked_ok++; 1610*7c478bd9Sstevel@tonic-gate if (num_walked_ok > UP_REFRESH_TTL_NUM) { 1611*7c478bd9Sstevel@tonic-gate 1612*7c478bd9Sstevel@tonic-gate *refresh_ttl = *refresh_ttl * 2; 1613*7c478bd9Sstevel@tonic-gate if (*refresh_ttl > refresh_ttl_max) 1614*7c478bd9Sstevel@tonic-gate *refresh_ttl = refresh_ttl_max; 1615*7c478bd9Sstevel@tonic-gate 1616*7c478bd9Sstevel@tonic-gate num_walked_ok = 0; 1617*7c478bd9Sstevel@tonic-gate } 1618*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_SERVER_LIST_REFRESH) { 1619*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl:(4) refresh ttl is %d " 1620*7c478bd9Sstevel@tonic-gate "seconds\n", *refresh_ttl); 1621*7c478bd9Sstevel@tonic-gate } 1622*7c478bd9Sstevel@tonic-gate } else if (num_good_servers == 0) { 1623*7c478bd9Sstevel@tonic-gate /* 1624*7c478bd9Sstevel@tonic-gate * if no good server found, 1625*7c478bd9Sstevel@tonic-gate * set refresh TTL to miminum 1626*7c478bd9Sstevel@tonic-gate */ 1627*7c478bd9Sstevel@tonic-gate *refresh_ttl = refresh_ttl_min; 1628*7c478bd9Sstevel@tonic-gate *no_gd_server = TRUE; 1629*7c478bd9Sstevel@tonic-gate num_walked_ok = 0; 1630*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_SERVER_LIST_REFRESH) { 1631*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl:(5) refresh ttl is %d " 1632*7c478bd9Sstevel@tonic-gate "seconds\n", *refresh_ttl); 1633*7c478bd9Sstevel@tonic-gate } 1634*7c478bd9Sstevel@tonic-gate } else if (num_prev_good_servers > num_good_servers) { 1635*7c478bd9Sstevel@tonic-gate /* 1636*7c478bd9Sstevel@tonic-gate * if more down/bad servers found, 1637*7c478bd9Sstevel@tonic-gate * decrease the refresh TTL by half 1638*7c478bd9Sstevel@tonic-gate * but no less than the min. refresh TTL 1639*7c478bd9Sstevel@tonic-gate */ 1640*7c478bd9Sstevel@tonic-gate *refresh_ttl = *refresh_ttl / 2; 1641*7c478bd9Sstevel@tonic-gate if (*refresh_ttl < refresh_ttl_min) 1642*7c478bd9Sstevel@tonic-gate *refresh_ttl = refresh_ttl_min; 1643*7c478bd9Sstevel@tonic-gate num_walked_ok = 0; 1644*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl:(6) refresh ttl is %d " 1645*7c478bd9Sstevel@tonic-gate "seconds\n", *refresh_ttl); 1646*7c478bd9Sstevel@tonic-gate 1647*7c478bd9Sstevel@tonic-gate } 1648*7c478bd9Sstevel@tonic-gate 1649*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_SERVER_LIST_REFRESH) { 1650*7c478bd9Sstevel@tonic-gate logit("getldap_set_refresh_ttl:(7) refresh ttl is %d seconds\n", 1651*7c478bd9Sstevel@tonic-gate *refresh_ttl); 1652*7c478bd9Sstevel@tonic-gate } 1653*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&refresh_mutex); 1654*7c478bd9Sstevel@tonic-gate return (0); 1655*7c478bd9Sstevel@tonic-gate } 1656*7c478bd9Sstevel@tonic-gate 1657*7c478bd9Sstevel@tonic-gate static int 1658*7c478bd9Sstevel@tonic-gate getldap_serverInfo_op(info_op_t op, char *input, char **output) 1659*7c478bd9Sstevel@tonic-gate { 1660*7c478bd9Sstevel@tonic-gate 1661*7c478bd9Sstevel@tonic-gate static rwlock_t info_lock = DEFAULTRWLOCK; 1662*7c478bd9Sstevel@tonic-gate static rwlock_t info_lock_old = DEFAULTRWLOCK; 1663*7c478bd9Sstevel@tonic-gate static mutex_t info_mutex; 1664*7c478bd9Sstevel@tonic-gate static cond_t info_cond; 1665*7c478bd9Sstevel@tonic-gate static int creating = FALSE; 1666*7c478bd9Sstevel@tonic-gate static int refresh_ttl = 0; 1667*7c478bd9Sstevel@tonic-gate static int sec_to_refresh = 0; 1668*7c478bd9Sstevel@tonic-gate static int in_no_server_mode = FALSE; 1669*7c478bd9Sstevel@tonic-gate 1670*7c478bd9Sstevel@tonic-gate static server_info_t *serverInfo = NULL; 1671*7c478bd9Sstevel@tonic-gate static server_info_t *serverInfo_old = NULL; 1672*7c478bd9Sstevel@tonic-gate server_info_t *serverInfo_1; 1673*7c478bd9Sstevel@tonic-gate int is_creating; 1674*7c478bd9Sstevel@tonic-gate int err, no_server_good = FALSE; 1675*7c478bd9Sstevel@tonic-gate int server_removed = FALSE; 1676*7c478bd9Sstevel@tonic-gate static struct timespec timeout; 1677*7c478bd9Sstevel@tonic-gate struct timespec new_timeout; 1678*7c478bd9Sstevel@tonic-gate struct timeval tp; 1679*7c478bd9Sstevel@tonic-gate static time_t prev_refresh = 0, next_refresh = 0; 1680*7c478bd9Sstevel@tonic-gate 1681*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 1682*7c478bd9Sstevel@tonic-gate logit("getldap_serverInfo_op()...\n"); 1683*7c478bd9Sstevel@tonic-gate } 1684*7c478bd9Sstevel@tonic-gate switch (op) { 1685*7c478bd9Sstevel@tonic-gate case INFO_OP_CREATE: 1686*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 1687*7c478bd9Sstevel@tonic-gate logit("operation is INFO_OP_CREATE...\n"); 1688*7c478bd9Sstevel@tonic-gate } 1689*7c478bd9Sstevel@tonic-gate 1690*7c478bd9Sstevel@tonic-gate /* 1691*7c478bd9Sstevel@tonic-gate * indicate that the server info is being 1692*7c478bd9Sstevel@tonic-gate * (re)created, so that the refresh thread 1693*7c478bd9Sstevel@tonic-gate * will not refresh the info list right 1694*7c478bd9Sstevel@tonic-gate * after the list got (re)created 1695*7c478bd9Sstevel@tonic-gate */ 1696*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info_mutex); 1697*7c478bd9Sstevel@tonic-gate is_creating = creating; 1698*7c478bd9Sstevel@tonic-gate creating = TRUE; 1699*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info_mutex); 1700*7c478bd9Sstevel@tonic-gate 1701*7c478bd9Sstevel@tonic-gate if (is_creating) 1702*7c478bd9Sstevel@tonic-gate break; 1703*7c478bd9Sstevel@tonic-gate /* 1704*7c478bd9Sstevel@tonic-gate * create an empty info list 1705*7c478bd9Sstevel@tonic-gate */ 1706*7c478bd9Sstevel@tonic-gate (void) getldap_init_serverInfo(&serverInfo_1); 1707*7c478bd9Sstevel@tonic-gate /* 1708*7c478bd9Sstevel@tonic-gate * exit if list not created 1709*7c478bd9Sstevel@tonic-gate */ 1710*7c478bd9Sstevel@tonic-gate if (serverInfo_1 == NULL) { 1711*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info_mutex); 1712*7c478bd9Sstevel@tonic-gate creating = FALSE; 1713*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info_mutex); 1714*7c478bd9Sstevel@tonic-gate break; 1715*7c478bd9Sstevel@tonic-gate } 1716*7c478bd9Sstevel@tonic-gate /* 1717*7c478bd9Sstevel@tonic-gate * make the new server info available: 1718*7c478bd9Sstevel@tonic-gate * use writer lock here, so that the switch 1719*7c478bd9Sstevel@tonic-gate * is done after all the reader locks have 1720*7c478bd9Sstevel@tonic-gate * been released. 1721*7c478bd9Sstevel@tonic-gate */ 1722*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&info_lock); 1723*7c478bd9Sstevel@tonic-gate serverInfo = serverInfo_1; 1724*7c478bd9Sstevel@tonic-gate /* 1725*7c478bd9Sstevel@tonic-gate * if this is the first time 1726*7c478bd9Sstevel@tonic-gate * the server list is being created, 1727*7c478bd9Sstevel@tonic-gate * (i.e., serverInfo_old is NULL) 1728*7c478bd9Sstevel@tonic-gate * make the old list same as the new 1729*7c478bd9Sstevel@tonic-gate * so the GETSERVER code can do its work 1730*7c478bd9Sstevel@tonic-gate */ 1731*7c478bd9Sstevel@tonic-gate if (serverInfo_old == NULL) 1732*7c478bd9Sstevel@tonic-gate serverInfo_old = serverInfo_1; 1733*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&info_lock); 1734*7c478bd9Sstevel@tonic-gate 1735*7c478bd9Sstevel@tonic-gate /* 1736*7c478bd9Sstevel@tonic-gate * fill the new info list 1737*7c478bd9Sstevel@tonic-gate */ 1738*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&info_lock); 1739*7c478bd9Sstevel@tonic-gate /* reset bind time (tcptimeout) */ 1740*7c478bd9Sstevel@tonic-gate (void) getldap_set_serverInfo(serverInfo, 1); 1741*7c478bd9Sstevel@tonic-gate 1742*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info_mutex); 1743*7c478bd9Sstevel@tonic-gate /* 1744*7c478bd9Sstevel@tonic-gate * set cache manager server list TTL, 1745*7c478bd9Sstevel@tonic-gate * set refresh_ttl to zero to indicate a fresh one 1746*7c478bd9Sstevel@tonic-gate */ 1747*7c478bd9Sstevel@tonic-gate refresh_ttl = 0; 1748*7c478bd9Sstevel@tonic-gate (void) getldap_set_refresh_ttl(serverInfo, 1749*7c478bd9Sstevel@tonic-gate &refresh_ttl, &no_server_good); 1750*7c478bd9Sstevel@tonic-gate sec_to_refresh = refresh_ttl; 1751*7c478bd9Sstevel@tonic-gate 1752*7c478bd9Sstevel@tonic-gate /* statistics: previous refresh time */ 1753*7c478bd9Sstevel@tonic-gate if (gettimeofday(&tp, NULL) == 0) 1754*7c478bd9Sstevel@tonic-gate prev_refresh = tp.tv_sec; 1755*7c478bd9Sstevel@tonic-gate 1756*7c478bd9Sstevel@tonic-gate creating = FALSE; 1757*7c478bd9Sstevel@tonic-gate 1758*7c478bd9Sstevel@tonic-gate /* 1759*7c478bd9Sstevel@tonic-gate * if no server found or available, 1760*7c478bd9Sstevel@tonic-gate * tell the server info refresh thread 1761*7c478bd9Sstevel@tonic-gate * to start the "no-server" refresh loop 1762*7c478bd9Sstevel@tonic-gate * otherwise reset the in_no_server_mode flag 1763*7c478bd9Sstevel@tonic-gate */ 1764*7c478bd9Sstevel@tonic-gate if (no_server_good) { 1765*7c478bd9Sstevel@tonic-gate sec_to_refresh = 0; 1766*7c478bd9Sstevel@tonic-gate in_no_server_mode = TRUE; 1767*7c478bd9Sstevel@tonic-gate } else 1768*7c478bd9Sstevel@tonic-gate in_no_server_mode = FALSE; 1769*7c478bd9Sstevel@tonic-gate /* 1770*7c478bd9Sstevel@tonic-gate * awake the sleeping refresh thread 1771*7c478bd9Sstevel@tonic-gate */ 1772*7c478bd9Sstevel@tonic-gate (void) cond_signal(&info_cond); 1773*7c478bd9Sstevel@tonic-gate 1774*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info_mutex); 1775*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&info_lock); 1776*7c478bd9Sstevel@tonic-gate 1777*7c478bd9Sstevel@tonic-gate /* 1778*7c478bd9Sstevel@tonic-gate * delete the old server info 1779*7c478bd9Sstevel@tonic-gate */ 1780*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&info_lock_old); 1781*7c478bd9Sstevel@tonic-gate if (serverInfo_old != serverInfo) 1782*7c478bd9Sstevel@tonic-gate (void) getldap_destroy_serverInfo(serverInfo_old); 1783*7c478bd9Sstevel@tonic-gate /* 1784*7c478bd9Sstevel@tonic-gate * serverInfo_old needs to be the same as 1785*7c478bd9Sstevel@tonic-gate * serverinfo now. 1786*7c478bd9Sstevel@tonic-gate * it will be used by GETSERVER processing. 1787*7c478bd9Sstevel@tonic-gate */ 1788*7c478bd9Sstevel@tonic-gate serverInfo_old = serverInfo; 1789*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&info_lock_old); 1790*7c478bd9Sstevel@tonic-gate break; 1791*7c478bd9Sstevel@tonic-gate case INFO_OP_DELETE: 1792*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 1793*7c478bd9Sstevel@tonic-gate logit("operation is INFO_OP_DELETE...\n"); 1794*7c478bd9Sstevel@tonic-gate } 1795*7c478bd9Sstevel@tonic-gate /* 1796*7c478bd9Sstevel@tonic-gate * use writer lock here, so that the delete would 1797*7c478bd9Sstevel@tonic-gate * not start until all the reader locks have 1798*7c478bd9Sstevel@tonic-gate * been released. 1799*7c478bd9Sstevel@tonic-gate */ 1800*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&info_lock); 1801*7c478bd9Sstevel@tonic-gate if (serverInfo) 1802*7c478bd9Sstevel@tonic-gate (void) getldap_destroy_serverInfo(serverInfo); 1803*7c478bd9Sstevel@tonic-gate serverInfo = NULL; 1804*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&info_lock); 1805*7c478bd9Sstevel@tonic-gate break; 1806*7c478bd9Sstevel@tonic-gate case INFO_OP_REFRESH: 1807*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_SERVER_LIST_REFRESH) { 1808*7c478bd9Sstevel@tonic-gate logit("operation is INFO_OP_REFRESH...\n"); 1809*7c478bd9Sstevel@tonic-gate } 1810*7c478bd9Sstevel@tonic-gate /* 1811*7c478bd9Sstevel@tonic-gate * if server info is currently being 1812*7c478bd9Sstevel@tonic-gate * (re)created, do nothing 1813*7c478bd9Sstevel@tonic-gate */ 1814*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info_mutex); 1815*7c478bd9Sstevel@tonic-gate is_creating = creating; 1816*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info_mutex); 1817*7c478bd9Sstevel@tonic-gate if (is_creating) 1818*7c478bd9Sstevel@tonic-gate break; 1819*7c478bd9Sstevel@tonic-gate 1820*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&info_lock); 1821*7c478bd9Sstevel@tonic-gate if (serverInfo) { 1822*7c478bd9Sstevel@tonic-gate /* do not reset bind time (tcptimeout) */ 1823*7c478bd9Sstevel@tonic-gate (void) getldap_set_serverInfo(serverInfo, 0); 1824*7c478bd9Sstevel@tonic-gate 1825*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info_mutex); 1826*7c478bd9Sstevel@tonic-gate 1827*7c478bd9Sstevel@tonic-gate /* statistics: previous refresh time */ 1828*7c478bd9Sstevel@tonic-gate if (gettimeofday(&tp, NULL) == 0) 1829*7c478bd9Sstevel@tonic-gate prev_refresh = tp.tv_sec; 1830*7c478bd9Sstevel@tonic-gate /* 1831*7c478bd9Sstevel@tonic-gate * set cache manager server list TTL 1832*7c478bd9Sstevel@tonic-gate */ 1833*7c478bd9Sstevel@tonic-gate (void) getldap_set_refresh_ttl(serverInfo, 1834*7c478bd9Sstevel@tonic-gate &refresh_ttl, &no_server_good); 1835*7c478bd9Sstevel@tonic-gate /* 1836*7c478bd9Sstevel@tonic-gate * if no good server found, 1837*7c478bd9Sstevel@tonic-gate * tell the server info refresh thread 1838*7c478bd9Sstevel@tonic-gate * to start the "no-server" refresh loop 1839*7c478bd9Sstevel@tonic-gate * otherwise reset the in_no_server_mode flag 1840*7c478bd9Sstevel@tonic-gate */ 1841*7c478bd9Sstevel@tonic-gate if (no_server_good) { 1842*7c478bd9Sstevel@tonic-gate in_no_server_mode = TRUE; 1843*7c478bd9Sstevel@tonic-gate sec_to_refresh = 0; 1844*7c478bd9Sstevel@tonic-gate } else { 1845*7c478bd9Sstevel@tonic-gate in_no_server_mode = FALSE; 1846*7c478bd9Sstevel@tonic-gate sec_to_refresh = refresh_ttl; 1847*7c478bd9Sstevel@tonic-gate } 1848*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= 1849*7c478bd9Sstevel@tonic-gate DBG_SERVER_LIST_REFRESH) { 1850*7c478bd9Sstevel@tonic-gate logit("getldap_serverInfo_op(" 1851*7c478bd9Sstevel@tonic-gate "INFO_OP_REFRESH):" 1852*7c478bd9Sstevel@tonic-gate " seconds refresh: %d second(s)....\n", 1853*7c478bd9Sstevel@tonic-gate sec_to_refresh); 1854*7c478bd9Sstevel@tonic-gate } 1855*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info_mutex); 1856*7c478bd9Sstevel@tonic-gate } 1857*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&info_lock); 1858*7c478bd9Sstevel@tonic-gate 1859*7c478bd9Sstevel@tonic-gate break; 1860*7c478bd9Sstevel@tonic-gate case INFO_OP_REFRESH_WAIT: 1861*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_SERVER_LIST_REFRESH) { 1862*7c478bd9Sstevel@tonic-gate logit("operation is INFO_OP_REFRESH_WAIT...\n"); 1863*7c478bd9Sstevel@tonic-gate } 1864*7c478bd9Sstevel@tonic-gate (void) cond_init(&info_cond, NULL, NULL); 1865*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info_mutex); 1866*7c478bd9Sstevel@tonic-gate err = 0; 1867*7c478bd9Sstevel@tonic-gate while (err != ETIME) { 1868*7c478bd9Sstevel@tonic-gate int sleeptime; 1869*7c478bd9Sstevel@tonic-gate /* 1870*7c478bd9Sstevel@tonic-gate * if need to go into the "no-server" refresh 1871*7c478bd9Sstevel@tonic-gate * loop, set timout value to 1872*7c478bd9Sstevel@tonic-gate * REFRESH_DELAY_WHEN_NO_SERVER 1873*7c478bd9Sstevel@tonic-gate */ 1874*7c478bd9Sstevel@tonic-gate if (sec_to_refresh == 0) { 1875*7c478bd9Sstevel@tonic-gate sec_to_refresh = refresh_ttl; 1876*7c478bd9Sstevel@tonic-gate timeout.tv_sec = time(NULL) + 1877*7c478bd9Sstevel@tonic-gate REFRESH_DELAY_WHEN_NO_SERVER; 1878*7c478bd9Sstevel@tonic-gate sleeptime = REFRESH_DELAY_WHEN_NO_SERVER; 1879*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= 1880*7c478bd9Sstevel@tonic-gate DBG_SERVER_LIST_REFRESH) { 1881*7c478bd9Sstevel@tonic-gate logit("getldap_serverInfo_op(" 1882*7c478bd9Sstevel@tonic-gate "INFO_OP_REFRESH_WAIT):" 1883*7c478bd9Sstevel@tonic-gate " entering no-server " 1884*7c478bd9Sstevel@tonic-gate "refresh loop...\n"); 1885*7c478bd9Sstevel@tonic-gate } 1886*7c478bd9Sstevel@tonic-gate } else { 1887*7c478bd9Sstevel@tonic-gate timeout.tv_sec = time(NULL) + sec_to_refresh; 1888*7c478bd9Sstevel@tonic-gate sleeptime = sec_to_refresh; 1889*7c478bd9Sstevel@tonic-gate } 1890*7c478bd9Sstevel@tonic-gate timeout.tv_nsec = 0; 1891*7c478bd9Sstevel@tonic-gate 1892*7c478bd9Sstevel@tonic-gate /* statistics: next refresh time */ 1893*7c478bd9Sstevel@tonic-gate next_refresh = timeout.tv_sec; 1894*7c478bd9Sstevel@tonic-gate 1895*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= 1896*7c478bd9Sstevel@tonic-gate DBG_SERVER_LIST_REFRESH) { 1897*7c478bd9Sstevel@tonic-gate logit("getldap_serverInfo_op(" 1898*7c478bd9Sstevel@tonic-gate "INFO_OP_REFRESH_WAIT):" 1899*7c478bd9Sstevel@tonic-gate " about to sleep for %d second(s)...\n", 1900*7c478bd9Sstevel@tonic-gate sleeptime); 1901*7c478bd9Sstevel@tonic-gate } 1902*7c478bd9Sstevel@tonic-gate err = cond_timedwait(&info_cond, 1903*7c478bd9Sstevel@tonic-gate &info_mutex, &timeout); 1904*7c478bd9Sstevel@tonic-gate } 1905*7c478bd9Sstevel@tonic-gate (void) cond_destroy(&info_cond); 1906*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info_mutex); 1907*7c478bd9Sstevel@tonic-gate break; 1908*7c478bd9Sstevel@tonic-gate case INFO_OP_GETSERVER: 1909*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 1910*7c478bd9Sstevel@tonic-gate logit("operation is INFO_OP_GETSERVER...\n"); 1911*7c478bd9Sstevel@tonic-gate } 1912*7c478bd9Sstevel@tonic-gate *output = NULL; 1913*7c478bd9Sstevel@tonic-gate /* 1914*7c478bd9Sstevel@tonic-gate * GETSERVER processing always use 1915*7c478bd9Sstevel@tonic-gate * serverInfo_old to retrieve server infomation. 1916*7c478bd9Sstevel@tonic-gate * serverInfo_old is equal to serverInfo 1917*7c478bd9Sstevel@tonic-gate * most of the time, except when a new 1918*7c478bd9Sstevel@tonic-gate * server list is being created. 1919*7c478bd9Sstevel@tonic-gate * This is why the check for is_creating 1920*7c478bd9Sstevel@tonic-gate * is needed below. 1921*7c478bd9Sstevel@tonic-gate */ 1922*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&info_lock_old); 1923*7c478bd9Sstevel@tonic-gate 1924*7c478bd9Sstevel@tonic-gate if (serverInfo_old == NULL) { 1925*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&info_lock_old); 1926*7c478bd9Sstevel@tonic-gate break; 1927*7c478bd9Sstevel@tonic-gate } else 1928*7c478bd9Sstevel@tonic-gate (void) getldap_get_serverInfo(serverInfo_old, 1929*7c478bd9Sstevel@tonic-gate input, output, &server_removed); 1930*7c478bd9Sstevel@tonic-gate 1931*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&info_lock_old); 1932*7c478bd9Sstevel@tonic-gate 1933*7c478bd9Sstevel@tonic-gate /* 1934*7c478bd9Sstevel@tonic-gate * if server info is currently being 1935*7c478bd9Sstevel@tonic-gate * (re)created, do nothing 1936*7c478bd9Sstevel@tonic-gate */ 1937*7c478bd9Sstevel@tonic-gate 1938*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info_mutex); 1939*7c478bd9Sstevel@tonic-gate is_creating = creating; 1940*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info_mutex); 1941*7c478bd9Sstevel@tonic-gate if (is_creating) 1942*7c478bd9Sstevel@tonic-gate break; 1943*7c478bd9Sstevel@tonic-gate 1944*7c478bd9Sstevel@tonic-gate /* 1945*7c478bd9Sstevel@tonic-gate * set cache manager server list TTL if necessary 1946*7c478bd9Sstevel@tonic-gate */ 1947*7c478bd9Sstevel@tonic-gate if (*output == NULL || server_removed) { 1948*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&info_lock); 1949*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&info_mutex); 1950*7c478bd9Sstevel@tonic-gate 1951*7c478bd9Sstevel@tonic-gate (void) getldap_set_refresh_ttl(serverInfo, 1952*7c478bd9Sstevel@tonic-gate &refresh_ttl, &no_server_good); 1953*7c478bd9Sstevel@tonic-gate 1954*7c478bd9Sstevel@tonic-gate /* 1955*7c478bd9Sstevel@tonic-gate * if no good server found, need to go into 1956*7c478bd9Sstevel@tonic-gate * the "no-server" refresh loop 1957*7c478bd9Sstevel@tonic-gate * to find a server as soon as possible 1958*7c478bd9Sstevel@tonic-gate * otherwise reset the in_no_server_mode flag 1959*7c478bd9Sstevel@tonic-gate */ 1960*7c478bd9Sstevel@tonic-gate if (no_server_good) { 1961*7c478bd9Sstevel@tonic-gate /* 1962*7c478bd9Sstevel@tonic-gate * if already in no-server mode, 1963*7c478bd9Sstevel@tonic-gate * don't brother 1964*7c478bd9Sstevel@tonic-gate */ 1965*7c478bd9Sstevel@tonic-gate if (in_no_server_mode == FALSE) { 1966*7c478bd9Sstevel@tonic-gate sec_to_refresh = 0; 1967*7c478bd9Sstevel@tonic-gate in_no_server_mode = TRUE; 1968*7c478bd9Sstevel@tonic-gate (void) cond_signal(&info_cond); 1969*7c478bd9Sstevel@tonic-gate } 1970*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info_mutex); 1971*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&info_lock); 1972*7c478bd9Sstevel@tonic-gate break; 1973*7c478bd9Sstevel@tonic-gate } else { 1974*7c478bd9Sstevel@tonic-gate in_no_server_mode = FALSE; 1975*7c478bd9Sstevel@tonic-gate sec_to_refresh = refresh_ttl; 1976*7c478bd9Sstevel@tonic-gate } 1977*7c478bd9Sstevel@tonic-gate /* 1978*7c478bd9Sstevel@tonic-gate * if the refresh thread will be timed out 1979*7c478bd9Sstevel@tonic-gate * longer than refresh_ttl seconds, 1980*7c478bd9Sstevel@tonic-gate * wake it up to make it wait on the new 1981*7c478bd9Sstevel@tonic-gate * time out value 1982*7c478bd9Sstevel@tonic-gate */ 1983*7c478bd9Sstevel@tonic-gate new_timeout.tv_sec = time(NULL) + refresh_ttl; 1984*7c478bd9Sstevel@tonic-gate if (new_timeout.tv_sec < timeout.tv_sec) 1985*7c478bd9Sstevel@tonic-gate (void) cond_signal(&info_cond); 1986*7c478bd9Sstevel@tonic-gate 1987*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&info_mutex); 1988*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&info_lock); 1989*7c478bd9Sstevel@tonic-gate } 1990*7c478bd9Sstevel@tonic-gate break; 1991*7c478bd9Sstevel@tonic-gate case INFO_OP_GETSTAT: 1992*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 1993*7c478bd9Sstevel@tonic-gate logit("operation is INFO_OP_GETSTAT...\n"); 1994*7c478bd9Sstevel@tonic-gate } 1995*7c478bd9Sstevel@tonic-gate *output = NULL; 1996*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&info_lock); 1997*7c478bd9Sstevel@tonic-gate if (serverInfo) { 1998*7c478bd9Sstevel@tonic-gate (void) getldap_get_server_stat(serverInfo, 1999*7c478bd9Sstevel@tonic-gate output, &prev_refresh, &next_refresh); 2000*7c478bd9Sstevel@tonic-gate } 2001*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&info_lock); 2002*7c478bd9Sstevel@tonic-gate break; 2003*7c478bd9Sstevel@tonic-gate default: 2004*7c478bd9Sstevel@tonic-gate logit("getldap_serverInfo_op(): " 2005*7c478bd9Sstevel@tonic-gate "invalid operation code (%d).\n", op); 2006*7c478bd9Sstevel@tonic-gate return (-1); 2007*7c478bd9Sstevel@tonic-gate break; 2008*7c478bd9Sstevel@tonic-gate } 2009*7c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 2010*7c478bd9Sstevel@tonic-gate } 2011*7c478bd9Sstevel@tonic-gate 2012*7c478bd9Sstevel@tonic-gate void 2013*7c478bd9Sstevel@tonic-gate getldap_serverInfo_refresh() 2014*7c478bd9Sstevel@tonic-gate { 2015*7c478bd9Sstevel@tonic-gate int always = 1; 2016*7c478bd9Sstevel@tonic-gate 2017*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2018*7c478bd9Sstevel@tonic-gate logit("getldap_serverInfo_refresh()...\n"); 2019*7c478bd9Sstevel@tonic-gate } 2020*7c478bd9Sstevel@tonic-gate 2021*7c478bd9Sstevel@tonic-gate /* create the server info list */ 2022*7c478bd9Sstevel@tonic-gate (void) getldap_serverInfo_op(INFO_OP_CREATE, NULL, NULL); 2023*7c478bd9Sstevel@tonic-gate 2024*7c478bd9Sstevel@tonic-gate while (always) { 2025*7c478bd9Sstevel@tonic-gate /* 2026*7c478bd9Sstevel@tonic-gate * the operation INFO_OP_REFRESH_WAIT 2027*7c478bd9Sstevel@tonic-gate * causes this thread to wait until 2028*7c478bd9Sstevel@tonic-gate * it is time to do refresh, 2029*7c478bd9Sstevel@tonic-gate * see getldap_serverInfo_op() for details 2030*7c478bd9Sstevel@tonic-gate */ 2031*7c478bd9Sstevel@tonic-gate (void) getldap_serverInfo_op(INFO_OP_REFRESH_WAIT, NULL, NULL); 2032*7c478bd9Sstevel@tonic-gate (void) getldap_serverInfo_op(INFO_OP_REFRESH, NULL, NULL); 2033*7c478bd9Sstevel@tonic-gate } 2034*7c478bd9Sstevel@tonic-gate } 2035*7c478bd9Sstevel@tonic-gate 2036*7c478bd9Sstevel@tonic-gate void 2037*7c478bd9Sstevel@tonic-gate getldap_getserver(ldap_return_t *out, ldap_call_t *in) 2038*7c478bd9Sstevel@tonic-gate { 2039*7c478bd9Sstevel@tonic-gate char *outstr = NULL; 2040*7c478bd9Sstevel@tonic-gate char req[] = "0"; 2041*7c478bd9Sstevel@tonic-gate 2042*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2043*7c478bd9Sstevel@tonic-gate logit("getldap_getserver()...\n"); 2044*7c478bd9Sstevel@tonic-gate } 2045*7c478bd9Sstevel@tonic-gate 2046*7c478bd9Sstevel@tonic-gate /* assume no server found */ 2047*7c478bd9Sstevel@tonic-gate out->ldap_errno = -1; 2048*7c478bd9Sstevel@tonic-gate out->ldap_return_code = NOTFOUND; 2049*7c478bd9Sstevel@tonic-gate out->ldap_bufferbytesused = sizeof (*out); 2050*7c478bd9Sstevel@tonic-gate 2051*7c478bd9Sstevel@tonic-gate /* make sure the request is valid */ 2052*7c478bd9Sstevel@tonic-gate req[0] = (in->ldap_u.servername)[0]; 2053*7c478bd9Sstevel@tonic-gate if ((req[0] != '\0') && 2054*7c478bd9Sstevel@tonic-gate (strcmp(req, NS_CACHE_NEW) != 0) && 2055*7c478bd9Sstevel@tonic-gate (strcmp(req, NS_CACHE_NORESP) != 0) && 2056*7c478bd9Sstevel@tonic-gate (strcmp(req, NS_CACHE_NEXT) != 0) && 2057*7c478bd9Sstevel@tonic-gate (strcmp(req, NS_CACHE_WRITE) != 0)) { 2058*7c478bd9Sstevel@tonic-gate return; 2059*7c478bd9Sstevel@tonic-gate } 2060*7c478bd9Sstevel@tonic-gate 2061*7c478bd9Sstevel@tonic-gate (void) getldap_serverInfo_op(INFO_OP_GETSERVER, 2062*7c478bd9Sstevel@tonic-gate in->ldap_u.domainname, &outstr); 2063*7c478bd9Sstevel@tonic-gate 2064*7c478bd9Sstevel@tonic-gate if (outstr == NULL) 2065*7c478bd9Sstevel@tonic-gate return; 2066*7c478bd9Sstevel@tonic-gate 2067*7c478bd9Sstevel@tonic-gate out->ldap_bufferbytesused = sizeof (ldap_return_t); 2068*7c478bd9Sstevel@tonic-gate (void) strncpy(out->ldap_u.config, outstr, strlen(outstr)+1); 2069*7c478bd9Sstevel@tonic-gate 2070*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_PROFILE_REFRESH) { 2071*7c478bd9Sstevel@tonic-gate /* Log server IP */ 2072*7c478bd9Sstevel@tonic-gate char *ptr; 2073*7c478bd9Sstevel@tonic-gate ptr = strstr(outstr, DOORLINESEP); 2074*7c478bd9Sstevel@tonic-gate if (ptr) { 2075*7c478bd9Sstevel@tonic-gate *ptr = '\0'; 2076*7c478bd9Sstevel@tonic-gate logit("getldap_getserver: got server %s\n", outstr); 2077*7c478bd9Sstevel@tonic-gate } else 2078*7c478bd9Sstevel@tonic-gate logit("getldap_getserver: Missing %s." 2079*7c478bd9Sstevel@tonic-gate " Internal error\n", DOORLINESEP); 2080*7c478bd9Sstevel@tonic-gate } 2081*7c478bd9Sstevel@tonic-gate free(outstr); 2082*7c478bd9Sstevel@tonic-gate out->ldap_return_code = SUCCESS; 2083*7c478bd9Sstevel@tonic-gate out->ldap_errno = 0; 2084*7c478bd9Sstevel@tonic-gate 2085*7c478bd9Sstevel@tonic-gate } 2086*7c478bd9Sstevel@tonic-gate 2087*7c478bd9Sstevel@tonic-gate void 2088*7c478bd9Sstevel@tonic-gate getldap_get_cacheData(ldap_return_t *out, ldap_call_t *in) 2089*7c478bd9Sstevel@tonic-gate { 2090*7c478bd9Sstevel@tonic-gate char *outstr = NULL, *instr = NULL; 2091*7c478bd9Sstevel@tonic-gate int datatype = CACHE_MAP_UNKNOWN; 2092*7c478bd9Sstevel@tonic-gate 2093*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2094*7c478bd9Sstevel@tonic-gate logit("getldap_get_cacheData()...\n"); 2095*7c478bd9Sstevel@tonic-gate } 2096*7c478bd9Sstevel@tonic-gate 2097*7c478bd9Sstevel@tonic-gate /* assume no cache data found */ 2098*7c478bd9Sstevel@tonic-gate out->ldap_errno = -1; 2099*7c478bd9Sstevel@tonic-gate out->ldap_return_code = NOTFOUND; 2100*7c478bd9Sstevel@tonic-gate out->ldap_bufferbytesused = sizeof (*out); 2101*7c478bd9Sstevel@tonic-gate 2102*7c478bd9Sstevel@tonic-gate /* make sure the request is valid */ 2103*7c478bd9Sstevel@tonic-gate if (strncmp(in->ldap_u.servername, 2104*7c478bd9Sstevel@tonic-gate NS_CACHE_DN2DOMAIN, strlen(NS_CACHE_DN2DOMAIN)) == 0) 2105*7c478bd9Sstevel@tonic-gate datatype = CACHE_MAP_DN2DOMAIN; 2106*7c478bd9Sstevel@tonic-gate 2107*7c478bd9Sstevel@tonic-gate if (datatype == CACHE_MAP_UNKNOWN) 2108*7c478bd9Sstevel@tonic-gate return; 2109*7c478bd9Sstevel@tonic-gate 2110*7c478bd9Sstevel@tonic-gate instr = strstr(in->ldap_u.servername, DOORLINESEP); 2111*7c478bd9Sstevel@tonic-gate if (instr == NULL) 2112*7c478bd9Sstevel@tonic-gate return; 2113*7c478bd9Sstevel@tonic-gate instr += strlen(DOORLINESEP); 2114*7c478bd9Sstevel@tonic-gate if (*instr == '\0') 2115*7c478bd9Sstevel@tonic-gate return; 2116*7c478bd9Sstevel@tonic-gate 2117*7c478bd9Sstevel@tonic-gate (void) getldap_cache_op(CACHE_OP_FIND, datatype, 2118*7c478bd9Sstevel@tonic-gate instr, &outstr); 2119*7c478bd9Sstevel@tonic-gate 2120*7c478bd9Sstevel@tonic-gate if (outstr == NULL) 2121*7c478bd9Sstevel@tonic-gate return; 2122*7c478bd9Sstevel@tonic-gate 2123*7c478bd9Sstevel@tonic-gate out->ldap_bufferbytesused = sizeof (ldap_return_t); 2124*7c478bd9Sstevel@tonic-gate (void) strncpy(out->ldap_u.config, outstr, strlen(outstr)+1); 2125*7c478bd9Sstevel@tonic-gate free(outstr); 2126*7c478bd9Sstevel@tonic-gate out->ldap_return_code = SUCCESS; 2127*7c478bd9Sstevel@tonic-gate out->ldap_errno = 0; 2128*7c478bd9Sstevel@tonic-gate } 2129*7c478bd9Sstevel@tonic-gate 2130*7c478bd9Sstevel@tonic-gate void 2131*7c478bd9Sstevel@tonic-gate getldap_set_cacheData(ldap_return_t *out, ldap_call_t *in) 2132*7c478bd9Sstevel@tonic-gate { 2133*7c478bd9Sstevel@tonic-gate char *instr1 = NULL; 2134*7c478bd9Sstevel@tonic-gate char *instr2 = NULL; 2135*7c478bd9Sstevel@tonic-gate int datatype = CACHE_MAP_UNKNOWN; 2136*7c478bd9Sstevel@tonic-gate int rc = 0; 2137*7c478bd9Sstevel@tonic-gate 2138*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2139*7c478bd9Sstevel@tonic-gate logit("getldap_set_cacheData()...\n"); 2140*7c478bd9Sstevel@tonic-gate } 2141*7c478bd9Sstevel@tonic-gate 2142*7c478bd9Sstevel@tonic-gate /* assume error */ 2143*7c478bd9Sstevel@tonic-gate out->ldap_errno = -1; 2144*7c478bd9Sstevel@tonic-gate out->ldap_return_code = NOTFOUND; 2145*7c478bd9Sstevel@tonic-gate out->ldap_bufferbytesused = sizeof (*out); 2146*7c478bd9Sstevel@tonic-gate 2147*7c478bd9Sstevel@tonic-gate /* make sure the request is valid */ 2148*7c478bd9Sstevel@tonic-gate if (strncmp(in->ldap_u.servername, 2149*7c478bd9Sstevel@tonic-gate NS_CACHE_DN2DOMAIN, strlen(NS_CACHE_DN2DOMAIN)) == 0) 2150*7c478bd9Sstevel@tonic-gate datatype = CACHE_MAP_DN2DOMAIN; 2151*7c478bd9Sstevel@tonic-gate 2152*7c478bd9Sstevel@tonic-gate if (datatype == CACHE_MAP_UNKNOWN) 2153*7c478bd9Sstevel@tonic-gate return; 2154*7c478bd9Sstevel@tonic-gate 2155*7c478bd9Sstevel@tonic-gate instr1 = strstr(in->ldap_u.servername, DOORLINESEP); 2156*7c478bd9Sstevel@tonic-gate if (instr1 == NULL) 2157*7c478bd9Sstevel@tonic-gate return; 2158*7c478bd9Sstevel@tonic-gate *instr1 = '\0'; 2159*7c478bd9Sstevel@tonic-gate instr1 += strlen(DOORLINESEP); 2160*7c478bd9Sstevel@tonic-gate if (*instr1 == '\0') 2161*7c478bd9Sstevel@tonic-gate return; 2162*7c478bd9Sstevel@tonic-gate instr2 = strstr(instr1, DOORLINESEP); 2163*7c478bd9Sstevel@tonic-gate if (instr2 == NULL) 2164*7c478bd9Sstevel@tonic-gate return; 2165*7c478bd9Sstevel@tonic-gate *instr2 = '\0'; 2166*7c478bd9Sstevel@tonic-gate instr2 += strlen(DOORLINESEP); 2167*7c478bd9Sstevel@tonic-gate if (*instr2 == '\0') 2168*7c478bd9Sstevel@tonic-gate return; 2169*7c478bd9Sstevel@tonic-gate 2170*7c478bd9Sstevel@tonic-gate rc = getldap_cache_op(CACHE_OP_ADD, datatype, 2171*7c478bd9Sstevel@tonic-gate instr1, &instr2); 2172*7c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) 2173*7c478bd9Sstevel@tonic-gate return; 2174*7c478bd9Sstevel@tonic-gate 2175*7c478bd9Sstevel@tonic-gate out->ldap_bufferbytesused = sizeof (ldap_return_t); 2176*7c478bd9Sstevel@tonic-gate out->ldap_return_code = SUCCESS; 2177*7c478bd9Sstevel@tonic-gate out->ldap_errno = 0; 2178*7c478bd9Sstevel@tonic-gate } 2179*7c478bd9Sstevel@tonic-gate 2180*7c478bd9Sstevel@tonic-gate void 2181*7c478bd9Sstevel@tonic-gate getldap_get_cacheStat(ldap_return_t *out) 2182*7c478bd9Sstevel@tonic-gate { 2183*7c478bd9Sstevel@tonic-gate char *foutstr = NULL; 2184*7c478bd9Sstevel@tonic-gate char *soutstr = NULL; 2185*7c478bd9Sstevel@tonic-gate char *coutstr = NULL; 2186*7c478bd9Sstevel@tonic-gate 2187*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2188*7c478bd9Sstevel@tonic-gate logit("getldap_get_cacheStat()...\n"); 2189*7c478bd9Sstevel@tonic-gate } 2190*7c478bd9Sstevel@tonic-gate 2191*7c478bd9Sstevel@tonic-gate /* setup for error return */ 2192*7c478bd9Sstevel@tonic-gate out->ldap_errno = -1; 2193*7c478bd9Sstevel@tonic-gate out->ldap_return_code = NOTFOUND; 2194*7c478bd9Sstevel@tonic-gate out->ldap_bufferbytesused = sizeof (*out); 2195*7c478bd9Sstevel@tonic-gate 2196*7c478bd9Sstevel@tonic-gate /* get refersh statisitcs */ 2197*7c478bd9Sstevel@tonic-gate (void) getldap_get_refresh_stat(&foutstr); 2198*7c478bd9Sstevel@tonic-gate if (foutstr == NULL) 2199*7c478bd9Sstevel@tonic-gate return; 2200*7c478bd9Sstevel@tonic-gate 2201*7c478bd9Sstevel@tonic-gate /* get server statisitcs */ 2202*7c478bd9Sstevel@tonic-gate (void) getldap_serverInfo_op(INFO_OP_GETSTAT, NULL, &soutstr); 2203*7c478bd9Sstevel@tonic-gate if (soutstr == NULL) { 2204*7c478bd9Sstevel@tonic-gate free(foutstr); 2205*7c478bd9Sstevel@tonic-gate return; 2206*7c478bd9Sstevel@tonic-gate } 2207*7c478bd9Sstevel@tonic-gate /* get cache data statisitcs */ 2208*7c478bd9Sstevel@tonic-gate (void) getldap_cache_op(CACHE_OP_GETSTAT, NULL, NULL, &coutstr); 2209*7c478bd9Sstevel@tonic-gate if (coutstr == NULL) { 2210*7c478bd9Sstevel@tonic-gate free(foutstr); 2211*7c478bd9Sstevel@tonic-gate free(soutstr); 2212*7c478bd9Sstevel@tonic-gate return; 2213*7c478bd9Sstevel@tonic-gate } 2214*7c478bd9Sstevel@tonic-gate 2215*7c478bd9Sstevel@tonic-gate out->ldap_bufferbytesused = sizeof (ldap_return_t); 2216*7c478bd9Sstevel@tonic-gate (void) strncpy(out->ldap_u.config, foutstr, strlen(foutstr) + 1); 2217*7c478bd9Sstevel@tonic-gate (void) strncat(out->ldap_u.config, soutstr, strlen(soutstr) + 1); 2218*7c478bd9Sstevel@tonic-gate (void) strncat(out->ldap_u.config, coutstr, strlen(coutstr) + 1); 2219*7c478bd9Sstevel@tonic-gate 2220*7c478bd9Sstevel@tonic-gate free(foutstr); 2221*7c478bd9Sstevel@tonic-gate free(soutstr); 2222*7c478bd9Sstevel@tonic-gate free(coutstr); 2223*7c478bd9Sstevel@tonic-gate 2224*7c478bd9Sstevel@tonic-gate out->ldap_return_code = SUCCESS; 2225*7c478bd9Sstevel@tonic-gate out->ldap_errno = 0; 2226*7c478bd9Sstevel@tonic-gate } 2227*7c478bd9Sstevel@tonic-gate 2228*7c478bd9Sstevel@tonic-gate static int 2229*7c478bd9Sstevel@tonic-gate checkupdate(int sighup) 2230*7c478bd9Sstevel@tonic-gate { 2231*7c478bd9Sstevel@tonic-gate int value; 2232*7c478bd9Sstevel@tonic-gate 2233*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ldap_lock); 2234*7c478bd9Sstevel@tonic-gate value = sighup; 2235*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2236*7c478bd9Sstevel@tonic-gate 2237*7c478bd9Sstevel@tonic-gate return (value == TRUE); 2238*7c478bd9Sstevel@tonic-gate } 2239*7c478bd9Sstevel@tonic-gate 2240*7c478bd9Sstevel@tonic-gate 2241*7c478bd9Sstevel@tonic-gate static int 2242*7c478bd9Sstevel@tonic-gate update_from_profile() 2243*7c478bd9Sstevel@tonic-gate { 2244*7c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = NULL; 2245*7c478bd9Sstevel@tonic-gate char searchfilter[BUFSIZ]; 2246*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *error; 2247*7c478bd9Sstevel@tonic-gate int rc; 2248*7c478bd9Sstevel@tonic-gate void **paramVal = NULL; 2249*7c478bd9Sstevel@tonic-gate ns_config_t *ptr = NULL; 2250*7c478bd9Sstevel@tonic-gate char *profile = NULL; 2251*7c478bd9Sstevel@tonic-gate char errstr[MAXERROR]; 2252*7c478bd9Sstevel@tonic-gate 2253*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2254*7c478bd9Sstevel@tonic-gate logit("update_from_profile....\n"); 2255*7c478bd9Sstevel@tonic-gate } 2256*7c478bd9Sstevel@tonic-gate do { 2257*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ldap_lock); 2258*7c478bd9Sstevel@tonic-gate sighup_update = FALSE; 2259*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2260*7c478bd9Sstevel@tonic-gate 2261*7c478bd9Sstevel@tonic-gate if ((rc = __ns_ldap_getParam(NS_LDAP_PROFILE_P, 2262*7c478bd9Sstevel@tonic-gate ¶mVal, &error)) != NS_LDAP_SUCCESS) { 2263*7c478bd9Sstevel@tonic-gate if (error != NULL && error->message != NULL) 2264*7c478bd9Sstevel@tonic-gate logit("Error: Unable to profile name: %s\n", 2265*7c478bd9Sstevel@tonic-gate error->message); 2266*7c478bd9Sstevel@tonic-gate else { 2267*7c478bd9Sstevel@tonic-gate char *tmp; 2268*7c478bd9Sstevel@tonic-gate 2269*7c478bd9Sstevel@tonic-gate __ns_ldap_err2str(rc, &tmp); 2270*7c478bd9Sstevel@tonic-gate logit("Error: Unable to profile name: %s\n", 2271*7c478bd9Sstevel@tonic-gate tmp); 2272*7c478bd9Sstevel@tonic-gate } 2273*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶mVal); 2274*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 2275*7c478bd9Sstevel@tonic-gate return (-1); 2276*7c478bd9Sstevel@tonic-gate } 2277*7c478bd9Sstevel@tonic-gate 2278*7c478bd9Sstevel@tonic-gate if (paramVal && *paramVal) 2279*7c478bd9Sstevel@tonic-gate profile = strdup((char *)*paramVal); 2280*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶mVal); 2281*7c478bd9Sstevel@tonic-gate 2282*7c478bd9Sstevel@tonic-gate if (profile == NULL) { 2283*7c478bd9Sstevel@tonic-gate return (-1); 2284*7c478bd9Sstevel@tonic-gate } 2285*7c478bd9Sstevel@tonic-gate 2286*7c478bd9Sstevel@tonic-gate (void) snprintf(searchfilter, BUFSIZ, _PROFILE_FILTER, 2287*7c478bd9Sstevel@tonic-gate _PROFILE1_OBJECTCLASS, _PROFILE2_OBJECTCLASS, profile); 2288*7c478bd9Sstevel@tonic-gate 2289*7c478bd9Sstevel@tonic-gate if ((rc = __ns_ldap_list(_PROFILE_CONTAINER, 2290*7c478bd9Sstevel@tonic-gate (const char *)searchfilter, NULL, 2291*7c478bd9Sstevel@tonic-gate NULL, NULL, 0, 2292*7c478bd9Sstevel@tonic-gate &result, &error, NULL, NULL)) != NS_LDAP_SUCCESS) { 2293*7c478bd9Sstevel@tonic-gate 2294*7c478bd9Sstevel@tonic-gate /* 2295*7c478bd9Sstevel@tonic-gate * Is profile name the DEFAULTCONFIGNAME? 2296*7c478bd9Sstevel@tonic-gate * syslog Warning, otherwise syslog error. 2297*7c478bd9Sstevel@tonic-gate */ 2298*7c478bd9Sstevel@tonic-gate if (strcmp(profile, DEFAULTCONFIGNAME) == 0) { 2299*7c478bd9Sstevel@tonic-gate syslog(LOG_WARNING, 2300*7c478bd9Sstevel@tonic-gate "Ignoring attempt to refresh nonexistent " 2301*7c478bd9Sstevel@tonic-gate "default profile: %s.\n", 2302*7c478bd9Sstevel@tonic-gate profile); 2303*7c478bd9Sstevel@tonic-gate logit("Ignoring attempt to refresh nonexistent " 2304*7c478bd9Sstevel@tonic-gate "default profile: %s.\n", 2305*7c478bd9Sstevel@tonic-gate profile); 2306*7c478bd9Sstevel@tonic-gate } else if ((error != NULL) && 2307*7c478bd9Sstevel@tonic-gate (error->message != NULL)) { 2308*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 2309*7c478bd9Sstevel@tonic-gate "Error: Unable to refresh profile:%s:" 2310*7c478bd9Sstevel@tonic-gate " %s\n", profile, error->message); 2311*7c478bd9Sstevel@tonic-gate logit("Error: Unable to refresh profile:" 2312*7c478bd9Sstevel@tonic-gate "%s:%s\n", profile, error->message); 2313*7c478bd9Sstevel@tonic-gate } else { 2314*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "Error: Unable to refresh " 2315*7c478bd9Sstevel@tonic-gate "from profile:%s. (error=%d)\n", 2316*7c478bd9Sstevel@tonic-gate profile, rc); 2317*7c478bd9Sstevel@tonic-gate logit("Error: Unable to refresh from profile " 2318*7c478bd9Sstevel@tonic-gate "%s (error=%d)\n", profile, rc); 2319*7c478bd9Sstevel@tonic-gate } 2320*7c478bd9Sstevel@tonic-gate 2321*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 2322*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 2323*7c478bd9Sstevel@tonic-gate free(profile); 2324*7c478bd9Sstevel@tonic-gate return (-1); 2325*7c478bd9Sstevel@tonic-gate } 2326*7c478bd9Sstevel@tonic-gate free(profile); 2327*7c478bd9Sstevel@tonic-gate 2328*7c478bd9Sstevel@tonic-gate 2329*7c478bd9Sstevel@tonic-gate } while (checkupdate(sighup_update) == TRUE); 2330*7c478bd9Sstevel@tonic-gate 2331*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ldap_lock); 2332*7c478bd9Sstevel@tonic-gate 2333*7c478bd9Sstevel@tonic-gate ptr = __ns_ldap_make_config(result); 2334*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 2335*7c478bd9Sstevel@tonic-gate 2336*7c478bd9Sstevel@tonic-gate if (ptr == NULL) { 2337*7c478bd9Sstevel@tonic-gate logit("Error: __ns_ldap_make_config failed.\n"); 2338*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2339*7c478bd9Sstevel@tonic-gate return (-1); 2340*7c478bd9Sstevel@tonic-gate } 2341*7c478bd9Sstevel@tonic-gate 2342*7c478bd9Sstevel@tonic-gate /* 2343*7c478bd9Sstevel@tonic-gate * cross check the config parameters 2344*7c478bd9Sstevel@tonic-gate */ 2345*7c478bd9Sstevel@tonic-gate if (__s_api_crosscheck(ptr, errstr, B_TRUE) == NS_SUCCESS) { 2346*7c478bd9Sstevel@tonic-gate /* 2347*7c478bd9Sstevel@tonic-gate * reset the local profile TTL 2348*7c478bd9Sstevel@tonic-gate */ 2349*7c478bd9Sstevel@tonic-gate if (ptr->paramList[NS_LDAP_CACHETTL_P].ns_pc) 2350*7c478bd9Sstevel@tonic-gate current_admin.ldap_stat.ldap_ttl = 2351*7c478bd9Sstevel@tonic-gate atol(ptr->paramList[NS_LDAP_CACHETTL_P].ns_pc); 2352*7c478bd9Sstevel@tonic-gate 2353*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_PROFILE_REFRESH) { 2354*7c478bd9Sstevel@tonic-gate logit("update_from_profile: reset profile TTL to %d" 2355*7c478bd9Sstevel@tonic-gate " seconds\n", 2356*7c478bd9Sstevel@tonic-gate current_admin.ldap_stat.ldap_ttl); 2357*7c478bd9Sstevel@tonic-gate logit("update_from_profile: expire time %d " 2358*7c478bd9Sstevel@tonic-gate "seconds\n", 2359*7c478bd9Sstevel@tonic-gate *ptr->paramList[NS_LDAP_EXP_P].ns_pi); 2360*7c478bd9Sstevel@tonic-gate } 2361*7c478bd9Sstevel@tonic-gate 2362*7c478bd9Sstevel@tonic-gate /* set ptr as current_config */ 2363*7c478bd9Sstevel@tonic-gate __s_api_init_config(ptr); 2364*7c478bd9Sstevel@tonic-gate rc = 0; 2365*7c478bd9Sstevel@tonic-gate } else { 2366*7c478bd9Sstevel@tonic-gate __s_api_destroy_config(ptr); 2367*7c478bd9Sstevel@tonic-gate logit("Error: downloaded profile failed to pass " 2368*7c478bd9Sstevel@tonic-gate "crosscheck (%s).\n", errstr); 2369*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "ldap_cachemgr: %s", errstr); 2370*7c478bd9Sstevel@tonic-gate rc = -1; 2371*7c478bd9Sstevel@tonic-gate } 2372*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2373*7c478bd9Sstevel@tonic-gate return (rc); 2374*7c478bd9Sstevel@tonic-gate } 2375*7c478bd9Sstevel@tonic-gate 2376*7c478bd9Sstevel@tonic-gate int 2377*7c478bd9Sstevel@tonic-gate getldap_init() 2378*7c478bd9Sstevel@tonic-gate { 2379*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *error; 2380*7c478bd9Sstevel@tonic-gate struct timeval tp; 2381*7c478bd9Sstevel@tonic-gate 2382*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2383*7c478bd9Sstevel@tonic-gate logit("getldap_init()...\n"); 2384*7c478bd9Sstevel@tonic-gate } 2385*7c478bd9Sstevel@tonic-gate 2386*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_setServer(TRUE); 2387*7c478bd9Sstevel@tonic-gate 2388*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ldap_lock); 2389*7c478bd9Sstevel@tonic-gate if ((error = __ns_ldap_LoadConfiguration()) != NULL) { 2390*7c478bd9Sstevel@tonic-gate logit("Error: Unable to read '%s': %s\n", 2391*7c478bd9Sstevel@tonic-gate NSCONFIGFILE, error->message); 2392*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2393*7c478bd9Sstevel@tonic-gate gettext("\nError: Unable to read '%s': %s\n"), 2394*7c478bd9Sstevel@tonic-gate NSCONFIGFILE, error->message); 2395*7c478bd9Sstevel@tonic-gate __ns_ldap_freeError(&error); 2396*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2397*7c478bd9Sstevel@tonic-gate return (-1); 2398*7c478bd9Sstevel@tonic-gate } 2399*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2400*7c478bd9Sstevel@tonic-gate 2401*7c478bd9Sstevel@tonic-gate if (gettimeofday(&tp, NULL) == 0) { 2402*7c478bd9Sstevel@tonic-gate /* statistics: previous refresh time */ 2403*7c478bd9Sstevel@tonic-gate prev_refresh_time = tp.tv_sec; 2404*7c478bd9Sstevel@tonic-gate } 2405*7c478bd9Sstevel@tonic-gate 2406*7c478bd9Sstevel@tonic-gate /* initialize the data cache */ 2407*7c478bd9Sstevel@tonic-gate (void) getldap_cache_op(CACHE_OP_CREATE, 2408*7c478bd9Sstevel@tonic-gate 0, NULL, NULL); 2409*7c478bd9Sstevel@tonic-gate 2410*7c478bd9Sstevel@tonic-gate return (0); 2411*7c478bd9Sstevel@tonic-gate } 2412*7c478bd9Sstevel@tonic-gate 2413*7c478bd9Sstevel@tonic-gate static void 2414*7c478bd9Sstevel@tonic-gate perform_update(void) 2415*7c478bd9Sstevel@tonic-gate { 2416*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *error; 2417*7c478bd9Sstevel@tonic-gate struct timeval tp; 2418*7c478bd9Sstevel@tonic-gate char buf[20]; 2419*7c478bd9Sstevel@tonic-gate int rc; 2420*7c478bd9Sstevel@tonic-gate 2421*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2422*7c478bd9Sstevel@tonic-gate logit("perform_update()...\n"); 2423*7c478bd9Sstevel@tonic-gate } 2424*7c478bd9Sstevel@tonic-gate 2425*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_setServer(TRUE); 2426*7c478bd9Sstevel@tonic-gate 2427*7c478bd9Sstevel@tonic-gate if (gettimeofday(&tp, NULL) != 0) 2428*7c478bd9Sstevel@tonic-gate return; 2429*7c478bd9Sstevel@tonic-gate 2430*7c478bd9Sstevel@tonic-gate /* 2431*7c478bd9Sstevel@tonic-gate * set the profile TTL parameter, just 2432*7c478bd9Sstevel@tonic-gate * in case that the downloading of 2433*7c478bd9Sstevel@tonic-gate * the profile from server would fail 2434*7c478bd9Sstevel@tonic-gate */ 2435*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_PROFILE_REFRESH) { 2436*7c478bd9Sstevel@tonic-gate logit("perform_update: current profile TTL is %d seconds\n", 2437*7c478bd9Sstevel@tonic-gate current_admin.ldap_stat.ldap_ttl); 2438*7c478bd9Sstevel@tonic-gate } 2439*7c478bd9Sstevel@tonic-gate /* 2440*7c478bd9Sstevel@tonic-gate * NS_LDAP_EXP_P is a no op for __ns_ldap_setParam 2441*7c478bd9Sstevel@tonic-gate * It depends on NS_LDAP_CACHETTL_P to set it's value 2442*7c478bd9Sstevel@tonic-gate * Set NS_LDAP_CACHETTL_P here so NS_LDAP_EXP_P value 2443*7c478bd9Sstevel@tonic-gate * can be set. 2444*7c478bd9Sstevel@tonic-gate * NS_LDAP_CACHETTL_P value can be reset after the profile is 2445*7c478bd9Sstevel@tonic-gate * downloaded from the server, so is NS_LDAP_EXP_P. 2446*7c478bd9Sstevel@tonic-gate */ 2447*7c478bd9Sstevel@tonic-gate buf[19] = '\0'; /* null terminated the buffer */ 2448*7c478bd9Sstevel@tonic-gate if (__ns_ldap_setParam(NS_LDAP_CACHETTL_P, 2449*7c478bd9Sstevel@tonic-gate lltostr((long long)current_admin.ldap_stat.ldap_ttl, &buf[19]), 2450*7c478bd9Sstevel@tonic-gate &error) != NS_LDAP_SUCCESS) { 2451*7c478bd9Sstevel@tonic-gate logit("Error: __ns_ldap_setParam failed, status: %d " 2452*7c478bd9Sstevel@tonic-gate "message: %s\n", error->status, error->message); 2453*7c478bd9Sstevel@tonic-gate __ns_ldap_freeError(&error); 2454*7c478bd9Sstevel@tonic-gate return; 2455*7c478bd9Sstevel@tonic-gate } 2456*7c478bd9Sstevel@tonic-gate 2457*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ldap_lock); 2458*7c478bd9Sstevel@tonic-gate sighup_update = FALSE; 2459*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2460*7c478bd9Sstevel@tonic-gate 2461*7c478bd9Sstevel@tonic-gate do { 2462*7c478bd9Sstevel@tonic-gate rc = update_from_profile(); 2463*7c478bd9Sstevel@tonic-gate if (rc != 0) { 2464*7c478bd9Sstevel@tonic-gate logit("Error: Unable to update from profile\n"); 2465*7c478bd9Sstevel@tonic-gate } 2466*7c478bd9Sstevel@tonic-gate } while (checkupdate(sighup_update) == TRUE); 2467*7c478bd9Sstevel@tonic-gate 2468*7c478bd9Sstevel@tonic-gate /* 2469*7c478bd9Sstevel@tonic-gate * recreate the server info list 2470*7c478bd9Sstevel@tonic-gate */ 2471*7c478bd9Sstevel@tonic-gate if (rc == 0) { 2472*7c478bd9Sstevel@tonic-gate (void) getldap_serverInfo_op(INFO_OP_CREATE, NULL, NULL); 2473*7c478bd9Sstevel@tonic-gate 2474*7c478bd9Sstevel@tonic-gate /* flush the data cache */ 2475*7c478bd9Sstevel@tonic-gate (void) getldap_cache_op(CACHE_OP_DELETE, 2476*7c478bd9Sstevel@tonic-gate 0, NULL, NULL); 2477*7c478bd9Sstevel@tonic-gate 2478*7c478bd9Sstevel@tonic-gate /* statistics: previous refresh time */ 2479*7c478bd9Sstevel@tonic-gate prev_refresh_time = tp.tv_sec; 2480*7c478bd9Sstevel@tonic-gate } 2481*7c478bd9Sstevel@tonic-gate 2482*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ldap_lock); 2483*7c478bd9Sstevel@tonic-gate if ((error = __ns_ldap_DumpConfiguration(NSCONFIGREFRESH)) != NULL) { 2484*7c478bd9Sstevel@tonic-gate logit("Error: __ns_ldap_DumpConfiguration(\"%s\") failed, " 2485*7c478bd9Sstevel@tonic-gate "status: %d " 2486*7c478bd9Sstevel@tonic-gate "message: %s\n", NSCONFIGREFRESH, 2487*7c478bd9Sstevel@tonic-gate error->status, error->message); 2488*7c478bd9Sstevel@tonic-gate __ns_ldap_freeError(&error); 2489*7c478bd9Sstevel@tonic-gate } 2490*7c478bd9Sstevel@tonic-gate if ((error = __ns_ldap_DumpConfiguration(NSCREDREFRESH)) != NULL) { 2491*7c478bd9Sstevel@tonic-gate logit("Error: __ns_ldap_DumpConfiguration(\"%s\") failed, " 2492*7c478bd9Sstevel@tonic-gate "status: %d " 2493*7c478bd9Sstevel@tonic-gate "message: %s\n", NSCREDREFRESH, 2494*7c478bd9Sstevel@tonic-gate error->status, error->message); 2495*7c478bd9Sstevel@tonic-gate __ns_ldap_freeError(&error); 2496*7c478bd9Sstevel@tonic-gate } 2497*7c478bd9Sstevel@tonic-gate if (rename(NSCONFIGREFRESH, NSCONFIGFILE) != 0) 2498*7c478bd9Sstevel@tonic-gate logit("Error: unlink failed - errno: %d\n", errno); 2499*7c478bd9Sstevel@tonic-gate if (rename(NSCREDREFRESH, NSCREDFILE) != 0) 2500*7c478bd9Sstevel@tonic-gate logit("Error: unlink failed - errno: %d\n", errno); 2501*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2502*7c478bd9Sstevel@tonic-gate 2503*7c478bd9Sstevel@tonic-gate } 2504*7c478bd9Sstevel@tonic-gate 2505*7c478bd9Sstevel@tonic-gate void 2506*7c478bd9Sstevel@tonic-gate getldap_refresh() 2507*7c478bd9Sstevel@tonic-gate { 2508*7c478bd9Sstevel@tonic-gate struct timespec timeout; 2509*7c478bd9Sstevel@tonic-gate int sleeptime; 2510*7c478bd9Sstevel@tonic-gate struct timeval tp; 2511*7c478bd9Sstevel@tonic-gate long expire = 0; 2512*7c478bd9Sstevel@tonic-gate void **paramVal = NULL; 2513*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *errorp; 2514*7c478bd9Sstevel@tonic-gate int always = 1, err; 2515*7c478bd9Sstevel@tonic-gate int first_time = 1; 2516*7c478bd9Sstevel@tonic-gate int sig_done = 0; 2517*7c478bd9Sstevel@tonic-gate int dbg_level; 2518*7c478bd9Sstevel@tonic-gate 2519*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2520*7c478bd9Sstevel@tonic-gate logit("getldap_refresh()...\n"); 2521*7c478bd9Sstevel@tonic-gate } 2522*7c478bd9Sstevel@tonic-gate 2523*7c478bd9Sstevel@tonic-gate /* 2524*7c478bd9Sstevel@tonic-gate * wait for an available server 2525*7c478bd9Sstevel@tonic-gate */ 2526*7c478bd9Sstevel@tonic-gate while (sig_done == 0) { 2527*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&sig_mutex); 2528*7c478bd9Sstevel@tonic-gate sig_done = signal_done; 2529*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&sig_mutex); 2530*7c478bd9Sstevel@tonic-gate } 2531*7c478bd9Sstevel@tonic-gate 2532*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_setServer(TRUE); 2533*7c478bd9Sstevel@tonic-gate while (always) { 2534*7c478bd9Sstevel@tonic-gate dbg_level = current_admin.debug_level; 2535*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ldap_lock); 2536*7c478bd9Sstevel@tonic-gate sleeptime = current_admin.ldap_stat.ldap_ttl; 2537*7c478bd9Sstevel@tonic-gate if (dbg_level >= DBG_PROFILE_REFRESH) { 2538*7c478bd9Sstevel@tonic-gate logit("getldap_refresh: current profile TTL is %d " 2539*7c478bd9Sstevel@tonic-gate "seconds\n", current_admin.ldap_stat.ldap_ttl); 2540*7c478bd9Sstevel@tonic-gate } 2541*7c478bd9Sstevel@tonic-gate if (gettimeofday(&tp, NULL) == 0) { 2542*7c478bd9Sstevel@tonic-gate if ((__ns_ldap_getParam(NS_LDAP_EXP_P, 2543*7c478bd9Sstevel@tonic-gate ¶mVal, &errorp) == NS_LDAP_SUCCESS) && 2544*7c478bd9Sstevel@tonic-gate paramVal != NULL && 2545*7c478bd9Sstevel@tonic-gate (char *)*paramVal != NULL) { 2546*7c478bd9Sstevel@tonic-gate errno = 0; 2547*7c478bd9Sstevel@tonic-gate expire = atol((char *)*paramVal); 2548*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶mVal); 2549*7c478bd9Sstevel@tonic-gate if (errno == 0) { 2550*7c478bd9Sstevel@tonic-gate if (expire == 0) { 2551*7c478bd9Sstevel@tonic-gate first_time = 0; 2552*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2553*7c478bd9Sstevel@tonic-gate (void) cond_init(&cond, 2554*7c478bd9Sstevel@tonic-gate NULL, NULL); 2555*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&sighuplock); 2556*7c478bd9Sstevel@tonic-gate timeout.tv_sec = 2557*7c478bd9Sstevel@tonic-gate CACHESLEEPTIME; 2558*7c478bd9Sstevel@tonic-gate timeout.tv_nsec = 0; 2559*7c478bd9Sstevel@tonic-gate if (dbg_level >= 2560*7c478bd9Sstevel@tonic-gate DBG_PROFILE_REFRESH) { 2561*7c478bd9Sstevel@tonic-gate logit("getldap_refresh: " 2562*7c478bd9Sstevel@tonic-gate "(1)about to sleep for %d " 2563*7c478bd9Sstevel@tonic-gate "seconds\n", 2564*7c478bd9Sstevel@tonic-gate CACHESLEEPTIME); 2565*7c478bd9Sstevel@tonic-gate } 2566*7c478bd9Sstevel@tonic-gate err = cond_reltimedwait(&cond, 2567*7c478bd9Sstevel@tonic-gate &sighuplock, &timeout); 2568*7c478bd9Sstevel@tonic-gate (void) cond_destroy(&cond); 2569*7c478bd9Sstevel@tonic-gate (void) mutex_unlock( 2570*7c478bd9Sstevel@tonic-gate &sighuplock); 2571*7c478bd9Sstevel@tonic-gate /* 2572*7c478bd9Sstevel@tonic-gate * if woke up by 2573*7c478bd9Sstevel@tonic-gate * getldap_revalidate(), 2574*7c478bd9Sstevel@tonic-gate * do update right away 2575*7c478bd9Sstevel@tonic-gate */ 2576*7c478bd9Sstevel@tonic-gate if (err == ETIME) 2577*7c478bd9Sstevel@tonic-gate continue; 2578*7c478bd9Sstevel@tonic-gate else { 2579*7c478bd9Sstevel@tonic-gate /* 2580*7c478bd9Sstevel@tonic-gate * if load 2581*7c478bd9Sstevel@tonic-gate * configuration failed 2582*7c478bd9Sstevel@tonic-gate * don't do update 2583*7c478bd9Sstevel@tonic-gate */ 2584*7c478bd9Sstevel@tonic-gate if (load_config()) 2585*7c478bd9Sstevel@tonic-gate perform_update(); 2586*7c478bd9Sstevel@tonic-gate continue; 2587*7c478bd9Sstevel@tonic-gate } 2588*7c478bd9Sstevel@tonic-gate } 2589*7c478bd9Sstevel@tonic-gate sleeptime = expire - tp.tv_sec; 2590*7c478bd9Sstevel@tonic-gate if (dbg_level >= DBG_PROFILE_REFRESH) { 2591*7c478bd9Sstevel@tonic-gate logit("getldap_refresh: expire time" 2592*7c478bd9Sstevel@tonic-gate " = %ld\n", expire); 2593*7c478bd9Sstevel@tonic-gate } 2594*7c478bd9Sstevel@tonic-gate 2595*7c478bd9Sstevel@tonic-gate } 2596*7c478bd9Sstevel@tonic-gate } 2597*7c478bd9Sstevel@tonic-gate } 2598*7c478bd9Sstevel@tonic-gate 2599*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2600*7c478bd9Sstevel@tonic-gate 2601*7c478bd9Sstevel@tonic-gate /* 2602*7c478bd9Sstevel@tonic-gate * if this is the first time downloading 2603*7c478bd9Sstevel@tonic-gate * the profile or expire time already passed, 2604*7c478bd9Sstevel@tonic-gate * do not wait, do update 2605*7c478bd9Sstevel@tonic-gate */ 2606*7c478bd9Sstevel@tonic-gate if (first_time == 0 && sleeptime > 0) { 2607*7c478bd9Sstevel@tonic-gate if (dbg_level >= DBG_PROFILE_REFRESH) { 2608*7c478bd9Sstevel@tonic-gate logit("getldap_refresh: (2)about to sleep " 2609*7c478bd9Sstevel@tonic-gate "for %d seconds\n", sleeptime); 2610*7c478bd9Sstevel@tonic-gate } 2611*7c478bd9Sstevel@tonic-gate (void) cond_init(&cond, NULL, NULL); 2612*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&sighuplock); 2613*7c478bd9Sstevel@tonic-gate timeout.tv_sec = sleeptime; 2614*7c478bd9Sstevel@tonic-gate timeout.tv_nsec = 0; 2615*7c478bd9Sstevel@tonic-gate err = cond_reltimedwait(&cond, 2616*7c478bd9Sstevel@tonic-gate &sighuplock, &timeout); 2617*7c478bd9Sstevel@tonic-gate (void) cond_destroy(&cond); 2618*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&sighuplock); 2619*7c478bd9Sstevel@tonic-gate } 2620*7c478bd9Sstevel@tonic-gate /* 2621*7c478bd9Sstevel@tonic-gate * if load concfiguration failed 2622*7c478bd9Sstevel@tonic-gate * don't do update 2623*7c478bd9Sstevel@tonic-gate */ 2624*7c478bd9Sstevel@tonic-gate if (load_config()) 2625*7c478bd9Sstevel@tonic-gate perform_update(); 2626*7c478bd9Sstevel@tonic-gate first_time = 0; 2627*7c478bd9Sstevel@tonic-gate } 2628*7c478bd9Sstevel@tonic-gate } 2629*7c478bd9Sstevel@tonic-gate 2630*7c478bd9Sstevel@tonic-gate void 2631*7c478bd9Sstevel@tonic-gate getldap_revalidate() 2632*7c478bd9Sstevel@tonic-gate { 2633*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2634*7c478bd9Sstevel@tonic-gate logit("getldap_revalidate()...\n"); 2635*7c478bd9Sstevel@tonic-gate } 2636*7c478bd9Sstevel@tonic-gate /* block signal SIGHUP */ 2637*7c478bd9Sstevel@tonic-gate (void) sighold(SIGHUP); 2638*7c478bd9Sstevel@tonic-gate 2639*7c478bd9Sstevel@tonic-gate /* now awake the sleeping refresh thread */ 2640*7c478bd9Sstevel@tonic-gate (void) cond_signal(&cond); 2641*7c478bd9Sstevel@tonic-gate 2642*7c478bd9Sstevel@tonic-gate /* release signal SIGHUP */ 2643*7c478bd9Sstevel@tonic-gate (void) sigrelse(SIGHUP); 2644*7c478bd9Sstevel@tonic-gate 2645*7c478bd9Sstevel@tonic-gate } 2646*7c478bd9Sstevel@tonic-gate 2647*7c478bd9Sstevel@tonic-gate void 2648*7c478bd9Sstevel@tonic-gate getldap_lookup(ldap_return_t *out, ldap_call_t *in) 2649*7c478bd9Sstevel@tonic-gate { 2650*7c478bd9Sstevel@tonic-gate LineBuf configinfo; 2651*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *error; 2652*7c478bd9Sstevel@tonic-gate 2653*7c478bd9Sstevel@tonic-gate if (current_admin.debug_level >= DBG_ALL) { 2654*7c478bd9Sstevel@tonic-gate logit("getldap_lookup()...\n"); 2655*7c478bd9Sstevel@tonic-gate } 2656*7c478bd9Sstevel@tonic-gate 2657*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ldap_lock); 2658*7c478bd9Sstevel@tonic-gate if ((error = __ns_ldap_LoadDoorInfo(&configinfo, in->ldap_u.domainname)) 2659*7c478bd9Sstevel@tonic-gate != NULL) { 2660*7c478bd9Sstevel@tonic-gate if (error != NULL && error->message != NULL) 2661*7c478bd9Sstevel@tonic-gate logit("Error: ldap_lookup: %s\n", error->message); 2662*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 2663*7c478bd9Sstevel@tonic-gate out->ldap_errno = -1; 2664*7c478bd9Sstevel@tonic-gate out->ldap_return_code = NOTFOUND; 2665*7c478bd9Sstevel@tonic-gate out->ldap_bufferbytesused = sizeof (*out); 2666*7c478bd9Sstevel@tonic-gate 2667*7c478bd9Sstevel@tonic-gate } else { 2668*7c478bd9Sstevel@tonic-gate out->ldap_bufferbytesused = sizeof (ldap_return_t); 2669*7c478bd9Sstevel@tonic-gate (void) strncpy(out->ldap_u.config, 2670*7c478bd9Sstevel@tonic-gate configinfo.str, configinfo.len); 2671*7c478bd9Sstevel@tonic-gate out->ldap_return_code = SUCCESS; 2672*7c478bd9Sstevel@tonic-gate out->ldap_errno = 0; 2673*7c478bd9Sstevel@tonic-gate } 2674*7c478bd9Sstevel@tonic-gate 2675*7c478bd9Sstevel@tonic-gate if (configinfo.str != NULL) { 2676*7c478bd9Sstevel@tonic-gate free(configinfo.str); 2677*7c478bd9Sstevel@tonic-gate configinfo.str = NULL; 2678*7c478bd9Sstevel@tonic-gate configinfo.alloc = 0; 2679*7c478bd9Sstevel@tonic-gate configinfo.len = 0; 2680*7c478bd9Sstevel@tonic-gate } 2681*7c478bd9Sstevel@tonic-gate 2682*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&ldap_lock); 2683*7c478bd9Sstevel@tonic-gate } 2684