/**************************************************************************** mod_dav_pgsql (DASL) for apache 2.X CopyRight(C) 2005 SolutionBox Inc. All Rights reserved. Author : sean kim (sean@solutionbox.co.kr) $Id: main.c,v 1.2 2007/01/25 06:52:16 elenoa Exp $ Redistribution and use in source and binary forms, with or with out modification, are not permitted in outside of SolutionBox Inc. ****************************************************************************/ #include #include #include #include #include /* for ap_construct_url */ #include #include #include #include #include #include "dav_repos.h" #include "dbms.h" #include "util.h" #include "share_common.h" #include "share_statistic.h" #include "share_anonymous.h" #include "transfer.h" #include "inout_filter.h" #define INHERIT_VALUE(parent, child, field) \ ((child)->field ? (child)->field : (parent)->field) #define DBMS_PRIVIDER_NAME "repos" #define MaxSizeOfQueryBuffer 1024 /* Note: the "dav_repos" prefix is mandatory */ extern module AP_MODULE_DECLARE_DATA dav_repos_module; #if APR_HAS_THREADS apr_thread_rwlock_t *db_lock = NULL; #endif //apr_global_mutex_t *db_global_lock = NULL; // 2012.07.04 dadamin // FreeBSD 경우 getmntent 함수 쓰레드 지원하지 않기 때문에 // 관련 함수 사용 로직에 lock을 사용하여 이를 대처함 #ifdef __FreeBSD__ apr_global_mutex_t *local_disk_lock = NULL; #endif // __FreeBSD__ static void *dav_repos_create_dir_config(apr_pool_t * p, char *dir) { /* NOTE: dir==NULL creates the default per-dir config */ dav_repos_dir_conf *conf; conf = (dav_repos_dir_conf *) apr_pcalloc(p, sizeof(*conf)); return conf; } static void *dav_repos_merge_dir_config(apr_pool_t * p, void *base, void *overrides) { dav_repos_dir_conf *newconf; newconf = apr_pcalloc(p, sizeof(*newconf)); return newconf; } static void *dav_repos_create_server_config(apr_pool_t * p, server_rec * s) { dav_repos_server_conf *newconf; newconf = (dav_repos_server_conf *) apr_pcalloc(p, sizeof(*newconf)); return newconf; } static void *dav_repos_merge_server_config(apr_pool_t * p, void *base, void *overrides) { dav_repos_server_conf *parent = base; dav_repos_server_conf *child = overrides; dav_repos_server_conf *newconf; newconf = (dav_repos_server_conf *) apr_pcalloc(p, sizeof(*newconf)); newconf->storage_dir = INHERIT_VALUE(parent, child, storage_dir); return newconf; } /* * Command handler for the DAV directive, which is TAKE1. */ static const char *dav_repos_storage_dir_cmd(cmd_parms * cmd, void *config, const char *arg1) { dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); char *pszSafeStr; pszSafeStr = apr_pcalloc(cmd->pool, strlen(arg1) + 1); dav_repos_replace_multi_slash_chars(arg1, pszSafeStr); conf->storage_dir = apr_pstrdup(cmd->pool, pszSafeStr); return NULL; } static const char *dav_repos_base_uri_cmd(cmd_parms * cmd, void *config, const char *arg1) { dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); conf->base_uri = apr_pstrdup(cmd->pool, arg1); return NULL; } static const char *dav_repos_host_name_cmd(cmd_parms * cmd, void *config, const char *arg1) { dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); conf->host_name = apr_pstrdup(cmd->pool, arg1); return NULL; } static const char *dav_repos_max_fhs(cmd_parms * cmd, void *config, const char *arg1) { dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); conf->max_fhs = apr_pstrdup(cmd->pool, arg1); return NULL; } static const char *dav_repos_max_anony(cmd_parms * cmd, void *config, const char *arg1) { dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); conf->max_anony_realm = apr_pstrdup(cmd->pool, arg1); return NULL; } static const char *dav_repos_max_progess(cmd_parms * cmd, void *config, const char *arg1) { dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); conf->max_progress = atoi(arg1); return NULL; } // CHG 2019-09-24 huibong Bigbox FHS 장비 사용에 따른 mount 별 운영여유공간 계산방식 개선 (#32807) // - 기존 conf 상의 DavProviderStorageLimit 설정은 제거 처리 /* static const char *dav_repos_storage_limit(cmd_parms * cmd, void *config, const char *arg1) { dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); conf->storage_limit = atoi(arg1); return NULL; } */ #define DEF_USER_CACHE 20 static const char *dav_repos_user_cache(cmd_parms * cmd, void *config, const char *arg1) { dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); conf->user_cache = atoi(arg1); if( conf->user_cache <= 0 ) { conf->user_cache = DEF_USER_CACHE; } return NULL; } static const char *dav_repos_db_charset(cmd_parms * cmd, void *config, const char *arg1) { dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); conf->db_charset = apr_pstrdup(cmd->pool, arg1); if(conf->db_charset == NULL || strlen(conf->db_charset) <= 0 ) { conf->db_charset = apr_pstrdup(cmd->pool, "UHC"); } return NULL; } static const char *dav_repos_close_insert(cmd_parms * cmd, void *config, const char *arg1) { dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); conf->close_insertoff = strcasecmp(arg1, "on"); return NULL; } // CHG 2012-06-27 dadamin // sibling 및 sync_host 기능은 2011 년 BD-06 사내망 제거 이후 더 이상 사용하지 않는 기능임. // 따라서 아래 관련 코드를 주석 처리함. //static const char *dav_repos_sibling(cmd_parms * cmd, void *config, const char *arg1) //{ // dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); // conf->sibling = apr_pstrdup(cmd->pool, arg1); // // return NULL; //} //static const char *dav_repos_sync_host(cmd_parms * cmd, void *config, const char *arg1) //{ // dav_repos_server_conf *conf = ap_get_module_config(cmd->server->module_config, &dav_repos_module); // conf->sync_host = apr_pstrdup(cmd->pool, arg1); // // return NULL; //} static const command_rec dav_repos_cmds[] = { /* per directory/location */ /* how can I make it mandatory */ /* RSRC_CONF : For server */ /* ACCESS_CONF : For dir */ AP_INIT_TAKE1("DavProviderBaseURI", dav_repos_base_uri_cmd, NULL, RSRC_CONF, "specify DavProviderBaseURI"), AP_INIT_TAKE1("DavProviderStorageDir", dav_repos_storage_dir_cmd, NULL, RSRC_CONF, "specify DavProviderStorageDir"), AP_INIT_TAKE1("DavProviderHostName", dav_repos_host_name_cmd, NULL, RSRC_CONF, "specify DavProviderHostName"), AP_INIT_TAKE1("DavProviderMaxFHS", dav_repos_max_fhs, NULL, RSRC_CONF, "specify DavProviderMaxFHS"), AP_INIT_TAKE1("DavProviderMaxAnonymous", dav_repos_max_anony, NULL, RSRC_CONF, "specify DavProviderMaxAnonymous"), AP_INIT_TAKE1("DavProviderMaxAccount", dav_repos_user_cache, NULL, RSRC_CONF, "specify DavProviderMaxAccount"), AP_INIT_TAKE1("DavProviderMaxProgess", dav_repos_max_progess, NULL, RSRC_CONF, "specify DavProviderMaxProgess"), // CHG 2019-09-24 huibong Bigbox FHS 장비 사용에 따른 mount 별 운영여유공간 계산방식 개선 (#32807) // - 기존 conf 상의 DavProviderStorageLimit 설정은 제거 처리 //AP_INIT_TAKE1("DavProviderStorageLimit", dav_repos_storage_limit, NULL, RSRC_CONF, "specify DavProviderStorageLimit"), // CHG 2012-06-27 dadamin // sibling 및 sync_host 기능은 2011 년 BD-06 사내망 제거 이후 더 이상 사용하지 않는 기능임. // 따라서 아래 관련 코드를 주석 처리함. //AP_INIT_TAKE1("DavProviderSibling", dav_repos_sibling, NULL, RSRC_CONF, "specify DavProviderSibling"), //AP_INIT_TAKE1("DavProviderSyncHost", dav_repos_sync_host, NULL, RSRC_CONF, "specify DavProviderSyncHost"), // 2012.06.27 dadamin // Database Client encoding AP_INIT_TAKE1("DavProviderDBCharset", dav_repos_db_charset, NULL, RSRC_CONF, "specify DavProviderDBCharset"), // 2012.07.13 dadamin // close 시 insert 유무 설정( On : Insert , off : insert X) AP_INIT_TAKE1("DavProviderCloseInsert", dav_repos_close_insert, NULL, RSRC_CONF, "specify dav_repos_close_insert"), {NULL} }; static int dav_repos_init_handler(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, server_rec * s) { void *data; const char *userdata_key = "mod_dav_repos_init"; //int dav_of_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s); ap_add_version_component(p, "OpenDisk/" VERSION #ifdef __OPENDAV_DEBUG__ ",DEBUG" #endif #ifdef __OPENDAV_DEBUG_AUTH__ ",Da" #endif #ifdef __OPENDAV_DEBUG_SHARED__ ",Ds" #endif #ifdef __OPENDAV_DEBUG_USER_AUTH__ ",Da" #endif #ifdef __OPENDAV_DEBUG_TRAFFIC_CONTROL__ ",Dtc" #endif #ifdef __USE_TRANSFER_LOG__ ",tl" #endif #ifdef __OPENDAV_BAND_CONTROL__ #ifdef __CLASSIFIED_TRAFFIC_MANAGE__ ",ct" #else ",nt" #endif #endif #ifdef __ONLY_GET_SUCCESS_OUT__ ",so" #endif #ifdef __OPENDAV_TRANSFER_LOG_ANONYMOUS__ ",tla" #endif #ifdef __USE_MULTIPLE_STORAGE__ ",ms" #endif #ifdef __USE_OLD_AUTH__ ",oa" #endif #ifdef __NOT_USE_AUTH_TIMESLICE__ ",nat" #endif /* from here, not affected, i supposed */ #ifdef __OPENDAV_USER_AUTH_GET ",uag" #endif #ifdef __NOT_USE_LOCKDB__ ",nul" #endif #ifdef __OPENDAV_OLDAUTH_LOG__ ",oal" #endif #ifdef __OPENDAV_SHARED_NOT_USE ",snu" #endif #ifdef __OPENDISK_SOLUTION__ ",os" #endif #ifdef __OPENDISK_SOLUTION_NOT_USE_TS__ ",nut" #endif // !__OPENDISK_SOLUTION_NOT_USE_TS__ #ifdef __UNUSE_FILELOCK__ ",nfl" #endif // __UNUSE_FILELOCK__ #ifdef __USE_AUTH_SOFTLINE_ONLY__ ",uso" #endif // __USE_AUTH_SOFTLINE_ONLY__ /* until here, not affected, i supposed */ ); /* Elenoa: 2006. 1. 3. spawn new child */ 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; } ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: initialize..."); /* shared memory */ // 2012.09.20 : dadamin // 공유 메모리 attach 실패 시 프로세스 종료되게 한다. if( dav_initialize_shared_memory(s, s->process->pool) != OK ) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: dav_initialize_shared_memory failed. Exit Process."); return !OK; } apr_pool_cleanup_register(p, s->process->pool, dav_cleanup_shared_memory, dav_cleanup_shared_memory); /* transfer queue */ if (dav_initialize_transfer_queue(s, s->process->pool) != OK) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: dav_initialize_transfer_queue failed. Exit Process."); return !OK; } apr_pool_cleanup_register(p, s->process->pool, dav_cleanup_transfer_queue, dav_cleanup_transfer_queue); return OK; } /* Provider interface */ static const dav_provider dav_repos_provider = { &dav_repos_hooks_repos, /* repos */ &dav_repos_hooks_propdb, /* prop */ #ifdef __NOT_USE_LOCKDB__ NULL, #else &dav_repos_hooks_locks, /* locks */ #endif NULL, /* versioning */ NULL, /* binding */ &dav_repos_hooks_search /* search */ }; static void register_hooks(apr_pool_t * p) { /* apache hooks */ ap_hook_post_config(dav_repos_init_handler, NULL, NULL, APR_HOOK_MIDDLE); //ap_hook_child_init(dav_repos_child_init, NULL, NULL, APR_HOOK_MIDDLE); /* live property handling */ dav_hook_find_liveprop(dav_repos_find_liveprop, NULL, NULL, APR_HOOK_MIDDLE); dav_hook_insert_all_liveprops(dav_repos_insert_all_liveprops, NULL, NULL, APR_HOOK_MIDDLE); /* register the namespace URIs */ dav_register_liveprop_group(p, &dav_repos_liveprop_group); /* register our provider */ dav_register_provider(p, DBMS_PRIVIDER_NAME, &dav_repos_provider); /* authentication / authorication */ #if AP_SERVER_MAJORVERSION_NUMBER > 2 || AP_SERVER_MINORVERSION_NUMBER >= 3 #else // 2.2.X ap_hook_auth_checker(dav_auth_authorization, NULL, NULL, APR_HOOK_FIRST); #endif // 2.3 over ap_hook_check_user_id(dav_auth_authenticate, NULL, NULL, APR_HOOK_MIDDLE); #ifndef __OPENDISK_SOLUTION_NOT_USE_TS__ /* statistics */ ap_hook_log_transaction(dav_shared_ts_access_statistic, NULL,NULL,APR_HOOK_FIRST); #endif // !__OPENDISK_SOLUTION_NOT_USE_TS__ ap_hook_log_transaction(dav_transfer_log_generate, NULL,NULL,APR_HOOK_LAST); /* anonymous realm */ ap_hook_post_read_request(dav_shared_ar_check_request, NULL, NULL, APR_HOOK_FIRST); // 2015.7.15 dadamin // in,out 트래픽 필터 추가 ap_register_input_filter("dav_input_statistic", dav_input_filter, NULL, AP_FTYPE_TRANSCODE); ap_register_output_filter("dav_bc_output", dav_bc_output_filter, NULL, AP_FTYPE_TRANSCODE); //apr_thread_rwlock_create(&db_lock, p); // 2012.07.09 dadamin // 암호화 관련 library 사용을 위한 lock 사용이지만, // 현재 사용하고 있는 libmcrypt 는 thread safe 하기 때문에 관련 lock 삭제처리 //apr_global_mutex_create(&db_global_lock, "/tmp/dav_repos", APR_LOCK_DEFAULT, p); // 2012.07.04 dadamin // FreeBSD 경우 getmntent 함수 쓰레드 지원하지 않기 때문에 // 관련 함수 사용 로직에 lock을 사용하여 이를 대처함 #ifdef __FreeBSD__ apr_global_mutex_create(&local_disk_lock, "/tmp/dav_repos_disk", APR_LOCK_DEFAULT, p); #endif // __FreeBSD__ } module DAV_DECLARE_DATA dav_repos_module = { STANDARD20_MODULE_STUFF, dav_repos_create_dir_config, /* dir config creater */ dav_repos_merge_dir_config, /* dir merger --- default is to override */ dav_repos_create_server_config, /* server config */ dav_repos_merge_server_config, /* merge server config */ dav_repos_cmds, /* command table */ register_hooks, /* register hooks */ };