/**************************************************************************** mod_dav_pgsql (DASL) for apache 2.X CopyRight(C) 2005 SolutionBox Inc. All Rights reserved. CopyRight(C) 2006 Netomi Inc. All Rights reserved. Author : elenoa lazyfake (elenoa@solutionbox.co.kr) $Id: share.c,v 1.8 2007/02/22 08:22:13 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 #include #include #include /* for ap_construct_url */ #include #include #include #include "dav_repos.h" #include "dbms.h" #include "util.h" #include "share_common.h" #include "share_account.h" /* for user cache */ static struct shm_mgnt ucah_mgnt = { NULL, NULL, SHM_UCAH, SHM_UCAH_LOCK, 0, 0 }; struct account_cache *g_ac; static int maxcache = 0 ; int dav_initialize_shared_account_cache(dav_repos_server_conf *dsc, server_rec *s, apr_pool_t *p) { if (dsc->user_cache <= 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: initialize_shared_memory: " "MaxUserCache <= 0 (%d)", dsc->user_cache); return !OK; } maxcache = dsc->user_cache; /* user cache : calculate shared memory size from user_cache value */ ucah_mgnt.size = (sizeof(struct account_cache) * dsc->user_cache); g_ac = (struct account_cache *)dav_shared_get_new_memory(&ucah_mgnt, s, p, false); if (!g_ac) return !OK; return OK; } void dav_cleanup_shared_account_cache() { if (ucah_mgnt.shm) { apr_shm_detach(ucah_mgnt.shm); } if (ucah_mgnt.lock) { apr_global_mutex_destroy(ucah_mgnt.lock); } } struct account_cache * dav_shared_ac_get_by_vol(const char * volume_name) { #ifndef __OPENDAV_SHARED_NOT_USE int i; if (!g_ac) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ac_get_by_vol:: Account cache NULL. [%s]", volume_name); return NULL; } #define AC_TIMEOUT 300 apr_global_mutex_lock(ucah_mgnt.lock); for (i = 0; i < maxcache; i++) { if ((g_ac + i)->id[0] == '\0') break; if (!strcmp((g_ac + i)->svc_id, volume_name)) { struct account_cache * retval = (g_ac + i); // 2015.7.15 dadamin // version 3.5ºÎÅÍ timeout ´ë½Å fimnd ÀÇÇØ¼­ ¼³Á¤µÈ flag °ª ÂüÁ¶ // 0 : Á¤»ó , 1 : »èÁ¦ if ((g_ac + i)->nFlag) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ac_get_by_vol:: The [%s] service is deleted.", (g_ac + i)->svc_id); retval = NULL; } apr_global_mutex_unlock(ucah_mgnt.lock); return retval; } } apr_global_mutex_unlock(ucah_mgnt.lock); ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ac_get_by_vol:: The [%s] service not found.", volume_name); #endif return NULL; } // NEW 2012-04-20 ³ë°æ¹Î // dav_shared_ac_get_by_vol() ÇÔ¼ö »óÀÇ TIMEOUT üũ ±â´ÉÀ¸·Î ÀÎÇØ // ¹«ÀÎÁõ °ü·Ã ¼­ºñ½ºÀÇ ´ë¼Ò¹®ÀÚ ±¸ºÐ/¹«½Ã ¿©ºÎ È®ÀΠ󸮽Ã... // Cache °ª º¯°æÀÌ ¹ß»ýµÇÁö ¾Ê¾Æ... NULL °ªÀÌ ¹ÝȯµÇ´Â ¹®Á¦ ¹ß»ý.. // µû¶ó¼­ À̸¦ ÇØ°áÇϱâ À§ÇØ TIMEOUT ºñ±³°¡ ¾ø´Â ÇÔ¼ö¸¦ Ãß°¡ÇÔ. struct account_cache * dav_shared_ac_get_by_vol_not_timeout(const char * volume_name) { #ifndef __OPENDAV_SHARED_NOT_USE int i; if (!g_ac) return NULL; apr_global_mutex_lock(ucah_mgnt.lock); for (i = 0; i < maxcache; i++) { if ((g_ac + i)->id[0] == '\0') break; // 2015.7.15 dadamin // version 3.5ºÎÅÍ timeout ´ë½Å fimnd ÀÇÇØ¼­ ¼³Á¤µÈ flag °ª ÂüÁ¶ // 0 : Á¤»ó , 1 : »èÁ¦ if ((g_ac + i)->nFlag) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ac_get_by_vol_not_timeout:: The [%s] service is deleted.", (g_ac + i)->svc_id); continue; } if (!strcmp((g_ac + i)->svc_id, volume_name)) { struct account_cache * retval = (g_ac + i); apr_global_mutex_unlock(ucah_mgnt.lock); return retval; } } apr_global_mutex_unlock(ucah_mgnt.lock); #endif return NULL; } // 2017-03-08 CHG huibong // - #28349 ¼­ºñ½º ÇØÁö ó¸®µÈ °æ¿ì ºÒÇÊ¿äÇÑ ·Î±×°¡ ÀÎÁõ½Ã¸¶´Ù ¹ß»ý, À̸¦ ÇØ°áÇϱâ À§ÇØ Flow ¼öÁ¤ ó¸®. // struct account_cache *dav_shared_ac_get_by_tranid(char *seq) { #ifndef __OPENDAV_SHARED_NOT_USE int i; if (!g_ac) return NULL; apr_global_mutex_lock(ucah_mgnt.lock); // 2015.7.15 dadamin // version 3.5ºÎÅÍ timeout ´ë½Å fimnd ÀÇÇØ¼­ ¼³Á¤µÈ flag °ª ÂüÁ¶ // 0 : Á¤»ó , 1 : »èÁ¦ // ÀÎÁõ ó¸® ºÎºÐÀ̹ǷΠ°Ë»ö ¼Óµµ´Â ÃÖ´ëÇÑ ºü¸£°Ô ÇÑ´Ù. for (i = 0; i < maxcache; i++) { if ((g_ac + i)->id[0] == '\0') break; // »èÁ¦µÈ ¼­ºñ½º´Â °Ë»ö Á¶°Ç¿¡¼­ Á¦°Å if((g_ac + i)->nFlag) { continue; } // ¼­ºñ½º sequece ºñ±³ if(!strcmp((g_ac + i)->tran_id, seq)) { struct account_cache * retval = (g_ac + i); apr_global_mutex_unlock(ucah_mgnt.lock); return retval; } } // »èÁ¦µÈ ¼­ºñ½º ¿äûÀ» ·Î±ë ó¸®. // - ¿äû·®ÀÌ ¸¹Áö ¾ÊÀ» °ÍÀ̹ǷÎ.. ÀÀ´äÀÌ ´Ê¾îµµ »ó°ü ¾øÀ½. // - ·Î±ë ó¸® ÈÄ NULL ¹Ýȯ //for (i = 0; i < maxcache; i++) //{ // if ((g_ac + i)->id[0] == '\0') // break; // // // »èÁ¦µÈ ¼­ºñ½º // if((g_ac + i)->nFlag) // { // // »èÁ¦ ¶Ç´Â ¸ð¸£´Â ¿äûÀÎ °æ¿ì.. Àü´Þ¹ÞÀº seq °ªÀÌ ¼ýÀÚ·Î º¯È¯µÇÁö ¾Ê°í ¿äûµÈ ±×´ë·Î µé¾î¿À¹Ç·Î... // // cache µÈ Á¤º¸¿Í seq ºñ±³´Â ÇÒ ¼ö ¾ø´Ù. // // µû¶ó¼­ ±×³É ÇØÁöµÈ ¼­ºñ½º´Â ¸ðµÎ ·Î±ë ó¸®ÇÑ´Ù. // ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ac_get_by_tranid:: service [%s] is deleted.", (g_ac + i)->svc_id); // // continue; // } //} apr_global_mutex_unlock(ucah_mgnt.lock); #endif return NULL; } // NEW 2012-03-20 ³ë°æ¹Î // °¢ ¼­ºñ½ºº° uri ¿¡ ´ëÇÑ ´ë¼Ò¹®ÀÚ ±¸ºÐ, ¹«½Ã ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù. // ÇØ´ç ¹Ýȯ°ªÀº RCDB t_sms_sp_svc_product Å×À̺í uri_ignore_case ÇʵåÀÇ ¼³Á¤°ªÀ» È®ÀÎÇÏ¿© ´ÙÀ½°ú °°ÀÌ ¹Ýȯó¸®ÇÑ´Ù. // 0 : ´ë¼Ò¹®ÀÚ ±¸ºÐ ( ¾ç¹æÇâ Default ) // 1 : ´ë¼Ò¹®ÀÚ ¹«½Ã // -1 : ¿À·ù ¹ß»ý. int dav_shared_is_uri_ignore_case(const dav_resource * resource) { struct account_cache * ac = NULL; dav_resource_private *info = NULL; char *tranid; if (resource == NULL || resource->info == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_is_uri_ignore_case: dav_resource NULL."); return -1; } info = resource->info; tranid = apr_psprintf(resource->pool, "%" APR_INT64_T_FMT "", info->user_id); ac = dav_shared_ac_get_by_tranid(tranid); // ÇØ´ç ¼­ºñ½º Á¤º¸¸¦ °øÀ¯ ¸Þ¸ð¸® »ó¿¡¼­ È®ÀÎÇÏÁö ¸øÇÑ °æ¿ì if (ac == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_is_uri_ignore_case: tranid[%s] uri ignore info not found.", tranid); return -1; } return ac->is_ignorecase; } int dav_shared_is_uri_ignore_case_by_tranid(char *tranid) { struct account_cache * ac = NULL; ac = dav_shared_ac_get_by_tranid(tranid); // ÇØ´ç ¼­ºñ½º Á¤º¸¸¦ °øÀ¯ ¸Þ¸ð¸® »ó¿¡¼­ È®ÀÎÇÏÁö ¸øÇÑ °æ¿ì if (ac == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_is_uri_ignore_case_by_tranid: tranid[%s] uri ignore info not found.", tranid); return -1; } return ac->is_ignorecase; } int dav_shared_is_uri_ignore_case_by_svcname(const char * svcname) { struct account_cache * ac = NULL; ac = dav_shared_ac_get_by_vol_not_timeout(svcname); // ÇØ´ç ¼­ºñ½º Á¤º¸¸¦ °øÀ¯ ¸Þ¸ð¸® »ó¿¡¼­ È®ÀÎÇÏÁö ¸øÇÑ °æ¿ì if (ac == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_is_uri_ignore_case_by_svcname: svcname[%s] uri ignore info not found.", svcname); return -1; } return ac->is_ignorecase; } static int dav_shared_ac_perform_find(char *haystack, char *__needle, int iscase) { char *needle = __needle; int i, h = strlen(haystack), n = strlen(needle); do { // ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: Referer: find: needle %s/%s", needle, __needle); __needle = needle; if (h < n) goto next_time; for (i = 0; i < (h - n + 1); i++) { if (tolower(*(haystack + i)) == tolower(*needle)) { #if 0 if (iscase == OK) { #endif if (!strncasecmp((haystack + i), needle, n)) { goto match_n_next; } #if 0 } else { if (!strncmp((haystack + i), needle, n)) { goto match_n_next; } } #endif continue; match_n_next: if (i != 0 && *(haystack + i - 1) != '|') continue; if (*(haystack + i + n) != '|' && *(haystack + i + n) != '\0') continue; return OK; } } //ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: Referer: find: done?"); next_time: needle = strchr(__needle, '.'); // ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: Referer: find: done? needle %x __needle %x", needle, __needle); if (needle) { needle++; if (*needle == '\0') break; n = strlen(needle); } } while (needle); // ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: Referer: find: ALL done?"); return !OK; } #define IS_PERMIT_EMPTY_REFERER(ac) (strlen(ac->mode) > 4 && ac->mode[4] == '1') int dav_shared_ac_check_referer(struct account_cache *ac, request_rec *r) { const char *referer = apr_table_get(r->headers_in, "Referer"); char *pszCopy, *pszUriCopy; char *p, *p2, *p3, *q; if ((!referer) || (NULL == referer) || (0 == strlen(referer))) { if (IS_PERMIT_EMPTY_REFERER(ac)) { if (ac->permitted_referer[0] != '\0') { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: empty referer checking: referer is NULL, not permited."); return !OK; } } return OK; } if (ac->permitted_referer[0] == '\0') return OK; pszCopy = apr_pstrdup(r->pool, referer); if (!pszCopy) return OK; if ((p = strstr(pszCopy, "://"))) p += 3; else p = pszCopy; p2 = strchr(p, '/'); p3 = strchr(p, ':'); if (p2 == NULL) { if (p3 == NULL) { if (IS_PERMIT_EMPTY_REFERER(ac)) { if (ac->permitted_referer[0] != '\0') ; else return OK; } else return OK; } else { q = p3; *q = '\0'; } } else { if (p3 == NULL) q = p2; else if (p2 < p3) q = p2; else q = p3; *q = '\0'; } pszUriCopy = apr_pstrdup(r->pool, r->uri); q = pszUriCopy; if ((p2 = strrchr(q, '.'))) q = p2 + 1; else q = NULL; if (ac->permitted_extend[0] != '\0') { if (!q) return OK; if (dav_shared_ac_perform_find(ac->permitted_extend, q, !OK) == !OK) return OK; } if (ac->permitted_referer[0] != '\0') { if (dav_shared_ac_perform_find(ac->permitted_referer, p, OK) == !OK) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: referer: uri %s, extension %s, permitted %s !!!!!" , p, (ac->permitted_extend[0] != '\0' ? ac->permitted_extend : "NONE"), ac->permitted_referer); return !OK; } } return OK; }