/************************************************************************* * 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 . **************************************************************************/ #ifndef CLIENT_ONLY #include "action_header.h" #include "../server_settings.h" #include "../../urbackupcommon/os_functions.h" #include "../server_status.h" #include "../../cryptoplugin/ICryptoFactory.h" #include "../server.h" #include "../ClientMain.h" #include "../dao/ServerBackupDao.h" #include #include extern ICryptoFactory *crypto_fak; namespace { bool client_download(Helper& helper, JSON::Array &client_downloads) { IDatabase *db=helper.getDatabase(); ServerSettings settings(db); if(!FileExists("urbackup/UrBackupUpdate.exe")) return false; if(!FileExists("urbackup/UrBackupUpdate.sig2")) return false; if(crypto_fak==NULL) return false; bool clientid_rights_all; std::vector clientid_rights=helper.clientRights(RIGHT_SETTINGS, clientid_rights_all); db_results res=db->Read("SELECT id, name FROM clients ORDER BY name"); bool has_client=false; for(size_t i=0;iRead("SELECT tvalue FROM misc WHERE tkey='stop_show_version'"); if (!res.empty()) { return res[0]["tvalue"]; } return std::string(); } void set_server_version_info(IDatabase* db, JSON::Object& ret) { std::auto_ptr infoProperties(Server->createFileSettingsReader("urbackup/server_version_info.properties")); if(infoProperties.get()) { std::string stop_show_version = get_stop_show_version(db); std::string curr_version_str; if (infoProperties->getValue("curr_version_str", &curr_version_str)) { if (stop_show_version != curr_version_str) { ret.set("curr_version_str", curr_version_str); std::string curr_version_num; if (infoProperties->getValue("curr_version_num", &curr_version_num)) { ret.set("curr_version_num", watoi64(curr_version_num)); } } } } } void add_remove_stop_show(IDatabase* db, std::string stop_show, bool add) { db_results res = db->Read("SELECT tvalue FROM misc WHERE tkey='stop_show'"); if (!res.empty()) { std::vector toks; Tokenize(res[0]["tvalue"], toks, ","); std::vector::iterator it = std::find(toks.begin(), toks.end(), stop_show); if (add) { if (it == toks.end()) { toks.push_back(stop_show); } } else { if (it != toks.end()) { toks.erase(it); } } std::string nval; for (size_t i = 0; i < toks.size(); ++i) { if (!nval.empty()) nval += ","; nval += toks[i]; } IQuery* q = db->Prepare("UPDATE misc SET tvalue=? WHERE tkey='stop_show'"); q->Bind(nval); q->Write(); q->Reset(); } else { IQuery* q = db->Prepare("INSERT INTO misc (tkey, tvalue) VALUES ('stop_show', ?)"); q->Bind(stop_show); q->Write(); q->Reset(); } } void set_stop_show_version(IDatabase* db, std::string ver) { db_results res = db->Read("SELECT tvalue FROM misc WHERE tkey='stop_show_version'"); if (!res.empty()) { IQuery* q = db->Prepare("UPDATE misc SET tvalue=? WHERE tkey='stop_show_version'"); q->Bind(ver); q->Write(); q->Reset(); } else { IQuery* q = db->Prepare("INSERT INTO misc (tkey, tvalue) VALUES ('stop_show_version', ?)"); q->Bind(ver); q->Write(); q->Reset(); } } bool is_stop_show(IDatabase* db, std::string stop_key) { db_results res = db->Read("SELECT tvalue FROM misc WHERE tkey='stop_show'"); if (!res.empty()) { std::vector toks; Tokenize(res[0]["tvalue"], toks, ","); return std::find(toks.begin(), toks.end(), stop_key) != toks.end(); } return false; } } ACTION_IMPL(status) { Helper helper(tid, &POST, &PARAMS); JSON::Object ret; std::string rights=helper.getRights("status"); std::vector clientids; IDatabase *db=helper.getDatabase(); if(rights!="all" && rights!="none" ) { std::vector s_clientid; Tokenize(rights, s_clientid, ","); for(size_t i=0;iid==SESSION_ID_INVALID) return; if(session!=NULL && (rights=="all" || !clientids.empty()) ) { if (rights == "all" && POST.find("stop_show") != POST.end()) { add_remove_stop_show(db, POST["stop_show"], true); } if (rights == "all" && POST.find("stop_show_version") != POST.end()) { set_stop_show_version(db, POST["stop_show_version"]); } if (rights == "all" && POST.find("reset_error") != POST.end()) { std::string reset_error = POST["reset_error"]; if (reset_error == "nospc_stalled") { ServerStatus::resetServerNospcStalled(); } else if (reset_error == "nospc_fatal") { ServerStatus::setServerNospcFatal(false); } else if (reset_error == "database_error") { Server->clearFailBit(IServer::FAIL_DATABASE_CORRUPTED); Server->clearFailBit(IServer::FAIL_DATABASE_IOERR); Server->clearFailBit(IServer::FAIL_DATABASE_FULL); } } if(rights=="all") { ret.set("has_status_check", true); if(ServerStatus::getServerNospcStalled()>0) { ret.set("nospc_stalled" ,true); } if(ServerStatus::getServerNospcFatal()) { ret.set("nospc_fatal" ,true); } if( (Server->getFailBits() & IServer::FAIL_DATABASE_CORRUPTED) || (Server->getFailBits() & IServer::FAIL_DATABASE_IOERR) || (Server->getFailBits() & IServer::FAIL_DATABASE_FULL) ) { ret.set("database_error", true); } } std::string hostname=POST["hostname"]; if(!hostname.empty() && rights=="all") { if(POST["remove"]=="true") { IQuery *q=db->Prepare("DELETE FROM settings_db.extra_clients WHERE id=?"); q->Bind(hostname); q->Write(); q->Reset(); } else { IQuery *q=db->Prepare("INSERT INTO settings_db.extra_clients (hostname) SELECT ? AS hostname WHERE NOT EXISTS (SELECT hostname FROM settings_db.extra_clients WHERE hostname=?)"); q->Bind(hostname); q->Bind(hostname); q->Write(); q->Reset(); } } std::string s_remove_client=POST["remove_client"]; if(!s_remove_client.empty() && helper.getRights("remove_client")=="all") { std::vector remove_client; Tokenize(s_remove_client, remove_client, ","); if(POST.find("stop_remove_client")!=POST.end()) { for(size_t i=0;iPrepare("UPDATE clients SET delete_pending=0 WHERE id=?"); q->Bind(remove_client[i]); q->Write(); q->Reset(); } } else { for(size_t i=0;iPrepare("UPDATE clients SET delete_pending=1 WHERE id=? OR virtualmain = (SELECT name FROM clients WHERE id=?)"); q->Bind(remove_client[i]); q->Bind(remove_client[i]); q->Write(); q->Reset(); } } BackupServer::updateDeletePending(); } JSON::Array status; IDatabase *db=helper.getDatabase(); std::string filter; if(!clientids.empty()) { filter=" WHERE "; for(size_t i=0;iRead("SELECT c.id AS id, delete_pending, c.name AS name, strftime('"+helper.getTimeFormatString()+"', lastbackup) AS lastbackup, strftime('"+helper.getTimeFormatString()+"', lastseen) AS lastseen," "strftime('"+helper.getTimeFormatString()+"', lastbackup_image) AS lastbackup_image, last_filebackup_issues, os_simple, os_version_str, client_version_str, cg.name AS groupname, file_ok, image_ok FROM " " clients c LEFT OUTER JOIN settings_db.si_client_groups cg ON c.groupid = cg.id "+filter+" ORDER BY name"); std::vector client_status=ServerStatus::getStatus(); for(size_t i=0;i lastseen) { lastseen = client_status[j].lastseen; } switch(client_status[j].status_error) { case se_ident_error: i_status=11; break; case se_too_many_clients: i_status=12; break; case se_authentication_error: i_status=13; break; default: if(!client_status[j].processes.empty()) { i_status = client_status[j].processes[0].action; } } for(size_t k=0;kRead("SELECT id, hostname, lastip FROM settings_db.extra_clients"); for(size_t i=0;ino_images); ret.set("no_file_backups", settings.getSettings()->no_file_backups); if(helper.getRights("all")=="all") { ret.set("admin", JSON::Value(true)); set_server_version_info(db, ret); } if(is_big_endian()) { ret.set("big_endian", true); } } else if (session != NULL) { ret.set("status", JSON::Array()); ret.set("extra_clients", JSON::Array()); ret.set("server_identity", helper.getStrippedServerIdentity()); ServerSettings settings(db); ret.set("no_images", settings.getSettings()->no_images); ret.set("no_file_backups", settings.getSettings()->no_file_backups); if (is_big_endian()) { ret.set("big_endian", true); } } else { ret.set("error", 1); } helper.Write(ret.stringify(false)); } #endif //CLIENT_ONLY