//---------------------------------------------------------------------------------------- nsresult nsFileSpec::Rename(const char* inNewName) //---------------------------------------------------------------------------------------- { NS_ASSERTION(inNewName, "Attempt to Rename with a null string"); // This function should not be used to move a file on disk. if (mPath.IsEmpty() || strchr(inNewName, '/')) return NS_FILE_FAILURE; char* oldPath = nsCRT::strdup(mPath); SetLeafName(inNewName); if (PR_Rename(oldPath, mPath) != NS_OK) { // Could not rename, set back to the original. mPath = oldPath; nsCRT::free(oldPath); return NS_FILE_FAILURE; } nsCRT::free(oldPath); return NS_OK; } // nsFileSpec::Rename
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; }
/* * Delete a module from the Data Base */ SECStatus sftkdb_DeleteSecmodDB(SDBType dbType, const char *appName, const char *filename, const char *dbname, char *args, PRBool rw) { /* SHDB_FIXME implement */ FILE *fd = NULL; FILE *fd2 = NULL; char line[MAX_LINE_LENGTH]; char *dbname2 = NULL; char *block = NULL; char *name = NULL; char *lib = NULL; int name_len, lib_len; PRBool skip = PR_FALSE; PRBool found = PR_FALSE; if (dbname == NULL) { return SECFailure; } if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { return sftkdbCall_DeleteSecmodDB(appName, filename, dbname, args, rw); } if (!rw) { return SECFailure; } dbname2 = strdup(dbname); if (dbname2 == NULL) goto loser; dbname2[strlen(dbname)-1]++; /* do we really want to use streams here */ fd = fopen(dbname, "r"); if (fd == NULL) goto loser; #ifdef WINCE fd2 = fopen(dbname2, "w+"); #else fd2 = lfopen(dbname2, "w+", O_CREAT|O_RDWR|O_TRUNC); #endif if (fd2 == NULL) goto loser; name = sftk_argGetParamValue("name",args); if (name) { name_len = PORT_Strlen(name); } lib = sftk_argGetParamValue("library",args); if (lib) { lib_len = PORT_Strlen(lib); } /* * the following loop takes line separated config files and collapses * the lines to a single string, escaping and quoting as necessary. */ /* loop state variables */ block = NULL; skip = PR_FALSE; while (fgets(line, sizeof(line), fd) != NULL) { /* If we are processing a block (we haven't hit a blank line yet */ if (*line != '\n') { /* skip means we are in the middle of a block we are deleting */ if (skip) { continue; } /* if we haven't found the block yet, check to see if this block * matches our requirements */ if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) && (PORT_Strncmp(line+5,name,name_len) == 0)) || (lib && (PORT_Strncasecmp(line,"library=",8) == 0) && (PORT_Strncmp(line+8,lib,lib_len) == 0)))) { /* yup, we don't need to save any more data, */ PORT_Free(block); block=NULL; /* we don't need to collect more of this block */ skip = PR_TRUE; /* we don't need to continue searching for the block */ found =PR_TRUE; continue; } /* not our match, continue to collect data in this block */ block = sftkdb_DupCat(block,line); continue; } /* we've collected a block of data that wasn't the module we were * looking for, write it out */ if (block) { fwrite(block, PORT_Strlen(block), 1, fd2); PORT_Free(block); block = NULL; } /* If we didn't just delete the this block, keep the blank line */ if (!skip) { fputs(line,fd2); } /* we are definately not in a deleted block anymore */ skip = PR_FALSE; } fclose(fd); fclose(fd2); if (found) { /* rename dbname2 to dbname */ PR_Delete(dbname); PR_Rename(dbname2,dbname); } else { PR_Delete(dbname2); } PORT_Free(dbname2); PORT_Free(lib); PORT_Free(name); PORT_Free(block); return SECSuccess; loser: if (fd != NULL) { fclose(fd); } if (fd2 != NULL) { fclose(fd2); } if (dbname2) { PR_Delete(dbname2); PORT_Free(dbname2); } PORT_Free(lib); PORT_Free(name); return SECFailure; }
/* * Delete a module from the Data Base */ static SECStatus nssutil_DeleteSecmodDBEntry(const char *appName, const char *filename, const char *dbname, char *args, PRBool rw) { /* SHDB_FIXME implement */ os_stat_type stat_existing; os_open_permissions_type file_mode; FILE *fd = NULL; FILE *fd2 = NULL; char line[MAX_LINE_LENGTH]; char *dbname2 = NULL; char *block = NULL; char *name = NULL; char *lib = NULL; int name_len = 0, lib_len = 0; PRBool skip = PR_FALSE; PRBool found = PR_FALSE; if (dbname == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } if (!rw) { PORT_SetError(SEC_ERROR_READ_ONLY); return SECFailure; } dbname2 = PORT_Strdup(dbname); if (dbname2 == NULL) goto loser; dbname2[strlen(dbname)-1]++; /* get the permissions of the existing file, or use the default */ if (!os_stat(dbname, &stat_existing)) { file_mode = stat_existing.st_mode; } else { file_mode = os_open_permissions_default; } /* do we really want to use streams here */ fd = fopen(dbname, "r"); if (fd == NULL) goto loser; fd2 = lfopen(dbname2, lfopen_truncate, file_mode); if (fd2 == NULL) goto loser; name = NSSUTIL_ArgGetParamValue("name",args); if (name) { name_len = PORT_Strlen(name); } lib = NSSUTIL_ArgGetParamValue("library",args); if (lib) { lib_len = PORT_Strlen(lib); } /* * the following loop takes line separated config files and collapses * the lines to a single string, escaping and quoting as necessary. */ /* loop state variables */ block = NULL; skip = PR_FALSE; while (fgets(line, sizeof(line), fd) != NULL) { /* If we are processing a block (we haven't hit a blank line yet */ if (*line != '\n') { /* skip means we are in the middle of a block we are deleting */ if (skip) { continue; } /* if we haven't found the block yet, check to see if this block * matches our requirements */ if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) && (PORT_Strncmp(line+5,name,name_len) == 0)) || (lib && (PORT_Strncasecmp(line,"library=",8) == 0) && (PORT_Strncmp(line+8,lib,lib_len) == 0)))) { /* yup, we don't need to save any more data, */ PORT_Free(block); block=NULL; /* we don't need to collect more of this block */ skip = PR_TRUE; /* we don't need to continue searching for the block */ found =PR_TRUE; continue; } /* not our match, continue to collect data in this block */ block = nssutil_DupCat(block,line); continue; } /* we've collected a block of data that wasn't the module we were * looking for, write it out */ if (block) { fwrite(block, PORT_Strlen(block), 1, fd2); PORT_Free(block); block = NULL; } /* If we didn't just delete the this block, keep the blank line */ if (!skip) { fputs(line,fd2); } /* we are definately not in a deleted block anymore */ skip = PR_FALSE; } fclose(fd); fclose(fd2); if (found) { /* rename dbname2 to dbname */ PR_Delete(dbname); PR_Rename(dbname2,dbname); } else { PR_Delete(dbname2); } PORT_Free(dbname2); PORT_Free(lib); PORT_Free(name); PORT_Free(block); return SECSuccess; loser: if (fd != NULL) { fclose(fd); } if (fd2 != NULL) { fclose(fd2); } if (dbname2) { PR_Delete(dbname2); PORT_Free(dbname2); } PORT_Free(lib); PORT_Free(name); return SECFailure; }
void RunWriter(void* arg) { PR_SetCurrentThreadName("Shutdown Statistics Writer"); MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(arg); // Shutdown will generally complete before we have a chance to // deallocate. This is not a leak. // Setup destinationPath and tmpFilePath nsCString destinationPath(static_cast<char*>(arg)); nsAutoCString tmpFilePath; tmpFilePath.Append(destinationPath); tmpFilePath.AppendLiteral(".tmp"); // Cleanup any file leftover from a previous run Unused << PR_Delete(tmpFilePath.get()); Unused << PR_Delete(destinationPath.get()); while (true) { // // Check whether we have received data from the main thread. // // We perform the check before waiting on `gWriteReady` as we may // have received data while we were busy writing. // // Also note that gWriteData may have been modified several times // since we last checked. That's ok, we are not losing any important // data (since we keep adding data), and we are not leaking memory // (since the main thread deallocates any data that hasn't been // consumed by the writer thread). // UniquePtr<nsCString> data(gWriteData.exchange(nullptr)); if (!data) { // Data is not available yet. // Wait until the main thread provides it. PR_EnterMonitor(gWriteReady); PR_Wait(gWriteReady, PR_INTERVAL_NO_TIMEOUT); PR_ExitMonitor(gWriteReady); continue; } MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(data.get()); // Shutdown may complete before we have a chance to deallocate. // This is not a leak. // // Write to a temporary file // // In case of any error, we simply give up. Since the data is // hardly critical, we don't want to spend too much effort // salvaging it. // UniquePtr<PRFileDesc, PR_CloseDelete> tmpFileDesc(PR_Open(tmpFilePath.get(), PR_WRONLY | PR_TRUNCATE | PR_CREATE_FILE, 00600)); // Shutdown may complete before we have a chance to close the file. // This is not a leak. MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(tmpFileDesc.get()); if (tmpFileDesc == nullptr) { break; } if (PR_Write(tmpFileDesc.get(), data->get(), data->Length()) == -1) { break; } tmpFileDesc.reset(); // // Rename on top of destination file. // // This is not sufficient to guarantee that the destination file // will be written correctly, but, again, we don't care enough // about the data to make more efforts. // if (PR_Rename(tmpFilePath.get(), destinationPath.get()) != PR_SUCCESS) { break; } } }
/* 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; }
/** * Commits changes to the config file */ TPS_PUBLIC int ConfigStore::Commit(const bool backup, char *error_msg, int len) { char name_tmp[256], cdate[256], name_bak[256], bak_dir[256]; char basename[256], dirname[256]; PRFileDesc *ftmp = NULL; PRExplodedTime time; PRTime now; PRStatus status; if (m_cfg_file_path == NULL) { PR_snprintf(error_msg, len, "ConfigStore::Commit(): m_cfg_file_path is NULL!"); return 1; } if (strrchr(m_cfg_file_path, '/') != NULL) { PR_snprintf((char *) basename, 256, "%s", strrchr(m_cfg_file_path, '/') +1); PR_snprintf((char *) dirname, PL_strlen(m_cfg_file_path) - PL_strlen(basename), "%s", m_cfg_file_path); PL_strcat(dirname, '\0'); } else { PR_snprintf((char *) basename, 256, "%s", m_cfg_file_path); PR_snprintf((char *) dirname, 256, "."); } PR_snprintf(bak_dir, 256, "%s/bak", dirname); now = PR_Now(); PR_ExplodeTime(now, PR_LocalTimeParameters, &time); PR_snprintf(cdate, 16, "%04d%02d%02d%02d%02d%02dZ", time.tm_year, (time.tm_month + 1), time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec); PR_snprintf(name_tmp, 256, "%s.%s.tmp", m_cfg_file_path,cdate); PR_snprintf(name_bak, 256, "%s/%s.%s", bak_dir, basename, cdate); ftmp = PR_Open(name_tmp, PR_WRONLY| PR_CREATE_FILE, 00400|00200); if (ftmp == NULL) { // unable to create temporary config file PR_snprintf(error_msg, len, "ConfigStore::Commit(): unable to create temporary config file"); return 1; } PRCList order_list; PR_INIT_CLIST(&order_list); PR_Lock(m_lock); PL_HashTableEnumerateEntries(m_root->getSet(), &OrderLoop, &order_list); PR_Unlock(m_lock); PRCList *current = PR_LIST_HEAD(&order_list); PRCList *next; while (current != &order_list) { OrderedEntry_t *entry = (OrderedEntry_t *) current; PR_Write(ftmp, entry->key, PL_strlen(entry->key)); PR_Write(ftmp, "=", 1); const char *value = GetConfigAsString(entry->key, ""); PR_Write(ftmp, value, PL_strlen(value)); PR_Write(ftmp, "\n", 1); // free the memory for the Ordered Entry if (entry->key != NULL) PL_strfree(entry->key); next = PR_NEXT_LINK(current); PR_REMOVE_AND_INIT_LINK(current); if (current != NULL) { PR_Free(current); } current = next; } PR_Close(ftmp); if (backup) { // create the backup directory if it does not exist if (PR_Access(bak_dir, PR_ACCESS_EXISTS) != PR_SUCCESS) { PR_MkDir(bak_dir, 00770); } status = PR_Rename(m_cfg_file_path, name_bak); if (status != PR_SUCCESS) { // failed to back up CS.cfg } } if (PR_Access(m_cfg_file_path, PR_ACCESS_EXISTS) == PR_SUCCESS) { // backup is false, or backup failed status = PR_Delete(m_cfg_file_path); if (status != PR_SUCCESS) { // failed to delete old CS.cfg file PR_snprintf(error_msg, len, "ConfigStore::Commit(): unable to delete old CS.cfg file"); return 1; } } status = PR_Rename(name_tmp, m_cfg_file_path); if (status != PR_SUCCESS) { // failed to move tmp to CS.cfg // major badness - we now have only tmp file, no CS.cfg PR_snprintf(error_msg, len, "ConfigStore::Commit(): failed to move tmp file to CS.cfg"); return 1; } return 0; }
bool ValidWriteAssert(bool ok) { if (gShutdownChecks == SCM_CRASH && !ok) { MOZ_CRASH(); } // We normally don't poison writes if gShutdownChecks is SCM_NOTHING, but // write poisoning can get more users in the future (profiling for example), // so make sure we behave correctly. if (gShutdownChecks == SCM_NOTHING || ok || !sProfileDirectory || !Telemetry::CanRecord()) { return ok; } // Write the stack and loaded libraries to a file. We can get here // concurrently from many writes, so we use multiple temporary files. std::vector<uintptr_t> rawStack; NS_StackWalk(RecordStackWalker, /* skipFrames */ 0, /* maxFrames */ 0, reinterpret_cast<void*>(&rawStack), 0, nullptr); Telemetry::ProcessedStack stack = Telemetry::GetStackAndModules(rawStack); nsPrintfCString nameAux("%s%s%s", sProfileDirectory, NS_SLASH, "Telemetry.LateWriteTmpXXXXXX"); char *name; nameAux.GetMutableData(&name); // We want the sha1 of the entire file, so please don't write to fd // directly; use sha1Stream. FILE *stream; #ifdef XP_WIN HANDLE hFile; do { // mkstemp isn't supported so keep trying until we get a file int result = _mktemp_s(name, strlen(name) + 1); hFile = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); } while (GetLastError() == ERROR_FILE_EXISTS); if (hFile == INVALID_HANDLE_VALUE) { NS_RUNTIMEABORT("Um, how did we get here?"); } // http://support.microsoft.com/kb/139640 int fd = _open_osfhandle((intptr_t)hFile, _O_APPEND); if (fd == -1) { NS_RUNTIMEABORT("Um, how did we get here?"); } stream = _fdopen(fd, "w"); #else int fd = mkstemp(name); stream = fdopen(fd, "w"); #endif SHA1Stream sha1Stream(stream); size_t numModules = stack.GetNumModules(); sha1Stream.Printf("%u\n", (unsigned)numModules); for (size_t i = 0; i < numModules; ++i) { Telemetry::ProcessedStack::Module module = stack.GetModule(i); sha1Stream.Printf("%s %s\n", module.mBreakpadId.c_str(), module.mName.c_str()); } size_t numFrames = stack.GetStackSize(); sha1Stream.Printf("%u\n", (unsigned)numFrames); for (size_t i = 0; i < numFrames; ++i) { const Telemetry::ProcessedStack::Frame &frame = stack.GetFrame(i); // NOTE: We write the offsets, while the atos tool expects a value with // the virtual address added. For example, running otool -l on the the firefox // binary shows // cmd LC_SEGMENT_64 // cmdsize 632 // segname __TEXT // vmaddr 0x0000000100000000 // so to print the line matching the offset 123 one has to run // atos -o firefox 0x100000123. sha1Stream.Printf("%d %x\n", frame.mModIndex, (unsigned)frame.mOffset); } SHA1Sum::Hash sha1; sha1Stream.Finish(sha1); // Note: These files should be deleted by telemetry once it reads them. If // there were no telemery runs by the time we shut down, we just add files // to the existing ones instead of replacing them. Given that each of these // files is a bug to be fixed, that is probably the right thing to do. // We append the sha1 of the contents to the file name. This provides a simple // client side deduplication. nsPrintfCString finalName("%s%s", sProfileDirectory, "/Telemetry.LateWriteFinal-"); for (int i = 0; i < 20; ++i) { finalName.AppendPrintf("%02x", sha1[i]); } PR_Delete(finalName.get()); PR_Rename(name, finalName.get()); return false; }