diff --git a/include/yazproxy/proxy.h b/include/yazproxy/proxy.h index c2d295c..5a7eafe 100644 --- a/include/yazproxy/proxy.h +++ b/include/yazproxy/proxy.h @@ -131,6 +131,7 @@ class YAZ_EXPORT Yaz_Proxy : public yazpp_1::Z_Assoc { Z_APDU *handle_target_charset_conversion(Z_APDU *apdu); Z_APDU *handle_syntax_validation(Z_APDU *apdu); + Z_APDU *handle_database_validation(Z_APDU *apdu); void handle_charset_lang_negotiation(Z_APDU *apdu); diff --git a/src/proxyp.h b/src/proxyp.h index f791372..101f796 100644 --- a/src/proxyp.h +++ b/src/proxyp.h @@ -148,6 +148,7 @@ class Yaz_ProxyConfig { char *get_explain_doc(ODR odr, const char *name, const char *db, int *len, int *http_status); const char *get_explain_name(const char *db, const char **backend_db); + int check_is_defined_database(const char *name, const char *db); private: void operator=(const Yaz_ProxyConfig &conf); class Yaz_ProxyConfigP *m_cp; diff --git a/src/yaz-proxy-config.cpp b/src/yaz-proxy-config.cpp index ae235d5..6720fa1 100644 --- a/src/yaz-proxy-config.cpp +++ b/src/yaz-proxy-config.cpp @@ -484,6 +484,30 @@ int Yaz_ProxyConfigP::check_type_1(ODR odr, xmlNodePtr ptr, Z_RPNQuery *query, } #endif +int Yaz_ProxyConfig::check_is_defined_database(const char *name, const char *db) { +#if YAZ_HAVE_XSLT + xmlNodePtr ptr; + struct _xmlAttr *attr; + + ptr = m_cp->find_target_node(name); + + if (ptr) + { + for (attr = ptr->properties; attr; attr = attr->next) + { + if (attr->children && attr->children->type == XML_TEXT_NODE) { + if (!strcmp((const char *)attr->name, "database") + && !strcmp((const char *)attr->children->content, db)) + { + return 1; + } + } + } + } +#endif + return 0; +} + int Yaz_ProxyConfig::check_query(ODR odr, const char *name, Z_Query *query, char **addinfo) { diff --git a/src/yaz-proxy.cpp b/src/yaz-proxy.cpp index 351725b..21dee1b 100644 --- a/src/yaz-proxy.cpp +++ b/src/yaz-proxy.cpp @@ -2695,6 +2695,34 @@ int Yaz_Proxy::handle_global_authentication(Z_APDU *apdu) return ret; } +Z_APDU *Yaz_Proxy::handle_database_validation(Z_APDU *apdu) +{ + Yaz_ProxyConfig *cfg = check_reconfigure(); + + if (cfg && apdu->which == Z_APDU_searchRequest) + { + Z_SearchRequest *sr = apdu->u.searchRequest; + + for (int i = 0; i < sr->num_databaseNames; i++) { + // This works only with the default target + if (!cfg->check_is_defined_database(m_default_target, (const char *)sr->databaseNames[i])) { + Z_APDU *new_apdu = create_Z_PDU(Z_APDU_searchResponse); + + new_apdu->u.searchResponse->referenceId = sr->referenceId; + new_apdu->u.searchResponse->records = + create_nonSurrogateDiagnostics(odr_encode(), YAZ_BIB1_ACCESS_TO_SPECIFIED_DATABASE_DENIED, NULL); + *new_apdu->u.searchResponse->searchStatus = 0; + + send_to_client(new_apdu); + + return 0; + } + } + } + + return apdu; +} + Z_APDU *Yaz_Proxy::handle_syntax_validation(Z_APDU *apdu) { m_marcxml_mode = none; @@ -3647,6 +3675,9 @@ void Yaz_Proxy::handle_incoming_Z_PDU_2(Z_APDU *apdu) { handle_max_record_retrieve(apdu); + if (apdu) + apdu = handle_database_validation(apdu); + if (apdu) apdu = handle_syntax_validation(apdu);