void db_put_dn(char *data_dn) { int ret; char *db_path = DATABASE; char *db_path_bak = DATABASE_BACK; PRFileInfo64 info; PRFileDesc *prfd; PRInt32 data_sz; char *data_dnp = NULL; if(db_lock == NULL){ db_lock = PR_NewLock(); } PR_Lock(db_lock); /* if db_path is a directory, rename it */ ret = PR_GetFileInfo64(db_path, &info); if (PR_SUCCESS == ret) { if (PR_FILE_DIRECTORY == info.type) { /* directory */ ret = PR_GetFileInfo64(db_path_bak, &info); if (PR_SUCCESS == ret) { if (PR_FILE_DIRECTORY != info.type) { /* not a directory */ PR_Delete(db_path_bak); } } PR_Rename(db_path, db_path_bak); } } /* open a file */ if ((prfd = PR_Open(db_path, PR_RDWR | PR_CREATE_FILE | PR_APPEND, 0600)) == NULL ) { slapi_log_error(SLAPI_LOG_FATAL, DB_PLUGIN_NAME, "db: Could not open file \"%s\" for read/write; %d (%s)\n", db_path, PR_GetError(), slapd_pr_strerror(PR_GetError())); return; } data_dnp = slapi_ch_smprintf("%s\n", data_dn); data_sz = (PRInt32)strlen(data_dnp); ret = PR_Write(prfd, data_dnp, data_sz); if (ret == data_sz) { slapi_log_error(SLAPI_LOG_PLUGIN, DB_PLUGIN_NAME, "db: %s: key stored.\n", data_dn); ret = 0; } else { slapi_log_error(SLAPI_LOG_FATAL, DB_PLUGIN_NAME, "db: Failed to store key \"%s\"; %d (%s)\n", data_dn, PR_GetError(), slapd_pr_strerror(PR_GetError())); ret = 1; } if(ret) { slapi_log_error(SLAPI_LOG_FATAL, DB_PLUGIN_NAME, "db: Error detected in db_put_dn \n"); } slapi_ch_free_string(&data_dnp); PR_Close(prfd); PR_Unlock(db_lock); return; }
static int _csngen_start_test_threads(CSNGen *gen) { int i; PR_ASSERT (gen); s_thread_count = 0; s_must_exit = 0; /* create threads that generate csns */ for(i=0; i< GEN_TREAD_COUNT; i++) { if (PR_CreateThread(PR_USER_THREAD, _csngen_gen_tester_main, gen, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE) == NULL) { PRErrorCode prerr = PR_GetError(); slapi_log_err(SLAPI_LOG_ERR, "_csngen_start_test_threads", "Failed to create a CSN generator thread number %d; " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", i, prerr, slapd_pr_strerror(prerr)); return -1; } s_thread_count ++; } /* create a thread that modifies remote time */ if (PR_CreateThread(PR_USER_THREAD, _csngen_remote_tester_main, (void *)gen, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE) == NULL) { PRErrorCode prerr = PR_GetError(); slapi_log_err(SLAPI_LOG_ERR, "_csngen_start_test_threads", "Failed to create the remote CSN tester thread; " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", prerr, slapd_pr_strerror(prerr)); return -1; } s_thread_count ++; /* create a thread that modifies local time */ if (PR_CreateThread(PR_USER_THREAD, _csngen_local_tester_main, (void *)gen, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE) == NULL) { PRErrorCode prerr = PR_GetError(); slapi_log_err(SLAPI_LOG_ERR, "_csngen_start_test_threads", "Failed to create the local CSN tester thread; " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", prerr, slapd_pr_strerror(prerr)); return -1; } s_thread_count ++; return 0; }
/* mkdir -p */ int mkdir_p(char *dir, unsigned int mode) { PRFileInfo info; int rval; char sep = get_sep(dir); rval = PR_GetFileInfo(dir, &info); if (PR_SUCCESS == rval) { if (PR_FILE_DIRECTORY != info.type) /* not a directory */ { PR_Delete(dir); if (PR_SUCCESS != PR_MkDir(dir, mode)) { LDAPDebug(LDAP_DEBUG_ANY, "mkdir_p %s: error %d (%s)\n", dir, PR_GetError(),slapd_pr_strerror(PR_GetError())); return -1; } } return 0; } else { /* does not exist */ char *p, *e; char c[2] = {0, 0}; int len = strlen(dir); rval = 0; e = dir + len - 1; if (*e == sep) { c[1] = *e; *e = '\0'; } c[0] = '/'; p = strrchr(dir, sep); if (NULL != p) { *p = '\0'; rval = mkdir_p(dir, mode); *p = c[0]; } if (c[1]) *e = c[1]; if (0 != rval) return rval; if (PR_SUCCESS != PR_MkDir(dir, mode)) { LDAPDebug(LDAP_DEBUG_ANY, "mkdir_p %s: error %d (%s)\n", dir, PR_GetError(),slapd_pr_strerror(PR_GetError())); return -1; } return 0; } }
/* * mempool_init creates NSPR thread private index, * then allocates per-thread-private. * mempool is initialized at the first mempool_return */ static void mempool_init(struct mempool **my_mempool) { int i; if (NULL == my_mempool) { return; } #ifdef SHARED_MEMPOOL for (i = 0; MEMPOOL_END != mempool[i].mempool_name; i++) { mempool[i].mempool_mutex = PR_NewLock(); if (NULL == mempool[i].mempool_mutex) { PRErrorCode ec = PR_GetError(); slapi_log_err(SLAPI_LOG_ERR, "mempool", "mempool_init: " "failed to create mutex - (%d - %s); mempool(%s) is disabled", ec, slapd_pr_strerror(ec), mempool[i].mempool_name); rc = LDAP_OPERATIONS_ERROR; } } #else PR_NewThreadPrivateIndex (&mempool_index, mempool_destroy); *my_mempool = (struct mempool *)slapi_ch_calloc(MAX_MEMPOOL, sizeof(struct mempool)); for (i = 0; i < MAX_MEMPOOL; i++) { (*my_mempool)[i].mempool_name = mempool_names[i]; } #endif }
/* * Add the given pblock to the list of outstanding persistent searches. * Then, start a thread to send the results to the client as they * are dispatched by add, modify, and modrdn operations. */ void ps_add( Slapi_PBlock *pb, ber_int_t changetypes, int send_entchg_controls ) { PSearch *ps; if ( PS_IS_INITIALIZED() && NULL != pb ) { /* Create the new node */ ps = psearch_alloc(); ps->ps_pblock = pb; ps->ps_changetypes = changetypes; ps->ps_send_entchg_controls = send_entchg_controls; /* Add it to the head of the list of persistent searches */ ps_add_ps( ps ); /* Start a thread to send the results */ ps->ps_tid = PR_CreateThread( PR_USER_THREAD, ps_send_results, (void *) ps, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE ); /* Checking if the thread is succesfully created and * if the thread is not created succesfully.... we send * error messages to the Log file */ if(NULL == (ps->ps_tid)){ int prerr; prerr = PR_GetError(); LDAPDebug(LDAP_DEBUG_ANY,"persistent search PR_CreateThread()failed in the " "ps_add function: " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", prerr, slapd_pr_strerror(prerr), 0); /* Now remove the ps from the list so call the function ps_remove */ ps_remove(ps); PR_DestroyLock ( ps->ps_lock ); ps->ps_lock = NULL; slapi_ch_free((void **) &ps->ps_pblock ); slapi_ch_free((void **) &ps ); } } }
/* * Write this record to the log file */ void writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn, char *newrdn, Slapi_DN *newsuperior, Slapi_DN *requestorsdn) { PRFileDesc *prfd; char buffer[MAX_LINE]; int len_to_write = 0; int rc; const char *requestordn = NULL; const char *newsuperiordn = NULL; size_t reqdn_len = 0; /* * Use this lock to protect file data when update integrity is occuring. * If betxn is enabled, this mutex is ignored; transaction itself takes * the role. */ referint_lock(); if (( prfd = PR_Open( logfilename, PR_WRONLY | PR_CREATE_FILE | PR_APPEND, REFERINT_DEFAULT_FILE_MODE )) == NULL ) { slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_postop could not write integrity log \"%s\" " SLAPI_COMPONENT_NAME_NSPR " %d (%s)\n", logfilename, PR_GetError(), slapd_pr_strerror(PR_GetError()) ); PR_Unlock(referint_mutex); referint_unlock(); return; } /* * Make sure we have enough room in our buffer before trying to write it. * add length of dn + 5(three tabs, a newline, and terminating \0) */ len_to_write = slapi_sdn_get_ndn_len(sdn) + 5; if(newrdn == NULL){ /* add the length of "NULL" */ len_to_write += 4; } else { /* add the length of the newrdn */ len_to_write += strlen(newrdn); } newsuperiordn = slapi_sdn_get_dn(newsuperior); if(NULL == newsuperiordn) { /* add the length of "NULL" */ len_to_write += 4; } else { /* add the length of the newsuperior */ len_to_write += slapi_sdn_get_ndn_len(newsuperior); } slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &requestordn); if (requestorsdn && (requestordn = slapi_sdn_get_udn(requestorsdn)) && (reqdn_len = strlen(requestordn))) { len_to_write += reqdn_len; } else { len_to_write += 4; /* "NULL" */ } if(len_to_write > MAX_LINE ){ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_postop could not write integrity log:" " line length exceeded. It will not be able" " to update references to this entry.\n"); } else { PR_snprintf(buffer, MAX_LINE, "%s\t%s\t%s\t%s\t\n", slapi_sdn_get_dn(sdn), (newrdn != NULL) ? newrdn : "NULL", (newsuperiordn != NULL) ? newsuperiordn : "NULL", requestordn ? requestordn : "NULL"); if (PR_Write(prfd,buffer,strlen(buffer)) < 0){ slapi_log_error(SLAPI_LOG_FATAL,REFERINT_PLUGIN_SUBSYSTEM, " writeintegritylog: PR_Write failed : The disk" " may be full or the file is unwritable :: NSPR error - %d\n", PR_GetError()); } } /* If file descriptor is closed successfully, PR_SUCCESS */ rc = PR_Close(prfd); if (rc != PR_SUCCESS){ slapi_log_error(SLAPI_LOG_FATAL,REFERINT_PLUGIN_SUBSYSTEM, " writeintegritylog: failed to close the file descriptor prfd; NSPR error - %d\n", PR_GetError()); } referint_unlock(); }
/* Extract just the configuration information we need for bootstrapping purposes 1) set up error logging 2) disable syntax checking 3) load the syntax plugins etc. */ int slapd_bootstrap_config(const char *configdir) { char configfile[MAXPATHLEN+1]; PRFileInfo prfinfo; int rc = 0; /* Fail */ int done = 0; PRInt32 nr = 0; PRFileDesc *prfd = 0; char *buf = 0; char *lastp = 0; char *entrystr = 0; if (NULL == configdir) { slapi_log_error(SLAPI_LOG_FATAL, "startup", "Passed null config directory\n"); return rc; /* Fail */ } PR_snprintf(configfile, sizeof(configfile), "%s/%s", configdir, CONFIG_FILENAME); if ( (rc = PR_GetFileInfo( configfile, &prfinfo )) != PR_SUCCESS ) { /* the "real" file does not exist; see if there is a tmpfile */ char tmpfile[MAXPATHLEN+1]; slapi_log_error(SLAPI_LOG_FATAL, "config", "The configuration file %s does not exist\n", configfile); PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.tmp", configdir, CONFIG_FILENAME); if ( PR_GetFileInfo( tmpfile, &prfinfo ) == PR_SUCCESS ) { rc = PR_Rename(tmpfile, configfile); if (rc == PR_SUCCESS) { slapi_log_error(SLAPI_LOG_FATAL, "config", "The configuration file %s was restored from backup %s\n", configfile, tmpfile); } else { slapi_log_error(SLAPI_LOG_FATAL, "config", "The configuration file %s was not restored from backup %s, error %d\n", configfile, tmpfile, rc); return rc; /* Fail */ } } else { slapi_log_error(SLAPI_LOG_FATAL, "config", "The backup configuration file %s does not exist, either.\n", tmpfile); return rc; /* Fail */ } } if ( (rc = PR_GetFileInfo( configfile, &prfinfo )) != PR_SUCCESS ) { PRErrorCode prerr = PR_GetError(); slapi_log_error(SLAPI_LOG_FATAL, "config", "The given config file %s could not be accessed, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", configfile, prerr, slapd_pr_strerror(prerr)); return rc; } else if (( prfd = PR_Open( configfile, PR_RDONLY, SLAPD_DEFAULT_FILE_MODE )) == NULL ) { PRErrorCode prerr = PR_GetError(); slapi_log_error(SLAPI_LOG_FATAL, "config", "The given config file %s could not be opened for reading, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", configfile, prerr, slapd_pr_strerror(prerr)); return rc; /* Fail */ } else { /* read the entire file into core */ buf = slapi_ch_malloc( prfinfo.size + 1 ); if (( nr = slapi_read_buffer( prfd, buf, prfinfo.size )) < 0 ) { slapi_log_error(SLAPI_LOG_FATAL, "config", "Could only read %d of %d bytes from config file %s\n", nr, prfinfo.size, configfile); rc = 0; /* Fail */ done= 1; } (void)PR_Close(prfd); buf[ nr ] = '\0'; if(!done) { char workpath[MAXPATHLEN+1]; char loglevel[BUFSIZ]; char maxdescriptors[BUFSIZ]; char val[BUFSIZ]; char _localuser[BUFSIZ]; char logenabled[BUFSIZ]; char schemacheck[BUFSIZ]; char syntaxcheck[BUFSIZ]; char syntaxlogging[BUFSIZ]; char plugintracking[BUFSIZ]; char dn_validate_strict[BUFSIZ]; Slapi_DN plug_dn; workpath[0] = loglevel[0] = maxdescriptors[0] = '\0'; val[0] = logenabled[0] = schemacheck[0] = syntaxcheck[0] = '\0'; syntaxlogging[0] = _localuser[0] = '\0'; plugintracking [0] = dn_validate_strict[0] = '\0'; /* Convert LDIF to entry structures */ slapi_sdn_init_ndn_byref(&plug_dn, PLUGIN_BASE_DN); while ((entrystr = dse_read_next_entry(buf, &lastp)) != NULL) { char errorbuf[BUFSIZ]; /* * XXXmcs: it would be better to also pass * SLAPI_STR2ENTRY_REMOVEDUPVALS in the flags, but * duplicate value checking requires that the syntax * and schema subsystems be initialized... and they * are not yet. */ Slapi_Entry *e = slapi_str2entry(entrystr, SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF); if (e == NULL) { LDAPDebug(LDAP_DEBUG_ANY, "The entry [%s] in the configfile %s was empty or could not be parsed\n", entrystr, configfile, 0); continue; } /* increase file descriptors */ #if !defined(_WIN32) && !defined(AIX) if (!maxdescriptors[0] && entry_has_attr_and_value(e, CONFIG_MAXDESCRIPTORS_ATTRIBUTE, maxdescriptors, sizeof(maxdescriptors))) { if (config_set_maxdescriptors( CONFIG_MAXDESCRIPTORS_ATTRIBUTE, maxdescriptors, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_MAXDESCRIPTORS_ATTRIBUTE, errorbuf); } } #endif /* !defined(_WIN32) && !defined(AIX) */ /* see if we need to enable error logging */ if (!logenabled[0] && entry_has_attr_and_value(e, CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE, logenabled, sizeof(logenabled))) { if (log_set_logging( CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE, logenabled, SLAPD_ERROR_LOG, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE, errorbuf); } } #ifndef _WIN32 /* set the local user name; needed to set up error log */ if (!_localuser[0] && entry_has_attr_and_value(e, CONFIG_LOCALUSER_ATTRIBUTE, _localuser, sizeof(_localuser))) { if (config_set_localuser(CONFIG_LOCALUSER_ATTRIBUTE, _localuser, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_LOCALUSER_ATTRIBUTE, errorbuf); } } #endif /* set the log file name */ workpath[0] = '\0'; if (!workpath[0] && entry_has_attr_and_value(e, CONFIG_ERRORLOG_ATTRIBUTE, workpath, sizeof(workpath))) { if (config_set_errorlog(CONFIG_ERRORLOG_ATTRIBUTE, workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_ERRORLOG_ATTRIBUTE, errorbuf); } } /* set the error log level */ if (!loglevel[0] && entry_has_attr_and_value(e, CONFIG_LOGLEVEL_ATTRIBUTE, loglevel, sizeof(loglevel))) { if (should_detach || !config_get_errorlog_level()) { /* -d wasn't on command line */ if (config_set_errorlog_level(CONFIG_LOGLEVEL_ATTRIBUTE, loglevel, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_LOGLEVEL_ATTRIBUTE, errorbuf); } } else { LDAPDebug(LDAP_DEBUG_ANY, "%s: ignoring %s (since -d %d was given on " "the command line)\n", CONFIG_LOGLEVEL_ATTRIBUTE, loglevel, config_get_errorlog_level()); } } /* set the cert dir; needed in slapd_nss_init */ workpath[0] = '\0'; if (entry_has_attr_and_value(e, CONFIG_CERTDIR_ATTRIBUTE, workpath, sizeof(workpath))) { if (config_set_certdir(CONFIG_CERTDIR_ATTRIBUTE, workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_CERTDIR_ATTRIBUTE, errorbuf); } } /* set the sasl path; needed in main */ workpath[0] = '\0'; if (entry_has_attr_and_value(e, CONFIG_SASLPATH_ATTRIBUTE, workpath, sizeof(workpath))) { if (config_set_saslpath(CONFIG_SASLPATH_ATTRIBUTE, workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_SASLPATH_ATTRIBUTE, errorbuf); } } #if defined(ENABLE_LDAPI) /* set the ldapi file path; needed in main */ workpath[0] = '\0'; if (entry_has_attr_and_value(e, CONFIG_LDAPI_FILENAME_ATTRIBUTE, workpath, sizeof(workpath))) { if (config_set_ldapi_filename(CONFIG_LDAPI_FILENAME_ATTRIBUTE, workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_LDAPI_FILENAME_ATTRIBUTE, errorbuf); } } /* set the ldapi switch; needed in main */ workpath[0] = '\0'; if (entry_has_attr_and_value(e, CONFIG_LDAPI_SWITCH_ATTRIBUTE, workpath, sizeof(workpath))) { if (config_set_ldapi_switch(CONFIG_LDAPI_SWITCH_ATTRIBUTE, workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_LDAPI_SWITCH_ATTRIBUTE, errorbuf); } } #endif /* see if the entry is a child of the plugin base dn */ if (slapi_sdn_isparent(&plug_dn, slapi_entry_get_sdn_const(e))) { if (entry_has_attr_and_value(e, "objectclass", "nsSlapdPlugin", 0) && (entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE, "syntax", 0) || entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE, "matchingrule", 0))) { /* add the syntax/matching scheme rule plugin */ if (plugin_setup(e, 0, 0, 1)) { LDAPDebug(LDAP_DEBUG_ANY, "The plugin entry [%s] in the configfile %s was invalid\n", slapi_entry_get_dn(e), configfile, 0); rc = 0; slapi_sdn_done(&plug_dn); goto bail; } } } /* see if the entry is a grand child of the plugin base dn */ if (slapi_sdn_isgrandparent(&plug_dn, slapi_entry_get_sdn_const(e))) { if (entry_has_attr_and_value(e, "objectclass", "nsSlapdPlugin", 0) && ( entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE, "pwdstoragescheme", 0) || entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE, "reverpwdstoragescheme", 0) ) ) { /* add the pwd storage scheme rule plugin */ if (plugin_setup(e, 0, 0, 1)) { LDAPDebug(LDAP_DEBUG_ANY, "The plugin entry [%s] in the configfile %s was invalid\n", slapi_entry_get_dn(e), configfile, 0); rc = 0; slapi_sdn_done(&plug_dn); goto bail; } } } /* see if we need to disable schema checking */ if (!schemacheck[0] && entry_has_attr_and_value(e, CONFIG_SCHEMACHECK_ATTRIBUTE, schemacheck, sizeof(schemacheck))) { if (config_set_schemacheck(CONFIG_SCHEMACHECK_ATTRIBUTE, schemacheck, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_SCHEMACHECK_ATTRIBUTE, errorbuf); } } /* see if we need to enable plugin binddn tracking */ if (!plugintracking[0] && entry_has_attr_and_value(e, CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE, plugintracking, sizeof(plugintracking))) { if (config_set_plugin_tracking(CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE, plugintracking, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE, errorbuf); } } /* see if we need to enable syntax checking */ if (!syntaxcheck[0] && entry_has_attr_and_value(e, CONFIG_SYNTAXCHECK_ATTRIBUTE, syntaxcheck, sizeof(syntaxcheck))) { if (config_set_syntaxcheck(CONFIG_SYNTAXCHECK_ATTRIBUTE, syntaxcheck, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_SYNTAXCHECK_ATTRIBUTE, errorbuf); } } /* see if we need to enable syntax warnings */ if (!syntaxlogging[0] && entry_has_attr_and_value(e, CONFIG_SYNTAXLOGGING_ATTRIBUTE, syntaxlogging, sizeof(syntaxlogging))) { if (config_set_syntaxlogging(CONFIG_SYNTAXLOGGING_ATTRIBUTE, syntaxlogging, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_SYNTAXLOGGING_ATTRIBUTE, errorbuf); } } /* see if we need to enable strict dn validation */ if (!dn_validate_strict[0] && entry_has_attr_and_value(e, CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE, dn_validate_strict, sizeof(dn_validate_strict))) { if (config_set_dn_validate_strict(CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE, dn_validate_strict, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE, errorbuf); } } /* see if we need to expect quoted schema values */ if (entry_has_attr_and_value(e, CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, val, sizeof(val))) { if (config_set_enquote_sup_oc( CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, errorbuf); } val[0] = 0; } /* see if we need to maintain case in AT and OC names */ if (entry_has_attr_and_value(e, CONFIG_RETURN_EXACT_CASE_ATTRIBUTE, val, sizeof(val))) { if (config_set_return_exact_case( CONFIG_RETURN_EXACT_CASE_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_RETURN_EXACT_CASE_ATTRIBUTE, errorbuf); } val[0] = 0; } /* see if we should allow attr. name exceptions, e.g. '_'s */ if (entry_has_attr_and_value(e, CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE, val, sizeof(val))) { if (config_set_attrname_exceptions( CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE, errorbuf); } val[0] = 0; } /* see if we need to maintain schema compatibility with 4.x */ if (entry_has_attr_and_value(e, CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE, val, sizeof(val))) { if (config_set_ds4_compatible_schema( CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE, errorbuf); } val[0] = 0; } /* see if we need to allow trailing spaces in OC and AT names */ if (entry_has_attr_and_value(e, CONFIG_SCHEMA_IGNORE_TRAILING_SPACES, val, sizeof(val))) { if (config_set_schema_ignore_trailing_spaces( CONFIG_SCHEMA_IGNORE_TRAILING_SPACES, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_SCHEMA_IGNORE_TRAILING_SPACES, errorbuf); } val[0] = 0; } /* rfc1274-rewrite */ if (entry_has_attr_and_value(e, CONFIG_REWRITE_RFC1274_ATTRIBUTE, val, sizeof(val))) { if (config_set_rewrite_rfc1274( CONFIG_REWRITE_RFC1274_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_REWRITE_RFC1274_ATTRIBUTE, errorbuf); } val[0] = 0; } /* what is our localhost name */ if (entry_has_attr_and_value(e, CONFIG_LOCALHOST_ATTRIBUTE, val, sizeof(val))) { if (config_set_localhost( CONFIG_LOCALHOST_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_LOCALHOST_ATTRIBUTE, errorbuf); } val[0] = 0; } if (e) slapi_entry_free(e); } /* kexcoff: initialize rootpwstoragescheme and pw_storagescheme * if not explicilty set in the config file */ if ( config_set_storagescheme() ) { /* default scheme plugin not loaded */ slapi_log_error(SLAPI_LOG_FATAL, "startup", "The default password storage scheme SSHA could not be read or was not found in the file %s. It is mandatory.\n", configfile); exit (1); } else { slapi_sdn_done(&plug_dn); rc= 1; /* OK */ } } slapi_ch_free_string(&buf); } bail: slapi_ch_free_string(&buf); return rc; }
static int passthru_bindpreop( Slapi_PBlock *pb ) { int rc, method, freeresctrls=1; char *matcheddn; const char *normbinddn = NULL; Slapi_DN *sdn = NULL; char *libldap_errmsg, *pr_errmsg, *errmsg; PassThruConfig *cfg; PassThruServer *srvr; struct berval *creds, **urls; LDAPControl **reqctrls, **resctrls; PASSTHRU_ASSERT( pb != NULL ); slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM, "=> passthru_bindpreop\n" ); /* * retrieve parameters for bind operation */ if ( slapi_pblock_get( pb, SLAPI_BIND_METHOD, &method ) != 0 || slapi_pblock_get( pb, SLAPI_BIND_TARGET_SDN, &sdn ) != 0 || slapi_pblock_get( pb, SLAPI_BIND_CREDENTIALS, &creds ) != 0 ) { slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM, "<= not handled (unable to retrieve bind parameters)\n" ); return( PASSTHRU_OP_NOT_HANDLED ); } normbinddn = slapi_sdn_get_dn(sdn); if ( normbinddn == NULL ) { normbinddn = ""; } /* * We only handle simple bind requests that include non-NULL binddn and * credentials. Let the Directory Server itself handle everything else. */ if ( method != LDAP_AUTH_SIMPLE || *normbinddn == '\0' || creds->bv_len == 0 ) { slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM, "<= not handled (not simple bind or NULL dn/credentials)\n" ); return( PASSTHRU_OP_NOT_HANDLED ); } /* * Get pass through authentication configuration. */ cfg = passthru_get_config(); /* * Check to see if the target DN is one we should "pass through" to * another server. */ if ( passthru_dn2server( cfg, normbinddn, &srvr ) != LDAP_SUCCESS ) { slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM, "<= not handled (not one of our suffixes)\n" ); return( PASSTHRU_OP_NOT_HANDLED ); } /* * We are now committed to handling this bind request. * Chain it off to another server. */ matcheddn = errmsg = libldap_errmsg = pr_errmsg = NULL; urls = NULL; resctrls = NULL; if ( slapi_pblock_get( pb, SLAPI_REQCONTROLS, &reqctrls ) != 0 ) { rc = LDAP_OPERATIONS_ERROR; errmsg = "unable to retrieve bind controls"; slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM, "%s\n", errmsg ); } else { int lderrno; if (( rc = passthru_simple_bind_s( pb, srvr, PASSTHRU_CONN_TRIES, normbinddn, creds, reqctrls, &lderrno, &matcheddn, &libldap_errmsg, &urls, &resctrls )) == LDAP_SUCCESS ) { rc = lderrno; errmsg = libldap_errmsg; } else if ( rc != LDAP_USER_CANCELLED ) { /* not abandoned */ PRErrorCode prerr = PR_GetError(); pr_errmsg = PR_smprintf( "error %d - %s %s (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", rc, ldap_err2string( rc ), srvr->ptsrvr_url, prerr, slapd_pr_strerror(prerr)); if ( NULL != pr_errmsg ) { errmsg = pr_errmsg; } else { errmsg = ldap_err2string( rc ); } rc = LDAP_OPERATIONS_ERROR; } } /* * If bind succeeded, change authentication information associated * with this connection. */ if ( rc == LDAP_SUCCESS ) { char *ndn = slapi_ch_strdup( normbinddn ); if (slapi_pblock_set(pb, SLAPI_CONN_DN, ndn) != 0 || slapi_pblock_set(pb, SLAPI_CONN_AUTHMETHOD, SLAPD_AUTH_SIMPLE) != 0) { slapi_ch_free((void **)&ndn); rc = LDAP_OPERATIONS_ERROR; errmsg = "unable to set connection DN or AUTHTYPE"; slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM, "%s\n", errmsg ); } } if ( rc != LDAP_USER_CANCELLED ) { /* not abandoned */ /* * Send a result to our client. */ if ( resctrls != NULL ) { (void)slapi_pblock_set( pb, SLAPI_RESCONTROLS, resctrls ); freeresctrls=0; } slapi_send_ldap_result( pb, rc, matcheddn, errmsg, 0, urls ); } /* * Clean up -- free allocated memory, etc. */ if ( urls != NULL ) { passthru_free_bervals( urls ); } if ( libldap_errmsg != NULL ) { ldap_memfree( errmsg ); } if ( pr_errmsg != NULL ) { PR_smprintf_free( pr_errmsg ); } if ( freeresctrls && (resctrls != NULL) ) { ldap_controls_free( resctrls ); } if ( matcheddn != NULL ) { ldap_memfree( matcheddn ); } slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM, "<= handled (error %d - %s)\n", rc, ldap_err2string( rc )); return( PASSTHRU_OP_HANDLED ); }
int cb_get_connection(cb_conn_pool * pool, LDAP ** lld, cb_outgoing_conn ** cc, struct timeval * maxtime, char **errmsg) { int rc=LDAP_SUCCESS; /* optimistic */ cb_outgoing_conn *conn=NULL; cb_outgoing_conn *connprev=NULL; LDAP *ld=NULL; time_t endbefore=0; int checktime=0; struct timeval bind_to, op_to; unsigned int maxconcurrency,maxconnections; char *password,*binddn,*hostname; unsigned int port; int secure; char *mech = NULL;; static char *error1="Can't contact remote server : %s"; int isMultiThread = ENABLE_MULTITHREAD_PER_CONN ; /* by default, we enable multiple operations per connection */ /* ** return an error if we can't get a connection ** before the operation timeout has expired ** bind_timeout: timeout for the bind operation (if bind needed) ** ( checked in ldap_result ) ** op_timeout: timeout for the op that needs a connection ** ( checked in the loop ) */ *cc=NULL; slapi_rwlock_rdlock(pool->rwl_config_lock); maxconcurrency=pool->conn.maxconcurrency; maxconnections=pool->conn.maxconnections; bind_to.tv_sec = pool->conn.bind_timeout.tv_sec; bind_to.tv_usec = pool->conn.bind_timeout.tv_usec; op_to.tv_sec = pool->conn.op_timeout.tv_sec; op_to.tv_usec = pool->conn.op_timeout.tv_usec; /* SD 02/10/2000 temp fix */ /* allow dynamic update of the binddn & password */ /* host, port and security mode */ /* previous values are NOT freed when changed */ /* won't likely to be changed often */ /* pointers put in the waste basket fields and */ /* freed when the backend is stopped. */ password=pool->password; binddn=pool->binddn; hostname=pool->hostname; port=pool->port; secure=pool->secure; if (pool->starttls) { secure = 2; } mech=pool->mech; slapi_rwlock_unlock(pool->rwl_config_lock); if (secure) { isMultiThread = DISABLE_MULTITHREAD_PER_CONN ; } /* For stupid admins */ if (maxconnections <=0) { static int warned_maxconn = 0; if (!warned_maxconn) { slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - Error (no connection available)\n"); warned_maxconn = 1; } if ( errmsg ) { *errmsg = slapi_ch_smprintf("%s", ENDUSERMSG); } return LDAP_CONNECT_ERROR; } if (maxtime) { if (maxtime->tv_sec != 0) { checktime=1; endbefore = current_time() + maxtime->tv_sec; /* make sure bind to <= operation timeout */ if ((bind_to.tv_sec==0) || (bind_to.tv_sec > maxtime->tv_sec)) bind_to.tv_sec=maxtime->tv_sec; } } else { if (op_to.tv_sec != 0) { checktime=1; endbefore = current_time() + op_to.tv_sec; /* make sure bind to <= operation timeout */ if ((bind_to.tv_sec==0) || (bind_to.tv_sec > op_to.tv_sec)) bind_to.tv_sec=op_to.tv_sec; } } /* * Close (or mark to be closed) any connections for this farm server that have * exceeded the maximum connection lifetime. */ cb_check_for_stale_connections(pool); /* * Look for an available, already open connection */ slapi_lock_mutex( pool->conn.conn_list_mutex ); if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - server %s conns: %d maxconns: %d\n", hostname, pool->conn.conn_list_count, maxconnections ); } for (;;) { /* time limit mgmt */ if (checktime) { if (current_time() > endbefore ) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - server %s expired.\n", hostname ); if ( errmsg ) { *errmsg = PR_smprintf(error1,"timelimit exceeded"); } rc=LDAP_TIMELIMIT_EXCEEDED; conn=NULL; ld=NULL; goto unlock_and_return; } } /* * First, look for an available, already open/bound connection */ if (secure) { for (conn = pool->connarray[PR_ThreadSelf()]; conn != NULL; conn = conn->next) { if ((conn->ThreadId == PR_MyThreadId()) && (conn->status == CB_CONNSTATUS_OK && conn->refcount < maxconcurrency)){ if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - server found conn 0x%p to use)\n", conn ); } goto unlock_and_return; /* found one */ } } } else { connprev = NULL; for ( conn = pool->conn.conn_list; conn != NULL; conn = conn->next ) { if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - conn 0x%p status %d refcount %lu\n", conn, conn->status, conn->refcount ); } if ( conn->status == CB_CONNSTATUS_OK && conn->refcount < maxconcurrency ) { if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - server found conn 0x%p to use)\n", conn ); } goto unlock_and_return; /* found one */ } connprev = conn; } } if ( secure || pool->conn.conn_list_count <maxconnections) { int version=LDAP_VERSION3; /* * we have not exceeded the maximum number of connections allowed, * so we initialize a new one and add it to the end of our list. */ /* No need to lock. url can't be changed dynamically */ ld = slapi_ldap_init(hostname, port, secure, isMultiThread); if (NULL == ld) { static int warned_init = 0; if (!warned_init) { slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - Can't contact server <%s> port <%d>.\n", hostname, port ); warned_init = 1; } if ( errmsg ) { *errmsg = slapi_ch_smprintf("%s", ENDUSERMSG); } rc = LDAP_CONNECT_ERROR; goto unlock_and_return; } ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); /* Don't chase referrals */ ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF ); /* no controls and simple bind only */ /* For now, bind even if no user to detect error */ /* earlier */ if (pool->bindit) { PRErrorCode prerr = 0; LDAPControl **serverctrls=NULL; char *plain = NULL; int ret = -1; rc=LDAP_SUCCESS; if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - Bind to to server <%s> port <%d> as <%s>\n", hostname, port, binddn); } ret = pw_rever_decode(password, &plain, CB_CONFIG_USERPASSWORD); /* Pb occured in decryption: stop now, binding will fail */ if ( ret == -1 ) { static int warned_pw = 0; if (!warned_pw) { slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - Internal credentials decoding error; " "password storage schemes do not match or " "encrypted password is corrupted.\n"); warned_pw = 1; } if ( errmsg ) { *errmsg = slapi_ch_smprintf("%s", ENDUSERMSG); } rc = LDAP_INVALID_CREDENTIALS; goto unlock_and_return; } /* Password-based client authentication */ rc = slapi_ldap_bind(ld, binddn, plain, mech, NULL, &serverctrls, &bind_to, NULL); if ( ret == 0 ) slapi_ch_free_string(&plain); /* free plain only if it has been duplicated */ if ( rc == LDAP_TIMEOUT ) { static int warned_bind_timeout = 0; if (!warned_bind_timeout) { slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - Can't bind to server <%s> port <%d>. (%s)\n", hostname, port, "time-out expired"); warned_bind_timeout = 1; } if ( errmsg ) { *errmsg = slapi_ch_smprintf("%s", ENDUSERMSG); } rc = LDAP_CONNECT_ERROR; goto unlock_and_return; } else if ( rc != LDAP_SUCCESS ) { prerr=PR_GetError(); static int warned_bind_err = 0; if (!warned_bind_err) { slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - Can't bind to server <%s> port <%d>. " "(LDAP error %d - %s; " SLAPI_COMPONENT_NAME_NSPR " error %d - %s)\n", hostname, port, rc, ldap_err2string(rc), prerr, slapd_pr_strerror(prerr)); warned_bind_err = 1; } if ( errmsg ) { *errmsg = slapi_ch_smprintf("%s", ENDUSERMSG); } rc = LDAP_CONNECT_ERROR; goto unlock_and_return; } if ( serverctrls ) { int i; for( i = 0; serverctrls[ i ] != NULL; ++i ) { if ( !(strcmp( serverctrls[ i ]->ldctl_oid, LDAP_CONTROL_PWEXPIRED)) ) { /* Bind is successful but password has expired */ slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - Successfully bound as %s to remote server %s:%d, " "but password has expired.\n", binddn, hostname, port); } else if ( !(strcmp( serverctrls[ i ]->ldctl_oid, LDAP_CONTROL_PWEXPIRING)) ) { /* The password is expiring in n seconds */ if ( (serverctrls[ i ]->ldctl_value.bv_val != NULL) && (serverctrls[ i ]->ldctl_value.bv_len > 0) ) { int password_expiring = atoi( serverctrls[ i ]->ldctl_value.bv_val ); slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - Successfully bound as %s to remote server %s:%d, " "but password is expiring in %d seconds.\n", binddn, hostname, port, password_expiring); } } } ldap_controls_free(serverctrls); } } else if (secure == 2) { /* the start_tls operation is usually performed in slapi_ldap_bind, but since we are not binding we still need to start_tls */ if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - doing start_tls on connection 0x%p\n", conn ); } if ((rc = ldap_start_tls_s(ld, NULL, NULL))) { PRErrorCode prerr = PR_GetError(); slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - Unable to do start_tls on connection to %s:%d " "LDAP error %d:%s NSS error %d:%s\n", hostname, port, rc, ldap_err2string(rc), prerr, slapd_pr_strerror(prerr)); goto unlock_and_return; } } conn = (cb_outgoing_conn *) slapi_ch_malloc(sizeof(cb_outgoing_conn)); conn->ld=ld; conn->status=CB_CONNSTATUS_OK; conn->refcount=0; /* incremented below */ conn->opentime=current_time(); conn->ThreadId=PR_MyThreadId(); /* store the thread id */ conn->next=NULL; if (secure) { if (pool->connarray[PR_ThreadSelf()] == NULL) { pool->connarray[PR_ThreadSelf()] = conn; } else { conn->next = pool->connarray[PR_ThreadSelf()]; pool->connarray[PR_ThreadSelf()] = conn ; } } else { if ( NULL == connprev ) { pool->conn.conn_list = conn; } else { connprev->next=conn; } } ++pool->conn.conn_list_count; if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - added new conn 0x%p, " "conn count now %d\n", conn->ld, pool->conn.conn_list_count ); } goto unlock_and_return; /* got a new one */ } if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - waiting for conn to free up\n" ); } if (!secure) slapi_wait_condvar( pool->conn.conn_list_cv, NULL ); if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - awake again\n" ); } } unlock_and_return: if ( conn != NULL ) { ++conn->refcount; *lld=conn->ld; *cc=conn; if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - ld=0x%p (concurrency now %lu)\n",*lld, conn->refcount ); } } else { if ( NULL != ld ) { slapi_ldap_unbind( ld ); } if (cb_debug_on()) { slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM, "cb_get_connection - error %d\n", rc ); } } slapi_unlock_mutex(pool->conn.conn_list_mutex); return( rc ); }
static int dbverify_ext( ldbm_instance *inst, int verbose ) { char dbdir[MAXPATHLEN]; char *filep = NULL; PRDir *dirhandle = NULL; PRDirEntry *direntry = NULL; DB *dbp = NULL; size_t tmplen = 0; size_t filelen = 0; int rval = 1; int rval_main = 0; struct ldbminfo *li = inst->inst_li; dblayer_private *priv = (dblayer_private*)li->li_dblayer_private; struct dblayer_private_env *pEnv = priv->dblayer_env; dbdir[sizeof(dbdir)-1] = '\0'; PR_snprintf(dbdir, sizeof(dbdir), "%s/%s", inst->inst_parent_dir_name, inst->inst_dir_name); if ('\0' != dbdir[sizeof(dbdir)-1]) /* overflown */ { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "db path too long: %s/%s\n", inst->inst_parent_dir_name, inst->inst_dir_name); return 1; } tmplen = strlen(dbdir); filep = dbdir + tmplen; filelen = sizeof(dbdir) - tmplen; /* run dbverify on each each db file */ dirhandle = PR_OpenDir(dbdir); if (! dirhandle) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "PR_OpenDir (%s) failed (%d): %s\n", dbdir, PR_GetError(),slapd_pr_strerror(PR_GetError())); return 1; } while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) { /* struct attrinfo *ai = NULL; */ dbp = NULL; if (!direntry->name) { break; } if (!strstr(direntry->name, LDBM_FILENAME_SUFFIX)) /* non db file */ { continue; } if (sizeof(direntry->name) + 2 > filelen) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "db path too long: %s/%s\n", dbdir, direntry->name); continue; } PR_snprintf(filep, filelen, "/%s", direntry->name); rval = db_create(&dbp, pEnv->dblayer_DB_ENV, 0); if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to create id2entry db file %d\n", rval); return rval; } #define VLVPREFIX "vlv#" if (0 != strncmp(direntry->name, ID2ENTRY, strlen(ID2ENTRY))) { struct attrinfo *ai = NULL; char *p = NULL; p = strstr(filep, LDBM_FILENAME_SUFFIX); /* since already checked, it must have it */ if(p) *p = '\0'; ainfo_get( inst->inst_be, filep+1, &ai ); if(p) *p = '.'; if (ai->ai_key_cmp_fn) { dbp->app_private = (void *)ai->ai_key_cmp_fn; dbp->set_bt_compare(dbp, dblayer_bt_compare); } if (idl_get_idl_new()) { rval = dbp->set_pagesize(dbp, (priv->dblayer_index_page_size == 0) ? DBLAYER_INDEX_PAGESIZE : priv->dblayer_index_page_size); } else { rval = dbp->set_pagesize(dbp, (priv->dblayer_page_size == 0) ? DBLAYER_PAGESIZE : priv->dblayer_page_size); } if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "DB verify", "Unable to set pagesize flags to db (%d)\n", rval); return rval; } if (0 == strncmp(direntry->name, VLVPREFIX, strlen(VLVPREFIX))) { rval = dbp->set_flags(dbp, DB_RECNUM); if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to set RECNUM flag to vlv index (%d)\n", rval); return rval; } } else if (idl_get_idl_new()) { rval = dbp->set_flags(dbp, DB_DUP | DB_DUPSORT); if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to set DUP flags to db (%d)\n", rval); return rval; } if (ai->ai_dup_cmp_fn) { /* If set, use the special dup compare callback */ rval = dbp->set_dup_compare(dbp, ai->ai_dup_cmp_fn); } else { rval = dbp->set_dup_compare(dbp, idl_new_compare_dups); } if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to set dup_compare to db (%d)\n", rval); return rval; } } } #undef VLVPREFIX rval = dbp->verify(dbp, dbdir, NULL, NULL, 0); if (0 == rval) { if (verbose) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "%s: ok\n", dbdir); } } else { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "verify failed(%d): %s\n", rval, dbdir); } rval_main |= rval; *filep = '\0'; } PR_CloseDir(dirhandle); return rval_main; }