cloud-mu 3.6.10 → 3.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Berksfile +2 -3
- data/Berksfile.lock +11 -14
- data/bin/mu-aws-setup +16 -4
- data/bin/mu-configure +2 -1
- data/cloud-mu.gemspec +2 -2
- data/cookbooks/mu-firewall/Berksfile +1 -1
- data/cookbooks/mu-firewall/attributes/default.rb +2 -2
- data/cookbooks/mu-firewall/metadata.rb +3 -3
- data/cookbooks/mu-firewall/recipes/default.rb +11 -2
- data/cookbooks/mu-master/Berksfile +1 -1
- data/cookbooks/mu-master/attributes/default.rb +14 -1
- data/cookbooks/mu-master/files/default/389ds-perl/ASDialogs.pm +173 -0
- data/cookbooks/mu-master/files/default/389ds-perl/AdminMigration.pm +569 -0
- data/cookbooks/mu-master/files/default/389ds-perl/AdminServer.pm +952 -0
- data/cookbooks/mu-master/files/default/389ds-perl/AdminUtil.pm +983 -0
- data/cookbooks/mu-master/files/default/389ds-perl/ConfigDSDialogs.pm +449 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSCreate.pm +1551 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSDialogs.pm +233 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSMigration.pm +1175 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSUpdate.pm +534 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSUpdateDialogs.pm +152 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSUtil.pm +1710 -0
- data/cookbooks/mu-master/files/default/389ds-perl/Dialog.pm +249 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DialogManager.pm +212 -0
- data/cookbooks/mu-master/files/default/389ds-perl/FileConn.pm +461 -0
- data/cookbooks/mu-master/files/default/389ds-perl/Inf.pm +268 -0
- data/cookbooks/mu-master/files/default/389ds-perl/Migration.pm +327 -0
- data/cookbooks/mu-master/files/default/389ds-perl/RegDSDialogs.pm +94 -0
- data/cookbooks/mu-master/files/default/389ds-perl/Resource.pm +137 -0
- data/cookbooks/mu-master/files/default/389ds-perl/Setup.pm +240 -0
- data/cookbooks/mu-master/files/default/389ds-perl/SetupDialogs.pm +243 -0
- data/cookbooks/mu-master/files/default/389ds-perl/SetupLog.pm +82 -0
- data/cookbooks/mu-master/files/default/setCertName.ldif +4 -0
- data/cookbooks/mu-master/libraries/mu.rb +2 -2
- data/cookbooks/mu-master/metadata.rb +1 -1
- data/cookbooks/mu-master/recipes/389ds.rb +71 -32
- data/cookbooks/mu-master/recipes/basepackages.rb +5 -0
- data/cookbooks/mu-master/recipes/default.rb +16 -5
- data/cookbooks/mu-master/recipes/init.rb +36 -3
- data/cookbooks/mu-master/recipes/ssl-certs.rb +6 -0
- data/cookbooks/mu-master/recipes/sssd.rb +85 -62
- data/cookbooks/mu-master/recipes/update_nagios_only.rb +7 -1
- data/cookbooks/mu-master/templates/default/389-directory-setup.inf.erb +11 -26
- data/cookbooks/mu-master/templates/default/sssd.conf.erb +18 -8
- data/cookbooks/mu-tools/files/default/Mu_CA.pem +33 -0
- data/cookbooks/mu-tools/metadata.rb +0 -1
- data/cookbooks/mu-tools/recipes/set_local_fw.rb +7 -1
- data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +5 -1
- data/cookbooks/nagios/CHANGELOG.md +679 -0
- data/cookbooks/nagios/LICENSE +201 -0
- data/cookbooks/nagios/README.md +340 -0
- data/cookbooks/nagios/attributes/config.rb +163 -0
- data/cookbooks/nagios/attributes/default.rb +204 -0
- data/cookbooks/nagios/libraries/base.rb +311 -0
- data/cookbooks/nagios/libraries/command.rb +68 -0
- data/cookbooks/nagios/libraries/contact.rb +229 -0
- data/cookbooks/nagios/libraries/contactgroup.rb +111 -0
- data/cookbooks/{firewall/recipes/disable_firewall.rb → nagios/libraries/custom_option.rb} +20 -7
- data/cookbooks/nagios/libraries/data_bag_helper.rb +23 -0
- data/cookbooks/nagios/libraries/default.rb +90 -0
- data/cookbooks/nagios/libraries/helpers.rb +229 -0
- data/cookbooks/nagios/libraries/host.rb +410 -0
- data/cookbooks/nagios/libraries/hostdependency.rb +178 -0
- data/cookbooks/nagios/libraries/hostescalation.rb +170 -0
- data/cookbooks/nagios/libraries/hostgroup.rb +117 -0
- data/cookbooks/nagios/libraries/nagios.rb +277 -0
- data/cookbooks/nagios/libraries/resource.rb +59 -0
- data/cookbooks/nagios/libraries/service.rb +449 -0
- data/cookbooks/nagios/libraries/servicedependency.rb +213 -0
- data/cookbooks/nagios/libraries/serviceescalation.rb +193 -0
- data/cookbooks/nagios/libraries/servicegroup.rb +142 -0
- data/cookbooks/nagios/libraries/timeperiod.rb +159 -0
- data/cookbooks/nagios/libraries/users_helper.rb +54 -0
- data/cookbooks/nagios/metadata.json +44 -0
- data/cookbooks/nagios/metadata.rb +22 -0
- data/cookbooks/nagios/recipes/_load_databag_config.rb +153 -0
- data/cookbooks/nagios/recipes/_load_default_config.rb +241 -0
- data/cookbooks/nagios/recipes/apache.rb +114 -0
- data/cookbooks/nagios/recipes/default.rb +41 -0
- data/cookbooks/nagios/recipes/nginx.rb +114 -0
- data/cookbooks/nagios/recipes/pagerduty.rb +95 -0
- data/cookbooks/nagios/recipes/server.rb +182 -0
- data/cookbooks/nagios/recipes/server_package.rb +85 -0
- data/cookbooks/nagios/recipes/server_source.rb +137 -0
- data/cookbooks/nagios/resources/command.rb +34 -0
- data/cookbooks/nagios/resources/conf.rb +52 -0
- data/cookbooks/nagios/resources/contact.rb +34 -0
- data/cookbooks/nagios/resources/contactgroup.rb +35 -0
- data/cookbooks/nagios/resources/host.rb +35 -0
- data/cookbooks/nagios/resources/hostdependency.rb +35 -0
- data/cookbooks/nagios/resources/hostescalation.rb +36 -0
- data/cookbooks/nagios/resources/hostgroup.rb +35 -0
- data/cookbooks/nagios/resources/resource.rb +34 -0
- data/cookbooks/nagios/resources/service.rb +35 -0
- data/cookbooks/nagios/resources/servicedependency.rb +35 -0
- data/cookbooks/nagios/resources/serviceescalation.rb +35 -0
- data/cookbooks/nagios/resources/servicegroup.rb +35 -0
- data/cookbooks/nagios/resources/timeperiod.rb +35 -0
- data/cookbooks/nagios/templates/apache2.conf.erb +102 -0
- data/cookbooks/nagios/templates/cgi.cfg.erb +266 -0
- data/cookbooks/nagios/templates/commands.cfg.erb +13 -0
- data/cookbooks/nagios/templates/contacts.cfg.erb +37 -0
- data/cookbooks/nagios/templates/hostgroups.cfg.erb +25 -0
- data/cookbooks/nagios/templates/hosts.cfg.erb +15 -0
- data/cookbooks/nagios/templates/htpasswd.users.erb +6 -0
- data/cookbooks/nagios/templates/nagios.cfg.erb +22 -0
- data/cookbooks/nagios/templates/nginx.conf.erb +80 -0
- data/cookbooks/nagios/templates/pagerduty.cgi.erb +185 -0
- data/cookbooks/nagios/templates/resource.cfg.erb +27 -0
- data/cookbooks/nagios/templates/servicedependencies.cfg.erb +15 -0
- data/cookbooks/nagios/templates/servicegroups.cfg.erb +14 -0
- data/cookbooks/nagios/templates/services.cfg.erb +14 -0
- data/cookbooks/nagios/templates/spawn-fcgi.erb +10 -0
- data/cookbooks/nagios/templates/templates.cfg.erb +31 -0
- data/cookbooks/nagios/templates/timeperiods.cfg.erb +13 -0
- data/extras/platform_berksfile_base +3 -3
- data/extras/python_rpm/build.sh +4 -4
- data/extras/python_rpm/muthon.spec +2 -4
- data/extras/vault_tools/export_vaults.sh +11 -1
- data/install/installer +1 -1
- data/modules/mu/kittens.rb +27523 -0
- data/modules/mu/master/ldap.rb +48 -31
- data/modules/mu/master.rb +69 -0
- data/modules/mu/mu.yaml.rb +351 -0
- data/modules/mu/providers/aws/firewall_rule.rb +3 -1
- data/modules/mu/providers/aws.rb +11 -5
- data/modules/mu.rb +5 -4
- metadata +99 -48
- data/cookbooks/firewall/CHANGELOG.md +0 -488
- data/cookbooks/firewall/LICENSE +0 -202
- data/cookbooks/firewall/README.md +0 -366
- data/cookbooks/firewall/TODO.md +0 -6
- data/cookbooks/firewall/attributes/default.rb +0 -5
- data/cookbooks/firewall/attributes/firewalld.rb +0 -8
- data/cookbooks/firewall/attributes/iptables.rb +0 -17
- data/cookbooks/firewall/attributes/ufw.rb +0 -12
- data/cookbooks/firewall/attributes/windows.rb +0 -8
- data/cookbooks/firewall/libraries/helpers.rb +0 -105
- data/cookbooks/firewall/libraries/helpers_firewalld.rb +0 -116
- data/cookbooks/firewall/libraries/helpers_firewalld_dbus.rb +0 -72
- data/cookbooks/firewall/libraries/helpers_iptables.rb +0 -112
- data/cookbooks/firewall/libraries/helpers_nftables.rb +0 -170
- data/cookbooks/firewall/libraries/helpers_ufw.rb +0 -142
- data/cookbooks/firewall/libraries/helpers_windows.rb +0 -129
- data/cookbooks/firewall/libraries/provider_firewall_firewalld.rb +0 -179
- data/cookbooks/firewall/libraries/provider_firewall_iptables.rb +0 -171
- data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb +0 -200
- data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb +0 -200
- data/cookbooks/firewall/libraries/provider_firewall_rule.rb +0 -34
- data/cookbooks/firewall/libraries/provider_firewall_ufw.rb +0 -138
- data/cookbooks/firewall/libraries/provider_firewall_windows.rb +0 -126
- data/cookbooks/firewall/libraries/resource_firewall.rb +0 -26
- data/cookbooks/firewall/libraries/resource_firewall_rule.rb +0 -52
- data/cookbooks/firewall/metadata.json +0 -40
- data/cookbooks/firewall/metadata.rb +0 -15
- data/cookbooks/firewall/recipes/default.rb +0 -76
- data/cookbooks/firewall/recipes/firewalld.rb +0 -87
- data/cookbooks/firewall/resources/firewalld.rb +0 -28
- data/cookbooks/firewall/resources/firewalld_config.rb +0 -39
- data/cookbooks/firewall/resources/firewalld_helpers.rb +0 -106
- data/cookbooks/firewall/resources/firewalld_icmptype.rb +0 -88
- data/cookbooks/firewall/resources/firewalld_ipset.rb +0 -104
- data/cookbooks/firewall/resources/firewalld_policy.rb +0 -115
- data/cookbooks/firewall/resources/firewalld_service.rb +0 -98
- data/cookbooks/firewall/resources/firewalld_zone.rb +0 -118
- data/cookbooks/firewall/resources/nftables.rb +0 -71
- data/cookbooks/firewall/resources/nftables_rule.rb +0 -113
- data/cookbooks/firewall/templates/default/ufw/default.erb +0 -13
- /data/cookbooks/{firewall → nagios}/chefignore +0 -0
- /data/cookbooks/{firewall → nagios}/renovate.json +0 -0
@@ -0,0 +1,1551 @@
|
|
1
|
+
# BEGIN COPYRIGHT BLOCK
|
2
|
+
# Copyright (C) 2013 Red Hat, Inc.
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# License: GPL (version 3 or any later version).
|
6
|
+
# See LICENSE for details.
|
7
|
+
# END COPYRIGHT BLOCK
|
8
|
+
#
|
9
|
+
|
10
|
+
###########################
|
11
|
+
#
|
12
|
+
# This perl module provides a way to create a new instance of
|
13
|
+
# directory server.
|
14
|
+
#
|
15
|
+
##########################
|
16
|
+
|
17
|
+
package DSCreate;
|
18
|
+
use DSUtil;
|
19
|
+
use Inf;
|
20
|
+
use FileConn;
|
21
|
+
use Config;
|
22
|
+
|
23
|
+
use Sys::Hostname;
|
24
|
+
# tempfiles
|
25
|
+
use File::Temp qw(tempfile tempdir);
|
26
|
+
use File::Path;
|
27
|
+
use File::Copy;
|
28
|
+
use File::Basename qw(basename dirname);
|
29
|
+
use POSIX qw(:errno_h);
|
30
|
+
|
31
|
+
# load perldap
|
32
|
+
use Mozilla::LDAP::Conn;
|
33
|
+
use Mozilla::LDAP::Utils qw(normalizeDN);
|
34
|
+
use Mozilla::LDAP::API qw(ldap_explode_dn);
|
35
|
+
use Mozilla::LDAP::LDIF;
|
36
|
+
|
37
|
+
use POSIX ":sys_wait_h";
|
38
|
+
|
39
|
+
use Exporter;
|
40
|
+
@ISA = qw(Exporter);
|
41
|
+
@EXPORT = qw(createDSInstance removeDSInstance setDefaults createInstanceScripts
|
42
|
+
makeOtherConfigFiles installSchema updateSelinuxPolicy updateTmpfilesDotD
|
43
|
+
get_initconfigdir updateSystemD makeDSDirs);
|
44
|
+
@EXPORT_OK = qw(createDSInstance removeDSInstance setDefaults createInstanceScripts
|
45
|
+
makeOtherConfigFiles installSchema updateSelinuxPolicy updateTmpfilesDotD
|
46
|
+
get_initconfigdir updateSystemD makeDSDirs);
|
47
|
+
|
48
|
+
use strict;
|
49
|
+
|
50
|
+
use SetupLog;
|
51
|
+
|
52
|
+
sub get_initconfigdir {
|
53
|
+
my $prefix = shift;
|
54
|
+
|
55
|
+
# determine initconfig_dir
|
56
|
+
if (getLogin eq 'root') {
|
57
|
+
return "$prefix/etc/sysconfig";
|
58
|
+
} else {
|
59
|
+
return "$ENV{HOME}/.dirsrv";
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
sub checkPort {
|
64
|
+
my $inf = shift;
|
65
|
+
|
66
|
+
# allow port 0 if ldapi is used
|
67
|
+
if ("1") {
|
68
|
+
if ($inf->{slapd}->{ldapifilepath} &&
|
69
|
+
($inf->{slapd}->{ServerPort} == 0)) {
|
70
|
+
return ();
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
if ($inf->{slapd}->{ServerPort} !~ /^\d+$/) {
|
75
|
+
return ('error_port_invalid', $inf->{slapd}->{ServerPort});
|
76
|
+
}
|
77
|
+
if (!portAvailable($inf->{slapd}->{ServerPort})) {
|
78
|
+
return ('error_port_available', $inf->{slapd}->{ServerPort}, $!);
|
79
|
+
}
|
80
|
+
|
81
|
+
return ();
|
82
|
+
}
|
83
|
+
|
84
|
+
# checks the parameters in $inf to make sure the supplied values
|
85
|
+
# are valid
|
86
|
+
# returns null if successful, or an error string for use with getText()
|
87
|
+
sub sanityCheckParams {
|
88
|
+
my $inf = shift;
|
89
|
+
my @errs = ();
|
90
|
+
|
91
|
+
# if we don't need to start the server right away, we can skip the
|
92
|
+
# port number checks
|
93
|
+
if (!defined($inf->{slapd}->{start_server}) or
|
94
|
+
($inf->{slapd}->{start_server} == 1)) {
|
95
|
+
|
96
|
+
if (@errs = checkPort($inf)) {
|
97
|
+
return @errs;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
if($inf->{slapd}->{ServerIdentifier} eq "admin"){
|
102
|
+
return ('error_reserved_serverid' ,"admin");
|
103
|
+
} elsif (!isValidServerID($inf->{slapd}->{ServerIdentifier})) {
|
104
|
+
return ('error_invalid_serverid', $inf->{slapd}->{ServerIdentifier});
|
105
|
+
} elsif (-d $inf->{slapd}->{config_dir}) {
|
106
|
+
return ('error_server_already_exists', $inf->{slapd}->{config_dir});
|
107
|
+
}
|
108
|
+
|
109
|
+
if (@errs = isValidUser($inf->{General}->{SuiteSpotUserID})) {
|
110
|
+
return @errs;
|
111
|
+
}
|
112
|
+
|
113
|
+
if (@errs = isValidGroup($inf->{General}->{SuiteSpotGroup})) {
|
114
|
+
return @errs;
|
115
|
+
}
|
116
|
+
|
117
|
+
if (!isValidDN($inf->{slapd}->{Suffix})) {
|
118
|
+
return ('dialog_dssuffix_error', $inf->{slapd}->{Suffix});
|
119
|
+
}
|
120
|
+
|
121
|
+
if (!isValidDN($inf->{slapd}->{RootDN})) {
|
122
|
+
return ('dialog_dsrootdn_error', $inf->{slapd}->{RootDN});
|
123
|
+
}
|
124
|
+
|
125
|
+
if ($inf->{slapd}->{RootDNPwd} =~ /^\{\w+\}.+/) {
|
126
|
+
debug(1, "The root password is already hashed - no checking will be performed\n");
|
127
|
+
} elsif (length($inf->{slapd}->{RootDNPwd}) < 8) {
|
128
|
+
debug(0, "WARNING: The root password is less than 8 characters long. You should choose a longer one.\n");
|
129
|
+
}
|
130
|
+
|
131
|
+
$inf->{General}->{StrictHostCheck} = lc $inf->{General}->{StrictHostCheck};
|
132
|
+
|
133
|
+
if ("true" ne $inf->{General}->{StrictHostCheck} && "false" ne $inf->{General}->{StrictHostCheck}) {
|
134
|
+
debug(1, "StrictHostCheck is not a valid boolean");
|
135
|
+
return ('error_invalid_boolean', $inf->{General}->{StrictHostCheck});
|
136
|
+
}
|
137
|
+
|
138
|
+
if ($inf->{General}->{StrictHostCheck} eq "true" ) {
|
139
|
+
if (@errs = checkHostname($inf->{General}->{FullMachineName}, 0)) {
|
140
|
+
debug(1, @errs);
|
141
|
+
return @errs;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
# We need to make sure this value is lowercase
|
146
|
+
$inf->{slapd}->{InstScriptsEnabled} = lc $inf->{slapd}->{InstScriptsEnabled};
|
147
|
+
|
148
|
+
if ("true" ne $inf->{slapd}->{InstScriptsEnabled} && "false" ne $inf->{slapd}->{InstScriptsEnabled}) {
|
149
|
+
debug(1, "InstScriptsEnabled is not a valid boolean");
|
150
|
+
return ('error_invalid_boolean', $inf->{slapd}->{InstScriptsEnabled});
|
151
|
+
}
|
152
|
+
|
153
|
+
|
154
|
+
return ();
|
155
|
+
}
|
156
|
+
|
157
|
+
sub getMode {
|
158
|
+
my $inf = shift;
|
159
|
+
my $mode = shift;
|
160
|
+
my $rest = shift;
|
161
|
+
if (!$rest) {
|
162
|
+
$rest = "0";
|
163
|
+
}
|
164
|
+
if (defined($inf->{General}->{SuiteSpotGroup})) {
|
165
|
+
$mode = "0" . $mode . $mode . $rest;
|
166
|
+
} else {
|
167
|
+
$mode = "0" . $mode . $rest . $rest;
|
168
|
+
}
|
169
|
+
|
170
|
+
return oct($mode);
|
171
|
+
}
|
172
|
+
|
173
|
+
# This is used to change the ownership and permissions of files and directories
|
174
|
+
# The mode is just a single digit octal number (e.g. 4 6 7)
|
175
|
+
# If there is a group, the ownership and permissions will allow group access
|
176
|
+
# otherwise, only the owner will be allowed access
|
177
|
+
sub changeOwnerMode {
|
178
|
+
my $inf = shift;
|
179
|
+
my $mode = shift;
|
180
|
+
my $it = shift;
|
181
|
+
my $gidonly = shift;
|
182
|
+
my $othermode = shift;
|
183
|
+
|
184
|
+
my $uid = getpwnam $inf->{General}->{SuiteSpotUserID};
|
185
|
+
my $gid = -1; # default to leave it alone
|
186
|
+
my $mode_string = "";
|
187
|
+
|
188
|
+
if (defined($inf->{General}->{SuiteSpotGroup})) {
|
189
|
+
$gid = getgrnam $inf->{General}->{SuiteSpotGroup};
|
190
|
+
}
|
191
|
+
|
192
|
+
$mode = getMode($inf, $mode, $othermode);
|
193
|
+
|
194
|
+
$! = 0; # clear errno
|
195
|
+
chmod $mode, $it;
|
196
|
+
if ($!) {
|
197
|
+
return ('error_chmoding_file', $it, $!);
|
198
|
+
}
|
199
|
+
|
200
|
+
$mode_string = sprintf "%lo", $mode;
|
201
|
+
debug(1, "changeOwnerMode: changed mode of $it to $mode_string\n");
|
202
|
+
|
203
|
+
$! = 0; # clear errno
|
204
|
+
if ( $gidonly ) {
|
205
|
+
chown -1, $gid, $it;
|
206
|
+
} else {
|
207
|
+
chown $uid, $gid, $it;
|
208
|
+
}
|
209
|
+
if ($!) {
|
210
|
+
return ('error_chowning_file', $it, $inf->{General}->{SuiteSpotUserID}, $!);
|
211
|
+
}
|
212
|
+
|
213
|
+
if ( $gidonly ) {
|
214
|
+
debug(1, "changeOwnerMode: changed group ownership of $it to group $gid\n");
|
215
|
+
} else {
|
216
|
+
debug(1, "changeOwnerMode: changed ownership of $it to user $uid group $gid\n");
|
217
|
+
}
|
218
|
+
|
219
|
+
return ();
|
220
|
+
}
|
221
|
+
|
222
|
+
sub makeDSDirs {
|
223
|
+
my $inf = shift;
|
224
|
+
my $verbose = ($DSUtil::debuglevel > 0);
|
225
|
+
my $mode = getMode($inf, 7);
|
226
|
+
my @errs;
|
227
|
+
|
228
|
+
my @dsdirs = qw(config_dir schema_dir log_dir lock_dir run_dir tmp_dir cert_dir db_dir ldif_dir bak_dir);
|
229
|
+
if ($inf->{slapd}->{InstScriptsEnabled} eq "true") {
|
230
|
+
@dsdirs = qw(inst_dir config_dir schema_dir log_dir lock_dir run_dir tmp_dir cert_dir db_dir ldif_dir bak_dir);
|
231
|
+
}
|
232
|
+
|
233
|
+
# These paths are owned by the SuiteSpotGroup
|
234
|
+
# This allows the admin server to run as a different,
|
235
|
+
# more privileged user than the directory server, but
|
236
|
+
# still allows the admin server to manage directory
|
237
|
+
# server files/dirs without being root
|
238
|
+
for my $kw (@dsdirs) {
|
239
|
+
my $dir = $inf->{slapd}->{$kw};
|
240
|
+
@errs = makePaths($dir, $mode, $inf->{General}->{SuiteSpotUserID},
|
241
|
+
$inf->{General}->{SuiteSpotGroup});
|
242
|
+
if (@errs) {
|
243
|
+
return @errs;
|
244
|
+
}
|
245
|
+
}
|
246
|
+
# run_dir is a special case because it is usually shared among
|
247
|
+
# all instances and the admin server
|
248
|
+
# all instances must be able to write to it
|
249
|
+
# if the SuiteSpotUserID is root or 0, we can just skip
|
250
|
+
# this because root will have access to it - we really
|
251
|
+
# shouldn't be using root anyway, primarily just for
|
252
|
+
# legacy migration support
|
253
|
+
# if there are two different user IDs that need access
|
254
|
+
# to this directory, then SuiteSpotGroup must be defined,
|
255
|
+
# and both users must be members of the SuiteSpotGroup
|
256
|
+
if (($inf->{General}->{SuiteSpotUserID} eq 'root') ||
|
257
|
+
(defined($inf->{General}->{SuiteSpotUserID}) &&
|
258
|
+
($inf->{General}->{SuiteSpotUserID} =~ /^0$/))) {
|
259
|
+
# skip
|
260
|
+
debug(3, "Root user " . $inf->{General}->{SuiteSpotUserID} . " already has access to $inf->{slapd}->{run_dir} - skipping\n");
|
261
|
+
} else {
|
262
|
+
my $dir = $inf->{slapd}->{run_dir};
|
263
|
+
# rwx by user only, or by user & group if a group is defined. Also only change the group ownership.
|
264
|
+
@errs = changeOwnerMode($inf, 7, $dir, 1);
|
265
|
+
debug(3, "\t" . `/bin/ls -ld $dir`);
|
266
|
+
}
|
267
|
+
# set the group of the parent dir of config_dir and inst_dir
|
268
|
+
if (defined($inf->{General}->{SuiteSpotGroup})) {
|
269
|
+
for my $kw (qw(inst_dir config_dir)) {
|
270
|
+
my $dir = $inf->{slapd}->{$kw};
|
271
|
+
my $parent = dirname($dir);
|
272
|
+
# changeOwnerMode(inf, mode, file, gidonly, othermode);
|
273
|
+
@errs = changeOwnerMode($inf, 7, $parent, 1, 5);
|
274
|
+
if (@errs) {
|
275
|
+
return @errs;
|
276
|
+
}
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
return @errs;
|
281
|
+
}
|
282
|
+
|
283
|
+
sub createInstanceScripts {
|
284
|
+
my $inf = shift;
|
285
|
+
my $skip = shift;
|
286
|
+
my $perlexec = "/usr/bin/perl" || "/usr/bin/env perl";
|
287
|
+
my $myperl = "!$perlexec";
|
288
|
+
my $mydevnull = (-c "/dev/null" ? " /dev/null " : " NUL ");
|
289
|
+
|
290
|
+
# If we have InstScriptsEnabled, we likely have setup.inf or the argument.
|
291
|
+
# However, during an upgrade, we need to know if we should upgrade the template files or not.
|
292
|
+
# For now, the easiest way is to check to if the directory exists, and if is does, we assume we want to upgrade / create the updated scripts.
|
293
|
+
if ($inf->{slapd}->{InstScriptsEnabled} eq "true" || -d $inf->{slapd}->{inst_dir} ) {
|
294
|
+
debug(1, "Creating or updating instance directory scripts\n");
|
295
|
+
# determine initconfig_dir
|
296
|
+
my $initconfig_dir = $inf->{slapd}->{initconfig_dir} || get_initconfigdir($inf->{General}->{prefix});
|
297
|
+
|
298
|
+
my %maptable = (
|
299
|
+
"DS-ROOT" => $inf->{General}->{prefix},
|
300
|
+
"SEP" => "/", # works on all platforms
|
301
|
+
"SERVER-NAME" => $inf->{General}->{FullMachineName},
|
302
|
+
"SERVER-PORT" => $inf->{slapd}->{ServerPort},
|
303
|
+
"PERL-EXEC" => $myperl,
|
304
|
+
"DEV-NULL" => $mydevnull,
|
305
|
+
"ROOT-DN" => $inf->{slapd}->{RootDN},
|
306
|
+
"LDIF-DIR" => $inf->{slapd}->{ldif_dir},
|
307
|
+
"SERV-ID" => $inf->{slapd}->{ServerIdentifier},
|
308
|
+
"BAK-DIR" => $inf->{slapd}->{bak_dir},
|
309
|
+
"SERVER-DIR" => $inf->{General}->{ServerRoot},
|
310
|
+
"CONFIG-DIR" => $inf->{slapd}->{config_dir},
|
311
|
+
"INITCONFIG-DIR" => $initconfig_dir,
|
312
|
+
"INST-DIR" => $inf->{slapd}->{inst_dir},
|
313
|
+
"RUN-DIR" => $inf->{slapd}->{run_dir},
|
314
|
+
"PRODUCT-NAME" => "slapd",
|
315
|
+
"SERVERBIN-DIR" => $inf->{slapd}->{sbindir},
|
316
|
+
"DB-DIR" => $inf->{slapd}->{db_dir}
|
317
|
+
);
|
318
|
+
|
319
|
+
|
320
|
+
my $dir = "$inf->{General}->{prefix}/usr/share/dirsrv/script-templates";
|
321
|
+
for my $file (glob("$dir/template-*")) {
|
322
|
+
my $basename = $file;
|
323
|
+
$basename =~ s/^.*template-//;
|
324
|
+
my $destfile = "$inf->{slapd}->{inst_dir}/$basename";
|
325
|
+
debug(1, "$destfile\n");
|
326
|
+
|
327
|
+
next if ($skip and -f $destfile); # in skip mode, skip files that already exist
|
328
|
+
|
329
|
+
if (!open(SRC, "< $file")) {
|
330
|
+
return ("error_opening_scripttmpl", $file, $!);
|
331
|
+
}
|
332
|
+
if (!open(DEST, "> $destfile")) {
|
333
|
+
return ("error_opening_scripttmpl", $destfile, $!);
|
334
|
+
}
|
335
|
+
my $contents; # slurp entire file into memory
|
336
|
+
read SRC, $contents, int(-s $file);
|
337
|
+
close(SRC);
|
338
|
+
while (my ($key, $val) = each %maptable) {
|
339
|
+
$contents =~ s/\{\{$key\}\}/$val/g;
|
340
|
+
}
|
341
|
+
print DEST $contents;
|
342
|
+
close(DEST);
|
343
|
+
my @errs = changeOwnerMode($inf, 5, $destfile);
|
344
|
+
if (@errs) {
|
345
|
+
return @errs;
|
346
|
+
}
|
347
|
+
}
|
348
|
+
} else {
|
349
|
+
debug(1, "No instance directory scripts will be updated or created\n");
|
350
|
+
}
|
351
|
+
|
352
|
+
return ();
|
353
|
+
}
|
354
|
+
|
355
|
+
sub createConfigFile {
|
356
|
+
my $inf = shift;
|
357
|
+
my $conffile = "$inf->{slapd}->{config_dir}/dse.ldif";
|
358
|
+
my $conn = new FileConn;
|
359
|
+
my @errs;
|
360
|
+
|
361
|
+
# first, create the basic config
|
362
|
+
my $mapper = new Inf("$inf->{General}->{prefix}/usr/share/dirsrv/inf/dscreate.map");
|
363
|
+
my $dsinf = new Inf("$inf->{General}->{prefix}/usr/share/dirsrv/inf/slapd.inf");
|
364
|
+
if (!$inf->{slapd}->{ds_bename}) {
|
365
|
+
$inf->{slapd}->{ds_bename} = "userRoot"; # for suffix-db
|
366
|
+
}
|
367
|
+
$mapper = process_maptbl($mapper, \@errs, $inf, $dsinf);
|
368
|
+
if (!$mapper or @errs) {
|
369
|
+
$conn->close();
|
370
|
+
if (!@errs) {
|
371
|
+
@errs = ('error_creating_file', $conffile, $!);
|
372
|
+
}
|
373
|
+
return @errs;
|
374
|
+
}
|
375
|
+
|
376
|
+
my @ldiffiles = ("$inf->{General}->{prefix}/usr/share/dirsrv/data/template-dse.ldif",
|
377
|
+
"$inf->{General}->{prefix}/usr/share/dirsrv/data/template-suffix-db.ldif",
|
378
|
+
"$inf->{General}->{prefix}/usr/share/dirsrv/data/template-sasl.ldif");
|
379
|
+
|
380
|
+
# additional configuration LDIF files
|
381
|
+
if (exists($inf->{slapd}->{ConfigFile})) {
|
382
|
+
if (ref($inf->{slapd}->{ConfigFile})) {
|
383
|
+
push @ldiffiles, @{$inf->{slapd}->{ConfigFile}};
|
384
|
+
} else {
|
385
|
+
push @ldiffiles, $inf->{slapd}->{ConfigFile};
|
386
|
+
}
|
387
|
+
}
|
388
|
+
|
389
|
+
getMappedEntries($mapper, \@ldiffiles, \@errs, \&check_and_add_entry,
|
390
|
+
[$conn]);
|
391
|
+
|
392
|
+
if (@errs) {
|
393
|
+
$conn->close();
|
394
|
+
return @errs;
|
395
|
+
}
|
396
|
+
|
397
|
+
if ("1") {
|
398
|
+
my $ent = $conn->search("cn=config", "base", "(objectclass=*)");
|
399
|
+
if (defined($inf->{slapd}->{ldapifilepath})) {
|
400
|
+
$ent->setValues("nsslapd-ldapifilepath", $inf->{slapd}->{ldapifilepath});
|
401
|
+
$ent->setValues("nsslapd-ldapilisten", "on");
|
402
|
+
} else {
|
403
|
+
my $parent = dirname($inf->{slapd}->{run_dir});
|
404
|
+
$ent->setValues("nsslapd-ldapifilepath",
|
405
|
+
"$parent/slapd-$inf->{slapd}->{ServerIdentifier}.socket");
|
406
|
+
$ent->setValues("nsslapd-ldapilisten", "off");
|
407
|
+
}
|
408
|
+
if ("1") {
|
409
|
+
$ent->setValues("nsslapd-ldapiautobind", "off");
|
410
|
+
$ent->setValues("nsslapd-ldapimaprootdn", $inf->{slapd}->{RootDN});
|
411
|
+
$ent->setValues("nsslapd-ldapimaptoentries", "off");
|
412
|
+
$ent->setValues("nsslapd-ldapiuidnumbertype", "uidNumber");
|
413
|
+
$ent->setValues("nsslapd-ldapigidnumbertype", "gidNumber");
|
414
|
+
$ent->setValues("nsslapd-ldapientrysearchbase", $inf->{slapd}->{Suffix});
|
415
|
+
if ("") {
|
416
|
+
$ent->setValues("nsslapd-ldapiautodnsuffix", "cn=peercred,cn=external,cn=auth");
|
417
|
+
}
|
418
|
+
}
|
419
|
+
$ent->setValues("nsslapd-defaultNamingContext", $inf->{slapd}->{Suffix});
|
420
|
+
if (!$conn->update($ent)) {
|
421
|
+
$conn->close();
|
422
|
+
return ("error_enabling_feature", "ldapi", $conn->getErrorString());
|
423
|
+
}
|
424
|
+
}
|
425
|
+
|
426
|
+
if ($inf->{slapd}->{sasl_path}) {
|
427
|
+
my $ent = $conn->search("cn=config", "base", "(objectclass=*)");
|
428
|
+
$ent->setValues("nsslapd-saslpath", $inf->{slapd}->{sasl_path});
|
429
|
+
if (!$conn->update($ent)) {
|
430
|
+
$conn->close();
|
431
|
+
return ("error_enabling_feature", "sasl_path", $conn->getErrorString());
|
432
|
+
}
|
433
|
+
}
|
434
|
+
|
435
|
+
if (!$conn->write($conffile)) {
|
436
|
+
$conn->close();
|
437
|
+
return ("error_writing_ldif", $conffile, $!);
|
438
|
+
}
|
439
|
+
$conn->close();
|
440
|
+
|
441
|
+
if (@errs = changeOwnerMode($inf, 6, $conffile)) {
|
442
|
+
return @errs;
|
443
|
+
}
|
444
|
+
# make a copy
|
445
|
+
my $origconf = "$inf->{slapd}->{config_dir}/dse_original.ldif";
|
446
|
+
$! = 0; # clear errno
|
447
|
+
copy($conffile, $origconf);
|
448
|
+
if ($!) {
|
449
|
+
return ('error_copying_file', $conffile, $origconf, $!);
|
450
|
+
}
|
451
|
+
if (@errs = changeOwnerMode($inf, 4, $origconf)) {
|
452
|
+
return @errs;
|
453
|
+
}
|
454
|
+
|
455
|
+
return @errs;
|
456
|
+
}
|
457
|
+
|
458
|
+
sub makeOtherConfigFiles {
|
459
|
+
my $inf = shift;
|
460
|
+
my $skip = shift;
|
461
|
+
my @errs;
|
462
|
+
my %maptable = (
|
463
|
+
"DS-ROOT" => $inf->{General}->{prefix},
|
464
|
+
"SERVER-DIR" => $inf->{General}->{ServerRoot},
|
465
|
+
"CONFIG-DIR" => $inf->{slapd}->{config_dir},
|
466
|
+
"INST-DIR" => $inf->{slapd}->{inst_dir},
|
467
|
+
"RUN-DIR" => $inf->{slapd}->{run_dir},
|
468
|
+
"PRODUCT-NAME" => "slapd",
|
469
|
+
"SERVERBIN-DIR" => $inf->{slapd}->{sbindir},
|
470
|
+
);
|
471
|
+
|
472
|
+
# install certmap.conf at <configdir>
|
473
|
+
my $src = "$inf->{General}->{prefix}/etc/dirsrv/config/certmap.conf";
|
474
|
+
my $dest = "$inf->{slapd}->{config_dir}/certmap.conf";
|
475
|
+
$! = 0; # clear errno
|
476
|
+
|
477
|
+
#in skip mode, skip files that already exist
|
478
|
+
unless ($skip and -f $dest) {
|
479
|
+
copy($src, $dest);
|
480
|
+
if ($!) {
|
481
|
+
return ('error_copying_file', $src, $dest, $!);
|
482
|
+
}
|
483
|
+
if (@errs = changeOwnerMode($inf, 4, $dest)) {
|
484
|
+
return @errs;
|
485
|
+
}
|
486
|
+
}
|
487
|
+
|
488
|
+
$src = "$inf->{General}->{prefix}/etc/dirsrv/config/slapd-collations.conf";
|
489
|
+
$dest = "$inf->{slapd}->{config_dir}/slapd-collations.conf";
|
490
|
+
|
491
|
+
$! = 0; # clear errno
|
492
|
+
|
493
|
+
#in skip mode, skip files that already exist
|
494
|
+
unless ($skip and -f $dest) {
|
495
|
+
copy($src, $dest);
|
496
|
+
if ($!) {
|
497
|
+
return ('error_copying_file', $src, $dest, $!);
|
498
|
+
}
|
499
|
+
if (@errs = changeOwnerMode($inf, 4, $dest)) {
|
500
|
+
return @errs;
|
501
|
+
}
|
502
|
+
}
|
503
|
+
|
504
|
+
# determine initconfig_dir
|
505
|
+
my $initconfig_dir = $inf->{slapd}->{initconfig_dir} || get_initconfigdir($inf->{General}->{prefix});
|
506
|
+
|
507
|
+
# install instance specific initconfig script
|
508
|
+
$src = "$inf->{General}->{prefix}/etc/dirsrv/config/template-initconfig";
|
509
|
+
$dest = "$initconfig_dir/dirsrv-$inf->{slapd}->{ServerIdentifier}";
|
510
|
+
|
511
|
+
$! = 0; # clear errno
|
512
|
+
|
513
|
+
# in skip mode, skip files that already exist
|
514
|
+
unless ($skip and -f $dest) {
|
515
|
+
if (!open(SRC, "< $src")) {
|
516
|
+
return ("error_opening_scripttmpl", $src, $!);
|
517
|
+
}
|
518
|
+
if (!open(DEST, "> $dest")) {
|
519
|
+
return ("error_opening_scripttmpl", $dest, $!);
|
520
|
+
}
|
521
|
+
my $contents; # slurp entire file into memory
|
522
|
+
read SRC, $contents, int(-s $src);
|
523
|
+
close(SRC);
|
524
|
+
while (my ($key, $val) = each %maptable) {
|
525
|
+
$contents =~ s/\{\{$key\}\}/$val/g;
|
526
|
+
}
|
527
|
+
print DEST $contents;
|
528
|
+
close(DEST);
|
529
|
+
if (@errs = changeOwnerMode($inf, 4, $dest)) {
|
530
|
+
return @errs;
|
531
|
+
}
|
532
|
+
}
|
533
|
+
|
534
|
+
return ();
|
535
|
+
}
|
536
|
+
|
537
|
+
sub installSchema {
|
538
|
+
my $inf = shift;
|
539
|
+
my $skip = shift;
|
540
|
+
my @errs;
|
541
|
+
my @schemafiles = ();
|
542
|
+
if (!defined($inf->{slapd}->{install_full_schema}) or
|
543
|
+
$inf->{slapd}->{install_full_schema}) {
|
544
|
+
push @schemafiles, glob("$inf->{General}->{prefix}/etc/dirsrv/schema/*");
|
545
|
+
} else {
|
546
|
+
push @schemafiles, "$inf->{General}->{prefix}/etc/dirsrv/schema/00core.ldif",
|
547
|
+
"$inf->{General}->{prefix}/etc/dirsrv/schema/01core389.ldif";
|
548
|
+
}
|
549
|
+
|
550
|
+
# additional schema files
|
551
|
+
if (exists($inf->{slapd}->{SchemaFile})) {
|
552
|
+
if (ref($inf->{slapd}->{SchemaFile})) {
|
553
|
+
push @schemafiles, @{$inf->{slapd}->{SchemaFile}};
|
554
|
+
} else {
|
555
|
+
push @schemafiles, $inf->{slapd}->{SchemaFile};
|
556
|
+
}
|
557
|
+
}
|
558
|
+
for my $file (@schemafiles) {
|
559
|
+
my $src = $file;
|
560
|
+
my $basename = basename($src);
|
561
|
+
my $dest = "$inf->{slapd}->{schema_dir}/$basename";
|
562
|
+
|
563
|
+
next if ($skip and -f $dest); # skip files that already exist
|
564
|
+
|
565
|
+
$! = 0; # clear errno
|
566
|
+
copy($src, $dest);
|
567
|
+
if ($!) {
|
568
|
+
return ('error_copying_file', $src, $dest, $!);
|
569
|
+
}
|
570
|
+
my $mode = 4; # default read only
|
571
|
+
if ($basename eq "99user.ldif") {
|
572
|
+
$mode = 6; # read write
|
573
|
+
}
|
574
|
+
if (@errs = changeOwnerMode($inf, $mode, $dest)) {
|
575
|
+
return @errs;
|
576
|
+
}
|
577
|
+
}
|
578
|
+
|
579
|
+
return ();
|
580
|
+
}
|
581
|
+
|
582
|
+
# maps the suffix attr to the filename to use
|
583
|
+
my %suffixTable = (
|
584
|
+
'o' => "/usr/share/dirsrv/data/template-org.ldif",
|
585
|
+
'dc' => "/usr/share/dirsrv/data/template-domain.ldif",
|
586
|
+
'ou' => "/usr/share/dirsrv/data/template-orgunit.ldif",
|
587
|
+
'st' => "/usr/share/dirsrv/data/template-state.ldif",
|
588
|
+
'l' => "/usr/share/dirsrv/data/template-locality.ldif",
|
589
|
+
'c' => "/usr/share/dirsrv/data/template-country.ldif"
|
590
|
+
);
|
591
|
+
|
592
|
+
sub initDatabase {
|
593
|
+
my $inf = shift;
|
594
|
+
my $istempldif = 0;
|
595
|
+
# If the user has specified an LDIF file to use to initialize the database,
|
596
|
+
# load it now
|
597
|
+
my $ldiffile = $inf->{slapd}->{InstallLdifFile};
|
598
|
+
if ($ldiffile =~ /none/i) {
|
599
|
+
debug(1, "No ldif file or org entries specified - no initial database will be created\n");
|
600
|
+
return ();
|
601
|
+
} elsif ($ldiffile && ($ldiffile !~ /suggest/i)) {
|
602
|
+
debug(1, "Loading initial ldif file $ldiffile\n");
|
603
|
+
if (! -r $ldiffile) {
|
604
|
+
return ('error_opening_init_ldif', $ldiffile);
|
605
|
+
}
|
606
|
+
} elsif (($inf->{slapd}->{Suffix} =~ /^(.*?)=/) && $suffixTable{$1}) {
|
607
|
+
my @errs;
|
608
|
+
my $template = $inf->{General}->{prefix} . $suffixTable{$1};
|
609
|
+
my $mapper = new Inf("$inf->{General}->{prefix}/usr/share/dirsrv/inf/dsorgentries.map");
|
610
|
+
my $dsinf = new Inf("$inf->{General}->{prefix}/usr/share/dirsrv/inf/slapd.inf");
|
611
|
+
my @rdns = ldap_explode_dn($inf->{slapd}->{Suffix}, 1);
|
612
|
+
$inf->{slapd}->{naming_value} = $rdns[0];
|
613
|
+
$mapper = process_maptbl($mapper, \@errs, $inf, $dsinf);
|
614
|
+
if (!$mapper or @errs) {
|
615
|
+
return @errs;
|
616
|
+
}
|
617
|
+
|
618
|
+
my @ldiffiles = ($template, "$inf->{General}->{prefix}/usr/share/dirsrv/data/template-baseacis.ldif");
|
619
|
+
# default is to create org entries unless explicitly set to none
|
620
|
+
if (!exists($inf->{slapd}->{InstallLdifFile}) or
|
621
|
+
($inf->{slapd}->{InstallLdifFile} =~ /suggest/i)) {
|
622
|
+
push @ldiffiles, "$inf->{General}->{prefix}/usr/share/dirsrv/data/template.ldif";
|
623
|
+
}
|
624
|
+
|
625
|
+
my ($fh, $templdif) = tempfile("ldifXXXXXX", SUFFIX => ".ldif", OPEN => 0,
|
626
|
+
DIR => File::Spec->tmpdir);
|
627
|
+
if (!$templdif) {
|
628
|
+
return ('error_creating_templdif', $!);
|
629
|
+
}
|
630
|
+
my $conn = new FileConn;
|
631
|
+
$conn->setNamingContext($inf->{slapd}->{Suffix});
|
632
|
+
getMappedEntries($mapper, \@ldiffiles, \@errs, \&check_and_add_entry,
|
633
|
+
[$conn]);
|
634
|
+
if (@errs) {
|
635
|
+
$conn->close();
|
636
|
+
return @errs;
|
637
|
+
}
|
638
|
+
if (!$conn->write($templdif)) {
|
639
|
+
$conn->close();
|
640
|
+
return ('error_writing_ldif', $templdif, $!);
|
641
|
+
}
|
642
|
+
$conn->close();
|
643
|
+
if (@errs) {
|
644
|
+
return @errs;
|
645
|
+
}
|
646
|
+
if (@errs = changeOwnerMode($inf, 4, $templdif)) {
|
647
|
+
unlink($ldiffile);
|
648
|
+
return @errs;
|
649
|
+
}
|
650
|
+
# $templdif now contains the ldif to import
|
651
|
+
$ldiffile = $templdif;
|
652
|
+
$istempldif = 1;
|
653
|
+
}
|
654
|
+
if (!$ldiffile) {
|
655
|
+
return ();
|
656
|
+
}
|
657
|
+
|
658
|
+
my $cmd = "$inf->{slapd}->{sbindir}/ldif2db -Z $inf->{slapd}->{ServerIdentifier} -n $inf->{slapd}->{ds_bename} -i \'$ldiffile\'";
|
659
|
+
$? = 0; # clear error condition
|
660
|
+
my $output = `$cmd 2>&1`;
|
661
|
+
my $result = $?;
|
662
|
+
if ($istempldif) {
|
663
|
+
unlink($ldiffile);
|
664
|
+
}
|
665
|
+
if ($result) {
|
666
|
+
return ('error_importing_ldif', $ldiffile, $result, $output);
|
667
|
+
}
|
668
|
+
|
669
|
+
debug(1, $output);
|
670
|
+
|
671
|
+
return ();
|
672
|
+
}
|
673
|
+
|
674
|
+
sub startServer {
|
675
|
+
my $inf = shift;
|
676
|
+
return () if (defined($inf->{slapd}->{start_server}) && !$inf->{slapd}->{start_server});
|
677
|
+
|
678
|
+
my @errs;
|
679
|
+
# get error log
|
680
|
+
my $errLog = "$inf->{slapd}->{log_dir}/errors";
|
681
|
+
my $startcmd = "$inf->{slapd}->{sbindir}/start-dirsrv $inf->{slapd}->{ServerIdentifier}";
|
682
|
+
if ("/usr/lib/systemd/system" and (getLogin() eq 'root')) {
|
683
|
+
$startcmd = "/bin/systemctl start dirsrv\@$inf->{slapd}->{ServerIdentifier}.service";
|
684
|
+
}
|
685
|
+
|
686
|
+
# emulate tail -f
|
687
|
+
# if the last line we see does not contain "slapd started", try again
|
688
|
+
my $done = 0;
|
689
|
+
my $started = 0;
|
690
|
+
my $code = 0;
|
691
|
+
my $lastLine = "";
|
692
|
+
my $cmdPat = 'slapd started\.';
|
693
|
+
my $timeout = $inf->{slapd}->{startup_timeout};
|
694
|
+
|
695
|
+
$timeout = $timeout?$timeout:600; # default is 10 minutes
|
696
|
+
$timeout = time + $timeout;
|
697
|
+
|
698
|
+
debug(1, "Starting the server: $startcmd\n");
|
699
|
+
|
700
|
+
# We have to do this because docker is incapable of sane process management
|
701
|
+
# Sadly we have to sacrifice output collection, because of perl issues
|
702
|
+
my $cpid = open(my $output, "-|", "$startcmd 2>&1");
|
703
|
+
my $code = -512;
|
704
|
+
if ($cpid) {
|
705
|
+
# Parent process
|
706
|
+
waitpid($cpid,0);
|
707
|
+
$code = $?;
|
708
|
+
}
|
709
|
+
close($output);
|
710
|
+
if ($code) {
|
711
|
+
debug(0, "Process returned $code\n");
|
712
|
+
} else {
|
713
|
+
debug(1, "Process returned $code\n");
|
714
|
+
}
|
715
|
+
|
716
|
+
# try to open the server error log
|
717
|
+
my $ii = 0;
|
718
|
+
while (time < $timeout) {
|
719
|
+
if (open(IN, $errLog)) {
|
720
|
+
last;
|
721
|
+
}
|
722
|
+
sleep(1);
|
723
|
+
if (!($ii % 10)) {
|
724
|
+
debug(0, "Attempting to obtain server status . . .\n");
|
725
|
+
}
|
726
|
+
++$ii;
|
727
|
+
}
|
728
|
+
|
729
|
+
if (! -f $errLog) {
|
730
|
+
debug(0, "Error: Could not read error log $errLog to get server startup status. Error: $!\n");
|
731
|
+
return ('error_starting_server', $startcmd, "no status", $!);
|
732
|
+
}
|
733
|
+
if (time >= $timeout) {
|
734
|
+
debug(0, "Error: timed out waiting for the server to start and write to $errLog");
|
735
|
+
return ('error_starting_server', $startcmd, "timeout", 0);
|
736
|
+
}
|
737
|
+
|
738
|
+
my $pos = tell(IN);
|
739
|
+
my $line;
|
740
|
+
while (($done == 0) && (time < $timeout)) {
|
741
|
+
for (; ($done == 0) && ($line = <IN>); $pos = tell(IN)) {
|
742
|
+
$lastLine = $line;
|
743
|
+
debug(1, $line);
|
744
|
+
if ($line =~ /$cmdPat/) {
|
745
|
+
$done = 1;
|
746
|
+
$started = 1;
|
747
|
+
} elsif ($line =~ /Initialization Failed/) {
|
748
|
+
debug(1, "Server failed to start, retrying . . .\n");
|
749
|
+
$code = system($startcmd);
|
750
|
+
} elsif ($line =~ /exiting\./) {
|
751
|
+
debug(1, "Server failed to start, retrying . . .\n");
|
752
|
+
$code = system($startcmd);
|
753
|
+
}
|
754
|
+
}
|
755
|
+
if ($lastLine =~ /PR_Bind/) {
|
756
|
+
# server port conflicts with another one, just report and punt
|
757
|
+
debug(0, $lastLine);
|
758
|
+
@errs = ('error_port_available', $inf->{slapd}->{ServerPort}, $!);
|
759
|
+
$done = 1;
|
760
|
+
}
|
761
|
+
if ($done == 0) {
|
762
|
+
# rest a bit, then . . .
|
763
|
+
sleep(2);
|
764
|
+
# . . . reset the EOF status of the file desc
|
765
|
+
seek(IN, $pos, 0);
|
766
|
+
}
|
767
|
+
}
|
768
|
+
close(IN);
|
769
|
+
|
770
|
+
if (!$started) {
|
771
|
+
$! = $code;
|
772
|
+
my $now = time;
|
773
|
+
if ($now > $timeout) {
|
774
|
+
debug(0, "Possible timeout starting server: timeout=$timeout now=$now\n");
|
775
|
+
}
|
776
|
+
@errs = ('error_starting_server', $startcmd, $lastLine, $!);
|
777
|
+
} else {
|
778
|
+
debug(1, "Your new directory server has been started.\n");
|
779
|
+
}
|
780
|
+
|
781
|
+
return @errs;
|
782
|
+
}
|
783
|
+
|
784
|
+
sub set_path_attribute {
|
785
|
+
my $val = shift;
|
786
|
+
my $defaultval = shift;
|
787
|
+
my $prefix = shift;
|
788
|
+
|
789
|
+
if ($val) {
|
790
|
+
return "$prefix" . "$val";
|
791
|
+
} else {
|
792
|
+
return "$prefix" . "$defaultval";
|
793
|
+
}
|
794
|
+
}
|
795
|
+
|
796
|
+
sub set_localrundir {
|
797
|
+
my $val = shift;
|
798
|
+
my $prefix = shift;
|
799
|
+
|
800
|
+
if ($val) {
|
801
|
+
return "$prefix" . "$val";
|
802
|
+
} else {
|
803
|
+
return "";
|
804
|
+
}
|
805
|
+
}
|
806
|
+
|
807
|
+
sub setDefaults {
|
808
|
+
my $inf = shift;
|
809
|
+
# set default values
|
810
|
+
|
811
|
+
# this turns off the warnings
|
812
|
+
if (!defined($inf->{General}->{prefix})) {
|
813
|
+
$inf->{General}->{prefix} = "";
|
814
|
+
}
|
815
|
+
|
816
|
+
if (!$inf->{General}->{FullMachineName}) {
|
817
|
+
$inf->{General}->{FullMachineName} = hostname();
|
818
|
+
}
|
819
|
+
|
820
|
+
if (!$inf->{General}->{SuiteSpotUserID}) {
|
821
|
+
if ($> != 0) { # if not root, use the user's uid
|
822
|
+
$inf->{General}->{SuiteSpotUserID} = getLogin;
|
823
|
+
} else {
|
824
|
+
return('error_missing_userid');
|
825
|
+
}
|
826
|
+
}
|
827
|
+
|
828
|
+
if (!$inf->{General}->{SuiteSpotGroup}) {
|
829
|
+
# If the group wasn't specified, use the primary group
|
830
|
+
# of the SuiteSpot user
|
831
|
+
$inf->{General}->{SuiteSpotGroup} = getGroup($inf->{General}->{SuiteSpotUserID});
|
832
|
+
}
|
833
|
+
|
834
|
+
if (!$inf->{slapd}->{RootDN}) {
|
835
|
+
$inf->{slapd}->{RootDN} = "cn=Directory Manager";
|
836
|
+
}
|
837
|
+
|
838
|
+
if (!$inf->{slapd}->{Suffix}) {
|
839
|
+
my $suffix = $inf->{General}->{FullMachineName};
|
840
|
+
# convert fqdn to dc= domain components
|
841
|
+
$suffix =~ s/^[^\.]*\.//; # just the domain part
|
842
|
+
$suffix = "dc=$suffix";
|
843
|
+
$suffix =~ s/\./,dc=/g;
|
844
|
+
$inf->{slapd}->{Suffix} = $suffix;
|
845
|
+
}
|
846
|
+
$inf->{slapd}->{Suffix} = normalizeDN($inf->{slapd}->{Suffix});
|
847
|
+
|
848
|
+
if (!$inf->{slapd}->{ServerIdentifier}) {
|
849
|
+
my $servid = $inf->{General}->{FullMachineName};
|
850
|
+
# strip out the leftmost domain component
|
851
|
+
$servid =~ s/\..*$//;
|
852
|
+
$inf->{slapd}->{ServerIdentifier} = $servid;
|
853
|
+
}
|
854
|
+
|
855
|
+
if ("") {
|
856
|
+
$inf->{General}->{ServerRoot} = "$inf->{General}->{prefix}/opt/dirsrv";
|
857
|
+
} else {
|
858
|
+
$inf->{General}->{ServerRoot} = "$inf->{General}->{prefix}/usr/lib64/dirsrv";
|
859
|
+
}
|
860
|
+
|
861
|
+
if (!defined($inf->{slapd}->{sasl_path})) {
|
862
|
+
if ($Config{'osname'} ne "linux") {
|
863
|
+
$inf->{slapd}->{sasl_path} = "$inf->{General}->{prefix}/usr/lib64/sasl2";
|
864
|
+
}
|
865
|
+
}
|
866
|
+
|
867
|
+
if (!defined($inf->{slapd}->{ServerPort}) and
|
868
|
+
!defined($inf->{slapd}->{ldapifilepath})) {
|
869
|
+
if ("1") {
|
870
|
+
return ('error_missing_port_and_ldapi');
|
871
|
+
} else {
|
872
|
+
return ('error_missing_port');
|
873
|
+
}
|
874
|
+
}
|
875
|
+
|
876
|
+
if (!defined($inf->{slapd}->{ServerPort})) {
|
877
|
+
$inf->{slapd}->{ServerPort} = 0;
|
878
|
+
}
|
879
|
+
|
880
|
+
$inf->{slapd}->{HashedRootDNPwd} = getHashedPassword($inf->{slapd}->{RootDNPwd});
|
881
|
+
|
882
|
+
$inf->{slapd}->{localstatedir} = set_path_attribute($inf->{slapd}->{localstatedir},
|
883
|
+
"/var",
|
884
|
+
$inf->{General}->{prefix});
|
885
|
+
my $localstatedir = $inf->{slapd}->{localstatedir};
|
886
|
+
my $servid = $inf->{slapd}->{ServerIdentifier};
|
887
|
+
$inf->{slapd}->{sysconfdir} = set_path_attribute($inf->{slapd}->{sysconfdir},
|
888
|
+
"/etc",
|
889
|
+
$inf->{General}->{prefix});
|
890
|
+
my $sysconfdir = $inf->{slapd}->{sysconfdir};
|
891
|
+
$inf->{slapd}->{bindir} = set_path_attribute($inf->{slapd}->{bindir},
|
892
|
+
"/usr/bin",
|
893
|
+
$inf->{General}->{prefix});
|
894
|
+
$inf->{slapd}->{sbindir} = set_path_attribute($inf->{slapd}->{sbindir},
|
895
|
+
"/usr/sbin",
|
896
|
+
$inf->{General}->{prefix});
|
897
|
+
$inf->{slapd}->{datadir} = set_path_attribute($inf->{slapd}->{datadir},
|
898
|
+
"/usr/share",
|
899
|
+
$inf->{General}->{prefix});
|
900
|
+
|
901
|
+
if (!defined($inf->{slapd}->{InstScriptsEnabled})) {
|
902
|
+
$inf->{slapd}->{InstScriptsEnabled} = "true";
|
903
|
+
}
|
904
|
+
|
905
|
+
if (!defined($inf->{General}->{StrictHostCheck})) {
|
906
|
+
$inf->{General}->{StrictHostCheck} = "true";
|
907
|
+
}
|
908
|
+
|
909
|
+
if (!defined($inf->{slapd}->{inst_dir})) {
|
910
|
+
$inf->{slapd}->{inst_dir} = "$inf->{General}->{ServerRoot}/slapd-$servid";
|
911
|
+
}
|
912
|
+
|
913
|
+
if (!defined($inf->{slapd}->{config_dir})) {
|
914
|
+
$inf->{slapd}->{config_dir} = "$inf->{General}->{prefix}/etc/dirsrv/slapd-$servid";
|
915
|
+
}
|
916
|
+
$ENV{DS_CONFIG_DIR} = $inf->{slapd}->{config_dir};
|
917
|
+
|
918
|
+
if (!defined($inf->{slapd}->{schema_dir})) {
|
919
|
+
$inf->{slapd}->{schema_dir} = "$sysconfdir/dirsrv/slapd-$servid/schema";
|
920
|
+
}
|
921
|
+
|
922
|
+
if (!defined($inf->{slapd}->{lock_dir})) {
|
923
|
+
if ("") {
|
924
|
+
$inf->{slapd}->{lock_dir} = "$localstatedir/dirsrv/slapd-$servid/lock";
|
925
|
+
} else {
|
926
|
+
$inf->{slapd}->{lock_dir} = "$localstatedir/lock/dirsrv/slapd-$servid";
|
927
|
+
}
|
928
|
+
}
|
929
|
+
|
930
|
+
if (!defined($inf->{slapd}->{log_dir})) {
|
931
|
+
if ("") {
|
932
|
+
$inf->{slapd}->{log_dir} = "$localstatedir/dirsrv/slapd-$servid/log";
|
933
|
+
} else {
|
934
|
+
$inf->{slapd}->{log_dir} = "$localstatedir/log/dirsrv/slapd-$servid";
|
935
|
+
}
|
936
|
+
}
|
937
|
+
|
938
|
+
if (!defined($inf->{slapd}->{run_dir})) {
|
939
|
+
if ("") {
|
940
|
+
$inf->{slapd}->{run_dir} = "$localstatedir/dirsrv/slapd-$servid/run";
|
941
|
+
} else {
|
942
|
+
$inf->{slapd}->{run_dir} = "$localstatedir/run/dirsrv";
|
943
|
+
}
|
944
|
+
}
|
945
|
+
$ENV{DS_RUN_DIR} = $inf->{slapd}->{run_dir};
|
946
|
+
|
947
|
+
if (!defined($inf->{slapd}->{db_dir})) {
|
948
|
+
if ("") {
|
949
|
+
$inf->{slapd}->{db_dir} = "$localstatedir/dirsrv/slapd-$servid/db";
|
950
|
+
} else {
|
951
|
+
$inf->{slapd}->{db_dir} = "$localstatedir/lib/dirsrv/slapd-$servid/db";
|
952
|
+
}
|
953
|
+
}
|
954
|
+
|
955
|
+
if (!defined($inf->{slapd}->{bak_dir})) {
|
956
|
+
if ("") {
|
957
|
+
$inf->{slapd}->{bak_dir} = "$localstatedir/dirsrv/slapd-$servid/bak";
|
958
|
+
} else {
|
959
|
+
$inf->{slapd}->{bak_dir} = "$localstatedir/lib/dirsrv/slapd-$servid/bak";
|
960
|
+
}
|
961
|
+
}
|
962
|
+
$ENV{DS_BAK_DIR} = $inf->{slapd}->{bak_dir};
|
963
|
+
|
964
|
+
if (!defined($inf->{slapd}->{ldif_dir})) {
|
965
|
+
if ("") {
|
966
|
+
$inf->{slapd}->{ldif_dir} = "$localstatedir/dirsrv/slapd-$servid/ldif";
|
967
|
+
} else {
|
968
|
+
$inf->{slapd}->{ldif_dir} = "$localstatedir/lib/dirsrv/slapd-$servid/ldif";
|
969
|
+
}
|
970
|
+
}
|
971
|
+
|
972
|
+
if (!defined($inf->{slapd}->{tmp_dir})) {
|
973
|
+
if ("") {
|
974
|
+
$inf->{slapd}->{tmp_dir} = "/tmp";
|
975
|
+
} else {
|
976
|
+
$inf->{slapd}->{tmp_dir} = "/tmp";
|
977
|
+
}
|
978
|
+
}
|
979
|
+
$ENV{DS_TMP_DIR} = $inf->{slapd}->{tmp_dir};
|
980
|
+
|
981
|
+
if (!defined($inf->{slapd}->{cert_dir})) {
|
982
|
+
$inf->{slapd}->{cert_dir} = $inf->{slapd}->{config_dir};
|
983
|
+
}
|
984
|
+
|
985
|
+
return ();
|
986
|
+
}
|
987
|
+
|
988
|
+
sub updateSelinuxPolicy {
|
989
|
+
my $inf = shift;
|
990
|
+
my $mydevnull = (-c "/dev/null" ? " /dev/null " : " NUL ");
|
991
|
+
|
992
|
+
# if selinux is not available, do nothing
|
993
|
+
# In perl, exit(1) is 256 from system. ds_selinux_enable returns 1 on true, 0 on false.
|
994
|
+
if ((getLogin() eq 'root') and "yes" and system("$inf->{slapd}->{sbindir}/ds_selinux_enabled") == 256 ) {
|
995
|
+
debug(1, "Selinux is enabled or permissive, fixing contexts\n");
|
996
|
+
# -f "/usr/sbin/sestatus" and !system ("/usr/sbin/sestatus | egrep -i \"selinux status:\\s*enabled\" > $mydevnull 2>&1")) {
|
997
|
+
my $localstatedir = $inf->{slapd}->{localstatedir};
|
998
|
+
|
999
|
+
# run restorecon on all of the parent directories we
|
1000
|
+
# may have created (this only happens if this is the
|
1001
|
+
# first instance created).
|
1002
|
+
if ("") {
|
1003
|
+
system("restorecon -R $localstatedir/dirsrv");
|
1004
|
+
} else {
|
1005
|
+
system("restorecon -R $localstatedir/lock/dirsrv");
|
1006
|
+
system("restorecon -R $localstatedir/log/dirsrv");
|
1007
|
+
system("restorecon -R $localstatedir/run/dirsrv");
|
1008
|
+
system("restorecon -R $localstatedir/lib/dirsrv");
|
1009
|
+
}
|
1010
|
+
|
1011
|
+
my @inst_dirs = qw(config_dir schema_dir log_dir lock_dir run_dir tmp_dir cert_dir db_dir ldif_dir bak_dir);
|
1012
|
+
if ($inf->{slapd}->{InstScriptsEnabled} eq "true") {
|
1013
|
+
@inst_dirs = qw(inst_dir config_dir schema_dir log_dir lock_dir run_dir tmp_dir cert_dir db_dir ldif_dir bak_dir);
|
1014
|
+
}
|
1015
|
+
# run restorecon on all instance directories we created
|
1016
|
+
for my $kw (@inst_dirs) {
|
1017
|
+
my $dir = $inf->{slapd}->{$kw};
|
1018
|
+
system("restorecon -R $dir");
|
1019
|
+
}
|
1020
|
+
|
1021
|
+
# label the selected port as ldap_port_t
|
1022
|
+
# We should be doing this for secure port too .....
|
1023
|
+
if ($inf->{slapd}->{ServerPort} != 0 and not $ENV{DS_SKIP_LABEL}) {
|
1024
|
+
my $port_query_cmd = ("$inf->{slapd}->{sbindir}/ds_selinux_port_query $inf->{slapd}->{ServerPort} ldap_port_t 2> $mydevnull");
|
1025
|
+
my $need_label = 0;
|
1026
|
+
my $result = system($port_query_cmd);
|
1027
|
+
|
1028
|
+
# 0 is false, 1 is true. True means 'already in policy'.
|
1029
|
+
if ($result == 0) {
|
1030
|
+
debug(1, "Port $inf->{slapd}->{ServerPort} must be labeled as ldap_port_t \n");
|
1031
|
+
$need_label = 1;
|
1032
|
+
}
|
1033
|
+
if ($result == 512) {
|
1034
|
+
$need_label = 0;
|
1035
|
+
debug(0, "Port $inf->{slapd}->{ServerPort} already belongs to another selinux type.\n");
|
1036
|
+
debug(0, " The command below will show you the current type that owns the port.\n");
|
1037
|
+
debug(0, "sudo $inf->{slapd}->{sbindir}/ds_selinux_port_query $inf->{slapd}->{ServerPort} ldap_port_t\n");
|
1038
|
+
debug(0, " It is highly likely your server will fail to start ... \n");
|
1039
|
+
}
|
1040
|
+
if ($result == 131072) {
|
1041
|
+
$need_label = 0;
|
1042
|
+
debug(0, "An error occured running ds_selinux_port_query. This is probably a bug\n");
|
1043
|
+
debug(0, "$port_query_cmd \n");
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
if ($need_label == 1) {
|
1047
|
+
my $semanage_err;
|
1048
|
+
my $rc;
|
1049
|
+
# 60 is a bit excessive, we should fail faster.
|
1050
|
+
my $retry = 2;
|
1051
|
+
$ENV{LANG} = "C";
|
1052
|
+
while (($retry > 0) && ($semanage_err = `semanage port -a -t ldap_port_t -p tcp $inf->{slapd}->{ServerPort} 2>&1`) && ($rc = $?)) {
|
1053
|
+
debug(1, "Adding port $inf->{slapd}->{ServerPort} to selinux policy failed - $semanage_err (return code: $rc, $retry attempts remain).\n");
|
1054
|
+
debug(1, "Retrying in 5 seconds\n");
|
1055
|
+
sleep(5);
|
1056
|
+
$retry--;
|
1057
|
+
}
|
1058
|
+
if (0 == $retry) {
|
1059
|
+
debug(1, "Adding port $inf->{slapd}->{ServerPort} to selinux policy failed - $semanage_err (return code: $rc).\n");
|
1060
|
+
debug(1, "Reached time limit.\n");
|
1061
|
+
}
|
1062
|
+
}
|
1063
|
+
}
|
1064
|
+
}
|
1065
|
+
}
|
1066
|
+
|
1067
|
+
sub updateTmpfilesDotD {
|
1068
|
+
my $inf = shift;
|
1069
|
+
my $dir = "/etc/tmpfiles.d";
|
1070
|
+
my $rundir;
|
1071
|
+
my $lockdir;
|
1072
|
+
my $parentdir;
|
1073
|
+
|
1074
|
+
# if tmpfiles.d is not available, do nothing
|
1075
|
+
if ((getLogin() eq 'root') and $dir and -d $dir) {
|
1076
|
+
my $filename = "$dir/dirsrv-$inf->{slapd}->{ServerIdentifier}.conf";
|
1077
|
+
if (-f $filename) {
|
1078
|
+
debug(3, "Removing the old tmpfile: $filename\n");
|
1079
|
+
if (!unlink($filename)){
|
1080
|
+
debug(1, "Can not delete old tmpfile $filename ($!)\n");
|
1081
|
+
return();
|
1082
|
+
}
|
1083
|
+
}
|
1084
|
+
debug(3, "Creating $filename\n");
|
1085
|
+
my $username = "";
|
1086
|
+
my $groupname = "";
|
1087
|
+
my $conffile = "$inf->{slapd}->{config_dir}/dse.ldif";
|
1088
|
+
# use the owner:group from the dse.ldif for the instance
|
1089
|
+
if (-f $conffile) {
|
1090
|
+
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
|
1091
|
+
$atime,$mtime,$ctime,$blksize,$blocks)
|
1092
|
+
= stat(_);
|
1093
|
+
$username = getpwuid($uid);
|
1094
|
+
if (!$username) {
|
1095
|
+
debug(1, "Error: could not get username from uid $uid\n");
|
1096
|
+
}
|
1097
|
+
$groupname = getgrgid($gid);
|
1098
|
+
}
|
1099
|
+
# else, see if we were passed in values to use
|
1100
|
+
if (!$username) {
|
1101
|
+
$username = $inf->{General}->{SuiteSpotUserID};
|
1102
|
+
}
|
1103
|
+
if (!$groupname) {
|
1104
|
+
if (defined($inf->{General}->{SuiteSpotGroup})) {
|
1105
|
+
$groupname = $inf->{General}->{SuiteSpotGroup};
|
1106
|
+
} else { # $groupname
|
1107
|
+
$groupname = "-"; # use default
|
1108
|
+
}
|
1109
|
+
}
|
1110
|
+
if (!open(DOTDFILE, ">$filename")) {
|
1111
|
+
return ( [ 'error_creating_file', $filename, $! ] );
|
1112
|
+
}
|
1113
|
+
# Type Path Mode UID GID Age
|
1114
|
+
# d /var/run/user 0755 root root 10d
|
1115
|
+
# we don't use age
|
1116
|
+
my $localrundir = set_localrundir("/run", $inf->{General}->{prefix});
|
1117
|
+
if( $localrundir ne "" && -d "$localrundir"){
|
1118
|
+
$rundir = "$localrundir/dirsrv";
|
1119
|
+
$lockdir = "$localrundir/lock/dirsrv/slapd-$inf->{slapd}->{ServerIdentifier}";
|
1120
|
+
$parentdir = "$localrundir/lock/dirsrv";
|
1121
|
+
} else {
|
1122
|
+
$rundir = $inf->{slapd}->{run_dir};
|
1123
|
+
$lockdir = $inf->{slapd}->{lock_dir};
|
1124
|
+
$parentdir = dirname($inf->{slapd}->{lock_dir});
|
1125
|
+
}
|
1126
|
+
print DOTDFILE "d $rundir 0770 $username $groupname\n";
|
1127
|
+
print DOTDFILE "d $parentdir 0770 $username $groupname\n";
|
1128
|
+
print DOTDFILE "d $lockdir 0770 $username $groupname\n";
|
1129
|
+
|
1130
|
+
close DOTDFILE;
|
1131
|
+
} else {
|
1132
|
+
debug(3, "no tmpfiles.d - skipping\n");
|
1133
|
+
}
|
1134
|
+
|
1135
|
+
return ();
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
sub updateSystemD {
|
1139
|
+
my $noservicelink = shift;
|
1140
|
+
my $inf = shift;
|
1141
|
+
my $unitdir = "/usr/lib/systemd/system";
|
1142
|
+
my $confbasedir = "/etc/systemd/system";
|
1143
|
+
my $confdir = "$confbasedir/dirsrv.target.wants";
|
1144
|
+
|
1145
|
+
if ((getLogin() ne 'root') or !$unitdir or !$confdir or ! -d $unitdir or ! -d $confdir) {
|
1146
|
+
debug(3, "no systemd - skipping\n");
|
1147
|
+
return ();
|
1148
|
+
}
|
1149
|
+
|
1150
|
+
my @errs = ();
|
1151
|
+
my $initconfigdir = $inf->{slapd}->{initconfigdir} || get_initconfigdir($inf->{General}->{prefix});
|
1152
|
+
debug(1, "updating systemd files in $unitdir and $confdir for all directory server instances in $initconfigdir\n");
|
1153
|
+
my $pkgname = "dirsrv";
|
1154
|
+
my $changes = 0;
|
1155
|
+
# installation should already have put down the files and
|
1156
|
+
# directories - we just need to update the symlinks
|
1157
|
+
my $servicefile = "$unitdir/$pkgname\@.service";
|
1158
|
+
# first, look for new instances
|
1159
|
+
for my $file (glob("$initconfigdir/$pkgname-*")) {
|
1160
|
+
my $inst = $file;
|
1161
|
+
$inst =~ s/^.*$pkgname-//;
|
1162
|
+
# see if this is the admin or snmp or some other service
|
1163
|
+
if (-f "$unitdir/$pkgname-$inst.service") {
|
1164
|
+
debug(1, "$unitdir/$pkgname-$inst.service already exists - skipping\n");
|
1165
|
+
next;
|
1166
|
+
} elsif (-f "$confbasedir/$pkgname-$inst.service") {
|
1167
|
+
debug(1, "$confbasedir/$pkgname-$inst.service already exists - skipping\n");
|
1168
|
+
next;
|
1169
|
+
} else {
|
1170
|
+
my $servicelink = "$confdir/$pkgname\@$inst.service";
|
1171
|
+
if (! -l $servicelink && ! $noservicelink) {
|
1172
|
+
if (!symlink($servicefile, $servicelink)) {
|
1173
|
+
debug(1, "error updating link $servicelink to $servicefile - $!\n");
|
1174
|
+
push @errs, [ 'error_linking_file', $servicefile, $servicelink, $! ];
|
1175
|
+
} else {
|
1176
|
+
debug(2, "updated link $servicelink to $servicefile\n");
|
1177
|
+
}
|
1178
|
+
$changes++;
|
1179
|
+
}
|
1180
|
+
}
|
1181
|
+
}
|
1182
|
+
# next, look for instances that have been removed
|
1183
|
+
for my $file (glob("$confdir/$pkgname\@*.service")) {
|
1184
|
+
my $inst = $file;
|
1185
|
+
$inst =~ s/^.*$pkgname\@(.*?).service$/$1/;
|
1186
|
+
if (! -f "$initconfigdir/$pkgname-$inst") {
|
1187
|
+
if (!unlink($file)) {
|
1188
|
+
debug(1, "error removing $file - $!\n");
|
1189
|
+
push @errs, [ 'error_removing_path', $file, $! ];
|
1190
|
+
} else {
|
1191
|
+
debug(2, "removed systemd file $file for removed instance $inst\n");
|
1192
|
+
}
|
1193
|
+
$changes++;
|
1194
|
+
}
|
1195
|
+
}
|
1196
|
+
if ($changes > 0) {
|
1197
|
+
$? = 0;
|
1198
|
+
my $cmd = '/bin/systemctl --system daemon-reload';
|
1199
|
+
# run the reload command
|
1200
|
+
my $output = `$cmd 2>&1`;
|
1201
|
+
my $status = $?;
|
1202
|
+
if ($status) {
|
1203
|
+
debug(1, "Error: $cmd failed - output $output: $!\n");
|
1204
|
+
push @errs, [ 'error_running_command', $cmd, $output, $! ];
|
1205
|
+
} else {
|
1206
|
+
debug(2, "$cmd succeeded\n");
|
1207
|
+
}
|
1208
|
+
} else {
|
1209
|
+
debug(1, "No changes to $unitdir or $confdir\n");
|
1210
|
+
}
|
1211
|
+
|
1212
|
+
|
1213
|
+
return @errs;
|
1214
|
+
}
|
1215
|
+
|
1216
|
+
sub createDSInstance {
|
1217
|
+
my $inf = shift;
|
1218
|
+
my @errs;
|
1219
|
+
|
1220
|
+
if (@errs = setDefaults($inf)) {
|
1221
|
+
return @errs;
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
if (@errs = sanityCheckParams($inf)) {
|
1225
|
+
return @errs;
|
1226
|
+
}
|
1227
|
+
|
1228
|
+
if (@errs = makeDSDirs($inf)) {
|
1229
|
+
return @errs;
|
1230
|
+
}
|
1231
|
+
|
1232
|
+
if (@errs = createConfigFile($inf)) {
|
1233
|
+
return @errs;
|
1234
|
+
}
|
1235
|
+
|
1236
|
+
if (@errs = makeOtherConfigFiles($inf)) {
|
1237
|
+
return @errs;
|
1238
|
+
}
|
1239
|
+
|
1240
|
+
if (@errs = createInstanceScripts($inf)) {
|
1241
|
+
return @errs;
|
1242
|
+
}
|
1243
|
+
|
1244
|
+
if (@errs = installSchema($inf)) {
|
1245
|
+
return @errs;
|
1246
|
+
}
|
1247
|
+
|
1248
|
+
if (@errs = initDatabase($inf)) {
|
1249
|
+
return @errs;
|
1250
|
+
}
|
1251
|
+
|
1252
|
+
updateSelinuxPolicy($inf);
|
1253
|
+
|
1254
|
+
if (@errs = updateTmpfilesDotD($inf)) {
|
1255
|
+
return @errs;
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
if (@errs = updateSystemD(0, $inf)) {
|
1259
|
+
return @errs;
|
1260
|
+
}
|
1261
|
+
|
1262
|
+
if (@errs = startServer($inf)) {
|
1263
|
+
return @errs;
|
1264
|
+
}
|
1265
|
+
|
1266
|
+
return @errs;
|
1267
|
+
}
|
1268
|
+
|
1269
|
+
sub stopServer {
|
1270
|
+
my $instance = shift;
|
1271
|
+
my $prog = "/usr/sbin/stop-dirsrv";
|
1272
|
+
if (-x $prog) {
|
1273
|
+
$? = 0;
|
1274
|
+
# run the stop command
|
1275
|
+
my $output = `$prog $instance 2>&1`;
|
1276
|
+
my $status = $?;
|
1277
|
+
debug(3, "stopping server $instance returns status $status: output $output\n");
|
1278
|
+
if ($status) {
|
1279
|
+
debug(1,"Warning: Could not stop directory server: status $status: output $output\n");
|
1280
|
+
# if the server is not running, that's ok
|
1281
|
+
if ($output =~ /not running/) {
|
1282
|
+
$! = ENOENT;
|
1283
|
+
return 1;
|
1284
|
+
}
|
1285
|
+
# else, some other error (e.g. permission) - return false for error
|
1286
|
+
return;
|
1287
|
+
}
|
1288
|
+
} else {
|
1289
|
+
debug(1, "stopping server: no such program $prog: cannot stop server\n");
|
1290
|
+
return;
|
1291
|
+
}
|
1292
|
+
|
1293
|
+
debug(1, "Successfully stopped server $instance\n");
|
1294
|
+
return 1;
|
1295
|
+
}
|
1296
|
+
|
1297
|
+
# NOTE: Returns a list of array ref - each array ref is suitable for passing
|
1298
|
+
# to Resource::getText
|
1299
|
+
sub removeDSInstance {
|
1300
|
+
my $inst = shift;
|
1301
|
+
my $force = shift;
|
1302
|
+
my $all = shift;
|
1303
|
+
my $initconfig_dir = shift || get_initconfigdir();
|
1304
|
+
my $baseconfigdir = $ENV{DS_CONFIG_DIR} || "/etc/dirsrv";
|
1305
|
+
my $instname = "slapd-$inst";
|
1306
|
+
my $configdir;
|
1307
|
+
my $rundir;
|
1308
|
+
my $product_name;
|
1309
|
+
my @errs;
|
1310
|
+
|
1311
|
+
my $initconfig = "$initconfig_dir/dirsrv-$inst";
|
1312
|
+
my $pkglockdir = "/var/lock/dirsrv";
|
1313
|
+
my $pkgrundir = "/var/run/dirsrv";
|
1314
|
+
my $pkglibdir = "/var/lib/dirsrv";
|
1315
|
+
|
1316
|
+
# Get the configdir, rundir and product_name from the instance initconfig script.
|
1317
|
+
unless(open(INFILE, $initconfig)) {
|
1318
|
+
return ( [ 'error_no_such_instance', $instname, $! ] );
|
1319
|
+
}
|
1320
|
+
|
1321
|
+
my $line;
|
1322
|
+
while($line = <INFILE>) {
|
1323
|
+
if ($line =~ /CONFIG_DIR=(.*) ; export CONFIG_DIR/) {
|
1324
|
+
$configdir = $1;
|
1325
|
+
} elsif ($line =~ /CONFIG_DIR=(.*)$/) {
|
1326
|
+
$configdir = $1;
|
1327
|
+
} elsif ($line =~ /RUN_DIR=(.*) ; export RUN_DIR/) {
|
1328
|
+
$rundir = $1;
|
1329
|
+
} elsif ($line =~ /RUN_DIR=(.*)$/) {
|
1330
|
+
$rundir = $1;
|
1331
|
+
} elsif ($line =~ /PRODUCT_NAME=(.*) ; export PRODUCT_NAME/) {
|
1332
|
+
$product_name = $1;
|
1333
|
+
} elsif ($line =~ /PRODUCT_NAME=(.*)$/) {
|
1334
|
+
$product_name = $1;
|
1335
|
+
}
|
1336
|
+
}
|
1337
|
+
close(INFILE);
|
1338
|
+
|
1339
|
+
if ( ! -d $configdir )
|
1340
|
+
{
|
1341
|
+
debug(1, "Error: $configdir does not exist: $!\n");
|
1342
|
+
return ( [ 'error_no_such_instance', $configdir, $! ] );
|
1343
|
+
}
|
1344
|
+
# read the config file to find out the paths
|
1345
|
+
my $dseldif = "$configdir/dse.ldif";
|
1346
|
+
my $conn = new FileConn($dseldif, 1);
|
1347
|
+
if (!$conn) {
|
1348
|
+
debug(1, "Error: Could not open config file $dseldif: Error $!\n");
|
1349
|
+
return ( [ 'error_opening_dseldif', $dseldif, $! ] );
|
1350
|
+
}
|
1351
|
+
|
1352
|
+
my $dn = "cn=config";
|
1353
|
+
my $entry = $conn->search($dn, "base", "(cn=*)", 0);
|
1354
|
+
if (!$entry)
|
1355
|
+
{
|
1356
|
+
debug(1, "Error: Search $dn in $dseldif failed: $entry\n");
|
1357
|
+
push @errs, [ 'error_finding_config_entry', $dn, $dseldif, $conn->getErrorString() ];
|
1358
|
+
}
|
1359
|
+
|
1360
|
+
$dn = "cn=config,cn=ldbm database,cn=plugins,cn=config";
|
1361
|
+
my $dbentry = $conn->search($dn, "base", "(cn=*)", 0);
|
1362
|
+
if (!$dbentry)
|
1363
|
+
{
|
1364
|
+
debug(1, "Error: Search $dn in $dseldif failed: $dbentry\n");
|
1365
|
+
push @errs, [ 'error_finding_config_entry', $dn, $dseldif, $conn->getErrorString() ];
|
1366
|
+
}
|
1367
|
+
$conn->close();
|
1368
|
+
|
1369
|
+
# stop the server
|
1370
|
+
if (!stopServer($inst)) {
|
1371
|
+
if ($force) {
|
1372
|
+
debug(1, "Warning: Could not stop directory server - Error: $! - forcing continue\n");
|
1373
|
+
} elsif ($! == ENOENT) { # stop script not found or server not running
|
1374
|
+
debug(1, "Warning: Could not stop directory server: already removed or not running\n");
|
1375
|
+
push @errs, [ 'error_stopping_server', $inst, $! ];
|
1376
|
+
} else { # real error
|
1377
|
+
debug(1, "Error: Could not stop directory server - aborting - use -f flag to force removal\n");
|
1378
|
+
push @errs, [ 'error_stopping_server', $inst, $! ];
|
1379
|
+
return @errs;
|
1380
|
+
}
|
1381
|
+
}
|
1382
|
+
|
1383
|
+
# remove physical dirs/files
|
1384
|
+
if ($dbentry) {
|
1385
|
+
push @errs, remove_tree($dbentry, "nsslapd-directory", $instname, 1);
|
1386
|
+
push @errs, remove_tree($dbentry, "nsslapd-db-logdirectory", $instname, 1);
|
1387
|
+
}
|
1388
|
+
if ($entry) {
|
1389
|
+
push @errs, remove_tree($entry, "nsslapd-lockdir", $instname, 0);
|
1390
|
+
push @errs, remove_tree($entry, "nsslapd-tmpdir", $instname, 0);
|
1391
|
+
push @errs, remove_tree($entry, "nsslapd-bakdir", $instname, 1);
|
1392
|
+
push @errs, remove_tree($entry, "nsslapd-errorlog", $instname, 1);
|
1393
|
+
}
|
1394
|
+
|
1395
|
+
|
1396
|
+
# instance dir
|
1397
|
+
my $instdir = "";
|
1398
|
+
if ($entry) {
|
1399
|
+
foreach my $instdir ( @{$entry->{"nsslapd-instancedir"}} )
|
1400
|
+
{
|
1401
|
+
if ( -d $instdir && $instdir =~ /$instname/ )
|
1402
|
+
{
|
1403
|
+
# clean up pid files (if any)
|
1404
|
+
remove_pidfile("STARTPIDFILE", $inst, $instdir, $instname, $rundir, $product_name);
|
1405
|
+
remove_pidfile("PIDFILE", $inst, $instdir, $instname, $rundir, $product_name);
|
1406
|
+
|
1407
|
+
my $rc = rmtree($instdir);
|
1408
|
+
if ( 0 == $rc )
|
1409
|
+
{
|
1410
|
+
push @errs, [ 'error_removing_path', $instdir, $! ];
|
1411
|
+
debug(1, "Warning: $instdir was not removed. Error: $!\n");
|
1412
|
+
}
|
1413
|
+
}
|
1414
|
+
}
|
1415
|
+
}
|
1416
|
+
# Finally, config dir
|
1417
|
+
if ($all) {
|
1418
|
+
push @errs, remove_tree($entry, "nsslapd-schemadir", $instname, 1);
|
1419
|
+
} else {
|
1420
|
+
push @errs, remove_tree($entry, "nsslapd-schemadir", $instname, 1, "\.db\$");
|
1421
|
+
}
|
1422
|
+
|
1423
|
+
# Remove the instance specific initconfig script
|
1424
|
+
if ( -f $initconfig ) {
|
1425
|
+
my $rc = unlink($initconfig);
|
1426
|
+
if ( 0 == $rc )
|
1427
|
+
{
|
1428
|
+
push @errs, [ 'error_removing_path', $initconfig, $! ];
|
1429
|
+
debug(1, "Warning: $initconfig was not removed. Error: $!\n");
|
1430
|
+
}
|
1431
|
+
}
|
1432
|
+
|
1433
|
+
my $tmpfilesdir = "/etc/tmpfiles.d";
|
1434
|
+
my $tmpfilesname = "$tmpfilesdir/dirsrv-$inst.conf";
|
1435
|
+
if ((getLogin() eq 'root') && $tmpfilesdir && -d $tmpfilesdir && -f $tmpfilesname) {
|
1436
|
+
my $rc = unlink($tmpfilesname);
|
1437
|
+
if ( 0 == $rc )
|
1438
|
+
{
|
1439
|
+
push @errs, [ 'error_removing_path', $tmpfilesname, $! ];
|
1440
|
+
debug(1, "Warning: $tmpfilesname was not removed. Error: $!\n");
|
1441
|
+
}
|
1442
|
+
}
|
1443
|
+
|
1444
|
+
# remove the selinux label from the ports if needed
|
1445
|
+
my $mydevnull = (-c "/dev/null" ? " /dev/null " : " NUL ");
|
1446
|
+
if ((getLogin() eq 'root') and "yes" and system("/usr/sbin/ds_selinux_enabled") == 256 and not $ENV{DS_SKIP_UNLABEL}) {
|
1447
|
+
foreach my $port (@{$entry->{"nsslapd-port"}})
|
1448
|
+
{
|
1449
|
+
|
1450
|
+
my $need_remove_label = 0;
|
1451
|
+
my $port_query_cmd = ("/usr/sbin/ds_selinux_port_query $port ldap_port_t 2> $mydevnull");
|
1452
|
+
my $result = system($port_query_cmd);
|
1453
|
+
|
1454
|
+
if ($result == 256) {
|
1455
|
+
debug(1, "Port $port may be removed as ldap_port_t \n");
|
1456
|
+
$need_remove_label = 1;
|
1457
|
+
}
|
1458
|
+
if ($result == 131072) {
|
1459
|
+
$need_remove_label = 0;
|
1460
|
+
debug(0, "An error occured running ds_selinux_port_query. This is probably a bug\n");
|
1461
|
+
debug(0, "$port_query_cmd \n");
|
1462
|
+
}
|
1463
|
+
|
1464
|
+
my $semanage_err;
|
1465
|
+
my $rc;
|
1466
|
+
my $retry = 5;
|
1467
|
+
$ENV{LANG} = "C";
|
1468
|
+
if ($need_remove_label) {
|
1469
|
+
while (($retry > 0) && ($semanage_err = `semanage port -d -t ldap_port_t -p tcp $port 2>&1`) && ($rc = $?)) {
|
1470
|
+
if (($semanage_err =~ /defined in policy, cannot be deleted/) || ($semanage_err =~ /is not defined/)) {
|
1471
|
+
$retry = -1;
|
1472
|
+
} else {
|
1473
|
+
debug(1, "Warning: Port $port not removed from selinux policy correctly, $retry attempts remain. Error: $semanage_err\n");
|
1474
|
+
debug(1, "Retrying in 5 seconds\n");
|
1475
|
+
sleep(5);
|
1476
|
+
$retry--;
|
1477
|
+
}
|
1478
|
+
}
|
1479
|
+
if (0 == $retry) {
|
1480
|
+
push @errs, [ 'error_removing_port_label', $port, $semanage_err];
|
1481
|
+
debug(1, "Warning: Port $port not removed from selinux policy correctly. Error: $semanage_err\n");
|
1482
|
+
debug(1, "Reached time limit.\n");
|
1483
|
+
}
|
1484
|
+
}
|
1485
|
+
}
|
1486
|
+
|
1487
|
+
foreach my $secureport (@{$entry->{"nsslapd-secureport"}})
|
1488
|
+
{
|
1489
|
+
my $need_remove_label = 0;
|
1490
|
+
my $port_query_cmd = ("/usr/sbin/ds_selinux_port_query $secureport ldap_port_t 2> $mydevnull");
|
1491
|
+
my $result = system($port_query_cmd);
|
1492
|
+
|
1493
|
+
if ($result == 256) {
|
1494
|
+
debug(1, "Port $secureport may be removed as ldap_port_t \n");
|
1495
|
+
$need_remove_label = 1;
|
1496
|
+
}
|
1497
|
+
if ($result == 131072) {
|
1498
|
+
$need_remove_label = 0;
|
1499
|
+
debug(0, "An error occured running ds_selinux_port_query. This is probably a bug\n");
|
1500
|
+
debug(0, "$port_query_cmd \n");
|
1501
|
+
}
|
1502
|
+
my $semanage_err;
|
1503
|
+
my $rc;
|
1504
|
+
my $retry = 60;
|
1505
|
+
$ENV{LANG} = "C";
|
1506
|
+
if ($need_remove_label) {
|
1507
|
+
while (($retry > 0) && ($semanage_err = `semanage port -d -t ldap_port_t -p tcp $secureport 2>&1`) && ($rc = $?)) {
|
1508
|
+
if (($semanage_err =~ /defined in policy, cannot be deleted/) || ($semanage_err =~ /is not defined/)) {
|
1509
|
+
$retry = -1;
|
1510
|
+
} else {
|
1511
|
+
debug(1, "Warning: Port $secureport not removed from selinux policy correctly. Error: $semanage_err\n");
|
1512
|
+
debug(1, "Retrying in 5 seconds\n");
|
1513
|
+
sleep(5);
|
1514
|
+
$retry--;
|
1515
|
+
}
|
1516
|
+
}
|
1517
|
+
if (0 == $retry) {
|
1518
|
+
push @errs, [ 'error_removing_port_label', $secureport, $semanage_err];
|
1519
|
+
debug(1, "Warning: Port $secureport not removed from selinux policy correctly. Error: $semanage_err\n");
|
1520
|
+
debug(1, "Reached time limit.\n");
|
1521
|
+
}
|
1522
|
+
}
|
1523
|
+
}
|
1524
|
+
}
|
1525
|
+
|
1526
|
+
# update systemd files
|
1527
|
+
push @errs, updateSystemD(0);
|
1528
|
+
|
1529
|
+
# if we got here, report success
|
1530
|
+
if (@errs) {
|
1531
|
+
debug(1, "Could not successfully remove $instname\n");
|
1532
|
+
} else {
|
1533
|
+
if (!<$pkglockdir/*>){
|
1534
|
+
# If this was the last instance, remove /var/lock/dirsrv & /var/run/dirsrv
|
1535
|
+
rmdir $pkglockdir;
|
1536
|
+
rmdir $pkgrundir;
|
1537
|
+
}
|
1538
|
+
debug(1, "Instance $instname removed.\n");
|
1539
|
+
}
|
1540
|
+
|
1541
|
+
return @errs;
|
1542
|
+
}
|
1543
|
+
|
1544
|
+
1;
|
1545
|
+
|
1546
|
+
# emacs settings
|
1547
|
+
# Local Variables:
|
1548
|
+
# mode:perl
|
1549
|
+
# indent-tabs-mode: nil
|
1550
|
+
# tab-width: 4
|
1551
|
+
# End:
|