454 lines
14 KiB
C
454 lines
14 KiB
C
/****************************************************************************
|
|
|
|
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 <httpd.h>
|
|
#include <http_config.h>
|
|
#include <http_protocol.h>
|
|
#include <http_log.h>
|
|
#include <http_core.h> /* for ap_construct_url */
|
|
#include <http_request.h>
|
|
#include <http_connection.h>
|
|
|
|
#include <apr_strings.h>
|
|
#include <apr_hash.h>
|
|
#include <apr_base64.h>
|
|
|
|
#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 */
|
|
};
|