mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
392 lines
8.3 KiB
C++
392 lines
8.3 KiB
C++
/*************************************************************************
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
**************************************************************************/
|
|
|
|
#include "../vld.h"
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#ifdef _WIN32
|
|
# include <conio.h>
|
|
# include <ws2tcpip.h>
|
|
#endif
|
|
#include "../Interface/Server.h"
|
|
#include "CTCPFileServ.h"
|
|
#include "settings.h"
|
|
#include "../stringtools.h"
|
|
#include "log.h"
|
|
|
|
std::fstream logfile;
|
|
CTCPFileServ *TCPServer=nullptr;
|
|
|
|
#ifdef LINUX
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <syslog.h>
|
|
#include <string.h>
|
|
#endif
|
|
#include <algorithm>
|
|
|
|
#ifdef DLL_EXPORT
|
|
# define EXPORT_METHOD_INT 5
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
void RestartServer()
|
|
{
|
|
_u16 tcpport=TCPServer->getTCPPort();
|
|
_u16 udpport=TCPServer->getUDPPort();
|
|
std::string servername=TCPServer->getServername();
|
|
bool use_fqdn=TCPServer->getUseFQDN();
|
|
|
|
TCPServer->KickClients();
|
|
delete TCPServer;
|
|
Sleep(1000);
|
|
|
|
TCPServer=new CTCPFileServ;
|
|
int tries=20;
|
|
while(!TCPServer->Start(tcpport, udpport, servername, use_fqdn) )
|
|
{
|
|
Sleep(1000);
|
|
if(tries<=0)
|
|
{
|
|
_exit(32);
|
|
}
|
|
--tries;
|
|
}
|
|
}
|
|
|
|
bool EnumerateInterfaces()
|
|
{
|
|
static std::vector<std::vector<char> > ips;
|
|
char hostname[MAX_PATH];
|
|
|
|
_i32 rc=gethostname(hostname, MAX_PATH);
|
|
if(rc==SOCKET_ERROR)
|
|
return false;
|
|
|
|
bool new_ifs=false;
|
|
|
|
std::vector<std::vector<char> > new_ips;
|
|
|
|
struct addrinfo* h;
|
|
if(getaddrinfo(hostname, NULL, NULL, &h)==0)
|
|
{
|
|
for(addrinfo* ptr = h;ptr!=NULL;ptr=ptr->ai_next)
|
|
{
|
|
if(ptr->ai_family==AF_INET || ptr->ai_family==AF_INET6)
|
|
{
|
|
std::vector<char> address;
|
|
address.resize(ptr->ai_addrlen);
|
|
memcpy(&address[0], ptr->ai_addr, ptr->ai_addrlen);
|
|
|
|
if(std::find(ips.begin(), ips.end(), address)==ips.end())
|
|
{
|
|
new_ifs=true;
|
|
}
|
|
|
|
new_ips.push_back(address);
|
|
}
|
|
}
|
|
|
|
freeaddrinfo(h);
|
|
}
|
|
|
|
for(size_t i=0;i<ips.size();++i)
|
|
{
|
|
if(std::find(new_ips.begin(), new_ips.end(), ips[i])==new_ips.end())
|
|
{
|
|
new_ifs=true;
|
|
}
|
|
}
|
|
|
|
ips=new_ips;
|
|
|
|
return new_ifs;
|
|
}
|
|
|
|
void LookForInterfaceChanges()
|
|
{
|
|
static int num=-1;
|
|
if(num>=10 )
|
|
{
|
|
num=0;
|
|
if(EnumerateInterfaces()==true)
|
|
{
|
|
RestartServer();
|
|
}
|
|
}
|
|
if( num==-1 )
|
|
EnumerateInterfaces();
|
|
++num;
|
|
}
|
|
|
|
HRESULT ModifyPrivilege(
|
|
IN LPCTSTR szPrivilege,
|
|
IN BOOL fEnable)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
TOKEN_PRIVILEGES NewState;
|
|
LUID luid;
|
|
HANDLE hToken = NULL;
|
|
|
|
// Open the process token for this process.
|
|
if (!OpenProcessToken(GetCurrentProcess(),
|
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
|
&hToken ))
|
|
{
|
|
Log("Failed OpenProcessToken", LL_ERROR);
|
|
return ERROR_FUNCTION_FAILED;
|
|
}
|
|
|
|
// Get the local unique ID for the privilege.
|
|
if ( !LookupPrivilegeValue( NULL,
|
|
szPrivilege,
|
|
&luid ))
|
|
{
|
|
CloseHandle( hToken );
|
|
Log("Failed LookupPrivilegeValue", LL_ERROR);
|
|
return ERROR_FUNCTION_FAILED;
|
|
}
|
|
|
|
// Assign values to the TOKEN_PRIVILEGE structure.
|
|
NewState.PrivilegeCount = 1;
|
|
NewState.Privileges[0].Luid = luid;
|
|
NewState.Privileges[0].Attributes =
|
|
(fEnable ? SE_PRIVILEGE_ENABLED : 0);
|
|
|
|
// Adjust the token privilege.
|
|
if (!AdjustTokenPrivileges(hToken,
|
|
FALSE,
|
|
&NewState,
|
|
0,
|
|
NULL,
|
|
NULL))
|
|
{
|
|
Log("Failed AdjustTokenPrivileges", LL_ERROR);
|
|
hr = ERROR_FUNCTION_FAILED;
|
|
}
|
|
|
|
// Close the handle.
|
|
CloseHandle(hToken);
|
|
|
|
return hr;
|
|
}
|
|
|
|
bool optain_backup_privs()
|
|
{
|
|
#ifdef BACKUP_SEM
|
|
bool ret = true;
|
|
HRESULT hr = ModifyPrivilege(SE_BACKUP_NAME, TRUE);
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
Log("Failed to modify backup privileges", LL_ERROR);
|
|
ret = false;
|
|
}
|
|
else
|
|
{
|
|
Log("Backup privileges set successfully", LL_DEBUG);
|
|
}
|
|
hr = ModifyPrivilege(SE_SECURITY_NAME, TRUE);
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
Log("Failed to modify backup privileges (SE_SECURITY_NAME)", LL_ERROR);
|
|
ret = false;
|
|
}
|
|
else
|
|
{
|
|
Log("Backup privileges set successfully (SE_SECURITY_NAME)", LL_DEBUG);
|
|
}
|
|
hr = ModifyPrivilege(SE_RESTORE_NAME, TRUE);
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
Log("Failed to modify backup privileges (SE_RESTORE_NAME)", LL_ERROR);
|
|
ret = false;
|
|
}
|
|
else
|
|
{
|
|
Log("Backup privileges set successfully (SE_RESTORE_NAME)", LL_DEBUG);
|
|
}
|
|
return ret;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
#endif //_WIN32
|
|
|
|
#ifdef LINUX_DAEMON
|
|
bool c_run=true;
|
|
void termination_handler(int signum)
|
|
{
|
|
c_run=false;
|
|
_exit(2);
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONSOLE_ON
|
|
int main(int argc, char* argv[])
|
|
{
|
|
#elif AS_SERVICE
|
|
void my_init_fcn(void)
|
|
{
|
|
#elif EXPORT_METHOD_INT
|
|
int start_server_int(unsigned short tcpport, unsigned short udpport, const std::string &pSname, const bool *pDostop, bool use_fqdn)
|
|
{
|
|
#else
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
|
{
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
{
|
|
#endif
|
|
#ifdef LINUX_DAEMON
|
|
std::cout << "Starting as Daemon..." << std::endl;
|
|
if( fork()==0 )
|
|
{
|
|
setsid();
|
|
for (int i=getdtablesize();i>=0;--i) close(i);
|
|
int i=open("/dev/null",O_RDWR);
|
|
dup(i);
|
|
dup(i);
|
|
}
|
|
else
|
|
exit(0);
|
|
|
|
|
|
if (signal (SIGINT, termination_handler) == SIG_IGN)
|
|
signal (SIGINT, SIG_IGN);
|
|
if (signal (SIGHUP, termination_handler) == SIG_IGN)
|
|
signal (SIGHUP, SIG_IGN);
|
|
if (signal (SIGTERM, termination_handler) == SIG_IGN)
|
|
signal (SIGTERM, SIG_IGN);
|
|
|
|
c_run=true;
|
|
#endif
|
|
|
|
#ifndef _DEBUG
|
|
#ifndef AS_SERVICE
|
|
#ifndef EXPORT_METHOD_INT
|
|
WriteReg();
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
std::string servername;
|
|
|
|
#ifdef CONSOLE_ON
|
|
if(argc==2)
|
|
servername=argv[1];
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
optain_backup_privs();
|
|
#endif
|
|
|
|
#ifdef LOG_FILE
|
|
#ifdef _WIN32
|
|
logfile.open("C:\\urinstallsrv.log", std::ios::out | std::ios::binary );
|
|
#else
|
|
logfile.open("/var/log/urinstallsrv.log", std::ios::out | std::ios::binary );
|
|
#endif
|
|
#endif
|
|
|
|
/*std::fstream out(testfilename.c_str(), std::ios::out | std::ios::binary );
|
|
if( out.is_open()==false )
|
|
Log("Can't create testfile... Could perhaps cause problems.");
|
|
|
|
|
|
char* buffer=new char[1024];
|
|
for(size_t i=0;i<1024;++i)
|
|
out.write(buffer, 1024);
|
|
out.close();
|
|
delete[] buffer;
|
|
*/
|
|
|
|
#ifdef _WIN32
|
|
SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
|
|
#endif
|
|
|
|
TCPServer=new CTCPFileServ;
|
|
|
|
#ifndef EXPORT_METHOD_INT
|
|
bool suc=TCPServer->Start(55634,55635,servername);
|
|
#else
|
|
bool suc=TCPServer->Start(tcpport, udpport, (pSname=="")?servername:pSname, use_fqdn);
|
|
#endif
|
|
|
|
if(suc==false)
|
|
{
|
|
delete TCPServer;
|
|
TCPServer=nullptr;
|
|
|
|
#ifdef _WIN32
|
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
|
|
#endif
|
|
return 99;
|
|
}
|
|
|
|
|
|
#ifndef AS_SERVICE
|
|
while(true)
|
|
{
|
|
#if defined(_DEBUG) && defined(_WIN32)
|
|
if( _kbhit() )
|
|
{
|
|
break;
|
|
}
|
|
#endif
|
|
bool b=TCPServer->Run();
|
|
|
|
if( b==false )
|
|
break;
|
|
|
|
#ifdef LINUX_DEAMON
|
|
if( c_run==false )
|
|
break;
|
|
#endif
|
|
#if EXPORT_METHOD_INT
|
|
if(*pDostop==true)
|
|
{
|
|
TCPServer->KickClients();
|
|
break;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
delete TCPServer;
|
|
#endif //AS_SERVICE
|
|
|
|
#ifdef _WIN32
|
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
|
|
#endif
|
|
|
|
#ifndef AS_SERVICE
|
|
return 2;
|
|
#endif
|
|
#ifdef _DEBUG
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
|