/usr/share/dirsrv/updates/60upgradeschemafiles.pl is in 389-ds-base 1.3.2.16-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | use Mozilla::LDAP::LDIF;
use DSCreate qw(installSchema);
sub runinst {
my ($inf, $inst, $dseldif, $conn) = @_;
if (!$inf->{slapd}->{schema_dir} or (! -d $inf->{slapd}->{schema_dir})) {
return ('error_reading_schema_dir', $inf->{slapd}->{schema_dir});
}
# these schema files are obsolete, or we want to replace
# them with newer versions
my @toremove = qw(00core.ldif 01core389.ldif 01common.ldif 02common.ldif 05rfc2247.ldif 05rfc4523.ldif 05rfc4524.ldif 06inetorgperson.ldif 10presence.ldif 28pilot.ldif 30ns-common.ldif 50ns-directory.ldif 60mozilla.ldif 60pam-plugin.ldif 60sudo.ldif 60rfc3712.ldif);
# these hashes will be used to check for obsolete schema
# in 99user.ldif
my %attrsbyname;
my %attrsbyoid;
my %objclassesbyname;
my %objclassesbyoid;
my $userschemaentry;
# make a backup directory to store the deleted schema, then
# don't really delete it, just move it to that directory
my $mode = (stat($inf->{slapd}->{schema_dir}))[2];
my $bakdir = $inf->{slapd}->{schema_dir} . ".bak";
if (! -d $bakdir) {
$! = 0; # clear
mkdir $bakdir, $mode;
if ($!) {
return ('error_creating_directory', $bakdir, $!);
}
}
my @errs;
for my $file (@toremove) {
my $oldname = $inf->{slapd}->{schema_dir} . "/" . $file;
next if (! -f $oldname); # does not exist - skip - already (re)moved
my $newname = "$bakdir/$file";
$! = 0; # clear
rename $oldname, $newname;
if ($!) {
push @errs, ["error_renaming_schema", $oldname, $newname, $!];
}
}
# Remove obsolete schema from 99user.ldif. Compare by name and OID.
if (!open( OLDUSERSCHEMA, $inf->{slapd}->{schema_dir} . "/99user.ldif")) {
push @errs, ["error_reading_schema_file", $inf->{slapd}->{schema_dir} . "/99user.ldif", $!];
} else {
my $olduserschema = new Mozilla::LDAP::LDIF(*OLDUSERSCHEMA);
# Find the cn=schema entry.
while ($userschemaentry = readOneEntry $olduserschema) {
my $dn = $userschemaentry->getDN();
# The only entry should be cn=schema, but best to play it safe.
next if ($dn ne "cn=schema");
# create the attributeTypes hashes (name->value, oid->value)
my @attrtypes = $userschemaentry->getValues("attributeTypes");
foreach my $attrtype (@attrtypes) {
# parse out the attribute name and oid
if ($attrtype =~ /^\(\s*([\d\.]+)\s+NAME\s+'(\w+)'/) {
# normalize the attribute name
$attrsbyname{lc "$2"} = "$attrtype";
$attrsbyoid{"$1"} = "$attrtype";
}
}
# create the objectClasses hashes (name->value, oid->value)
my @objclasses = $userschemaentry->getValues("objectClasses");
foreach my $objclass (@objclasses) {
# parse out the objectclass name and oid
if ($objclass =~ /^\(\s*([\d\.]+)\s+NAME\s+'(\w+)'/) {
# normalize the objectclass name
$objclassesbyname{lc "$2"} = "$objclass";
$objclassesbyoid{"$1"} = "$objclass";
}
}
# We found the cn=schema entry, so there's no need
# to look for more entries.
last;
}
close OLDUSERSCHEMA;
}
for my $file (@toremove) {
my $fullname = "$bakdir/$file";
next if (! -f $fullname); # does not exist - skip - already (re)moved
if (!open( OBSOLETESCHEMA, "$fullname")) {
push @errs, ["error_reading_schema_file", $fullname, $!];
} else {
my $obsoleteschema = new Mozilla::LDAP::LDIF(*OBSOLETESCHEMA);
# Find the cn=schema entry.
while (my $entry = readOneEntry $obsoleteschema) {
my $dn = $entry->getDN();
# The only entry should be cn=schema, but best to play it safe.
next if ($dn ne "cn=schema");
# Check if any of the attributeTypes in this file
# are defined in 99user.ldif and remove them if so.
my @attrtypes = $entry->getValues("attributeTypes");
foreach $attrtype (@attrtypes) {
# parse out the attribute name and oid
if ($attrtype =~ /^\(\s*([\d\.]+)\s+NAME\s+'(\w+)'/) {
# normalize the attribute name
if ($attrsbyname{lc "$2"}) {
$userschemaentry->removeValue("attributeTypes", $attrsbyname{lc "$2"});
} elsif ($attrsbyoid{"$1"}) {
$userschemaentry->removeValue("attributeTypes", $attrsbyoid{"$1"});
}
}
}
# Check if any of the objectClasses in this file
# are defined in 99user.ldif and remove them if so.
my @objclasses = $entry->getValues("objectClasses");
foreach $objclass (@objclasses) {
# parse out the objectclass name and oid
if ($objclass =~ /^\(\s*([\d\.]+)\s+NAME\s+'(\w+)'/) {
# normalize the objectclass name
if ($objclassesbyname{lc "$2"}) {
$userschemaentry->removeValue("objectClasses", $objclassesbyname{lc "$2"});
} elsif ($objclassesbyoid{"$1"}) {
$userschemaentry->removeValue("objectClasses", $objclassesbyoid{"$1"});
}
}
}
}
close OBSOLETESCHEMA;
}
}
# Backup the original 99user.ldif
$! = 0; # clear
rename $inf->{slapd}->{schema_dir} . "/99user.ldif", "$bakdir/99user.ldif";
if ($!) {
push @errs, ["error_renaming_schema", $inf->{slapd}->{schema_dir} . "/99user.ldif", "$bakdir/99user.ldif", $!];
}
# Write the new 99user.ldif
if (!open ( NEWUSERSCHEMA, ">" . $inf->{slapd}->{schema_dir} . "/99user.ldif")) {
push @errs, ["error_writing_schema_file", $inf->{slapd}->{schema_dir} . "/99user.ldif", $!];
} else {
my $newuserschema = new Mozilla::LDAP::LDIF(*NEWUSERSCHEMA);
writeOneEntry $newuserschema $userschemaentry;
close NEWUSERSCHEMA;
# Set permissions based off of the original 99user.ldif.
my @stat = stat("$bakdir/99user.ldif");
my $mode = $stat[2];
my $uid = $stat[4];
my $gid = $stat[5];
chmod $mode, $inf->{slapd}->{schema_dir} . "/99user.ldif";
chown $uid, $gid, $inf->{slapd}->{schema_dir} . "/99user.ldif";
}
# If we've encountered any errors up to this point, restore
# the original schema.
if (@errs) {
# restore the original schema files
for my $file (@toremove) {
my $oldname = "$bakdir/$file";
next if (! -f $oldname); # does not exist - not backed up
my $newname = $inf->{slapd}->{schema_dir} . "/" . $file;
next if (-f $newname); # not removed
rename $oldname, $newname;
}
# Restore 99user.ldif. We overwrite whatever is there since
# it is possible that we have modified it.
if (-f "$bakdir/99user.ldif") {
rename "$bakdir/99user.ldif", $inf->{slapd}->{schema_dir} . "/99user.ldif";
}
return @errs;
}
# after removing them, just add everything in the default
# schema directory
return installSchema($inf, 1);
}
|