/************************************************************************* * UrBackup - Client/Server backup system * Copyright (C) 2011-2016 Martin Raiber * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . **************************************************************************/ #include "helper.h" #include "../../stringtools.h" #include "../database.h" #include #include #include "../server_settings.h" #include "../../urlplugin/IUrlFactory.h" #include "../../urbackupcommon/glob.h" #include "../../cryptoplugin/ICryptoFactory.h" extern std::string server_identity; extern IUrlFactory *url_fak; extern ICryptoFactory *crypto_fak; Helper::Helper(THREAD_ID pTID, str_map *pPOST, str_map *pPARAMS) { prioritized = os_enable_prioritize(prio_info, Prio_SlightPrioritize); session=NULL; update(pTID,pPOST,pPARAMS); Server->addHeader(pTID, "X-Frame-Options: DENY"); } void Helper::update(THREAD_ID pTID, str_map *pPOST, str_map *pPARAMS) { tid=pTID; POST=pPOST; PARAMS=pPARAMS; if(POST==NULL) { return; } if( session==NULL ) { session=Server->getSessionMgr()->getUser( (*POST)["ses"], getIdentData() ); if(session!=NULL) { str_map::iterator it = session->mStr.find("ldap_rights"); if(it!=session->mStr.end()) { ldap_rights = parseRightsString(it->second); } } } //Get language from ACCEPT_LANGUAGE str_map::iterator lit=POST->find("lang"); if(lit!=POST->end() && lit->second!="-") { language=lit->second; } else { std::string langs=(*POST)["langs"]; std::vector clangs; Tokenize(langs, clangs, ","); for(size_t j=0;jfind("ACCEPT_LANGUAGE"); if(al==PARAMS->end()) al=PARAMS->find("HTTP_ACCEPT_LANGUAGE"); if(al!=PARAMS->end()) { std::vector toks; Tokenize(al->second, toks, ","); for(size_t i=0;igetDatabase(tid, TRANSLATIONDB); ITemplate *tmpl=Server->createTemplate("urbackup/templates/"+name); /*if( db!=NULL ) { tmpl->addValueTable(db, "translation_"+language ); }*/ if( invalid_session==true ) tmpl->setValue("INVALID_SESSION","true"); else if(session!=NULL) tmpl->setValue("SESSION", session->session); if( session!=NULL && session->id==SESSION_ID_INVALID ) tmpl->setValue("INVALID_ID","true"); templates.push_back( tmpl ); return tmpl; } Helper::~Helper(void) { if( session!=NULL ) Server->getSessionMgr()->releaseUser(session); for(size_t i=0;idestroy( templates[i] ); } if (prioritized) { os_disable_prioritize(prio_info); } } void Helper::Write(std::string str, bool content_type_json) { if (content_type_json) { Server->setContentType(tid, "application/json"); } Server->Write( tid, str ); } void Helper::WriteTemplate(ITemplate *tmpl) { Server->Write( tid, tmpl->getData() ); } IDatabase *Helper::getDatabase(void) { return Server->getDatabase(tid, URBACKUPDB_SERVER); } std::string Helper::generateSession(std::string username) { return Server->getSessionMgr()->GenerateSessionIDWithUser( username, getIdentData()); } std::string Helper::getRights(const std::string &domain) { if(session==NULL) return "none"; if(session->id==SESSION_ID_ADMIN) return "all"; if(session->id==SESSION_ID_TOKEN_AUTH && ldap_rights.empty()) return "none"; if(getRightsInt("all")=="all") return "all"; return getRightsInt(domain); } std::string Helper::getIdentData() { std::string user_agent = (*PARAMS)["HTTP_USER_AGENT"]; str_map::iterator it_remote = PARAMS->find("HTTP_X_FORWARDED_FOR"); if (it_remote != PARAMS->end()) { if (it_remote->second.find(",") != std::string::npos) { return trim(getuntil(",", it_remote->second)) + user_agent; } return it_remote->second + user_agent; } return (*PARAMS)["REMOTE_ADDR"] + user_agent; } std::string Helper::getRightsInt(const std::string &domain) { if(session==NULL) return "none"; std::map::iterator it=ldap_rights.find(domain); if(it!=ldap_rights.end()) { return it->second; } IQuery *q=getDatabase()->Prepare("SELECT t_right FROM settings_db.si_permissions WHERE clientid=? AND t_domain=?"); q->Bind(session->id); q->Bind(domain); db_results res=q->Read(); q->Reset(); if(!res.empty()) { return res[0]["t_right"]; } else { return "none"; } } void Helper::releaseAll(void) { if(session!=NULL) { Server->getSessionMgr()->releaseUser(session); session=NULL; } } std::string Helper::getTimeFormatString(void) { return "%s"; } std::string Helper::getLanguage(void) { return language; } std::vector Helper::getRightIDs(std::string rights) { std::vector clientid; if(rights!="all" && rights!="none" ) { std::vector s_clientid; Tokenize(rights, s_clientid, ","); for(size_t i=0;i right_ids) { bool r_ok=false; if(rights!="all") { for(size_t i=0;iPrepare("SELECT id, name, password_md5, salt, pbkdf2_rounds FROM settings_db.si_users WHERE name=?"); q->Bind(username); db_results res=q->Read(); if(!res.empty()) { std::string password_md5=res[0]["password_md5"]; if(!plainpw) { std::string r_password=Server->GenerateHexMD5((session->mStr["rnd"]+password_md5)); if(r_password!=password) { return false; } else { if(user_id!=NULL) { *user_id=watoi(res[0]["id"]); } return true; } } else { std::string db_password = Server->GenerateHexMD5((res[0]["salt"]+password)); size_t pbkdf2_rounds = watoi(res[0]["pbkdf2_rounds"]); if(pbkdf2_rounds>0) { db_password = strlower(crypto_fak->generatePasswordHash(hexToBytes(db_password), (res[0]["salt"]), pbkdf2_rounds)); } if(db_password!=password_md5) { return false; } else { if(user_id!=NULL) { *user_id=watoi(res[0]["id"]); } return true; } } } return false; } std::vector Helper::clientRights(const std::string& right_name, bool& all_client_rights) { std::string rights=getRights(right_name); std::vector clientid; if(rights!="all" && rights!="none" ) { std::vector s_clientid; Tokenize(rights, s_clientid, ","); for(size_t i=0;i3) { if(next(ret, 0, "#I")) { ret=ret.substr(2); } if(ret[ret.size()-1]=='#') { ret=ret.substr(0, ret.size()-1); } } return ret; } void Helper::sleep(unsigned int ms) { if(session!=NULL) { Server->getSessionMgr()->unlockUser(session); } Server->wait(ms); if(session!=NULL) { Server->getSessionMgr()->lockUser(session); } } bool Helper::ldapEnabled() { IDatabase *db=getDatabase(); IQuery *q=db->Prepare("SELECT value FROM settings_db.settings WHERE clientid=0 AND key='ldap_login_enabled'"); if(q!=NULL) { db_results res = q->Read(); if(!res.empty()) { return res[0]["value"]=="true"; } } return false; } bool Helper::ldapLogin( const std::string &username, const std::string &password, std::string* ret_errmsg, std::string* rights, bool dry_login) { if(url_fak==NULL) { return false; } ServerSettings settings(getDatabase()); SLDAPSettings ldap_settings = settings.getLDAPSettings(); if (!ldap_settings.login_enabled) { return false; } std::string sanitized_username = username; std::string to_sanitize = "\"[]:;|=+*?<>/\\,"; for(size_t i=0;i0?(":" + convert(ldap_settings.server_port)):"") + "/" + (group_class_query); std::string errmsg; std::vector > data = url_fak->queryLDAP(ldap_query, ldap_settings.username_prefix+(username)+ldap_settings.username_suffix, (password), &errmsg); if(data.empty()) { if(!errmsg.empty()) { Server->Log("Login via LDAP failed: "+errmsg, LL_ERROR); if(ret_errmsg) { *ret_errmsg = errmsg; } } return false; } else { if(data.size()!=1) { Server->Log("LDAP query returned "+convert(data.size())+" items, but should return only one. Login failed.", LL_ERROR); if(ret_errmsg) { *ret_errmsg="LDAP query returned more than one result"; } return false; } IQuery* q = getDatabase()->Prepare("SELECT clientid FROM users_on_client WHERE username=?"); q->Bind(strlower(ldap_settings.username_prefix + username + ldap_settings.username_suffix)); db_results db_res = q->Read(); q->Reset(); std::string autoclients; for(size_t i=0;i sdata = data[0]; std::string str_ldap_rights; std::multimap::iterator it = sdata.find(ldap_settings.group_key_name); while(it!=sdata.end() && it->first == ldap_settings.group_key_name) { for(std::map::iterator it_rights= ldap_settings.group_rights_map.begin();it_rights!=ldap_settings.group_rights_map.end(); ++it_rights) { if(amatch((it->second).c_str(), it_rights->first.c_str())) { str_ldap_rights = greplace("{AUTOCLIENTS}", autoclients, (it_rights->second)); break; } } ++it; } if(str_ldap_rights.empty()) { std::multimap::iterator it = sdata.find(ldap_settings.class_key_name); while(it!=sdata.end() && it->first == ldap_settings.class_key_name) { for(std::map::iterator it_rights= ldap_settings.class_rights_map.begin();it_rights!=ldap_settings.class_rights_map.end(); ++it_rights) { if(amatch((it->second).c_str(), it_rights->first.c_str())) { str_ldap_rights = greplace("{AUTOCLIENTS}", autoclients, (it_rights->second)); break; } } ++it; } } if(!str_ldap_rights.empty() && !dry_login) { ldap_rights = parseRightsString(str_ldap_rights); } if(!str_ldap_rights.empty() && session!=NULL && !dry_login) { session->mStr["ldap_rights"] = str_ldap_rights; } q= getDatabase()->Prepare("SELECT token FROM user_tokens WHERE username = ?"); q->Bind(strlower(ldap_settings.username_prefix + username + ldap_settings.username_suffix)); db_res = q->Read(); q->Reset(); std::string fileaccesstokens; for(size_t i=0;imStr["fileaccesstokens"]=fileaccesstokens; } if(rights) { *rights = str_ldap_rights; } return !str_ldap_rights.empty(); } } std::map Helper::parseRightsString( const std::string& rights ) { std::vector toks; Tokenize(rights, toks, ","); std::map ret; for(size_t i=0;i