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.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/Berksfile +2 -3
  3. data/Berksfile.lock +11 -14
  4. data/bin/mu-aws-setup +16 -4
  5. data/bin/mu-configure +2 -1
  6. data/cloud-mu.gemspec +2 -2
  7. data/cookbooks/mu-firewall/Berksfile +1 -1
  8. data/cookbooks/mu-firewall/attributes/default.rb +2 -2
  9. data/cookbooks/mu-firewall/metadata.rb +3 -3
  10. data/cookbooks/mu-firewall/recipes/default.rb +11 -2
  11. data/cookbooks/mu-master/Berksfile +1 -1
  12. data/cookbooks/mu-master/attributes/default.rb +14 -1
  13. data/cookbooks/mu-master/files/default/389ds-perl/ASDialogs.pm +173 -0
  14. data/cookbooks/mu-master/files/default/389ds-perl/AdminMigration.pm +569 -0
  15. data/cookbooks/mu-master/files/default/389ds-perl/AdminServer.pm +952 -0
  16. data/cookbooks/mu-master/files/default/389ds-perl/AdminUtil.pm +983 -0
  17. data/cookbooks/mu-master/files/default/389ds-perl/ConfigDSDialogs.pm +449 -0
  18. data/cookbooks/mu-master/files/default/389ds-perl/DSCreate.pm +1551 -0
  19. data/cookbooks/mu-master/files/default/389ds-perl/DSDialogs.pm +233 -0
  20. data/cookbooks/mu-master/files/default/389ds-perl/DSMigration.pm +1175 -0
  21. data/cookbooks/mu-master/files/default/389ds-perl/DSUpdate.pm +534 -0
  22. data/cookbooks/mu-master/files/default/389ds-perl/DSUpdateDialogs.pm +152 -0
  23. data/cookbooks/mu-master/files/default/389ds-perl/DSUtil.pm +1710 -0
  24. data/cookbooks/mu-master/files/default/389ds-perl/Dialog.pm +249 -0
  25. data/cookbooks/mu-master/files/default/389ds-perl/DialogManager.pm +212 -0
  26. data/cookbooks/mu-master/files/default/389ds-perl/FileConn.pm +461 -0
  27. data/cookbooks/mu-master/files/default/389ds-perl/Inf.pm +268 -0
  28. data/cookbooks/mu-master/files/default/389ds-perl/Migration.pm +327 -0
  29. data/cookbooks/mu-master/files/default/389ds-perl/RegDSDialogs.pm +94 -0
  30. data/cookbooks/mu-master/files/default/389ds-perl/Resource.pm +137 -0
  31. data/cookbooks/mu-master/files/default/389ds-perl/Setup.pm +240 -0
  32. data/cookbooks/mu-master/files/default/389ds-perl/SetupDialogs.pm +243 -0
  33. data/cookbooks/mu-master/files/default/389ds-perl/SetupLog.pm +82 -0
  34. data/cookbooks/mu-master/files/default/setCertName.ldif +4 -0
  35. data/cookbooks/mu-master/libraries/mu.rb +2 -2
  36. data/cookbooks/mu-master/metadata.rb +1 -1
  37. data/cookbooks/mu-master/recipes/389ds.rb +71 -32
  38. data/cookbooks/mu-master/recipes/basepackages.rb +5 -0
  39. data/cookbooks/mu-master/recipes/default.rb +16 -5
  40. data/cookbooks/mu-master/recipes/init.rb +36 -3
  41. data/cookbooks/mu-master/recipes/ssl-certs.rb +6 -0
  42. data/cookbooks/mu-master/recipes/sssd.rb +85 -62
  43. data/cookbooks/mu-master/recipes/update_nagios_only.rb +7 -1
  44. data/cookbooks/mu-master/templates/default/389-directory-setup.inf.erb +11 -26
  45. data/cookbooks/mu-master/templates/default/sssd.conf.erb +18 -8
  46. data/cookbooks/mu-tools/files/default/Mu_CA.pem +33 -0
  47. data/cookbooks/mu-tools/metadata.rb +0 -1
  48. data/cookbooks/mu-tools/recipes/set_local_fw.rb +7 -1
  49. data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +5 -1
  50. data/cookbooks/nagios/CHANGELOG.md +679 -0
  51. data/cookbooks/nagios/LICENSE +201 -0
  52. data/cookbooks/nagios/README.md +340 -0
  53. data/cookbooks/nagios/attributes/config.rb +163 -0
  54. data/cookbooks/nagios/attributes/default.rb +204 -0
  55. data/cookbooks/nagios/libraries/base.rb +311 -0
  56. data/cookbooks/nagios/libraries/command.rb +68 -0
  57. data/cookbooks/nagios/libraries/contact.rb +229 -0
  58. data/cookbooks/nagios/libraries/contactgroup.rb +111 -0
  59. data/cookbooks/{firewall/recipes/disable_firewall.rb → nagios/libraries/custom_option.rb} +20 -7
  60. data/cookbooks/nagios/libraries/data_bag_helper.rb +23 -0
  61. data/cookbooks/nagios/libraries/default.rb +90 -0
  62. data/cookbooks/nagios/libraries/helpers.rb +229 -0
  63. data/cookbooks/nagios/libraries/host.rb +410 -0
  64. data/cookbooks/nagios/libraries/hostdependency.rb +178 -0
  65. data/cookbooks/nagios/libraries/hostescalation.rb +170 -0
  66. data/cookbooks/nagios/libraries/hostgroup.rb +117 -0
  67. data/cookbooks/nagios/libraries/nagios.rb +277 -0
  68. data/cookbooks/nagios/libraries/resource.rb +59 -0
  69. data/cookbooks/nagios/libraries/service.rb +449 -0
  70. data/cookbooks/nagios/libraries/servicedependency.rb +213 -0
  71. data/cookbooks/nagios/libraries/serviceescalation.rb +193 -0
  72. data/cookbooks/nagios/libraries/servicegroup.rb +142 -0
  73. data/cookbooks/nagios/libraries/timeperiod.rb +159 -0
  74. data/cookbooks/nagios/libraries/users_helper.rb +54 -0
  75. data/cookbooks/nagios/metadata.json +44 -0
  76. data/cookbooks/nagios/metadata.rb +22 -0
  77. data/cookbooks/nagios/recipes/_load_databag_config.rb +153 -0
  78. data/cookbooks/nagios/recipes/_load_default_config.rb +241 -0
  79. data/cookbooks/nagios/recipes/apache.rb +114 -0
  80. data/cookbooks/nagios/recipes/default.rb +41 -0
  81. data/cookbooks/nagios/recipes/nginx.rb +114 -0
  82. data/cookbooks/nagios/recipes/pagerduty.rb +95 -0
  83. data/cookbooks/nagios/recipes/server.rb +182 -0
  84. data/cookbooks/nagios/recipes/server_package.rb +85 -0
  85. data/cookbooks/nagios/recipes/server_source.rb +137 -0
  86. data/cookbooks/nagios/resources/command.rb +34 -0
  87. data/cookbooks/nagios/resources/conf.rb +52 -0
  88. data/cookbooks/nagios/resources/contact.rb +34 -0
  89. data/cookbooks/nagios/resources/contactgroup.rb +35 -0
  90. data/cookbooks/nagios/resources/host.rb +35 -0
  91. data/cookbooks/nagios/resources/hostdependency.rb +35 -0
  92. data/cookbooks/nagios/resources/hostescalation.rb +36 -0
  93. data/cookbooks/nagios/resources/hostgroup.rb +35 -0
  94. data/cookbooks/nagios/resources/resource.rb +34 -0
  95. data/cookbooks/nagios/resources/service.rb +35 -0
  96. data/cookbooks/nagios/resources/servicedependency.rb +35 -0
  97. data/cookbooks/nagios/resources/serviceescalation.rb +35 -0
  98. data/cookbooks/nagios/resources/servicegroup.rb +35 -0
  99. data/cookbooks/nagios/resources/timeperiod.rb +35 -0
  100. data/cookbooks/nagios/templates/apache2.conf.erb +102 -0
  101. data/cookbooks/nagios/templates/cgi.cfg.erb +266 -0
  102. data/cookbooks/nagios/templates/commands.cfg.erb +13 -0
  103. data/cookbooks/nagios/templates/contacts.cfg.erb +37 -0
  104. data/cookbooks/nagios/templates/hostgroups.cfg.erb +25 -0
  105. data/cookbooks/nagios/templates/hosts.cfg.erb +15 -0
  106. data/cookbooks/nagios/templates/htpasswd.users.erb +6 -0
  107. data/cookbooks/nagios/templates/nagios.cfg.erb +22 -0
  108. data/cookbooks/nagios/templates/nginx.conf.erb +80 -0
  109. data/cookbooks/nagios/templates/pagerduty.cgi.erb +185 -0
  110. data/cookbooks/nagios/templates/resource.cfg.erb +27 -0
  111. data/cookbooks/nagios/templates/servicedependencies.cfg.erb +15 -0
  112. data/cookbooks/nagios/templates/servicegroups.cfg.erb +14 -0
  113. data/cookbooks/nagios/templates/services.cfg.erb +14 -0
  114. data/cookbooks/nagios/templates/spawn-fcgi.erb +10 -0
  115. data/cookbooks/nagios/templates/templates.cfg.erb +31 -0
  116. data/cookbooks/nagios/templates/timeperiods.cfg.erb +13 -0
  117. data/extras/platform_berksfile_base +3 -3
  118. data/extras/python_rpm/build.sh +4 -4
  119. data/extras/python_rpm/muthon.spec +2 -4
  120. data/extras/vault_tools/export_vaults.sh +11 -1
  121. data/install/installer +1 -1
  122. data/modules/mu/kittens.rb +27523 -0
  123. data/modules/mu/master/ldap.rb +48 -31
  124. data/modules/mu/master.rb +69 -0
  125. data/modules/mu/mu.yaml.rb +351 -0
  126. data/modules/mu/providers/aws/firewall_rule.rb +3 -1
  127. data/modules/mu/providers/aws.rb +11 -5
  128. data/modules/mu.rb +5 -4
  129. metadata +99 -48
  130. data/cookbooks/firewall/CHANGELOG.md +0 -488
  131. data/cookbooks/firewall/LICENSE +0 -202
  132. data/cookbooks/firewall/README.md +0 -366
  133. data/cookbooks/firewall/TODO.md +0 -6
  134. data/cookbooks/firewall/attributes/default.rb +0 -5
  135. data/cookbooks/firewall/attributes/firewalld.rb +0 -8
  136. data/cookbooks/firewall/attributes/iptables.rb +0 -17
  137. data/cookbooks/firewall/attributes/ufw.rb +0 -12
  138. data/cookbooks/firewall/attributes/windows.rb +0 -8
  139. data/cookbooks/firewall/libraries/helpers.rb +0 -105
  140. data/cookbooks/firewall/libraries/helpers_firewalld.rb +0 -116
  141. data/cookbooks/firewall/libraries/helpers_firewalld_dbus.rb +0 -72
  142. data/cookbooks/firewall/libraries/helpers_iptables.rb +0 -112
  143. data/cookbooks/firewall/libraries/helpers_nftables.rb +0 -170
  144. data/cookbooks/firewall/libraries/helpers_ufw.rb +0 -142
  145. data/cookbooks/firewall/libraries/helpers_windows.rb +0 -129
  146. data/cookbooks/firewall/libraries/provider_firewall_firewalld.rb +0 -179
  147. data/cookbooks/firewall/libraries/provider_firewall_iptables.rb +0 -171
  148. data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb +0 -200
  149. data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb +0 -200
  150. data/cookbooks/firewall/libraries/provider_firewall_rule.rb +0 -34
  151. data/cookbooks/firewall/libraries/provider_firewall_ufw.rb +0 -138
  152. data/cookbooks/firewall/libraries/provider_firewall_windows.rb +0 -126
  153. data/cookbooks/firewall/libraries/resource_firewall.rb +0 -26
  154. data/cookbooks/firewall/libraries/resource_firewall_rule.rb +0 -52
  155. data/cookbooks/firewall/metadata.json +0 -40
  156. data/cookbooks/firewall/metadata.rb +0 -15
  157. data/cookbooks/firewall/recipes/default.rb +0 -76
  158. data/cookbooks/firewall/recipes/firewalld.rb +0 -87
  159. data/cookbooks/firewall/resources/firewalld.rb +0 -28
  160. data/cookbooks/firewall/resources/firewalld_config.rb +0 -39
  161. data/cookbooks/firewall/resources/firewalld_helpers.rb +0 -106
  162. data/cookbooks/firewall/resources/firewalld_icmptype.rb +0 -88
  163. data/cookbooks/firewall/resources/firewalld_ipset.rb +0 -104
  164. data/cookbooks/firewall/resources/firewalld_policy.rb +0 -115
  165. data/cookbooks/firewall/resources/firewalld_service.rb +0 -98
  166. data/cookbooks/firewall/resources/firewalld_zone.rb +0 -118
  167. data/cookbooks/firewall/resources/nftables.rb +0 -71
  168. data/cookbooks/firewall/resources/nftables_rule.rb +0 -113
  169. data/cookbooks/firewall/templates/default/ufw/default.erb +0 -13
  170. /data/cookbooks/{firewall → nagios}/chefignore +0 -0
  171. /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: