/** * Initialise the modsecurity engine. This function must be invoked * after configuration processing is complete as Apache needs to know the * username it is running as. */ int modsecurity_init(msc_engine *msce, apr_pool_t *mp) { apr_status_t rc; /* auditlog互斥锁 */ rc = apr_global_mutex_create(&msce->auditlog_lock, NULL, APR_LOCK_DEFAULT, mp); if (rc != APR_SUCCESS) { return -1; } #ifdef __SET_MUTEX_PERMS #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2 rc = ap_unixd_set_global_mutex_perms(msce->auditlog_lock); #else rc = unixd_set_global_mutex_perms(msce->auditlog_lock); #endif if (rc != APR_SUCCESS) { return -1; } #endif /* SET_MUTEX_PERMS */ /* geo互斥锁 */ rc = apr_global_mutex_create(&msce->geo_lock, NULL, APR_LOCK_DEFAULT, mp); if (rc != APR_SUCCESS) { return -1; } #ifdef __SET_MUTEX_PERMS #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2 rc = ap_unixd_set_global_mutex_perms(msce->geo_lock); #else rc = unixd_set_global_mutex_perms(msce->geo_lock); #endif if (rc != APR_SUCCESS) { return -1; } #endif /* SET_MUTEX_PERMS */ #ifdef DEBUG_FILELOG const char *file_name = ap_server_root_relative(mp, "logs/audit_log"); rc = apr_file_open(&auditlog_fd, file_name, APR_WRITE | APR_APPEND | APR_CREATE | APR_BINARY, CREATEMODE, mp); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "Create or open audit failed."); return -1; } #endif return 1; }
int zcache_mutex_init(MCConfigRecord *mc,apr_pool_t *p) { apr_status_t rv; if (mc->nMutexMode == ZCACHE_MUTEXMODE_NONE) return TRUE; if ((rv = apr_global_mutex_create(&mc->pMutex, mc->szMutexFile, mc->nMutexMech, p)) != APR_SUCCESS) { /* if (mc->szMutexFile) ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot create STORAGEMutex with file `%s'", mc->szMutexFile); else ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot create STORAGEMutex");*/ return FALSE; } #ifdef MOD_ZCACHE_SET_MUTEX_PERMS rv = unixd_set_global_mutex_perms(mc->pMutex); if (rv != APR_SUCCESS) { /*ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Could not set permissions on stroage_mutex; check User " "and Group directives");*/ return FALSE; } #endif return TRUE; }
int ssl_mutex_init(server_rec *s, apr_pool_t *p) { SSLModConfigRec *mc = myModConfig(s); apr_status_t rv; if (mc->nMutexMode == SSL_MUTEXMODE_NONE) return TRUE; if ((rv = apr_global_mutex_create(&mc->pMutex, mc->szMutexFile, mc->nMutexMech, p)) != APR_SUCCESS) { if (mc->szMutexFile) ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot create SSLMutex with file `%s'", mc->szMutexFile); else ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot create SSLMutex"); return FALSE; } #ifdef MOD_SSL_SET_MUTEX_PERMS rv = unixd_set_global_mutex_perms(mc->pMutex); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Could not set permissions on ssl_mutex; check User " "and Group directives"); return FALSE; } #endif return TRUE; }
/* * initialized the shared memory block in the parent process */ int oidc_cache_shm_post_config(server_rec *s) { oidc_cfg *cfg = (oidc_cfg *) ap_get_module_config(s->module_config, &auth_openidc_module); if (cfg->cache_cfg != NULL) return APR_SUCCESS; oidc_cache_cfg_shm_t *context = oidc_cache_shm_cfg_create(s->process->pool); cfg->cache_cfg = context; /* create the shared memory segment */ apr_status_t rv = apr_shm_create(&context->shm, sizeof(oidc_cache_shm_entry_t) * cfg->cache_shm_size_max, NULL, s->process->pool); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "oidc_cache_shm_post_config: apr_shm_create failed to create shared memory segment"); return HTTP_INTERNAL_SERVER_ERROR; } /* initialize the whole segment to '/0' */ int i; oidc_cache_shm_entry_t *table = apr_shm_baseaddr_get(context->shm); for (i = 0; i < cfg->cache_shm_size_max; i++) { table[i].key[0] = '\0'; table[i].access = 0; } const char *dir; apr_temp_dir_get(&dir, s->process->pool); /* construct the mutex filename */ context->mutex_filename = apr_psprintf(s->process->pool, "%s/httpd_mutex.%ld.%pp", dir, (long int) getpid(), s); /* create the mutex lock */ rv = apr_global_mutex_create(&context->mutex, (const char *) context->mutex_filename, APR_LOCK_DEFAULT, s->process->pool); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "oidc_cache_shm_post_config: apr_global_mutex_create failed to create mutex on file %s", context->mutex_filename); return HTTP_INTERNAL_SERVER_ERROR; } /* need this on Linux */ #ifdef AP_NEED_SET_MUTEX_PERMS #if MODULE_MAGIC_NUMBER_MAJOR >= 20081201 rv = ap_unixd_set_global_mutex_perms(context->mutex); #else rv = unixd_set_global_mutex_perms(context->mutex); #endif if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "oidc_cache_shm_post_config: unixd_set_global_mutex_perms failed; could not set permissions "); return HTTP_INTERNAL_SERVER_ERROR; } #endif return OK; }
/* * shm init. it should be called in ap_hook_post_config phase * code partially from mod_auth_digest.c */ static int shm_init(apr_pool_t *p, server_rec *s) { apr_status_t ret; void *data; const char *userdata_key = "akismet_dummy_key"; /* initialize_module() will be called twice, and if it's a DSO * then all static data from the first call will be lost. Only * set up our static data on the second call. */ apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (!data) { apr_pool_userdata_set((const void *)1, userdata_key, apr_pool_cleanup_null, s->process->pool); return OK; /* This would be the first time through */ } if ( ret = apr_shm_create(&api_cache_shm, API_CACHE_SHM_SIZE, api_cache_shm_file, p) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, ret, s, "Failed to create shared segment file '%s'", api_cache_shm_file ); return HTTP_INTERNAL_SERVER_ERROR; } if (ret = apr_global_mutex_create(&global_lock, global_lock_file, APR_LOCK_DEFAULT, p) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, ret, s, "Failed to create global mutex file '%s'", global_lock_file); return HTTP_INTERNAL_SERVER_ERROR; } #ifdef AP_NEED_SET_MUTEX_PERMS if( ret = unixd_set_global_mutex_perms(global_lock) != APR_SUCCESS ) { ap_log_perror(APLOG_MARK, APLOG_CRIT, ret, p, "%s:Failed to set mutex permission. " "please check out parent process's privileges!"); return HTTP_INTERNAL_SERVER_ERROR; } #endif key_verified_infos = apr_shm_baseaddr_get(api_cache_shm); if (!key_verified_infos) { ap_log_error(APLOG_MARK, APLOG_CRIT, -1, s, "failed to allocate shared memory" ); return HTTP_INTERNAL_SERVER_ERROR; } /* Clear all key_verified_info */ int i; for (i = 0; i < NUM_BUCKETS; i++) { key_verified_infos[i].status = -1; memset(key_verified_infos[i].key, 0, 1024); } /* Register a cleanup function */ apr_pool_cleanup_register(p, NULL, cleanup_shm_resources, apr_pool_cleanup_null); return OK; }
/** * Initialise the modsecurity engine. This function must be invoked * after configuration processing is complete as Apache needs to know the * username it is running as. */ int modsecurity_init(msc_engine *msce, apr_pool_t *mp) { apr_status_t rc; /* Serial audit log mutext */ rc = apr_global_mutex_create(&msce->auditlog_lock, NULL, APR_LOCK_DEFAULT, mp); if (rc != APR_SUCCESS) { //ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "mod_security: Could not create modsec_auditlog_lock"); //return HTTP_INTERNAL_SERVER_ERROR; return -1; } #if !defined(MSC_TEST) #ifdef __SET_MUTEX_PERMS #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2 rc = ap_unixd_set_global_mutex_perms(msce->auditlog_lock); #else rc = unixd_set_global_mutex_perms(msce->auditlog_lock); #endif if (rc != APR_SUCCESS) { // ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, "mod_security: Could not set permissions on modsec_auditlog_lock; check User and Group directives"); // return HTTP_INTERNAL_SERVER_ERROR; return -1; } #endif /* SET_MUTEX_PERMS */ rc = apr_global_mutex_create(&msce->geo_lock, NULL, APR_LOCK_DEFAULT, mp); if (rc != APR_SUCCESS) { return -1; } #ifdef __SET_MUTEX_PERMS #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2 rc = ap_unixd_set_global_mutex_perms(msce->geo_lock); #else rc = unixd_set_global_mutex_perms(msce->geo_lock); #endif if (rc != APR_SUCCESS) { return -1; } #endif /* SET_MUTEX_PERMS */ #endif return 1; }
/* * This callback is called when the parent initialized. * Note that this can happen multiple times. */ static int but_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { void *data; const char *userdata_key = "but_init_module"; apr_status_t status; /* * The following checks if this routine has been called before. * This is necessary because the parent process gets initialized * a couple of times as the server starts up, and we don't want * to create any more mutexes and shared memory segments than * we're actually going to use. */ apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (!data) { apr_pool_userdata_set((const void *) 1, userdata_key, apr_pool_cleanup_null, s->process->pool); return OK; } /* Create the shared memory segments. */ status = but_shm_initialize(pconf, plog, ptemp, s); if (status != APR_SUCCESS) { ERRLOG_SRV_CRIT("Failed to initialize session SHM."); return HTTP_INTERNAL_SERVER_ERROR; } status = but_shm_initialize_cookiestore(pconf, plog, ptemp, s); if (status != APR_SUCCESS) { ERRLOG_SRV_CRIT("Failed to initialize cookiestore SHM."); return HTTP_INTERNAL_SERVER_ERROR; } /* Create the module mutex. */ /* * Create another unique filename to lock upon. Note that * depending on OS and locking mechanism of choice, the file * may or may not be actually created. */ status = apr_global_mutex_create(&but_mutex, tmpnam(NULL), APR_LOCK_DEFAULT, pconf); if (status != APR_SUCCESS) { ERRLOG_SRV_CRIT("Failed to create mutex."); return HTTP_INTERNAL_SERVER_ERROR; } #ifdef MOD_BUT_SET_MUTEX_PERMS status = unixd_set_global_mutex_perms(but_mutex); if (status != APR_SUCCESS) { ERRLOG_SRV_CRIT("Failed to set mutex permissions."); return HTTP_INTERNAL_SERVER_ERROR; } #endif /* MOD_BUT_SET_MUTEX_PERMS */ return OK; }
/* Set up startup-time initialization */ static int vlimit_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { VLIMIT_DEBUG_SYSLOG("vlimit_init: ", MODULE_NAME " " MODULE_VERSION " started.", p); if(apr_file_open(&vlimit_log_fp, VLIMIT_LOG_FILE, APR_WRITE|APR_APPEND|APR_CREATE, APR_OS_DEFAULT, p) != APR_SUCCESS){ return OK; } apr_status_t status; apr_size_t retsize; apr_size_t shm_size; int t; SHM_DATA *shm_data = NULL; shm_size = (apr_size_t) (sizeof(shm_data) + sizeof(shm_data->file_stat_shm) + sizeof(shm_data->ip_stat_shm)) * (conf_counter + 1); //Create global mutex status = apr_global_mutex_create(&vlimit_mutex, NULL, APR_LOCK_DEFAULT, p); if(status != APR_SUCCESS){ VLIMIT_DEBUG_SYSLOG("vlimit_init: ", "Error creating global mutex.", p); return status; } #ifdef AP_NEED_SET_MUTEX_PERMS status = unixd_set_global_mutex_perms(vlimit_mutex); if(status != APR_SUCCESS){ VLIMIT_DEBUG_SYSLOG("vlimit_init: ", "Error xrent could not set permissions on global mutex.", p); return status; } #endif if(apr_global_mutex_child_init(&vlimit_mutex, NULL, p)) VLIMIT_DEBUG_SYSLOG("vlimit_init: ", "global mutex attached.", p); /* If there was a memory block already assigned.. destroy it */ if (shm) { status = apr_shm_destroy(shm); if (status != APR_SUCCESS) { VLIMIT_DEBUG_SYSLOG("vlimit_init: ", "Couldn't destroy old memory block", p); return status; } else { VLIMIT_DEBUG_SYSLOG("vlimit_init: ", "Old Shared memory block, destroyed.", p); } } /* Create shared memory block */ status = apr_shm_create(&shm, shm_size, NULL, p); if (status != APR_SUCCESS) { VLIMIT_DEBUG_SYSLOG("vlimit_init: ", "Error creating shm block", p); return status; } /* Check size of shared memory block */ retsize = apr_shm_size_get(shm); if (retsize != shm_size) { VLIMIT_DEBUG_SYSLOG("vlimit_init: ", "Error allocating shared memory block", p); return status; } /* Init shm block */ shm_base = apr_shm_baseaddr_get(shm); if (shm_base == NULL) { VLIMIT_DEBUG_SYSLOG("vlimit_init", "Error creating status block.", p); return status; } memset(shm_base, 0, retsize); vlimit_debug_log_buf = apr_psprintf(p , "Memory Allocated %d bytes (each conf takes %d bytes) MaxClient:%d" , (int) retsize , (int) (sizeof(shm_data) + sizeof(shm_data->file_stat_shm) + sizeof(shm_data->ip_stat_shm)) , MAX_CLIENTS ); VLIMIT_DEBUG_SYSLOG("vlimit_init: ", vlimit_debug_log_buf, p); if (retsize < (sizeof(shm_data) * conf_counter)) { VLIMIT_DEBUG_SYSLOG("vlimit_init ", "Not enough memory allocated!! Giving up" , p); return HTTP_INTERNAL_SERVER_ERROR; } int i; for (t = 0; t <= conf_counter; t++) { shm_data = shm_base + t; for (i = 0; i < MAX_CLIENTS; i++) { shm_data->file_stat_shm[i].filename[0] = '\0'; shm_data->ip_stat_shm[i].address[0] = '\0'; shm_data->file_stat_shm[i].counter = 0; shm_data->ip_stat_shm[i].counter = 0; } } vlimit_debug_log_buf = apr_psprintf(p , "%s Version %s - Initialized [%d Conf]" , MODULE_NAME , MODULE_VERSION , conf_counter ); VLIMIT_DEBUG_SYSLOG("vlimit_init: ", vlimit_debug_log_buf, p); return OK; }
static int exipc_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { void *data; /* These two help ensure that we only init once. */ const char *userdata_key; apr_status_t rs; exipc_data *base; const char *tempdir; /* * The following checks if this routine has been called before. * This is necessary because the parent process gets initialized * a couple of times as the server starts up, and we don't want * to create any more mutexes and shared memory segments than * we're actually going to use. * * The key needs to be unique for the entire web server, so put * the module name in it. */ userdata_key = "example_ipc_init_module"; apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (!data) { /* * If no data was found for our key, this must be the first * time the module is initialized. Put some data under that * key and return. */ apr_pool_userdata_set((const void *) 1, userdata_key, apr_pool_cleanup_null, s->process->pool); return OK; } /* Kilroy was here */ /* * Both the shared memory and mutex allocation routines take a * file name. Depending on system-specific implementation of these * routines, that file may or may not actually be created. We'd * like to store those files in the operating system's designated * temporary directory, which APR can point us to. */ rs = apr_temp_dir_get(&tempdir, pconf); if (APR_SUCCESS != rs) { ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, "Failed to find temporary directory"); return HTTP_INTERNAL_SERVER_ERROR; } /* Create the shared memory segment */ /* * Create a unique filename using our pid. This information is * stashed in the global variable so the children inherit it. */ shmfilename = apr_psprintf(pconf, "%s/httpd_shm.%ld", tempdir, (long int)getpid()); /* Now create that segment */ rs = apr_shm_create(&exipc_shm, sizeof(exipc_data), (const char *) shmfilename, pconf); if (APR_SUCCESS != rs) { ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, "Failed to create shared memory segment on file %s", shmfilename); return HTTP_INTERNAL_SERVER_ERROR; } /* Created it, now let's zero it out */ base = (exipc_data *)apr_shm_baseaddr_get(exipc_shm); base->counter = 0; /* Create global mutex */ /* * Create another unique filename to lock upon. Note that * depending on OS and locking mechanism of choice, the file * may or may not be actually created. */ mutexfilename = apr_psprintf(pconf, "%s/httpd_mutex.%ld", tempdir, (long int) getpid()); rs = apr_global_mutex_create(&exipc_mutex, (const char *) mutexfilename, APR_LOCK_DEFAULT, pconf); if (APR_SUCCESS != rs) { ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, "Failed to create mutex on file %s", mutexfilename); return HTTP_INTERNAL_SERVER_ERROR; } /* * After the mutex is created, its permissions need to be adjusted * on unix platforms so that the child processe can acquire * it. This call takes care of that. The preprocessor define was * set up early in this source file since Apache doesn't provide * it. */ #ifdef MOD_EXIPC_SET_MUTEX_PERMS rs = unixd_set_global_mutex_perms(exipc_mutex); if (APR_SUCCESS != rs) { ap_log_error(APLOG_MARK, APLOG_CRIT, rs, s, "Parent could not set permissions on Example IPC " "mutex: check User and Group directives"); return HTTP_INTERNAL_SERVER_ERROR; } #endif /* MOD_EXIPC_SET_MUTEX_PERMS */ /* * Destroy the shm segment when the configuration pool gets destroyed. This * happens on server restarts. The parent will then (above) allocate a new * shm segment that the new children will bind to. */ apr_pool_cleanup_register(pconf, NULL, shm_cleanup_wrapper, apr_pool_cleanup_null); return OK; }
int upload_progress_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { apr_status_t result; server_rec *s_vhost; ServerConfig *st_vhost; ServerConfig *config = (ServerConfig*)ap_get_module_config(s->module_config, &upload_progress_module); void *data; const char *userdata_key = "upload_progress_init"; /* upload_progress_init will be called twice. Don't bother * going through all of the initialization on the first call * because it will just be thrown away.*/ apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (!data) { apr_pool_userdata_set((const void *)1, userdata_key, apr_pool_cleanup_null, s->process->pool); #if APR_HAS_SHARED_MEMORY /* If the cache file already exists then delete it. Otherwise we are * going to run into problems creating the shared memory. */ if (config->cache_file) { char *lck_file = apr_pstrcat(ptemp, config->cache_file, ".lck", NULL); apr_file_remove(lck_file, ptemp); } #endif return OK; } #if APR_HAS_SHARED_MEMORY /* initializing cache if shared memory size is not zero and we already * don't have shm address */ if (!config->cache_shm && config->cache_bytes > 0) { #endif result = upload_progress_cache_init(p, config); if (result != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, result, s, "Upload Progress cache: could not create shared memory segment"); return DONE; } #if APR_HAS_SHARED_MEMORY if (config->cache_file) { config->lock_file = apr_pstrcat(config->pool, config->cache_file, ".lck", NULL); } #endif result = apr_global_mutex_create(&config->cache_lock, config->lock_file, APR_LOCK_DEFAULT, config->pool); if (result != APR_SUCCESS) { return result; } #ifdef AP_NEED_SET_MUTEX_PERMS result = unixd_set_global_mutex_perms(config->cache_lock); if (result != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, result, s, "Upload progress cache: failed to set mutex permissions"); return result; } #endif /* merge config in all vhost */ s_vhost = s->next; while (s_vhost) { st_vhost = (ServerConfig *) ap_get_module_config(s_vhost->module_config, &upload_progress_module); #if APR_HAS_SHARED_MEMORY st_vhost->cache_shm = config->cache_shm; st_vhost->cache_rmm = config->cache_rmm; st_vhost->cache_file = config->cache_file; st_vhost->cache_offset = config->cache_offset; st_vhost->cache = config->cache; ap_log_error(APLOG_MARK, APLOG_DEBUG, result, s, "Upload Progress: merging Shared Cache conf: shm=0x%pp rmm=0x%pp " "for VHOST: %s", config->cache_shm, config->cache_rmm, s_vhost->server_hostname); #endif st_vhost->lock_file = config->lock_file; s_vhost = s_vhost->next; } #if APR_HAS_SHARED_MEMORY } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Upload Progress cache: cache size is zero, disabling " "shared memory cache"); } #endif return(OK); }
static int mod_mapcache_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { apr_status_t rc; mapcache_server_cfg* cfg = ap_get_module_config(s->module_config, &mapcache_module); apr_lockmech_e lock_type = APR_LOCK_DEFAULT; server_rec *sconf; if(!cfg) { ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, "configuration not found in server context"); return 1; } #if APR_HAS_PROC_PTHREAD_SERIALIZE lock_type = APR_LOCK_PROC_PTHREAD; #endif rc = apr_global_mutex_create(&cfg->mutex,cfg->mutex_name,lock_type,p); if(rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s, "Could not create global parent mutex %s", cfg->mutex_name); return rc; } #ifdef AP_NEED_SET_MUTEX_PERMS rc = unixd_set_global_mutex_perms(cfg->mutex); if(rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s, "Could not set permissions on global parent mutex %s", cfg->mutex_name); return rc; } #endif apr_pool_cleanup_register(p,cfg->mutex, (void*)apr_global_mutex_destroy, apr_pool_cleanup_null); #ifndef DISABLE_VERSION_STRING ap_add_version_component(p, MAPCACHE_USERAGENT); #endif for (sconf = s->next; sconf; sconf = sconf->next) { mapcache_server_cfg* config = ap_get_module_config(sconf->module_config, &mapcache_module); config->mutex = cfg->mutex; } #if APR_HAS_FORK /* fork a child process to let it accomplish post-configuration tasks with the uid of the runtime user */ apr_proc_t proc; apr_status_t rv; rv = apr_proc_fork(&proc, ptemp); if (rv == APR_INCHILD) { #define ap_unixd_setup_child unixd_setup_child ap_unixd_setup_child(); mapcache_context *ctx = (mapcache_context*)apache_server_context_create(s,p); for (sconf = s; sconf; sconf = sconf->next) { mapcache_server_cfg* config = ap_get_module_config(sconf->module_config, &mapcache_module); if(config->aliases) { apr_hash_index_t *entry = apr_hash_first(ptemp,config->aliases); /* loop through the configured configurations */ while (entry) { const char *alias; apr_ssize_t aliaslen; mapcache_cfg *c; apr_hash_this(entry,(const void**)&alias,&aliaslen,(void**)&c); mapcache_configuration_post_config(ctx, c); if(GC_HAS_ERROR(ctx)) { ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "post config for %s failed: %s", alias, ctx->get_error_message(ctx)); exit(APR_EGENERAL); } entry = apr_hash_next(entry); } } } exit(0); } else if (rv == APR_INPARENT) { apr_exit_why_e exitwhy; int exitcode; apr_proc_wait(&proc,&exitcode,&exitwhy,APR_WAIT); if(exitwhy != APR_PROC_EXIT) { ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "mapcache post-config child terminated abnormally"); return APR_EGENERAL; } else { if(exitcode != 0) { return APR_EGENERAL; } } return OK; } else { ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "failed to fork mapcache post-config child"); return APR_EGENERAL; } #else /* APR_HAS_FORK */ mapcache_context *ctx = (mapcache_context*)apache_server_context_create(s,p); for (sconf = s; sconf; sconf = sconf->next) { mapcache_server_cfg* config = ap_get_module_config(sconf->module_config, &mapcache_module); if(config->aliases) { apr_hash_index_t *entry = apr_hash_first(ptemp,config->aliases); /* loop through the configured configurations */ while (entry) { const char *alias; apr_ssize_t aliaslen; mapcache_cfg *c; apr_hash_this(entry,(const void**)&alias,&aliaslen,(void**)&c); mapcache_configuration_post_config(ctx, c); if(GC_HAS_ERROR(ctx)) { ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "post config for %s failed: %s", alias, ctx->get_error_message(ctx)); return APR_EGENERAL; } entry = apr_hash_next(entry); } } } return OK; #endif }
/* * This routine is called in the parent, so we'll set up the shared * memory segments and mutexs here. */ static int dosblock_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { void *data; /* These two help ensure that we only init once. */ const char *userdata_key; apr_status_t rs; const char *tempdir; dosblockipc_data *base; dosblock_cfg *cfg = (dosblock_cfg *)ap_get_module_config(s->module_config, &mod_dosblock_module); /* * The following checks if this routine has been called before. * This is necessary because the parent process gets initialized * a couple of times as the server starts up, and we don't want * to create any more mutexes and shared memory segments than * we're actually going to use. * * The key needs to be unique for the entire web server, so put * the module name in it. */ userdata_key = "dosblock_ipc_init_module"; apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (!data) { /* * If no data was found for our key, this must be the first * time the module is initialized. Put some data under that * key and return. */ apr_pool_userdata_set((const void *) 1, userdata_key, apr_pool_cleanup_null, s->process->pool); return OK; } /* * The shared memory allocation routines take a file name. * Depending on system-specific implementation of these * routines, that file may or may not actually be created. We'd * like to store those files in the operating system's designated * temporary directory, which APR can point us to. */ rs = apr_temp_dir_get(&tempdir, pconf); if (APR_SUCCESS != rs) { ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, "Failed to find temporary directory"); return HTTP_INTERNAL_SERVER_ERROR; } /* Create the shared memory segments. We also populate a dosrule to shared * memory mapping table with all the shared memory segments */ const apr_array_header_t *tarr = apr_table_elts(cfg->dosrulemap); const apr_table_entry_t *telts = (const apr_table_entry_t*)tarr->elts; int i; for (i = 0; i < tarr->nelts; ++i) { /* * Create a unique filename using our pid. This information is * stashed in the global variable so the children inherit it. */ shmfilename = apr_psprintf(pconf, "%s/httpd_shm_%s.%ld", tempdir, telts[i].key, (long int)getpid()); mutex_filename = apr_psprintf(pconf, "%s/httpd_mutex_%s.%ld", tempdir, telts[i].key, (long int)getpid()); /* Now create that shm segment. We prefer anonymous shm */ rs = apr_shm_create(&dosblockipc_shm[i], sizeof(dosblockipc_data), NULL, pconf); if (APR_ENOTIMPL == rs) { rs = apr_shm_create(&dosblockipc_shm[i], sizeof(dosblockipc_data), (const char *) shmfilename, pconf); } if (APR_SUCCESS != rs) { ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, "Failed to create shared memory segment on file %s", shmfilename); return HTTP_INTERNAL_SERVER_ERROR; } apr_hash_set(cfg->dosrule_shm_map, telts[i].key, APR_HASH_KEY_STRING, apr_psprintf(pconf, "%d",i)); if (cfg->verbosity) ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "Dos Rule configured is %s", telts[i].key); base = (dosblockipc_data *)apr_shm_baseaddr_get(dosblockipc_shm[i]); /* Now initialise the array of structs. Zero it out */ base->ds.t = 0; base->ds.isblocked = 0; base->ds.rate_when_blocked = 0; base->next = 0; int j; for (j=0; j<ARSIZE; j++) { base->dh[j].t = 0; base->dh[j].counter = 0; } /* Create global mutex */ rs = apr_global_mutex_create(&dosblockipc_mutex[i], mutex_filename, APR_LOCK_DEFAULT, pconf); if (APR_SUCCESS != rs) { return HTTP_INTERNAL_SERVER_ERROR; } #ifdef AP_NEED_SET_MUTEX_PERMS rs = unixd_set_global_mutex_perms(dosblockipc_mutex[i]); if (rs != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rs, s, "mod_dosblock: Parent could not set permissions " "on shared memory; check User and Group directives"); return rs; } #endif apr_table_set(cfg->dosrule_mutex_map, telts[i].key, mutex_filename); } /* * Destroy the shm segment when the configuration pool gets destroyed. This *happens on server restarts. The parent will then (above) allocate a new * shm segment that the new children will bind to. */ /* apr_pool_cleanup_register(pconf, NULL, shm_cleanup_wrapper(), apr_pool_cleanup_null); */ return OK; }