/**************************************************************************** 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" #include "share_fhs_stat.h" #include "share_anonymous.h" /* for anonymous */ static struct shm_mgnt anon_mgnt = { NULL, NULL, SHM_ANON, SHM_ANON_LOCK, 0, 0 }; struct anonymous *g_ar; static int maxanon = 0; int dav_initialize_shared_anonymous(dav_repos_server_conf *dsc, server_rec *s, apr_pool_t *p) { if (!dsc->max_anony_realm || (maxanon = atoi(dsc->max_anony_realm)) <= 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: initialize_shared_memory: " "MaxAnonymous <= 0 (%d)", maxanon); return !OK; } /* anonymous control : calculate shared memory size from max_anony_realm value */ anon_mgnt.size = (sizeof(struct anonymous) * maxanon); g_ar = (struct anonymous *)dav_shared_get_new_memory(&anon_mgnt, s, p, false); if (!g_ar) return !OK; return OK; } void dav_cleanup_shared_anonymous() { if (anon_mgnt.shm) { apr_shm_detach(anon_mgnt.shm); } if (anon_mgnt.lock) { apr_global_mutex_destroy(anon_mgnt.lock); } } // CHG 2012-04-20 huibong // º» ÇÔ¼ö´Â HOOK ó¸®µÈ opendav ÀÇ ÃÖÃÊ ÁøÀÔÇÔ¼ö·Î¼­ ¿äû¿¡ ´ëÇÑ ¹«ÀÎÁõ ¿©ºÎ¸¦ È®ÀÎÇÔ. // ÇÏÁö¸¸ º» ÇÔ¼öÀÇ flow °¡ ºÒÇÊ¿ä loop ¸¦ µ¹·Á¼­ ó¸®Çϱ⠶§¹®¿¡.. ¹«ÀÎÁõ ¼³Á¤ Á¤º¸°¡ ¸¹À» °æ¿ì.. // Àüü ÀÀ´ä ¼º´ÉÀ» ÀúÇϽÃÄÑ... ÀüüÀûÀ¸·Î ¼öÁ¤ ó¸®ÇÔ. static int dav_find_location(request_rec *r, const char * svc_name, const char * uri, bool uricaseignore, bool urihassvcname) { // DB ó¸®¿ë º¯¼ö »ý¼º. char * temp_uri = NULL; char * db_uri = apr_pcalloc(r->pool, MaxSizeOfPathLength); char * red_uri = NULL; char * e_uri = NULL; char * query; ap_dbd_t *db; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; apr_status_t rv; char tblname[20] = { 0 }; int ntuple; char * host_name = NULL; unsigned int n = 0; char * p3 = NULL; // loop ó¸® °ü·Ã º¯¼ö int j; struct account_cache * ac = NULL; ac = dav_shared_ac_get_by_vol_not_timeout(svc_name); if (ac == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_find_location: svcname[%s] info not found.", svc_name); return !OK; } /* UTF-8. change UHC(CP949) */ temp_uri = transformDBCharacter(r, (char *)uri, "dav_find_location"); // 2012-08-10 CHG huibong // ¹«ÀÎÁõ URI »ó¿¡ \ ¹× ' ÀÇ Æ¯¼ö¹®ÀÚ°¡ Æ÷ÇÔµÈ °æ¿ì RCDB »ó¿¡ Äõ¸®°¡ Á¤»óÀûÀ¸·Î µÇÁö ¾Ê´Â ¹®Á¦°¡ ¹ß»ý. // À̸¦ ÇØ°áÇϱâ À§ÇØ Æ¯¼ö¹®ÀÚ¸¦ RCDB °¡ ÀνÄÇÒ ¼ö ÀÖµµ·Ï dav_repos_replace_unsafe_chars() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© º¯È¯ ó¸®Çϵµ·Ï ¼öÁ¤ memset(db_uri, 0x00, MaxSizeOfPathLength); dav_repos_replace_unsafe_chars(temp_uri, db_uri); p3 = strchr(db_uri, '?'); if (p3) *p3 = '\0'; // 2014-04-24 : dadamin // where ±¸¹®¿¡ ÆÄƼ¼Å´× ±âÁذª, depth Ãß°¡ int nDepth; nDepth = ap_count_dirs(db_uri); /* remake redirected uri */ // CHG 2010-08-11 ´ë¼Ò¹®ÀÚ ±¸ºÐ¿©ºÎ¿¡ µû¸¥ Query º¯°æ. // ChG 2012-04-19 huibong // - Query ±¸¹®»ó¿¡ MAX, GROUP BY, ORDER BY Á¶°Ç½ÄÀÌ ¾Æ·¡ ÄÚµåÀÇ Random ¼±Åà ÄÚµå·Î ÀÎÇØ ¹«ÀǹÌÇϹǷΠ¼öÁ¤ ó¸®. if (uricaseignore == true) // URI ´ë¼Ò¹®ÀÚ ¹«½Ã ¼­ºñ½ºÀÎ °æ¿ì { query = apr_psprintf(r->pool, "SELECT host_name, is_cache, filename_hash " "FROM %s " // CHG 2014.10.02 dadamin // WHERE Àý ±¸¹® Áß Á¶°Ç°ú Á¶°Ç »çÀÌ °ø¹é Ãß°¡ // ÇöÀç Á¤»ó ¼öÇàµÊÀ» È®ÀÎ ÇÏ¿´Áö¸¸ ¸¸¾à¿¡ ÀÖÀ» ¿À·ù ´ëºñÇÏ¿© ¼öÁ¤ÇÔ // e.g) SELECT ... WHERE sp_svc_tran_id = 214AND depth = 3... (Á¤»ó ¼öÇàµÊ) "WHERE sp_svc_tran_id = %s " "AND depth = %d " "AND %s = lower('/%s%s') AND deleted_yn = 'N' " , dav_get_target_table(ac->tran_id, tblname) , ac->tran_id, nDepth // 2014.06.12 // ½Å±Ô Çü»ó(9.3)¿¡¼­ ´ë¼Ò¹®ÀÚ ±¸ºÐÀº À妽º·Î Áö¿øÇÏÁö ¾ÊÀ½ , dav_use_display_name() == 0 ? "lower(uri)" : "uri" , ac->tran_id, db_uri ); } else { // ´ë¼Ò¹®ÀÚ ±¸ºÐÀ» ÇÏ´Â °æ¿ì query = apr_psprintf(r->pool, "SELECT host_name, is_cache, filename_hash " "FROM %s " // CHG 2014.10.02 dadamin // WHERE Àý ±¸¹® Áß Á¶°Ç°ú Á¶°Ç »çÀÌ °ø¹é Ãß°¡ // ÇöÀç Á¤»ó ¼öÇàµÊÀ» È®ÀÎ ÇÏ¿´Áö¸¸ ¸¸¾à¿¡ ÀÖÀ» ¿À·ù ´ëºñÇÏ¿© ¼öÁ¤ÇÔ // e.g) SELECT ... WHERE sp_svc_tran_id = 214AND depth = 3... (Á¤»ó ¼öÇàµÊ) "WHERE sp_svc_tran_id = %s " "AND depth = %d " "AND uri = '/%s%s' AND deleted_yn = 'N' " , dav_get_target_table(ac->tran_id, tblname) , ac->tran_id, nDepth, ac->tran_id, db_uri ); } db = dav_repos_get_db(r); if (db == NULL) { db_error_message(db, "dav_find_location: database acquire timeout", 0); return DECLINED; } rv = apr_dbd_select(db->driver, r->pool, db->handle, &res, query, 1); if (rv) { db_error_message(db, "dav_find_location: select", rv);; dav_repos_release_db(r, db, rv); return DECLINED; } ntuple = apr_dbd_num_tuples(db->driver, res); // Á¶È¸ °á°ú°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì if (ntuple < 1) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_find_location: request uri not found [%s][%s]", svc_name, db_uri); dav_repos_release_db(r, db, rv); return DECLINED; } // CHG 2012-04-19 huibong // Redirection ó¸® Àåºñ ¼±Åà ·ÎÁ÷ Àü¸é ¼öÁ¤.. // ±âÁ¸ ÄÚµå ·ÎÁ÷ Áß ºÒÇÊ¿äÇÑ loop ·ÎÁ÷ Á¸Àç.. // ±×¸®°í ¹«Á¶°Ç 301 Redirection ÀÀ´äÀ̹ǷÎ... ºÎÇÏ ºÐ»êÀ» À§ÇØ ÀÚ±â ÀڽŠÀåºñ°¡ ¿ì¼±ÀÌ ¾Æ´Ï¶ó.. »ì¾Æ ÀÖ´Â Àåºñ Áß random ¼±Åà ó¸®. host_name = NULL; // ÇØ´ç Àåºñ°¡ 1´ë ÀÎ °æ¿ì if (ntuple == 1) { rv = solbox_apr_dbd_get_row(db->driver, r->pool, res, &row, 0); host_name = apr_pstrdup(r->pool, apr_dbd_get_entry(db->driver, row, 0)); } else // ÇØ´ç Àåºñ°¡ ¿©·¯ ´ëÀÎ °æ¿ì { // C99À» Áö¿øÇÏ´Â ÄÄÆÄÀÏÀÏ °æ¿ì ¹è¿­ÀÇ ÀÎÀڷΠó¸® °¡´É ¸¸¾àÀ» ´ëºñÇÏ¿© µ¿ÀûÇÒ´ç ¹æ½ÄÀ¸·Î ¼öÁ¤ int * host_alive_index; int host_alive_count = 0; // ¸Þ¸ð¸® ÇÒ´ç host_alive_index = (int *)calloc(ntuple, sizeof(int)); // ¸Þ¸ð¸® ÇÒ´ç ½ÇÆÐ ½Ã => ù¹øÂ° rowÀÇ °ªÀ» »ç¿ë if (host_alive_index == NULL) { rv = solbox_apr_dbd_get_row(db->driver, r->pool, res, &row, 0); host_name = apr_pstrdup(r->pool, apr_dbd_get_entry(db->driver, row, 0)); ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_find_location: out of memory. default return first [%s][%s][%s]", svc_name, db_uri, host_name); } else { // Á¶È¸µÈ Àåºñ°¡ Alive »óÅÂÀÎÁö °Ë»çÇÑ´Ù. for (j = 0; j < ntuple; j++) { rv = solbox_apr_dbd_get_row(db->driver, r->pool, res, &row, j); if (dav_shared_du_is_alive(apr_dbd_get_entry(db->driver, row, 0)) != 0) { host_alive_index[host_alive_count] = j; host_alive_count++; } } // Alive ÀåºñÀÇ °¹¼ö È®ÀÎ if (host_alive_count <= 0) { // Alive »óÅ Àåºñ°¡ ¾ø´Â °æ¿ì... ù¹øÂ° Àåºñ Á¤º¸ »ç¿ë. rv = solbox_apr_dbd_get_row(db->driver, r->pool, res, &row, 0); host_name = apr_pstrdup(r->pool, apr_dbd_get_entry(db->driver, row, 0)); ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_find_location: alive host nothing. default return first [%s][%s][%s]", svc_name, db_uri, host_name); } else { // Alive »óÅÂÀÇ Àåºñ°¡ ¿©·¯´ë ÀÎ °æ¿ì... // Random ¼±Åà apr_generate_random_bytes((unsigned char *)&n, sizeof(int)); n = n % host_alive_count; rv = solbox_apr_dbd_get_row(db->driver, r->pool, res, &row, host_alive_index[n]); host_name = apr_pstrdup(r->pool, apr_dbd_get_entry(db->driver, row, 0)); ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "dav_find_location: alive target random select [%s][%s][%s]", svc_name, db_uri, host_name); } // ¸Þ¸ð¸® ÇØÁ¦ free(host_alive_index); } } // RCDB Á¢¼Ó ÇØÁ¦ dav_repos_release_db(r, db, rv); // 2014-06-11 dadamin uri query ±¸¹® ÀÎÄÚµù ¹æÁö p3 = strchr(uri, '?'); if (p3) *p3 = '\0'; // Redirect 󸮿ë URI »ý¼º if (urihassvcname) red_uri = apr_pstrcat(r->pool, dav_http_scheme(r), "://", host_name, "/dav/", svc_name, uri, NULL); else red_uri = apr_pstrcat(r->pool, dav_http_scheme(r), "://", host_name, "/dav", uri, NULL); e_uri = ap_os_escape_path(r->pool, red_uri, 1); if (r->parsed_uri.query) e_uri = apr_pstrcat(r->pool, e_uri, "?", r->parsed_uri.query, NULL); //ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "dav_shared_ar_check_request: redirect uri[%s] escape uri[%s]", red_uri, e_uri); apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, e_uri)); ap_parse_uri(r, e_uri); return OK; } int dav_shared_ar_check_request(request_rec *r) { #if defined(__OPENDISK_SOLUTION__) || defined(__OPENDAV_SHARED_NOT_USE) return DECLINED; #else dav_repos_server_conf *dsc = NULL; const char * domain_name; const char * p1; const char * p2; // ¼­ºñ½º¸í, uri, ¹«ÀÎÁõ Æú´õ Á¤º¸ ÀúÀåÀ» À§ÇÑ º¯¼ö char * svc_name = NULL; char * uri = NULL; char * folder_name = NULL; int svc_name_len = 0; int folder_name_len = 0; // ¹«ÀÎÁõ¿¡¼­ redirect ó¸®µÇ¾î µé¾î¿À´Â ¿äûÀÎÁö ¿©ºÎ ÀúÀå. bool is_redirect_request = false; // °¢ ¼­ºñ½ºº° URI ´ë¼Ò¹®ÀÚ ±¸ºÐ ¿©ºÎ Á¤º¸¸¦ ÀúÀåÇϱâ À§ÇÑ º¯¼ö. true: URI ´ë¼Ò¹®ÀÚ ¹«½Ã, false: URI ´ë¼Ò¹®ÀÚ ±¸ºÐ (default) int result = 0; bool is_uricaseignore = false; // loop ó¸® °ü·Ã º¯¼ö int i = 0; // request °ªÀÌ NULL °æ¿ì if (!r) return DECLINED; // ¹«ÀÎÁõ °ü·Ã °øÀ¯¸Þ¸ð¸® °ªÀÌ NULL ÀÎ °æ¿ì if (!g_ar) return DECLINED; // conf Á¤º¸¸¦ °¡Á®¿Ã ¼ö ¾ø´Â °æ¿ì dsc = dav_repos_get_server_conf(r->server); if (!dsc) return DECLINED; // 1. ¹«ÀÎÁõ¿¡ ´ëÇÑ Ã³¸®´Â GET ¿äû¿¡ ´ëÇØ¼­¸¸ Çã¿ëÇÑ´Ù. ³ª¸ÓÁö ¿äûÀº opendav ¸ðµâ·Î Åë°ú ó¸®. if (r->method_number != M_GET) { return OK; } // 2. HTTP Header »ó¿¡ ÀÎÁõ °ü·Ã Authorization Á¤º¸°¡ Á¸ÀçÇÏ´Â °æ¿ì.. ¾ç¹æÇâ ÀÎÁõÀ¸·Î 󸮵ǵµ·Ï Åë°ú ó¸®. if (apr_table_get(r->headers_in, "Authorization") != NULL) { return OK; } // 3. ¿äû¿¡¼­ ¼­ºñ½º name Á¤º¸¸¦ ÃßÃâÇÑ´Ù. ( ÇØ´ç ¼­ºñ½ºÀÇ ¹«ÀÎÁõ °æ·Î ¿äûÀÎÁö È®ÀÎÇϱâ À§ÇØ ÇÊ¿ä) // - HTTP Header ÀÇ Host: Á¤º¸¸¦ ÃßÃâÇÑ´Ù. // - ÃßÃâµÈ Á¤º¸´Â nctest.ktsh.co.kr, bd-04-fhs001.ktsh.co.kr, 222.122.165.9 ÀÌ µÉ ¼ö ÀÖÀ½. // - ÃßÃâ Á¤º¸°¡ ÇöÀç Àåºñ¸í°ú µ¿ÀÏÇÒ °æ¿ì... URL ¿¡¼­ ¼­ºñ½º name Á¤º¸ ÃßÃ⠽õµ. // - ÃßÃâ Á¤º¸¿¡¼­ IDC Domain Á¤º¸°¡ Á¸ÀçÇÏ´ÂÁö È®ÀÎÇÏ¿©.. // -- Á¸ÀçÇÒ °æ¿ì ¼­ºñ½º name Á¤º¸·Î »ç¿ëÇÑ´Ù. // -- Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì URL ¿¡¼­ ¼­ºñ½º name Á¤º¸ ÃßÃ⠽õµ if (!(domain_name = apr_table_get(r->headers_in, "Host"))) { // HTTP Header »ó¿¡ Host Á¤º¸°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_check_request: http Host tag not found. declined."); return DECLINED; } else { // ÃßÃâµÈ Á¤º¸°¡ ÇöÀç Àåºñ¸í°ú µ¿ÀÏÇÏÁö ºñ±³. ( ´ë¼Ò¹®ÀÚ ¹«½ÃÇÏ°í ºñ±³ ) if (strcasecmp(domain_name, dsc->host_name) != 0) { // Àåºñ¸í°ú µ¿ÀÏÇÏÁö ¾ÊÀº °æ¿ì... // IDC Domain Name Á¤º¸°¡ µ¿ÀÏÇÏÁö.. Host ÃßÃâ Á¤º¸¿Í Àåºñ¸íÀ» ºñ±³ÇÑ´Ù. ( ´ë¼Ò¹®ÀÚ ¹«½Ã ) p1 = strchr(domain_name, '.'); p2 = strchr(dsc->host_name, '.'); if (p1 != NULL && strcasecmp(p1, p2) == 0) { // µ¿ÀÏÇÑ °æ¿ì... // ¼­ºñ½º name Á¤º¸·Î »ç¿ëÇÑ´Ù. svc_name_len = (p1 - domain_name); svc_name = apr_pstrdup(r->pool, domain_name); *(svc_name + svc_name_len) = '\0'; } } } // À§¿¡¼­ ¼­ºñ½º Name ÃßÃâÀÌ ½ÇÆÐÇÑ °æ¿ì.. URL ¿¡¼­ ¼­ºñ½º Name Á¤º¸¸¦ ÃßÃ⠽õµÇÑ´Ù. // 4. ¿ì¼± URL ¿¡ ´ëÇÑ È®ÀÎ ¹× ÇÊ¿ä½Ã º¯È¯ ó¸®. ap_unescape_url(r->unparsed_uri); // °øÀ¯ ¸Þ¸ð¸®¿¡ UTF-8·Î ÀúÀåµÇ¾î Àֱ⠶§¹®¿¡ º¯È¯ ÇÊ¿ä uri = transformUTF8(r, r->unparsed_uri, "dav_shared_ar_check_request"); // 5. URL ¿¡¼­ ¹«ÀÎÁõ Æú´õ Á¤º¸¸¦ ÃßÃâÇÑ´Ù. // Ãß°¡·Î ¾Õ¿¡¼­ ¼­ºñ½º Name Á¤º¸¸¦ ÃßÃâÇÏÁö ¸øÇÑ °æ¿ì.. ¼­ºñ½º Name Á¤º¸µµ ÃßÃâ ó¸®ÇÑ´Ù. // ÀϹÝ, ¹«ÀÎÁõ ¿äû : /svc1_test/TEMP7.txt or /a // ¾ç¹æÇâ °ü·Ã ¿äû : /dav/svc1_test/temp1.txt ( /dav/ °æ·Î¸í : HTTP Authorization tag Á¸Àç·Î ÀÎÇØ »óÀ§¿¡¼­ ¿ì¼± return 󸮵Ê.) // ¹«ÀÎÁõ redirect ó¸® ÈÄ : /dav/nctest/SVC1_TEST/temp2.txt ( /dav/ ¼­ºñ½º Name / °æ·Î¸í ) // 5-1 uri ÀÇ ±æÀ̰ªÀ» È®ÀÎ // /·Î ½ÃÀÛÇØ¾ß Çϰí.. µÚ¿¡ °æ·Î Á¤º¸°¡ µé¾î ÀÖ¾î¾ß ÇϹǷÎ... // ÃÖ¼Ò Çü½ÄÀº /a/a, /dav ÀÇ 4 byte ÀÌ»óÀ̾î¾ß ÇÑ´Ù. if (strlen(uri) < 4) { // ¹«ÀÎÁõ uri ±ÔÄ¢ À§¹è »óȲÀ̰í.. Authorization Á¤º¸µµ Á¸ÀçÇÏÁö ¾ÊÀ¸¹Ç·Î.. °ÅºÎ ó¸®. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_check_request: uri not valid. length too small [%s]", uri); return DECLINED; } // 5-2 ¿ì¼± /dav/ ·Î ½ÃÀÛÇÏ´Â URI ÀÎÁö È®ÀÎ. if (strstr(uri, "/dav/") == uri) { // /dav/ ·Î ½ÃÀÛÇÏ´Â uri ÀÎ °æ¿ì.. // /dav/ ·Î ½ÃÀÛÇÏ´Â ºÎºÐÀ» °Ç³Ê¶Ù°í... ´ÙÀ½ ¹®ÀÚ¸¦ ¼­ºñ½º Name À¸·Î ó¸®.... ±× ´ÙÀ½À» °æ·Î·Î ó¸®.. p1 = uri; p1 = p1 + 5; // p1 -> nctest/SVC1_TEST/temp2.txt Çü½Ä p2 = strchr(p1, '/'); // p2 -> /SVC1_TEST/temp2.txt Çü½Ä if (p2 == NULL) { // ¹«ÀÎÁõ redirect ó¸® ±ÔÄ¢ À§¹è »óȲÀ̰í.. Authorization Á¤º¸µµ Á¸ÀçÇÏÁö ¾ÊÀ¸¹Ç·Î.. °ÅºÎ ó¸®. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_check_request: redirect uri format not valid [%s]", uri); return DECLINED; } // ¼­ºñ½º Name Á¤º¸¸¦ ÃßÃâÇÏÁö ¸øÇÑ °æ¿ì... if (svc_name == NULL) { svc_name_len = (p2 - p1); svc_name = apr_pstrdup(r->pool, p1); *(svc_name + svc_name_len) = '\0'; } // ¹«ÀÎÁõ Æú´õ Á¤º¸¸¦ ÃßÃâÇÑ´Ù. // Á¤»ó : /SVC1_TEST/a.txt Çü½Ä // ¿À·ù : /SVC1_TEST , // , //a.txt p2 = p2 + 1; // p2 -> SVC1_TEST/a.txt Çü½Ä p1 = strchr(p2, '/'); if (p1 == NULL) { // ¹«ÀÎÁõ redirect ó¸® ±ÔÄ¢ À§¹è »óȲÀ̰í.. Authorization Á¤º¸µµ Á¸ÀçÇÏÁö ¾ÊÀ¸¹Ç·Î.. °ÅºÎ ó¸®. //ap_log_error( APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_check_request: annoymous uri format not valid [%s]", uri ); return DECLINED; } else { folder_name_len = (p1 - p2); if (folder_name_len < 1) // ±¸Á¶°¡ a/ ±¸Á¶°¡ ¾Æ´Ñ °æ¿ì Áï.. // { // ¹«ÀÎÁõ ¿äû ±ÔÄ¢ À§¹èÀ̹ǷΠ°ÅºÎ ó¸®. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_check_request: annoymous folder name length not valid [%s]", uri); return DECLINED; } else { folder_name = apr_pstrdup(r->pool, p2); *(folder_name + folder_name_len) = '\0'; // folder_name -> SVC1_TEST Çü½Ä } } // redirect ó¸®µÇ¾î ´Ù½Ã µé¾î¿Â ¿äûÀÓ. is_redirect_request = true; } else { // /dav/ ·Î ½ÃÀÛÇÏÁö ¾Ê´Â °æ¿ì... // Á¤»ó : /svc1_test/temp7.txt, // Ư¼ö : /test.html ( ƯÁ¤ °í°´»çÀÇ alive üũ °ü·Ã Áö¿ø »çÇ× ) => ±×³É OK ·Î Åë°ú ó¸®. // ¿À·ù : //, //a.txt p1 = uri; // p1 -> /svc1_test/temp7.txt p1 = p1 + 1; // p1 -> svc1_test/temp7.txt p2 = strchr(p1, '/'); // p2 -> /temp7.txt if (p2 == NULL) { // ¿ø·¡´Â ¾ç¹æÇâ ±ÔÄ¢ À§¹è »óȲÀÌÁö¸¸.. // Ư¼öÇÑ »óȲÀ¸·Î /test.html , /ok.html µî¿Í °°ÀÌ °í°´»ç Áö¿ø ¿äûÀÌ Á¸ÀçÇÏ¿©.. ±×³É Åë°ú ó¸®ÇÑ´Ù. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_check_request: uri format not valid.. but pass! [%s]", uri); return OK; } folder_name_len = (p2 - p1); if (folder_name_len < 1) // ±¸Á¶°¡ a/ ±¸Á¶°¡ ¾Æ´Ñ °æ¿ì Áï.. // { // ¹«ÀÎÁõ ¿äû ±ÔÄ¢ À§¹èÀ̹ǷΠ°ÅºÎ ó¸®. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_check_request: annoymous folder name length not valid [%s]", uri); return DECLINED; } else { folder_name = apr_pstrdup(r->pool, p1); *(folder_name + folder_name_len) = '\0'; // folder_name -> svc1_test Çü½Ä } } // 6. ¼­ºñ½º Name Á¤º¸¸¦ È®ÀÎÇÏ¿© ÃßÃâÇÏÁö ¸øÇÑ °æ¿ì.. ¼­ºñ½º °ÅºÎ ó¸®. if (svc_name == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_check_request: svc name not found. http host info[%s] uri[%s]", domain_name, uri); return DECLINED; } // 6-1. Æú´õ Name Á¤º¸¸¦ È®ÀÎÇÏ¿© ÃßÃâÇÏÁö ¸øÇÑ °æ¿ì..±×³É Åë°ú ó¸® if (folder_name == NULL) { ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "dav_shared_ar_check_request: folder name not found. svc_name[%s] uri[%s]. pass!", svc_name, uri); return OK; } // 7. ÇØ´ç ¼­ºñ½ºÀÇ ´ë¼Ò¹®ÀÚ ¹«½Ã ¿©ºÎ¸¦ ÆÇ´ÜÇÑ´Ù. result = dav_shared_is_uri_ignore_case_by_svcname(svc_name); if (result == 1) // URI ´ë¼Ò¹®ÀÚ ¹«½Ã ¼­ºñ½ºÀÎ °æ¿ì { is_uricaseignore = true; } else { // ¸¸¾à dav_shared_is_uri_ignore_case È£Ãâ½Ã ¿À·ù°¡ ¹ß»ýÇÑ °æ¿ì.. ¾ç¹æÇ⠱⺻Àº ´ë¼Ò¹®ÀÚ ±¸ºÐ À¸·Î ó¸®. if (result == -1) ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_check_request: dav_shared_is_uri_ignore_case_by_svcname func fail. svc name[%s]. use default", svc_name); is_uricaseignore = false; } // 8. ¹«ÀÎÁõ Á¤º¸¸¦ Á¶È¸ÇÏ¿© ÇØ´ç Á¤º¸°¡ Á¸ÀçÇÏ´ÂÁö ÆÇ´ÜÇÑ´Ù. // - ¹«ÀÎÁõ Á¤º¸°¡ Á¸ÀçÇÒ °æ¿ì.. ÃÖÃÊ ¹«ÀÎÁõ ¿äûÀÎ °æ¿ì.. RCDB Á¤º¸¸¦ Á¶È¸ÇÏ¿© redirect ó¸® ½ÃÄÑ ÁØ´Ù.. // - ÃÖÃÊ ¹«ÀÎÁõ ¿äûÀÌ ¾Æ´Ï°í.. redirect ó¸®µÇ¾î µé¾î¿Â ¿äûÀÎ °æ¿ì... Authorization Á¤º¸¸¦ ¼³Á¤ÇÏ¿© opendav ·Î Àü´Þ ó¸®ÇÑ´Ù. for (i = 0; i < maxanon; i++) { // ¹«ÀÎÁõ ¼³Á¤ Á¤º¸°¡ ¾ø´Â °æ¿ì ±×³É Åë°ú... if ((g_ar + i)->domain[0] == '\0') break; // 2015.7.15 dadamin // version 3.5ºÎÅÍ fimngd ÀÇÇØ¼­ ¼³Á¤µÈ flag ÂüÁ¶ // 1 : »èÁ¦ if ((g_ar + i)->nFlag == 1) continue; // ´ë¼Ò¹®ÀÚ ±¸ºÐ ¿©ºÎ¿¡ µû¶ó.. ¹«ÀÎÁõ Æú´õ Á¸Àç ¿©ºÎ È®ÀÎ.. // URI ´ë¼Ò¹®ÀÚ ¹«½Ã ¼­ºñ½ºÀÎ °æ¿ì if (is_uricaseignore == true) { result = (!strcasecmp(folder_name, (g_ar + i)->uri) && !strncasecmp(svc_name, (g_ar + i)->domain, svc_name_len) && strlen((g_ar + i)->domain) == svc_name_len); } else // ¾ç¹æÇ⠱⺻ ( URI ´ë¼Ò¹®ÀÚ ±¸ºÐ ) { result = (strcmp(folder_name, (g_ar + i)->uri) == OK && !strncasecmp(svc_name, (g_ar + i)->domain, svc_name_len) && strlen((g_ar + i)->domain) == svc_name_len); } // Àü´Þ¹ÞÀº URL ÀÌ ¹«ÀÎÁõ Æú´õ»ó¿¡ Á¸ÀçÇÏ´Â °æ¿ì if (result) { // ÃÖÃÊ ¹«ÀÎÁõ ¿äûÀÎ °æ¿ì 301 redirect ó¸®.. // redirect ó¸®µÈ ¿äûÀÎ °æ¿ì... Authorization ¼³Á¤ ÈÄ Åë°ú ó¸®. // ÀÌ¹Ì redirect ó¸®µÇ¾î µé¾î¿Â ¿äûÀÎ °æ¿ì. if (is_redirect_request == true) { //ap_log_error( APLOG_MARK, APLOG_NOTICE, 0, NULL, "dav_shared_ar_check_request: already redirect request. set auth and pass. uri[%s]", uri); // HTTP Header »ó¿¡ Authorization Header Á¤º¸°¡ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì... ÇØ´ç Á¤º¸ °­Á¦·Î µî·Ï ó¸®. apr_table_setn(r->headers_in, "Authorization", apr_pstrdup(r->pool, "Basic REDIRECTED")); return OK; } else { // ÃÖÃÊ ¹«ÀÎÁõ È®ÀÎ ¿äûÀÎ °æ¿ì if (dav_find_location(r, svc_name, uri, is_uricaseignore, true) == OK) return HTTP_MOVED_PERMANENTLY; } } } // ¹«ÀÎÁõ Æú´õ Á¤º¸°¡ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì... // ±×³É opendav ·Î Åë°ú ó¸®. return OK; #endif // __OPENDISK_SOLUTION__ } // CHG 2012-04-21 huibong // º» ÇÔ¼ö´Â auth.c ¿¡¼­ ÀÎÁõ °ü·Ã ¿©ºÎ È®ÀΠ󸮸¦ À§ÇØ È£ÃâµÇ´Â ÇÔ¼öÀÌÁö¸¸.. // °ÅÁö °°Àº ó¸® flow ·Î ±¸¼ºµÇ¾î...Àü¸é Àç¼öÁ¤ ó¸®ÇÑ´Ù. // º» ÇÔ¼ö´Â µé¾î¿Â ¿äûÀÌ ¹«ÀÎÁõ °ü·Ã ¿äûÀÎÁö È®ÀÎÇϰí... // ¹«ÀÎÁõ ¿äûÀÎ °æ¿ì URL ÀÇ Á¤º¸¸¦ º¯°æÇϰí.. RedHost »ó¿¡ ¼­ºñ½º Name Á¤º¸¸¦ Àü´ÞÇÑ´Ù. int dav_shared_ar_get_value(request_rec *r) { #if defined(__OPENDISK_SOLUTION__) || defined(__OPENDAV_SHARED_NOT_USE) return DECLINED; #else // ¼­ºñ½º¸í, uri, ¹«ÀÎÁõ Æú´õ Á¤º¸ ÀúÀåÀ» À§ÇÑ º¯¼ö const char * p1 = NULL; char * request_path = NULL; char * svc_name = NULL; char * uri = NULL; char * folder_name = NULL; int svc_name_len = 0; int folder_name_len = 0; // °¢ ¼­ºñ½ºº° URI ´ë¼Ò¹®ÀÚ ±¸ºÐ ¿©ºÎ Á¤º¸¸¦ ÀúÀåÇϱâ À§ÇÑ º¯¼ö. true: URI ´ë¼Ò¹®ÀÚ ¹«½Ã, false: URI ´ë¼Ò¹®ÀÚ ±¸ºÐ (default) int result = 0; bool is_uricaseignore = false; // loop ó¸® °ü·Ã º¯¼ö int i; // 1. º¯¼ö°ª °Ë»ç if (!g_ar) return DECLINED; if (!r) return DECLINED; // 2. ¹«ÀÎÁõÀº GET ¿äû¸¸ Çã¿ë. if (r->method_number != M_GET) { return DECLINED; } // NEW 2012-04-23 huibong // - HTTP Header »ó¿¡ ÀÎÁõ °ü·Ã Authorization Á¤º¸°¡ Á¸ÀçÇϰí, dav_shared_ar_check_request() ÇÔ¼ö¿¡¼­ ÀÔ·ÂÇÑ "Basic REDIRECTED" Á¤º¸°¡ ¾Æ´Ñ °æ¿ì.. ¾ç¹æÇâ ÀÎÁõÀ¸·Î 󸮵ǵµ·Ï ó¸®. p1 = apr_table_get(r->headers_in, "Authorization"); if (p1 != NULL) { if (strcmp(p1, "Basic REDIRECTED") != 0) { return DECLINED; } } // 3. URL ÃßÃâ ap_unescape_url(r->unparsed_uri); // °øÀ¯ ¸Þ¸ð¸®¿¡ UTF-8·Î ÀúÀåµÇ¾î Àֱ⠶§¹®¿¡ º¯È¯ ÇÊ¿ä uri = transformUTF8(r, r->unparsed_uri, "dav_shared_ar_get_value"); // 3. ¿äûÀÌ ¹«ÀÎÁõ ¿äûÀÎÁö È®ÀÎÇÑ´Ù. // - Ãß°¡·Î ¹«ÀÎÁõ ¿äûÀÎ °æ¿ì ¹«ÀÎÁõ Á¤º¸ È®ÀÎÀ» À§ÇÑ ¼­ºñ½º¸í, Æú´õ¸íÀ» ÃßÃâÇÑ´Ù. // ¾ç¹æÇ⠱⺻ : /dav/svc1_test/temp1.txt // ¹«ÀÎÁõ redirect ó¸® ÈÄ : /dav/nctest/SVC1_TEST/temp2.txt ( /dav/ ¼­ºñ½º Name / °æ·Î¸í ) // ¹«ÀÎÁõ ÃÖÃÊ ¿äû : /svc1_test/TEMP7.txt // ±âŸ : /a , /ok.html µîµî. // 3-1 uri ÀÇ ±æÀ̰ªÀ» È®ÀÎ // /·Î ½ÃÀÛÇØ¾ß Çϰí.. µÚ¿¡ °æ·Î Á¤º¸°¡ µé¾î ÀÖ¾î¾ß ÇϹǷÎ... // ÃÖ¼Ò Çü½ÄÀº /a/a, /dav ÀÇ 4 byte ÀÌ»óÀ̾î¾ß ÇÑ´Ù. if (strlen(uri) < 4) { // ¹«ÀÎÁõ uri ±ÔÄ¢ À§¹è »óȲÀ̰í.. Authorization Á¤º¸µµ Á¸ÀçÇÏÁö ¾ÊÀ¸¹Ç·Î.. °ÅºÎ ó¸®. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_get_value: uri not valid. length too small [%s]", uri); return DECLINED; } // 3-2 /dav/ ·Î ½ÃÀÛÇØ¾ß ÇÔ. if (strstr(uri, "/dav/") == uri) { // /dav/ ·Î ½ÃÀÛÇÏ´Â uri ÀÎ °æ¿ì.. // /dav/ ·Î ½ÃÀÛÇÏ´Â ºÎºÐÀ» °Ç³Ê¶Ù°í... ´ÙÀ½ ¹®ÀÚ¸¦ ¼­ºñ½º Name À¸·Î ó¸®.... ±× ´ÙÀ½À» °æ·Î·Î ó¸®.. p1 = uri; p1 = p1 + 5; // p1 -> nctest/SVC1_TEST/temp2.txt Çü½Ä request_path = strchr(p1, '/'); // request_path -> /SVC1_TEST/temp2.txt Çü½Ä if (request_path == NULL) { // ¹«ÀÎÁõ redirect ó¸® ±ÔÄ¢ À§¹è »óȲ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_get_value: redirect uri format not valid [%s]", uri); return DECLINED; } // ¼­ºñ½º Name Á¤º¸¸¦ ÃßÃâ.. svc_name_len = (request_path - p1); svc_name = apr_pstrdup(r->pool, p1); *(svc_name + svc_name_len) = '\0'; // ¹«ÀÎÁõ Æú´õ Á¤º¸¸¦ ÃßÃâÇÑ´Ù. // Á¤»ó : /SVC1_TEST/a.txt Çü½Ä // ¿À·ù : /SVC1_TEST , // , //a.txt request_path = request_path + 1; // request_path -> SVC1_TEST/a.txt Çü½Ä p1 = strchr(request_path, '/'); if (p1 == NULL) { // ¹«ÀÎÁõ redirect ó¸® ±ÔÄ¢ À§¹è »óȲ.. °æ·Î Á¤º¸ Á¸ÀçÇÏÁö ¾ÊÀ½. //ap_log_error( APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_get_value: annoymous uri format not valid [%s]", uri ); return DECLINED; } else { folder_name_len = (p1 - request_path); if (folder_name_len < 1) // ±¸Á¶°¡ a/ ±¸Á¶°¡ ¾Æ´Ñ °æ¿ì Áï.. // { // ¹«ÀÎÁõ ¿äû ±ÔÄ¢ À§¹èÀ̹ǷΠ°ÅºÎ ó¸®. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_get_value: annoymous folder name length not valid [%s]", uri); return DECLINED; } else { folder_name = apr_pstrdup(r->pool, request_path); *(folder_name + folder_name_len) = '\0'; // folder_name -> SVC1_TEST Çü½Ä } } } // 4. ¼­ºñ½º Name, folder name Á¤º¸¸¦ È®ÀÎÇÏ¿© ÃßÃâÇÏÁö ¸øÇÑ °æ¿ì.. ¹«ÀÎÁõ ¿äûÀÌ ¾Æ´Ô. if (svc_name == NULL || folder_name == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_get_value: not valid annoymous request [%s]", uri); return DECLINED; } // 5. ÇØ´ç ¼­ºñ½ºÀÇ ´ë¼Ò¹®ÀÚ ¹«½Ã ¿©ºÎ¸¦ ÆÇ´ÜÇÑ´Ù. result = dav_shared_is_uri_ignore_case_by_svcname(svc_name); if (result == 1) // URI ´ë¼Ò¹®ÀÚ ¹«½Ã ¼­ºñ½ºÀÎ °æ¿ì { is_uricaseignore = true; } else { // ¸¸¾à dav_shared_is_uri_ignore_case È£Ãâ½Ã ¿À·ù°¡ ¹ß»ýÇÑ °æ¿ì.. ¾ç¹æÇ⠱⺻Àº ´ë¼Ò¹®ÀÚ ±¸ºÐ À¸·Î ó¸®. if (result == -1) ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_ar_get_value: dav_shared_is_uri_ignore_case_by_svcname func fail. svc name[%s]. use default", svc_name); is_uricaseignore = false; } // 6. ¹«ÀÎÁõ Á¤º¸¸¦ Á¶È¸ÇÏ¿© ÇØ´ç Á¤º¸°¡ Á¸ÀçÇÏ´ÂÁö ÆÇ´ÜÇÑ´Ù. for (i = 0; i < maxanon; i++) { // ¹«ÀÎÁõ ¼³Á¤ Á¤º¸°¡ ¾ø´Â °æ¿ì ±×³É Åë°ú... if ((g_ar + i)->domain[0] == '\0') break; // 2015.7.15 dadamin // version 3.5ºÎÅÍ fimnd ÀÇÇØ¼­ ¼³Á¤µÈ flag °ª ÂüÁ¶ // 1 : »èÁ¦ if ((g_ar + i)->nFlag == 1) continue; // ´ë¼Ò¹®ÀÚ ±¸ºÐ ¿©ºÎ¿¡ µû¶ó.. ¹«ÀÎÁõ Æú´õ Á¸Àç ¿©ºÎ È®ÀÎ.. // URI ´ë¼Ò¹®ÀÚ ¹«½Ã ¼­ºñ½ºÀÎ °æ¿ì if (is_uricaseignore == true) { result = (!strcasecmp(folder_name, (g_ar + i)->uri) && !strncasecmp(svc_name, (g_ar + i)->domain, svc_name_len) && strlen((g_ar + i)->domain) == svc_name_len); } else // ¾ç¹æÇ⠱⺻ ( URI ´ë¼Ò¹®ÀÚ ±¸ºÐ ) { result = (strcmp(folder_name, (g_ar + i)->uri) == OK && !strncasecmp(svc_name, (g_ar + i)->domain, svc_name_len) && strlen((g_ar + i)->domain) == svc_name_len); } // Àü´Þ¹ÞÀº URL ÀÌ ¹«ÀÎÁõ Æú´õ»ó¿¡ Á¸ÀçÇÏ´Â °æ¿ì if (result) { char * new_uri = NULL; // URI ºÎºÐ Áß ¹«ÀÎÁõ °æ·Î °ü·Ã ºÎºÐ¸¸ º¯È¯ ó¸® ¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù. if (uri == r->unparsed_uri) { new_uri = transformDBCharacter(r, request_path, "dav_shared_ar_get_value"); } // iconv º¯È¯ Çʿ䰡 ¾ø°Å³ª...º¯È¯ ½ÇÆÐ½Ã... ½Å±Ô URL À» Á¶¸³. if (!new_uri) { new_uri = apr_pstrcat(r->pool, "/dav/", request_path, NULL); } else { new_uri = apr_pstrcat(r->pool, "/dav/", new_uri, NULL); } ap_parse_uri(r, new_uri); ap_getparents(r->uri); // HTTP RedHost tag »ó¿¡´Â ¼­ºñ½º Name Á¤º¸¸¦ ÀԷ ó¸®ÇÑ´Ù. apr_table_setn(r->headers_in, "RedHost", svc_name); //ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "dav_shared_ar_get_value: new_uri [%s], RedHost [%s]", new_uri, svc_name); return OK; } } return DECLINED; #endif // __OPENDISK_SOLUTION__ }