+ Z_SearchRequest *req =
+ package.request().get()->u.z3950->u.searchRequest;
+
+ if (m_p->userBySession.count(package.session()) == 0) {
+ // It's a non-authenticated session, so just accept the operation
+ return package.move();
+ }
+
+ std::string user = m_p->userBySession[package.session()];
+ yf::AuthSimple::Rep::PasswordAndDBs pdb = m_p->userRegister[user];
+ for (int i = 0; i < req->num_databaseNames; i++) {
+ if (!contains(pdb.dbs, req->databaseNames[i]) &&
+ !contains(pdb.dbs, "*")) {
+ // Make an Search rejection APDU
+ mp::odr odr;
+ Z_APDU *apdu = odr.create_searchResponse(
+ package.request().get()->u.z3950,
+ YAZ_BIB1_ACCESS_TO_SPECIFIED_DATABASE_DENIED,
+ req->databaseNames[i]);
+ package.response() = apdu;
+ package.session().close();
+ return;
+ }
+ }
+
+ // All the requested databases are acceptable
+ return package.move();
+}
+
+
+void yf::AuthSimple::process_scan(mp::Package &package) const
+{
+ Z_ScanRequest *req =
+ package.request().get()->u.z3950->u.scanRequest;
+
+ if (m_p->userBySession.count(package.session()) == 0) {
+ // It's a non-authenticated session, so just accept the operation
+ return package.move();
+ }
+
+ std::string user = m_p->userBySession[package.session()];
+ yf::AuthSimple::Rep::PasswordAndDBs pdb = m_p->userRegister[user];
+ for (int i = 0; i < req->num_databaseNames; i++) {
+ if (!contains(pdb.dbs, req->databaseNames[i]) &&
+ !contains(pdb.dbs, "*")) {
+ // Make an Scan rejection APDU
+ mp::odr odr;
+ Z_APDU *apdu = odr.create_scanResponse(
+ package.request().get()->u.z3950,
+ YAZ_BIB1_ACCESS_TO_SPECIFIED_DATABASE_DENIED,
+ req->databaseNames[i]);
+ package.response() = apdu;
+ package.session().close();
+ return;
+ }
+ }
+
+ // All the requested databases are acceptable
+ return package.move();
+}
+
+
+static void reject_init(mp::Package &package, int err, const char *addinfo) {
+ if (err == 0)
+ err = YAZ_BIB1_INIT_AC_AUTHENTICATION_SYSTEM_ERROR;
+ // Make an Init rejection APDU
+ Z_GDU *gdu = package.request().get();
+ mp::odr odr;
+ Z_APDU *apdu = odr.create_initResponse(gdu->u.z3950, err, addinfo);
+ *apdu->u.initResponse->result = 0; // reject
+ package.response() = apdu;
+ package.session().close();
+}
+
+void yf::AuthSimple::check_targets(mp::Package & package) const
+{
+ Z_InitRequest *initReq = package.request().get()->u.z3950->u.initRequest;
+
+ std::string password;
+ std::string user = get_user(initReq, password);
+ std::list<std::string> authorisedTargets = m_p->targetsByUser[user];
+
+ std::list<std::string> targets;
+ Z_OtherInformation **otherInfo = &initReq->otherInfo;
+ mp::util::remove_vhost_otherinfo(otherInfo, targets);
+
+ // Check each of the targets specified in the otherInfo package
+ std::list<std::string>::iterator i;
+
+ i = targets.begin();
+ while (i != targets.end()) {
+ if (contains(authorisedTargets, *i) ||
+ contains(authorisedTargets, "*")) {
+ i++;
+ } else {
+ if (!m_p->discardUnauthorisedTargets)
+ return reject_init(package,
+ YAZ_BIB1_ACCESS_TO_SPECIFIED_DATABASE_DENIED, i->c_str());
+ i = targets.erase(i);
+ }
+ }
+
+ if (targets.size() == 0)
+ return reject_init(package,
+ YAZ_BIB1_ACCESS_TO_SPECIFIED_DATABASE_DENIED,
+ // ### It would be better to use the Z-db name
+ "all databases");
+ mp::odr odr;
+ mp::util::set_vhost_otherinfo(otherInfo, odr, targets);
+ package.move();
+}
+
+
+static mp::filter::Base* filter_creator()
+{
+ return new mp::filter::AuthSimple;