-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhostname.cpp
More file actions
98 lines (88 loc) · 3.58 KB
/
hostname.cpp
File metadata and controls
98 lines (88 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>
#include <fstream>
#include <regex>
#include <filesystem>
#include <boost/program_options.hpp>
int main ( int argc, char **argv) {
std::string oldhostname;
std::string olddomainname;
std::string hostname;
std::string domainname;
int current_uid = getuid();
try {
boost::program_options::options_description desc{"Options"};
desc.add_options()
("help,h", "Help screen")
("oldhostname", boost::program_options::value<std::string>(), "Old Hostname")
("olddomainname", boost::program_options::value<std::string>(), "Old Domainname")
("hostname", boost::program_options::value<std::string>(), "New Hostname")
("domainname", boost::program_options::value<std::string>(), "New Domainname");
boost::program_options::variables_map vm;
boost::program_options::command_line_style::allow_long_disguise;
store(parse_command_line(argc, argv, desc), vm);
if (vm.count("help")) {
std::cout << desc << '\n';
return 0;
}
notify(vm);
if (vm.count("oldhostname")) {
oldhostname = vm["oldhostname"].as<std::string>();
}
if (vm.count("olddomainname")) {
olddomainname = vm["olddomainname"].as<std::string>();
}
if (vm.count("hostname")) {
hostname = vm["hostname"].as<std::string>();
}
if (vm.count("domainname")) {
domainname = vm["domainname"].as<std::string>();
}
}
catch (const boost::program_options::error &ex) {
std::cerr << ex.what() << '\n';
}
std::regex oldhostnamePattern(oldhostname);
std::regex olddomainnamePattern(olddomainname);
std::regex hostnameRegex(R"(^[a-zA-Z0-9][a-zA-Z0-9\-]*$)");
std::regex domainnameRegex(R"(^[a-zA-Z0-9][a-zA-Z0-9\-.]*[a-zA-Z0-9]$)");
if (!std::regex_match(hostname, hostnameRegex)) {
std::cerr<<std::endl<<"Error! Invalid Hostname! Valid characters are a-z, numbers and the hyphen-minus ('-'). Hostname must not start with a hyphen."<<std::endl<<std::endl;
return 1;
}
if (domainname != "" && !std::regex_match(domainname, domainnameRegex)) {
std::cerr<<std::endl<<"Error! Invalid Domainname! Valid characters are a-z, numbers, the period and the hyphen-minus ('-'). Domainname must not start with a hyphen nor start or end with a period."<<std::endl<<std::endl;
return 1;
}
std::string hostnamectl = "/usr/bin/hostnamectl --static hostname "+hostname;
const char* command = hostnamectl.c_str();
if (setuid(0)) { //I am now root!
perror("setuid");
return 1;
}
if (hostname != "") {
std::system(command);
}
try {
std::string line;
std::ifstream hosts;
std::ofstream hosts_temp;
hosts.open("/etc/hosts");
hosts_temp.open("/tmp/hosts");
while(getline(hosts, line)) {
if (hostname != oldhostname && hostname != "") {
line = std::regex_replace(line, oldhostnamePattern, hostname);
}
if (domainname != olddomainname && domainname != "") {
line = std::regex_replace(line, olddomainnamePattern, domainname);
}
hosts_temp << line <<std::endl;;
}
hosts.close();
hosts_temp.close();
std::filesystem::copy("/tmp/hosts", "/etc/hosts", std::filesystem::copy_options::update_existing);
} catch (std::filesystem::filesystem_error& e) {
std::cout << e.what() << '\n';
}
setuid(current_uid); //return to previous user
return 0;
}