keeping ownership to the real user behind sudo
[feisty_meow.git] / scripts / system / add_domain.sh
1 #!/bin/bash
2
3 # this set of functions serve the main purpose of adding new domains or subdomains to the bind9 DNS server on the current host.
4 # it is currently highly specific to running a bunch of domains on a linux VM, where the VM has one IP address.
5 # note that bind 'named' must already be configured.
6 # also, it is assumed that if a subdomain is being added, then the containing domain has already been configured and is 
7 # configured in a file similar to "blah.com.conf" in /etc/bind.
8 #
9 # Author: Chris Koeritz
10
11 export WORKDIR="$( \cd "$(\dirname "$0")" && \pwd )"  # obtain the script's working directory.
12 export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
13
14 source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"
15
16 # some defaults that are convenient for current purposes.
17
18 # hmmm: !!! these would need to be parameterized somehow for this script to become really general.
19
20 # in our scheme, the single IP address that all our domains map to.
21 IP_ADDRESS="10.28.42.20"
22 # the email address (where first dot is replaced by @) for the administrator of the domain.
23 SERVER_ADMIN="developer.cakelampvm.com"
24 # the name of the name server for the new domains (should already be configured).
25 MAIN_NAME_SERVER="ns.cakelampvm.com"
26 # the name of the mail server for a new domain (should already be configured).
27 MAIL_SERVER="mail.cakelampvm.com"
28 # the distribution name to be listed in info for the new domain or subdomain.
29 DISTRO="ubuntu"
30
31 # creates a totally new domain config file for DNS.
32 function write_new_domain_file()
33 {
34   local domain_name="$1"; shift
35
36   local domain_file="/etc/bind/${domain_name}.conf"
37
38   echo "adding a totally new domain called $domain_name"
39   echo "using the config file: $domain_file"
40
41   if [ -f $domain_file ]; then
42     echo
43     echo "The domain configuration file already exists at:"
44     echo "  $domain_file"
45     echo "Since we don't want to tear that down if it has specialized configuration"
46     echo "data in it, we will just leave it in place and consider our job done."
47     echo
48     exit 0
49   fi
50
51   echo "
52 \$TTL 1W
53 @       IN SOA  @       ${SERVER_ADMIN}. (
54                 2017100801 ; serial
55                 2H ; refresh
56                 8M ; retry
57                 14D ; expiry
58                 6H ) ; minimum
59
60         IN NS           ${MAIN_NAME_SERVER}.
61         IN MX   10      ${MAIL_SERVER}.
62
63 ${domain_name}. IN A    ${IP_ADDRESS}
64         IN HINFO        \"linux server\" \"${DISTRO}\"
65 " >"$domain_file"
66
67   # our personalized configuration approach wants the real owner to own the file.
68   chown "$(logname):$(logname)" $domain_file
69   test_or_die "setting ownership on: $domain_file"
70 }
71
72 # hooks up a new config file into bind's list of zones.
73 function add_zone_for_new_domain()
74 {
75   local domain_name="$1"; shift
76
77   local domain_file="/etc/bind/${domain_name}.conf"
78
79   echo "adding a new domain configured by ${domain_file} into"
80   echo "the named.conf.local configuration file."
81
82   # append the reference to the new conf file in the zone list.
83   echo "
84 zone \"${domain_name}\" in {
85         file \"${domain_file}\";
86         type master;
87         allow-query { any; };
88 };
89
90 ////////////////////////////////////////////////////////////////////////////
91
92 " >> /etc/bind/named.conf.local
93
94   # keep ownership for the real user.
95   chown "$(logname):$(logname)" /etc/bind/named.conf.local
96   test_or_die "setting ownership on: /etc/bind/named.conf.local"
97
98 }
99
100 # adds a new subdomain under a containing domain.
101 function add_new_subdomain()
102 {
103   local new_domain="$1"; shift
104
105   # split up the full domain name into subdomain portion and containing domain.
106   local subdomain="${new_domain%.*.*}"
107   local containing_domain="${new_domain#*.}"
108
109   echo "adding a subdomain $subdomain to containing domain $containing_domain"
110
111   local domain_file="/etc/bind/${containing_domain}.conf"
112   # see if config file already exists; if not, complain.
113   if [ ! -f "$domain_file" ]; then
114     echo "The domain configuration file for $new_domain is missing."
115     echo "It should already be present in: $domain_file"
116     echo "Please add the containing domain before trying to add a subdomain."
117     exit 1
118   fi
119
120   # see if subdomain already present in config.
121   if [ $(grep -q "$new_domain" "$domain_file") ]; then
122     echo "The subdomain $subdomain already seems to exist in the domain"
123     echo "configuration file: $domain_file"
124     echo "Please edit the config file to remove the subdomain before trying"
125     echo "to re-add the subdomain."
126     exit 1
127   fi
128
129   # append the new subdomain into the config file.
130   echo "
131 ${subdomain}.${containing_domain}.    IN A    ${IP_ADDRESS}
132         IN HINFO \"linux server\" \"${DISTRO}\"
133 " >> /etc/bind/${containing_domain}.conf
134
135   # keep ownership for real user.
136   chown "$(logname):$(logname)" "/etc/bind/${containing_domain}.conf"
137   test_or_die "setting ownership on: /etc/bind/${containing_domain}.conf"
138 }
139
140 function restart_bind()
141 {
142   echo restarting DNS server.
143   service bind9 restart
144   if [ $? -ne 0 ]; then
145     echo "The bind service did not restart properly.  Please check the error logs."
146     exit 1
147   fi
148   echo DNS server restarted.
149 }
150
151 # main body of script.
152
153 if [[ $EUID != 0 ]]; then
154   echo "This script must be run as root or sudo."
155   exit 1
156 fi
157
158 new_domain="$1"; shift
159
160 if [ -z "$new_domain" ]; then
161   echo "This script needs a domain name to add to DNS." 
162   exit 1
163 fi
164
165 # if domain name has three or more components, then add a subdomain.
166 # otherwise, add a full new domain.
167 if [[ $new_domain == *"."*"."* ]]; then
168   # add a subdomain to the containing domain.
169   add_new_subdomain "$new_domain"
170   restart_bind
171 else
172   # create a totally new domain in DNS.
173   write_new_domain_file "$new_domain"
174   add_zone_for_new_domain "$new_domain"
175   restart_bind
176 fi
177
178