initial commit of file from CVS for e-smith-ldap on Wed 12 Jul 08:58:23 BST 2023

This commit is contained in:
Brian Read
2023-07-12 08:58:23 +01:00
parent a24f2abb0c
commit ae371ebfe0
84 changed files with 3651 additions and 2 deletions

View File

@@ -0,0 +1 @@
enabled

View File

@@ -0,0 +1 @@
service

View File

@@ -0,0 +1 @@
disabled

View File

@@ -0,0 +1 @@
389,636

View File

@@ -0,0 +1 @@
private

View File

@@ -0,0 +1 @@
Ottawa

View File

@@ -0,0 +1 @@
XYZ Corporation

View File

@@ -0,0 +1 @@
Main

View File

@@ -0,0 +1 @@
555-5555

View File

@@ -0,0 +1 @@
123 Main Street

View File

@@ -0,0 +1 @@
enabled

View File

@@ -0,0 +1 @@
service

View File

@@ -0,0 +1 @@
enabled

View File

@@ -0,0 +1,3 @@
{
-f "/etc/openldap/ldap.pw" || esmith::util::genLdapPassword();
}

View File

@@ -0,0 +1,7 @@
{
#this has been replaced by TLSProtocolMin with new default
$DB->get_prop_and_delete('ldap', 'SSLv3');
}

View File

@@ -0,0 +1,20 @@
#!/bin/bash -e
ldapauth=$(/sbin/e-smith/config getprop ldap Authentication || echo disabled)
# Exit unless ldap auth is enabled
[ "$ldapauth" == "enabled" ] || exit 0
# Users and group accounts are now stored in LDAP, so we need to delete them
# from the old passwd / group / shadow database
for USER in $(/usr/bin/getent passwd | sort | cut -d':' -f1 | uniq -d); do
/usr/sbin/luserdel -G $USER
done
for GROUP in $(/usr/bin/getent group | sort | cut -d':' -f1 | uniq -d); do
/usr/sbin/lgroupdel $GROUP
done
# And add the admin back in the root group, which is not in the LDAP database
/usr/bin/gpasswd -a admin root

View File

@@ -0,0 +1,61 @@
#!/usr/bin/perl -w
#----------------------------------------------------------------------
# copyright (C) 2002 Mitel Networks Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Technical support for this program is available from Mitel Networks
# Please visit our web site www.mitel.com/sme/ for details.
#----------------------------------------------------------------------
package esmith;
use strict;
use Errno;
use esmith::ConfigDB;
use esmith::util;
# Stop now if slapd.conf has syntax error
unless (system("/usr/sbin/slaptest -u 2>/dev/null") == 0){
die "Aborting ldap dump because of errors in slapd.conf\n";
}
my $c = esmith::ConfigDB->open_ro;
my $domain = $c->get('DomainName')
|| die("Couldn't determine domain name");
$domain = $domain->value;
# First try to run slapcat, which may fail if slapd is running
exit 0 unless
system("/usr/sbin/slapcat", "-l", "/home/e-smith/db/ldap/$domain.ldif");
# and failing that, restart ldap, which will generate a dump file
# in the process
my $l = $c->get('ldap');
my $status = $l->prop('status') || "disabled";
die "Couldn't run slapcat, and ldap is disabled. Won't restart." .
"No LDIF dump produced\n"
unless ($status eq "enabled" );
esmith::util::serviceControl
(
NAME => 'ldap',
ACTION => 'restart',
BACKGROUND => 'false',
) ||
die "Couldn't restart ldap";
exit (0);

View File

@@ -0,0 +1,132 @@
#!/usr/bin/perl -w
#----------------------------------------------------------------------
# copyright (C) 1999-2005 Mitel Networks Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#----------------------------------------------------------------------
package esmith;
use strict;
use Errno;
use esmith::ConfigDB;
use esmith::util;
use Net::LDAP;
my $db = esmith::ConfigDB->open_ro or die "Could not open config db";
exit(0) if ($db->get('ldap')->prop('Authentication') || 'disabled') eq 'enabled';
unless ($db->get('ldap')->prop('status') eq "enabled" )
{
warn "Not running action script $0, LDAP service not enabled!\n";
exit(0);
}
my $event = $ARGV [0];
my $name = $ARGV [1];
die "Username argument missing." unless defined ($name);
#------------------------------------------------------------
# Delete user from LDAP directory. First read LDAP password
#------------------------------------------------------------
my $pw = esmith::util::LdapPassword();
my $base = esmith::util::ldapBase ($db->get('DomainName')->value);
#------------------------------------------------------------
# Delete LDAP entry.
#------------------------------------------------------------
my $ldap = Net::LDAP->new('localhost')
or die "$@";
$ldap->bind(
dn => "cn=root,$base",
password => $pw
);
my $mesg;
# Delete any user object with this name
$mesg = $ldap->search( base=> "uid=$name,ou=Users,$base", filter => '(ObjectClass=*)', scope => 'base' );
if ($mesg->code && $mesg->code != 32)
{
warn "Failed ldap search uid=$name,ou=Users,$base: ", $mesg->error;
}
else
{
$ldap->delete($mesg->entry(0));
}
# Delete any computer object with this name
$mesg = $ldap->search( base=> "uid=$name,ou=Computers,$base", filter => '(ObjectClass=*)', scope => 'base' );
if ($mesg->code && $mesg->code != 32)
{
warn "Failed ldap search uid=$name,ou=Computers,$base: ", $mesg->error;
}
else
{
$ldap->delete($mesg->entry(0));
}
# Delete any (old) user/computer object with this name
$mesg = $ldap->search( base=> "uid=$name,$base", filter => '(ObjectClass=*)', scope => 'base' );
if ($mesg->code && $mesg->code != 32)
{
warn "Failed ldap search uid=$name,$base: ", $mesg->error;
}
else
{
$ldap->delete($mesg->entry(0));
}
# Delete any group object with this name
$mesg = $ldap->search( base=> "cn=$name,ou=Groups,$base", filter => '(ObjectClass=*)', scope => 'base' );
if ($mesg->code && $mesg->code != 32)
{
warn "Failed ldap search cn=$name,ou=Groups,$base: ", $mesg->error;
}
else
{
$ldap->delete($mesg->entry(0));
}
# Delete any (old) group object with this name
$mesg = $ldap->search( base=> "cn=$name,$base", filter => '(ObjectClass=*)', scope => 'base' );
if ($mesg->code && $mesg->code != 32)
{
warn "Failed ldap search cn=$name,$base: ", $mesg->error;
}
else
{
$ldap->delete($mesg->entry(0));
}
# Remove group membership for the account we are deleting
$mesg = $ldap->search( base=> "ou=Groups,$base", filter => "(memberUid=$name)", scope => 'one' );
if ($mesg->code && $mesg->code != 32)
{
warn "Failed ldap search memberUid=$name,ou=Groups,$base: ", $mesg->error;
}
else
{
$ldap->delete($_, 'memberUid' => [ $name ] ) foreach $mesg->entries();
}
$ldap->unbind;
exit (0);

View File

@@ -0,0 +1,63 @@
#!/usr/bin/perl -w
#----------------------------------------------------------------------
# copyright (C) 2002 Mitel Networks Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Technical support for this program is available from Mitel Networks
# Please visit our web site www.mitel.com/sme/ for details.
#----------------------------------------------------------------------
package esmith;
use strict;
use Errno;
use esmith::ConfigDB;
use esmith::util;
my $conf = esmith::ConfigDB->open;
my $domain = $conf->get('DomainName')
|| die("Couldn't determine domain name");
$domain = $domain->value;
my $ldap = $conf->get('ldap');
if($ldap and $ldap->prop('status') eq 'enabled')
{
esmith::util::serviceControl(
NAME => 'ldap',
ACTION => 'stop',
BACKGROUND => 'false')
or die "Unable to stop ldap\n";
}
my $file = "/home/e-smith/db/ldap/$domain.ldif";
if(-e $file)
{
unlink($file) or die "Unable to unlink $file: $!\n";
}
my $ldapdir = "/var/lib/ldap";
opendir DIR, $ldapdir;
foreach my $file (grep(!/^\./, readdir DIR))
{
if(-f "$ldapdir/$file")
{
unlink("$ldapdir/$file")
or warn "Unable to unlink $ldapdir/$file: $!\n";
}
}
closedir DIR;

View File

@@ -0,0 +1,63 @@
#!/usr/bin/perl -w
#----------------------------------------------------------------------
# copyright (C) 2002 Mitel Networks Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Technical support for this program is available from Mitel Networks
# Please visit our web site www.mitel.com/sme/ for details.
#----------------------------------------------------------------------
package esmith;
use strict;
use Errno;
use esmith::ConfigDB;
# Stop now if slapd.conf has syntax error
unless (system("/usr/sbin/slaptest -u 2>/dev/null") == 0){
die "Aborting ldap dump because of errors in slapd.conf\n";
}
my $domain = esmith::ConfigDB->open->get('DomainName')
|| die("Couldn't determine domain name");
$domain = $domain->value;
my $ldapconf = '/etc/openldap/ldap.conf';
open(LDCONF, "<$ldapconf") or die "Can't open $ldapconf: $!\n";
my @basedn = grep { /^BASE/ } <LDCONF>;
close(LDCONF);
# It should look something like this
# BASE dc=sme1,dc=nssg,dc=mitel,dc=com
unless (@basedn)
{
die "Failed to find the basedn in $ldapconf\n";
}
chomp( my $basedn = $basedn[0] );
$basedn =~ s/^BASE //;
$basedn =~ s/dc=//g;
$basedn =~ s/,/./g;
# If the basedn is not equal to the domain, remove any ldif file stored under
# the new domain, so it starts from scratch.
if ($basedn ne $domain)
{
my $backup = "/home/e-smith/db/ldap/$domain.ldif";
unlink $backup if -e $backup;
}
$domain = $basedn;
exec("/usr/sbin/slapcat", "-l", "/home/e-smith/db/ldap/$domain.ldif");
exit 1;

View File

@@ -0,0 +1,25 @@
#!/bin/bash
#----------------------------------------------------------------------
# copyright (C) 1999, 2000 e-smith, inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Technical support for this program is available from e-smith, inc.
# For details, please visit our web site at www.e-smith.com or
# call us on 1 888 ESMITH 1 (US/Canada toll free) or +1 613 564 8000
#----------------------------------------------------------------------
/sbin/e-smith/ldif-fix --update

View File

@@ -0,0 +1,248 @@
#!/usr/bin/perl -w
package esmith;
use strict;
use Errno;
use esmith::ConfigDB;
use esmith::AccountsDB;
use esmith::util;
use Net::LDAP;
use Date::Parse;
$ENV{'LANG'} = 'C';
$ENV{'TZ'} = '';
my $c = esmith::ConfigDB->open_ro;
my $a = esmith::AccountsDB->open_ro;
my $l = $c->get('ldap');
my $status = $l->prop('status') || "disabled";
unless ($status eq "enabled" )
{
warn "Not running action script $0, LDAP service not enabled!\n";
exit(0);
}
exit(0) if ($c->get('ldap')->prop('Authentication') || 'disabled') eq 'enabled';
my $domain = $c->get('DomainName')
|| die("Couldn't determine domain name");
$domain = $domain->value;
my $schema = '/etc/openldap/schema/samba.schema';
my $event = shift || die "Event name must be specified";
my @name = @ARGV;
die "Account name argument missing." unless scalar (@name) >= 1;
#------------------------------------------------------------
# Update LDAP database entry.
#------------------------------------------------------------
my $base = esmith::util::ldapBase ($domain);
my $pw = esmith::util::LdapPassword();
my $ldap = Net::LDAP->new('localhost')
or die "$@";
$ldap->bind(
dn => "cn=root,$base",
password => $pw
);
my @accounts;
my $account;
foreach my $name (@name)
{
$account = $a->get($name);
die "Account $name not found.\n" unless defined $account;
my $type = $account->prop('type') || "unknown";
die "Account $name is not a user, group, ibay, machine account; update LDAP entry failed.\n"
unless ($type =~ m{^(?:user|group|ibay|machine)$} or $name eq 'admin');
push @accounts, $account;
}
#------------------------------------------------------------
# Read all samba groups (can't do individual lookups)
#------------------------------------------------------------
my $groupmap = ();
# Only do if schema is found
if ( -f "$schema" and -x '/usr/bin/net' )
{
foreach (`/usr/bin/net groupmap list 2> /dev/null`){
chomp;
next if m{\(S-1-5-32-\d+\)};
$groupmap->{$3} = { name => "$1", sid => "$2" } if (/^(.*) \((S-.*-\d+)\) -> (.*)$/);
}
}
#------------------------------------------------------------
# Create a list of updates that need to happen
#------------------------------------------------------------
my $updates;
foreach my $acct (@accounts)
{
my $key = $acct->key;
my $type = $acct->prop('type');
my $desc = undef;
my $dn;
if ($type =~ m{^(?:user|group|ibay|machine)$} or $key eq 'admin')
{
#------------------------------------------------------------
# Do the user portion
#------------------------------------------------------------
if ($type eq 'machine')
{
$dn = "uid=$key,ou=Computers,$base";
}
else
{
$dn = "uid=$key,ou=Users,$base";
}
utf8::upgrade($dn);
# Read information from getent passwd
@{$updates->{$dn}}{'uid','userPassword'} = getpwnam($key);
unless ($updates->{$dn}->{uid})
{
delete $updates->{$dn};
next;
}
$updates->{$dn}->{userPassword} = "!*" if $updates->{$dn}->{userPassword} eq '!!';
$updates->{$dn}->{userPassword} =~ s/^/{CRYPT}/ unless $updates->{$dn}->{userPassword} =~ m/^{/;
# Samba parameters if we find the samba.schema
if ( -f "$schema" and -x '/usr/bin/pdbedit' )
{
my $line = `/usr/bin/pdbedit -wu '$key' 2> /dev/null`;
chomp($line);
if ($line)
{
@{$updates->{$dn}}{'junk','junk','sambaLMPassword','sambaNTPassword'} = split(/:/,$line);
foreach $line (`/usr/bin/pdbedit -vu '$key' 2> /dev/null`)
{
chomp($line);
$updates->{$dn}->{sambaSID} = $1 if $line =~ m{User SID:\s+(S-.*)$};
$updates->{$dn}->{displayName} = $1 if $line =~ m{Full Name:\s+(.*)$};
$updates->{$dn}->{sambaPrimaryGroupSID} = $1 if $line =~ m{Primary Group SID:\s+(S-.*)$};
$updates->{$dn}->{sambaAcctFlags} = $1 if $line =~ m{Account Flags:\s+(.*)$};
$updates->{$dn}->{sambaPwdLastSet} = str2time($1) if $line =~ m{Password last set:\s+(.*)$};
}
push @{$updates->{$dn}->{objectClass}}, 'sambaSamAccount';
}
else
{
$updates->{$dn}->{sambaLMPassword} = [];
$updates->{$dn}->{sambaNTPassword} = [];
$updates->{$dn}->{sambaSID} = [];
$updates->{$dn}->{displayName} = [];
$updates->{$dn}->{sambaPrimaryGroupSID} = [];
$updates->{$dn}->{sambaAcctFlags} = [];
$updates->{$dn}->{sambaPwdLastSet} = [];
}
}
}
}
endpwent();
#------------------------------------------------------------
# Do the group portion (only if we have samba)
#------------------------------------------------------------
if ( -f "$schema" )
{
foreach my $group ( (map { $_->key } $a->users), (map { $_->key } $a->groups), qw/admin nobody shared/ ){
my $dn = "cn=$group,ou=Groups,$base";
utf8::upgrade($dn);
if ( exists $groupmap->{$group} )
{
push @{$updates->{$dn}->{objectClass}}, 'sambaGroupMapping';
$updates->{$dn}->{displayName} = $groupmap->{$group}->{name};
$updates->{$dn}->{sambaSID} = $groupmap->{$group}->{sid};
$updates->{$dn}->{sambaGroupType} = '2';
}
else
{
$updates->{$dn}->{displayName} = [];
$updates->{$dn}->{sambaSID} = [];
$updates->{$dn}->{sambaGroupType} = [];
}
}
}
#------------------------------------------------------------
# Update LDAP database entry.
#------------------------------------------------------------
foreach my $dn (keys %$updates)
{
# Try and find record
my $result = $ldap->search( base => $dn, filter => '(objectClass=*)', scope => 'base' );
warn "failed looking up entry $dn: ", $result->error if $result->code && $result->code != 32;
my $code = $result->code;
my @objectClass = $code == 32 ? () : $result->entry(0)->get_value('objectClass');
# Clean up attributes and convert to utf8
delete $updates->{$dn}->{'junk'};
foreach my $attr ( keys %{$updates->{$dn}} )
{
if ( ref($updates->{$dn}->{$attr}) eq 'ARRAY' )
{
if ( $code == 32 and scalar(@{$updates->{$dn}->{$attr}}) == 0 )
{
delete $updates->{$dn}->{$attr};
}
else
{
for (my $c = 0; $c < scalar(@{$updates->{$dn}->{$attr}}); $c++)
{
utf8::upgrade($updates->{$dn}->{$attr}[$c]);
}
}
}
else
{
if ($updates->{$dn}->{$attr} !~ /^\s*$/)
{
utf8::upgrade($updates->{$dn}->{$attr});
}
elsif ( $code == 32 )
{
delete $updates->{$dn}->{$attr};
}
else
{
$updates->{$dn}->{$attr} = [];
}
}
}
# Perform insert or update
if ( $code == 32 )
{
$result = $ldap->add( $dn, attrs => [ %{$updates->{$dn}} ] );
$result->code && warn "failed to add entry $dn: ", $result->error;
}
else
{
# Don't overwrite objectClass (just update if necessary)
my $seen = ();
# Remove samba objectClasses if removing samba attributes
@{$seen}{'sambaSamAccount','sambaGroupMapping'} = (1,1) if ref($updates->{$dn}->{sambaSID}) eq 'ARRAY';
@{$updates->{$dn}->{objectClass}} = grep { ! $seen->{$_}++ } (@{$updates->{$dn}->{objectClass}}, @objectClass );
$result = $ldap->modify( $dn, replace => $updates->{$dn});
$result->code && warn "failed to modify entry $dn: ", $result->error;
}
}
$ldap->unbind;
exit (0);

View File

@@ -0,0 +1,24 @@
#!/bin/sh
#----------------------------------------------------------------------
# copyright (C) 2010 Firewall-Services
# daniel@firewall-services.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Technical support for this program is available from Mitel Networks
# Please visit our web site www.mitel.com/sme/ for details.
#----------------------------------------------------------------------
/sbin/e-smith/config delprop ldap Bootstrap

View File

@@ -0,0 +1,24 @@
#!/bin/sh
#----------------------------------------------------------------------
# copyright (C) 2010 Firewall-Services
# daniel@firewall-services.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Technical support for this program is available from Mitel Networks
# Please visit our web site www.mitel.com/sme/ for details.
#----------------------------------------------------------------------
/sbin/e-smith/config setprop ldap Bootstrap run

0
root/etc/e-smith/ldap/init/.gitignore vendored Normal file
View File

View File

@@ -0,0 +1,92 @@
<lexicon lang="en-us">
<entry>
<base>FORM_TITLE</base>
<trans>Change LDAP directory settings</trans>
</entry>
<entry>
<base>LABEL_ROOT</base>
<trans>Server root</trans>
</entry>
<entry>
<base>DESCRIPTION</base>
<trans>
The LDAP server provides a network-available listing of the user accounts
and groups on your server, and can be accessed using an LDAP client such as the Address Book feature in Netscape Communicator. Configure your LDAP client with the local IP address of your server, port number 389, and the server root parameter shown below.
</trans>
</entry>
<entry>
<base>DESC_DIRECTORY_ACCESS</base>
<trans> You can control access to your LDAP directory: the private setting allows access only from your local network, and the public setting allows access from anywhere on the Internet. </trans>
</entry>
<entry>
<base>DIRECTORY_ACCESS</base>
<trans>LDAP directory access</trans>
</entry>
<entry>
<base>DESC_DEPARTMENT</base>
<trans>
These fields are the LDAP defaults for your organization.
Whenever you create a new user account, you will be prompted
to enter all of these fields (they can be different for each
user) but the values you set here
will show up as defaults. This is a convenience to make it
faster to create user accounts.
</trans>
</entry>
<entry>
<base>DEPARTMENT</base>
<trans>Default department</trans>
</entry>
<entry>
<base>COMPANY</base>
<trans>Default company</trans>
</entry>
<entry>
<base>STREET</base>
<trans>Default Street address</trans>
</entry>
<entry>
<base>CITY</base>
<trans>Default City</trans>
</entry>
<entry>
<base>PHONENUMBER</base>
<trans>Default Phone Number</trans>
</entry>
<entry>
<base>DESC_EXISTING</base>
<trans>
You can either leave existing user accounts as they are, using the above defaults only for
new users, or you can apply the above defaults to all existing users as well.
</trans>
</entry>
<entry>
<base>EXISTING</base>
<trans>Existing users</trans>
</entry>
<entry>
<base>SUCCESS</base>
<trans>The new LDAP default settings have been saved.</trans>
</entry>
<entry>
<base>LEAVE</base>
<trans>Leave as they are</trans>
</entry>
<entry>
<base>UPDATE</base>
<trans>Update with new defaults</trans>
</entry>
<entry>
<base>Directory</base>
<trans>Directory</trans>
</entry>
</lexicon>

View File

@@ -0,0 +1,2 @@
GID="ldap"
PERMS=0640

View File

@@ -0,0 +1,4 @@
TEMPLATE_PATH="/home/e-smith/ssl.pem"
OUTPUT_FILENAME="/etc/openldap/ssl/slapd.pem"
GID="ldap"
PERMS=0640

View File

@@ -0,0 +1,2 @@
TEMPLATE_PATH="/home/e-smith/db/ldap/ldif"
OUTPUT_FILENAME=use esmith::ConfigDB; my $d = esmith::ConfigDB->open_ro->get('DomainName')->value; "/home/e-smith/db/ldap/$d.ldif"

View File

@@ -0,0 +1,3 @@
{
"# LDAP servers\n" . $DB->hosts_allow_spec('ldap', 'slapd')
}

View File

@@ -0,0 +1,20 @@
#
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable.
#BASE dc=OpenLDAP, dc=Org
#HOST ldap.openldap.org
#HOST ldap.openldap.org ldap-master.openldap.org:666
#PORT 389
BASE { esmith::util::ldapBase ($DomainName); }
HOST localhost
PORT 389
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never

View File

@@ -0,0 +1,7 @@
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/redhat/rfc822-MailMember.schema
include /etc/openldap/schema/mailRelatedObject.schema

View File

@@ -0,0 +1 @@
include /etc/openldap/schema/rfc2739.schema

View File

@@ -0,0 +1,3 @@
pidfile /var/run/openldap/slapd.pid

View File

@@ -0,0 +1,18 @@
TLSCipherSuite { $ldap{CipherSuite} || $modSSL{CipherSuite} || 'ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:HIGH@STRENGTH:!SSLv2:!ADH:!aNULL:!MD5:!RC4' }
TLSProtocolMin { my $TLSProtocolMin = $ldap{TLSProtocolMin} || 'TLSv1.2';
if ( $TLSProtocolMin eq 'SSLv3' ){
$OUT = " 3.0";
} elsif ( $TLSProtocolMin eq 'TLSv1.0' || $TLSProtocolMin eq 'TLSv1' ){
$OUT = " 3.1";
} elsif ( $TLSProtocolMin eq 'TLSv1.1' ){
$OUT = " 3.2";
} elsif ( $TLSProtocolMin eq 'TLSv1.2' ){
$OUT = " 3.3";
}
}
TLSCACertificateFile /etc/openldap/ssl/slapd.pem
TLSCertificateFile /etc/openldap//ssl/slapd.pem
TLSCertificateKeyFile /etc/openldap/ssl/slapd.pem
TLSVerifyClient never

View File

@@ -0,0 +1 @@
allow bind_v2

View File

@@ -0,0 +1 @@
sizelimit unlimited

View File

@@ -0,0 +1 @@
database bdb

View File

@@ -0,0 +1 @@
suffix "{ esmith::util::ldapBase ($DomainName); }"

View File

@@ -0,0 +1 @@
checkpoint 512 5

View File

@@ -0,0 +1 @@
directory /var/lib/ldap

View File

@@ -0,0 +1 @@
rootdn "cn=root,{ esmith::util::ldapBase ($DomainName); }"

View File

@@ -0,0 +1 @@
rootpw { esmith::util::LdapPassword (); }

View File

@@ -0,0 +1,5 @@
# Use md5crypt
password-hash \{CRYPT\}
password-crypt-salt-format "$1$%.8s"

View File

@@ -0,0 +1,6 @@
# Indices to maintain
#index objectClass eq
index objectClass,uid,uidNumber,gidNumber eq
index memberUid eq
index cn,mail,surname,givenname eq,subinitial

View File

@@ -0,0 +1,6 @@
access to attrs=userPassword
by self peername.ip="127.0.0.1" read
by self ssf=128 read
by anonymous peername.ip="127.0.0.1" auth
by anonymous ssf=128 auth
by * none

View File

@@ -0,0 +1,18 @@
# Anonymous users should only be able to see SME users and groups for addressbook purpose
# Prevent access to system, dummy and machine accounts
access to dn.children=ou=Users,{ esmith::util::ldapBase ($DomainName); } filter=(!(objectClass=inetOrgPerson))
by users peername.ip="127.0.0.1" read
by users ssf=128 read
by anonymous none
access to dn.children=ou=Groups,{ esmith::util::ldapBase ($DomainName); } filter=(!(objectClass=mailboxRelatedObject))
by users peername.ip="127.0.0.1" read
by users ssf=128 read
by anonymous none
access to dn.subtree=ou=Computers,{ esmith::util::ldapBase ($DomainName); }
by users peername.ip="127.0.0.1" read
by users ssf=128 read
by anonymous none

View File

@@ -0,0 +1,11 @@
{
# Array of attrs which should not be visible anonymously
@anon = ();
# Array of attrs which should not be visible by other users
@users = ();
$OUT .= '';
}

View File

@@ -0,0 +1,8 @@
{
# Sensible attributes related to posixAccount
push @anon, qw/loginShell gidNumber homeDirectory uidNumber/;
$OUT .= '';
}

View File

@@ -0,0 +1,8 @@
{
# Sensible attributes related to shadowAccount
push @anon, qw/shadowExpire shadowFlag shadowInactive shadowLastChange shadowMax shadowMin shadowWarning/;
$OUT .= '';
}

View File

@@ -0,0 +1,27 @@
{
my $anon_attrs = join(",",@anon);
my $users_attrs = join(",",@users);
unless ($anon_attrs eq ''){
$OUT .=<<"HERE";
access to attrs=$anon_attrs
by self peername.ip="127.0.0.1" read
by self ssf=128 read
by users peername.ip="127.0.0.1" read
by users ssf=128 read
by * none
HERE
}
unless ($users_attrs eq ''){
$OUT .=<<"HERE";
access to attrs=$users_attrs
by self peername.ip="127.0.0.1" read
by self ssf=128 read
by * none
HERE
}
}

View File

@@ -0,0 +1,10 @@
{
$anonAccess = (($ldap{'AnonymousAccess'} || 'enabled') eq 'enabled') ? 'read':'none';
$OUT .= '';
}
access to *
by users read
by anonymous {"$anonAccess";}
by * none

View File

@@ -0,0 +1,4 @@
#ldap
:programname, isequal, "slapd" /var/log/ldap/ldap.log
& stop

View File

@@ -0,0 +1,3 @@
# OpenLDAP server configuration
# see 'man slapd' for additional information

View File

@@ -0,0 +1,8 @@
# Where the server will run (-h option)
# - ldapi:/// is required for on-the-fly configuration using client tools
# (use SASL with EXTERNAL mechanism for authentication)
# - default: ldapi:/// ldap:///
# - example: ldapi:/// ldap://127.0.0.1/ ldap://10.0.0.1:1389/ ldaps:///
SLAPD_URLS="ldap:/// ldaps:/// ldapi:///"

View File

@@ -0,0 +1,4 @@
# Any custom options
SLAPD_OPTIONS=" -4 -d { $ldap{LogLevel} || 256 } -s 0 "

View File

@@ -0,0 +1,4 @@
# Keytab location for GSSAPI Kerberos authentication
#KRB5_KTNAME="FILE:/etc/openldap/ldap.keytab"

View File

@@ -0,0 +1,4 @@
#
# Set the database in memory cache size.
#
set_cachesize 0 2097152 0

View File

@@ -0,0 +1,8 @@
#
# Set log values.
#
set_lg_regionmax 1048576
set_lg_max 10485760
set_lg_bsize 2097152
set_lg_dir /var/log/bdb
set_flags DB_LOG_AUTOREMOVE

0
root/etc/e-smith/tests/.gitignore vendored Normal file
View File

View File

@@ -0,0 +1,151 @@
#!/usr/bin/perl -wT
# vim:ft=xml:
#----------------------------------------------------------------------
# heading : Configuration
# description : Directory
# navigation : 6000 6300
#----------------------------------------------------------------------
# copyright (C) 2002 Mitel Networks Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Technical support for this program is available from Mitel Networks
# Please visit our web site www.e-smith.com for details.
#----------------------------------------------------------------------
use strict;
use esmith::util;
use esmith::FormMagick::Panel::directory;
my $f = esmith::FormMagick::Panel::directory->new();
$f->display();
=head1 TESTING
=begin testing
use esmith::FormMagick::Tester;
use esmith::TestUtils;
use esmith::ConfigDB;
my $panel = 'directory';
my $panel_path = "/etc/e-smith/web/functions/".$panel;
my $ua = esmith::FormMagick::Tester->new();
is (mode($panel_path), '4750', "Check permissions on script");
ok ($ua->get_panel($panel), "ABOUT TO RUN L10N TESTS");
is ($ua->{status}, 200, "200 OK");
like($ua->{content}, qr/FORM_TITLE/, "Saw untranslated form title");
ok ($ua->set_language("en-us"), "Set language to U.S. English");
ok ($ua->get_panel($panel), "Get panel");
is ($ua->{status}, 200, "200 OK");
like($ua->{content}, qr/LDAP directory settings/, "Saw translated form title");
# Testing changes
ok ($ua->get_panel($panel), "Testing panel retrieval");
can_ok($ua, "field");
# Destructive testing:
ok ($ua->{form}->find_input('Department'), 'Finding the Department field');
$ua->field('Department' => 'TestDept' );
$ua->field('Existing' => 'update');
ok ($ua->click("Save"), "Click Save");
is ($ua->{status}, 200, "200 OK");
like($ua->{content}, qr/settings have been saved/, "Saw validation messages");
# Gotta open this later, so we don't cache stale data
my $db = esmith::ConfigDB->open;
ok($db->get('ldap')->prop('defaultDepartment') eq 'TestDept');
my $a = esmith::AccountsDB->open;
my @users = $a->users();
foreach $user (@users) {
ok( $user->prop('Dept') eq 'TestDept');
}
=end testing
=cut
__DATA__
<form title="FORM_TITLE" header="/etc/e-smith/web/common/head.tmpl" footer="/etc/e-smith/web/common/foot.tmpl">
<page
name="First"
post-event="change_settings()"
pre-event="print_status_message()">
<description>DESCRIPTION</description>
<field type="literal" value="get_ldap_base()">
<label>LABEL_ROOT</label>
</field>
<field
type="select"
id="Access"
value="get_prop('ldap','access')"
options="'private' => 'NETWORKS_ALLOW_LOCAL', 'public' => 'NETWORKS_ALLOW_PUBLIC'">
<label>DIRECTORY_ACCESS</label>
<description>DESC_DIRECTORY_ACCESS</description>
</field>
<field
type="text"
id="Department"
value="get_prop('ldap','defaultDepartment')">
<label>DEPARTMENT</label>
<description>DESC_DEPARTMENT</description>
</field>
<field type="text" id="Company" value="get_prop('ldap','defaultCompany')">
<label>COMPANY</label>
</field>
<field type="text" id="Street" value="get_prop('ldap','defaultStreet')">
<label>STREET</label>
</field>
<field type="text" id="City" value="get_prop('ldap','defaultCity')">
<label>CITY</label>
</field>
<field
type="text"
id="PhoneNumber"
value="get_prop('ldap','defaultPhoneNumber')">
<label>PHONENUMBER</label>
</field>
<field id="Existing"
type="select"
value='leave'
options="'leave' => 'LEAVE', 'update' => 'UPDATE'">
<label>EXISTING</label>
<description>DESC_EXISTING</description>
</field>
<subroutine src="print_button('SAVE')" />
</page>
</form>

11
root/etc/logrotate.d/ldap Normal file
View File

@@ -0,0 +1,11 @@
/var/log/ldap/*.log {
daily
missingok
notifempty
delaycompress
sharedscripts
postrotate
# OpenLDAP logs via syslog, restart syslog if running
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}

View File

@@ -0,0 +1,6 @@
objectClass ( 1.3.6.1.4.1.5427.1.389.6.9
NAME 'mailboxRelatedObject'
DESC 'For pointing to an associated RFC822 (functional) mailbox from any entry'
AUXILIARY
MAY ( mail $ displayName ) )

View File

@@ -0,0 +1,15 @@
attributetype
( 1.3.6.1.4.1.42.2.27.2.1.15
NAME 'rfc822MailMember'
DESC 'rfc822 mail address of group member(s)'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
)
objectclass ( 1.3.6.1.4.1.42.2.27.1.2.5
NAME 'nisMailAlias'
SUP top STRUCTURAL
DESC 'NIS mail alias'
MUST cn
MAY rfc822MailMember )

View File

@@ -0,0 +1,98 @@
#
# http://www.faqs.org/rfcs/rfc2739.html
#
# From the RFC:
# The calCalURI contains the URI to a snapshot of the user's entire
# default calendar. The calFBURL contains the URI to the user's default
# busy time data. The calCAPURI represents contains a URI that can be
# used to communicate with the user's calendar. The calCalAdrURI
# contains a URI that points to the location to which event requests
# should be sent for that user.
#
# The calOtherCalURIs is a multi-valued property containing URIs to
# snapshots of other calendars that the user may have. The
# calOtherFBURLs is a multi-valued property containing URIs to other
# free/busy data that the user may have. The calOtherCAPURIs attribute
# is a multi-valued property containing URIs to other calendars that
# the user may have. The calOtherCalAdrURIs attribute is a multi-valued
# property containing URIs to other locations that a user may want
# event requests sent to.
#
# There is no predetermined order to the values in either multi-valued
# property.
# EQUALITY caseIgnoreIA5Match
attribute (1.2.840.113556.1.4.478
NAME 'calCalURI'
DESC 'Snapshot of users entire default calendar'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
)
attribute (1.2.840.113556.1.4.479
NAME 'calFBURL'
DESC 'URI of the uses free and busy information'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
)
attribute (1.2.840.113556.1.4.480
NAME 'calCAPURI'
DESC 'URI used to communicate with the users calendar'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
)
attribute (1.2.840.113556.1.4.481
NAME 'calCalAdrURI'
DESC 'URI to which event requests should be sent for the user'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
)
attribute (1.2.840.113556.1.4.482
NAME 'calOtherCalURIs'
DESC 'URIs to non-default calendars belonging to the user'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
)
attribute (1.2.840.113556.1.4.483
NAME 'calOtherFBURLs'
DESC 'URIs to non-default free and busy information files'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
)
attribute (1.2.840.113556.1.4.484
NAME 'calOtherCAPURIs'
DESC 'URIs for communicating with non-default calendars'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
)
attribute (1.2.840.113556.1.4.485
NAME 'calOtherCalAdrURIs'
DESC 'Destinations for event requests to non-default calendars'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
)
objectclass (1.2.840.113556.1.5.87
NAME 'calEntry'
DESC 'Calendering and Free Busy information'
SUP top AUXILIARY
MAY (calCalURI $ calFBURL $ calCAPURI $ calCalAdrURI $
calOtherCalURIs $ calOtherFBURLs $ calOtherCAPURIs $
calOtherCalAdrURIs
)
)

0
root/etc/openldap/ssl/.gitignore vendored Normal file
View File

View File

@@ -0,0 +1,90 @@
#!/bin/bash
#----------------------------------------------------------------------
# copyright (C) 2010 Firewall-Services
# daniel@firewall-services.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Technical support for this program is available from Mitel Networks
# Please visit our web site www.mitel.com/sme/ for details.
#----------------------------------------------------------------------
# Source function library.
SYSTEMCTL_SKIP_REDIRECT=1
. /etc/rc.d/init.d/functions
if [ $# -lt 1 ]; then
echo "Usage: $0 <start|restart>" 1>&2
exit 1
fi
# We should only do something if $1 is 'start'.
if [ $1 != "start" ] && [ $1 != "restart" ]; then
exit 0
fi
for i in $(seq 1 10)
do
/usr/bin/ldapwhoami -x > /dev/null 2>&1
if [ $? = 0 ]
then
exit_value=0
for link in $((echo /etc/e-smith/ldap/init/50bootstrap; find /etc/e-smith/ldap/init -type f -o -type l) | sort)
do
F=$(basename $link | sed 's/S\?[0-9][0-9]_\?//')
case $F in
bootstrap)
BOOTSTRAP=$(/sbin/e-smith/db configuration getprop ldap Bootstrap)
if [ "$BOOTSTRAP" == "run" ]; then
action "Running bootstrap-ldap-save" /sbin/e-smith/signal-event bootstrap-ldap-save
fi
;;
*.ldif)
action "Loading $F into ldap" perl -e '
use esmith::util;
use esmith::ConfigDB;
my $c = esmith::ConfigDB->open_ro;
my $domain = $c->get("DomainName")
|| die("Could not determine domain name");
my $base = esmith::util::ldapBase ($domain->value);
my $pw = esmith::util::LdapPassword();
open (STDERR, "|/usr/bin/logger -p local1.info -t ldap.init");
open (STDOUT, ">&STDERR");
my $link = shift || die "Missing filename";
my @add = system("/bin/grep -q changetype $link") == 0 ? () : ("-a");
exec "/usr/bin/ldapmodify", @add, "-c", "-x", "-H", "ldap://localhost/",
"-D", "cn=root,$base", "-w", "$pw", "-f", "$link";' $link && /bin/rm $link
;;
*)
action "Loading $F into ldap" perl -e '
open (STDERR, "|/usr/bin/logger -p local1.info -t ldap.init");
open (STDOUT, ">&STDERR");
exec shift; ' $link && /bin/rm $link
;;
esac
# Record any failure for the final return value.
if [ $? -ne 0 ]; then
exit_value=1
fi
done
exit $exit_value
fi
echo "Waiting for slapd to startup" >&2
sleep 2
done
exit 1

0
root/home/e-smith/db/ldap/.gitignore vendored Normal file
View File

419
root/sbin/e-smith/ldif-fix Normal file
View File

@@ -0,0 +1,419 @@
#!/usr/bin/perl -T
use strict;
use warnings;
use Net::LDAP;
use Net::LDAP::LDIF;
use Date::Parse;
use esmith::ConfigDB;
use esmith::AccountsDB;
use esmith::util;
use Getopt::Long qw(:config bundling);
$ENV{'PATH'} = '/bin:/usr/bin:/sbin:/usr/sbin';
$ENV{'LANG'} = 'C';
$ENV{'TZ'} = '';
sub dnsort {
my %type = ( add => 1, modrdn => 2, moddn => 2, modify => 3, delete => 4);
my %attr = ( dc => 1, ou => 2, cn => 3, uid => 4);
my ($oa) = ($a->get_value('newrdn') || $a->dn) =~ /^([^=]+)=/;
my ($ob) = ($b->get_value('newrdn') || $b->dn) =~ /^([^=]+)=/;
my ($ua, $ub) = map { my $tu = $_->get_value('uidnumber'); defined $tu && $tu ne '' ? $tu : -1 } ($a, $b);
my ($ga, $gb) = map { my $tg = $_->get_value('gidnumber'); defined $tg && $tg ne '' ? $tg : -1 } ($a, $b);
($attr{$oa} || 9) <=> ($attr{$ob} || 9) || ($type{$a->changetype} || 9) <=> ($type{$b->changetype} || 9) ||
$ua <=> $ub || $ga <=> $gb || ($a->get_value('newrdn') || $a->dn) cmp ($b->get_value('newrdn') || $b->dn);
}
my $c = esmith::ConfigDB->open_ro;
my $a = esmith::AccountsDB->open_ro;
my $auth = $c->get('ldap')->prop('Authentication') || 'disabled';
my $schema = '/etc/openldap/schema/samba.schema';
my $domain = $c->get('DomainName')->value;
my $basedn = esmith::util::ldapBase($domain);
my $userou = 'ou=Users';
my $groupou = 'ou=Groups';
my $compou = 'ou=Computers';
my ($dc) = split /\./, $domain;
my $company = $c->get_prop('ldap', 'defaultCompany') || $domain;
my %opt;
GetOptions ( \%opt, "diff|d", "update|u", "input|i=s", "output|o=s" );
$opt{input} = '/usr/sbin/slapcat -c 2> /dev/null|' unless $opt{input} && ($opt{input} eq '-' || -f "$opt{input}" || -c "$opt{input}");
$opt{diff} = 1 if $opt{update};
if ( $opt{output} && $opt{output} =~ m{^([-\w/.]+)$}) {
$opt{output} = $1;
} else {
$opt{output} = '-';
}
my ($data, $dn);
# Top object (base)
$data->{$basedn} = {
objectclass => [qw/organization dcObject top/],
dc => $dc,
o => $company,
};
# Top containers for users/groups/computers
foreach (qw/Users Groups Computers/) {
$data->{"ou=$_,$basedn"} = {
objectclass => [qw/organizationalUnit top/],
ou => $_,
};
}
# Common accounts needed for SME to work properly
$data->{"cn=nobody,$groupou,$basedn"}->{objectclass} = [ qw/posixGroup/ ];
$data->{"uid=www,$userou,$basedn"}->{objectclass} = [ qw/account/ ];
$data->{"cn=www,$groupou,$basedn"} = { objectclass => [ qw/posixGroup/ ], memberuid => [ qw/admin/ ] };
$data->{"cn=rsshusers,$groupou,$basedn"}->{objectclass} = [ qw/posixGroup/ ];
$data->{"cn=shared,$groupou,$basedn"} = {
objectclass => [ qw/posixGroup mailboxRelatedObject/ ],
mail => "everyone\@$domain",
memberuid => [ qw/www/ ]
};
# Read in accounts database information
foreach my $acct ($a->get('admin'), $a->users, $a->groups, $a->ibays, $a->get_all_by_prop(type => 'machine')) {
my $key = $acct->key;
my $type = $acct->prop('type');
next if $key eq 'Primary';
$dn = "uid=$key,".($type eq 'machine' ? $compou : $userou).",$basedn";
if ($type =~ /^(?:user|group|machine|ibay)$/ || $key eq 'admin') {
if ($type eq 'user' || $key eq 'admin') {
# Allow removal of obsolete person objectclass and samba attributes
push @{$data->{$dn}->{_delete}->{objectclass}}, 'person';
push @{$data->{$dn}->{objectclass}}, 'inetOrgPerson';
$data->{$dn}->{mail} = "$key\@$domain";
@{$data->{$dn}}{qw/givenname sn telephonenumber o ou l street/} =
map { $acct->prop($_) || [] } qw/FirstName LastName Phone Company Dept City Street/;
$data->{$dn}->{cn} = $acct->prop('FirstName').' '.$acct->prop('LastName');
}
else {
push @{$data->{$dn}->{objectclass}}, 'account';
}
# users/ibays need to be a member of shared
push @{$data->{"cn=shared,$groupou,$basedn"}->{memberuid}}, $key if $type =~ /^(user|ibay)$/ || $key eq 'admin';
# users need to be a member of rsshusers if their shell is /usr/bin/rssh
push @{$data->{"cn=rsshusers,$groupou,$basedn"}->{memberuid}}, $key if ($type =~ /^(user)$/ || $key eq 'admin') && (($acct->prop('Shell') || '/usr/bin/rssh') eq '/usr/bin/rssh');
if ($auth ne 'enabled') {
# Allow removal of shadow properties
push @{$data->{$dn}->{_delete}->{objectclass}}, 'shadowAccount';
$data->{$dn}->{_delete}->{lc($_)} = 1 foreach qw/userPassword shadowLastChange shadowMin shadowMax
shadowWarning shadowInactive shadowExpire shadowFlag/;
if ( -f "$schema" ) {
# If we will be adding samba properties then allow removal
push @{$data->{$dn}->{_delete}->{objectclass}}, 'sambaSamAccount';
$data->{$dn}->{_delete}->{lc($_)} = 1 foreach qw/displayName sambaAcctFlags sambaLMPassword sambaNTPassword
sambaNTPassword sambaPrimaryGroupSID sambaPwdLastSet sambaSID/;
}
}
}
$dn = "cn=$key,$groupou,$basedn";
push @{$data->{$dn}->{objectclass}}, 'posixGroup';
if ($type eq 'group') {
# Allways replace memberuid with new set
$data->{$dn}->{_delete}->{memberuid} = 1;
push @{$data->{$dn}->{objectclass}}, 'mailboxRelatedObject';
$data->{$dn}->{mail} = "$key\@$domain";
$data->{$dn}->{description} = $acct->prop('Description') || [];
push @{$data->{$dn}->{memberuid}}, split /,/, ($acct->prop('Members') || '');
# www needs to be a memeber of every group
push @{$data->{$dn}->{memberuid}}, 'www';
if ($auth ne 'enabled' && -f "$schema" ) {
# If we will be adding samba properties then allow removal
push @{$data->{$dn}->{_delete}->{objectclass}}, 'sambaGroupMapping';
$data->{$dn}->{_delete}->{lc($_)} = 1 foreach qw/displayName sambaGroupType sambaSID/;
}
}
elsif ($type eq 'ibay') {
$dn = "cn=".$acct->prop('Group').",$groupou,$basedn";
push @{$data->{$dn}->{memberuid}}, $acct->key;
}
}
if ($auth ne 'enabled') {
# Read in information from unix (passwd) system
open PASSWD, '/etc/passwd';
while (<PASSWD>) {
chomp;
my @passwd = split /:/, $_;
next unless scalar @passwd == 7;
$dn = "uid=$passwd[0],".($passwd[0] =~ /\$$/ ? $compou : $userou).",$basedn";
next unless exists $data->{$dn};
push @{$data->{$dn}->{objectclass}}, 'posixAccount';
@{$data->{$dn}}{qw/cn uid uidnumber gidnumber homedirectory loginshell/} =
map { $passwd[$_] ? $passwd[$_] : [] } (4,0,2,3,5,6);
}
close (PASSWD);
# Shadow file defaults (pulled from cpu.conf)
my %shadow_def = ( 1 => [], 2 => 11192, 3 => -1, 4 => 99999, 5 => 7, 6 => -1, 7 => -1, 8 => 134538308 );
# Read in information from unix (shadow) system
open SHADOW, '/etc/shadow';
while (<SHADOW>) {
chomp;
my @shadow = split /:/, $_;
next unless scalar @shadow >= 6;
$shadow[1] = '!*' if $shadow[1] eq '!!';
$shadow[1] = "{CRYPT}$shadow[1]" unless $shadow[1] =~ /^\{/;
$dn = "uid=$shadow[0],".($shadow[0] =~ /\$$/ ? $compou : $userou).",$basedn";
next unless exists $data->{$dn};
push @{$data->{$dn}->{objectclass}}, 'shadowAccount';
@{$data->{$dn}}{ map { lc($_) } qw/userPassword shadowLastChange shadowMin shadowMax shadowWarning shadowInactive
shadowExpire shadowFlag/} = map { $shadow[$_] ? $shadow[$_] : $shadow_def{$_} } (1..8);
}
close (SHADOW);
# Read in information from unix (group) system
open GROUP, '/etc/group';
while (<GROUP>) {
chomp;
my @group = split /:/, $_;
next unless scalar @group >= 3;
$group[3] = [ split /,/, ($group[3] || '') ];
$dn = "cn=$group[0],$groupou,$basedn";
next unless exists $data->{$dn};
push @{$data->{$dn}->{objectclass}}, 'posixGroup';
@{$data->{$dn}}{qw/cn gidnumber/} = map { $group[$_] ? $group[$_] : [] } (0,2);
push @{$data->{$dn}->{memberuid}}, @{$group[3]};
}
close (GROUP);
my %smbprop = (
'User SID' => 'sambasid',
'Account Flags' => 'sambaacctflags',
'Primary Group SID' => 'sambaprimarygroupsid',
'Full Name' => 'displayname',
'Password last set' => 'sambapwdlastset',
);
# Read in information from unix (smbpasswd) system
if ( -f "$schema" && -x '/usr/bin/pdbedit' ) {
$dn = undef;
open SMBDETAIL, '/usr/bin/pdbedit -vL 2> /dev/null|';
while (<SMBDETAIL>) {
chomp;
$dn = ("uid=$1,".($1 =~ /\$$/ ? $compou : $userou).",$basedn") if m/^Unix username:\s+(\S.*)$/;
next unless $dn && exists $data->{$dn};
# Map the samba account properties that we care about
$data->{$dn}->{$smbprop{$1}} = ($2 ? str2time($2) : (defined $3 ? $3 : []))
if m/^(.+):\s+(?:(\S.*\d{4} \d{2}:\d{2}:\d{2}.*)|(.*))$/ && exists $smbprop{$1};
}
close (SMBDETAIL);
open SMBPASSWD, '/usr/bin/pdbedit -wL 2> /dev/null|';
while (<SMBPASSWD>) {
chomp;
my @smbpasswd = split /:/, $_;
next unless scalar @smbpasswd >= 6;
$dn = "uid=$smbpasswd[0],".($smbpasswd[0] =~ /\$$/ ? $compou : $userou).",$basedn";
next unless exists $data->{$dn} && exists $data->{$dn}->{uidnumber} && $data->{$dn}->{uidnumber} eq $smbpasswd[1];
push @{$data->{$dn}->{objectclass}}, 'sambaSamAccount';
@{$data->{$dn}}{qw/sambalmpassword sambantpassword/} = map { $smbpasswd[$_] ? $smbpasswd[$_] : [] } (2,3);
}
close (SMBPASSWD);
}
if ( -f "$schema" && -x '/usr/bin/net' ) {
open GROUPMAP, '/usr/bin/net groupmap list 2> /dev/null|';
while (<GROUPMAP>) {
chomp;
if (m/^(.+) \((.+)\) -> (.+)$/) {
# Skip local machine accounts
next if $2 =~ /S-1-5-32-\d+/;
$dn = "cn=$3,$groupou,$basedn";
next unless exists $data->{$dn};
push @{$data->{$dn}->{objectclass}}, 'sambaGroupMapping';
@{$data->{$dn}}{qw/displayname sambasid sambagrouptype/} = ($1, $2, 2);
}
}
close (GROUPMAP);
}
}
my @ldif;
# Loop through ldap data and update as necessary
my $reader = Net::LDAP::LDIF->new( $opt{input}, 'r', onerror => 'undef' );
while( not $reader->eof()) {
my $entry = $reader->read_entry() || next;
$dn = $entry->dn;
# Ensure the basedn is correct
$dn = "$1$basedn" if $dn =~ /^((?:(?!dc=)[^,]+,)*)dc=/;
# Ensure correct ou is part of user/groups/computers
if ($dn =~ /^(uid=([^,\$]+)(\$)?),((?:(?!dc=)[^,]+,)*)dc=/) {
if ( defined $3 && $3 eq '$') {
$dn = "$1,$compou,$basedn";
}
elsif (grep /posixGroup/, @{$entry->get_value('objectclass', asref => 1) || []}) {
$dn = "cn=$2,$groupou,$basedn";
# Cleanup attributes that the modrdn will perform
$entry->add(cn => $2);
$entry->delete(uid => [$2]);
}
else {
$dn = "$1,$userou,$basedn";
}
}
elsif ($dn =~ /^(cn=[^,]+),((?:(?!dc=)[^,]+,)*)dc=/) {
$dn = "$1,$groupou,$basedn" unless $2 =~ /^ou=auto\./;
}
# Don't process records twice
next if $data->{$dn}->{_done};
# Rename existing entry into place if we can
if ($dn ne $entry->dn) {
my $rdn = Net::LDAP::Entry->new;
$rdn->dn($entry->dn);
$rdn->changetype('modrdn');
my ($newdn, $newbase) = split /,/, $dn, 2;
$rdn->add(newrdn => $newdn, deleteoldrdn => 1, newsuperior => $newbase);
push @ldif, $rdn;
# Now we can change the entry to new dn
$entry->dn($dn);
}
# Change type to modify so that we can keep track of changes we make
$entry->changetype('modify');
# Hack to make upgrades work (add calEntry if calFGUrl attributes exists)
if ($entry->exists('calFBURL') && -f "/etc/openldap/schema/rfc2739.schema") {
push @{$data->{$dn}->{objectclass}}, 'calEntry';
}
my %attributes = ();
@attributes{ keys %{$data->{$dn}}, exists $data->{$dn}->{_delete} ? map { lc($_) } keys %{$data->{$dn}->{_delete}} : () } = ();
foreach my $attr (sort keys %attributes) {
# Skip the pseudo attributes
next if $attr =~ /^_/;
my @l = @{$entry->get_value($attr, asref => 1) || []};
my @u = exists $data->{$dn}->{$attr} ? (ref $data->{$dn}->{$attr} ? @{$data->{$dn}->{$attr}} : ($data->{$dn}->{$attr})) : ();
# Figure out differences between attributes
my (@lonly, @uonly, @donly, %lseen, %useen, %dseen) = () x 6;
# Unique lists of what is in ldap and what needs to be in ldap
@lseen{@l} = ();
@useen{@u} = ();
# Create list of attributes that aren't in the other
@uonly = grep { ! exists $lseen{$_} } keys %useen;
@lonly = grep { ! exists $useen{$_} } keys %lseen;
# Determine which of the ldap only attributes we need to remove
if ((keys %useen == 1 && keys %lseen == 1) || (keys %useen == 0 && exists $data->{$dn}->{$attr})) {
# Replacing a single entry or erasing entire entry
@donly = @lonly;
}
elsif ($data->{$dn}->{_delete} && $data->{$dn}->{_delete}->{$attr}) {
if (my $ref = ref($data->{$dn}->{_delete}->{$attr})) {
# Map hash keys or array elemts to valid values to delete
@dseen{$ref eq 'HASH' ? keys %{$data->{$dn}->{_delete}->{$attr}} : @{$data->{$dn}->{_delete}->{$attr}}} = ();
@donly = grep { exists $dseen{$_} } @lonly;
}
else {
# Permission to remove all values
@donly = @lonly;
}
}
if (@donly && @donly == keys %lseen) {
# If we are removing all ldap attributes do a remove or full delete
if (@uonly) {
$entry->replace($attr => [ @uonly ]);
}
else {
$entry->delete($attr => []);
}
}
else {
$entry->delete($attr => [ @donly ]) if @donly;
$entry->add($attr => [ @uonly ]) if @uonly;
}
}
$data->{$dn}->{_done} = 1;
push @ldif, $entry;
}
$reader->done();
# Add missing records that didn't exist in ldap yet
foreach $dn (grep { ! exists $data->{$_}->{_done} } sort keys %$data) {
my $entry = Net::LDAP::Entry->new;
$entry->dn($dn);
foreach my $attr (sort keys %{$data->{$dn}}) {
# Skip the pseudo attributes
next if $attr =~ /^_/;
my %seen = ();
@seen{ref $data->{$dn}->{$attr} ? @{$data->{$dn}->{$attr}} : ($data->{$dn}->{$attr})} = ();
$entry->add($attr => [ sort keys %seen ]) if keys %seen != 0;
}
push @ldif, $entry;
}
#------------------------------------------------------------
# Update LDAP database entry.
#------------------------------------------------------------
my $ldap;
if ($opt{update}) {
$ldap = Net::LDAP->new('localhost') or die "$@";
$ldap->bind( dn => "cn=root,$basedn", password => esmith::util::LdapPassword() );
}
my $writer = Net::LDAP::LDIF->new( $opt{output}, 'w', onerror => 'undef', wrap => 0, sort => 1, change => $opt{diff} );
foreach my $entry (sort dnsort @ldif) {
if ($opt{update} && ($entry->changetype ne 'modify' || @{$entry->{changes}}) ) {
my $result = $entry->update($ldap);
warn "Failure to ",$entry->changetype," ",$entry->dn,": ",$result->error,"\n" if $result->code;
}
if ($writer->{change} || $entry->changetype !~ /modr?dn/) {
$writer->write_entry($entry);
}
}

View File

@@ -0,0 +1,21 @@
#! /bin/sh
exec 2>&1
LDIF=$(readlink -n /etc/openldap/ldif)
TMP=$LDIF.$$
if /usr/sbin/slapcat -l $TMP
then
mv -f $TMP $LDIF
else
echo slapcat dump of ldif failed - shutting down ldap service >&2
echo probable corruption of ldap backend files >&2
# Don't bother to keep a zero length dump file
if test ! -s $TMP
then
rm -f $TMP
fi
fi

View File

@@ -0,0 +1,54 @@
#! /bin/sh
domain=$(/sbin/e-smith/config get DomainName)
ldif="/home/e-smith/db/ldap/$domain.ldif"
if [ -e /etc/openldap/ldif ]
then
old_ldif=$(readlink /etc/openldap/ldif)
if [ "$old_ldif" != "$ldif" ]
then
# The domain name has changed, so we need to delete
# the old directory contents. We still have the old
# dump.
mv -f $old_ldif $ldif
find /var/lib/ldap -type f | xargs rm -f
fi
fi
if [ -f /var/lib/ldap/nextid.dbb ]
then
# We are upgrading from an earlier version which used
# ldbm backend format. Delete the backend files, and
# restore from ldif
find /var/lib/ldap -type f | xargs rm -f
fi
# Set up symlink for ldap dump at shutdown
ln -sf $ldif /etc/openldap/ldif
/sbin/e-smith/expand-template /var/lib/ldap/DB_CONFIG
# Make sure we use the slapd.conf file instead of the new slapd.d
touch /etc/openldap/slapd.d/unused
find /etc/openldap/slapd.d/ -mindepth 1 -maxdepth 1 -not -name unused -exec rm -rf {} \;
/sbin/e-smith/expand-template /etc/openldap/slapd.conf
# Prime directory if required
if [ \! -f /var/lib/ldap/id2entry.bdb ]
then
if [ -e /etc/openldap/ldif ]
then
/sbin/e-smith/ldif-fix -i /etc/openldap/ldif | setuidgid ldap slapadd -c
else
/sbin/e-smith/ldif-fix -i /dev/null | setuidgid ldap slapadd -c
fi
else
setuidgid ldap /usr/bin/db_recover -v -h /var/lib/ldap
fi
# Make sure all DB files belongs to ldap:ldap
find /var/lib/ldap -not -name DB_CONFIG -exec chown ldap:ldap {} \;
exit 0

View File

@@ -0,0 +1,21 @@
[Unit]
Description=Koozali SME Server ldap.init
After=syslog.target network-online.target ldap.service
[Service]
Type=forking
Restart=no
TimeoutSec=5min
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=yes
ExecStartPre=/sbin/e-smith/service-status ldap.init
ExecStart=/etc/rc.d/init.d/ldap.init start
ExecStop=/etc/rc.d/init.d/ldap.init stop
[Install]
WantedBy=sme-server.target

View File

@@ -0,0 +1,26 @@
[Unit]
Description=Koozali SME Server OpenLDAP Server Daemon
After=syslog.target network-online.target
Documentation=man:slapd
Documentation=man:slapd-config
Documentation=man:slapd-hdb
Documentation=man:slapd-mdb
Documentation=file:///usr/share/doc/openldap-servers/guide.html
[Service]
Type=simple
PIDFile=/var/run/openldap/slapd.pid
Environment="SLAPD_URLS=ldap:/// ldaps:/// ldapi:///" "SLAPD_OPTIONS=-4 -d 256 -s 0"
EnvironmentFile=/etc/sysconfig/slapd
ExecStartPre=/sbin/e-smith/service-status ldap
ExecStartPre=/sbin/e-smith/expand-template /etc/openldap/ssl/slapd.pem
ExecStartPre=/sbin/e-smith/systemd/ldap-prepare
#ExecStartPre=/usr/libexec/openldap/check-config.sh
ExecStart=/usr/sbin/slapd -u ldap -h ${SLAPD_URLS} $SLAPD_OPTIONS
TimeoutStartSec=300
Restart=always
ExecStopPost=/sbin/e-smith/systemd/ldap-finish
[Install]
WantedBy=sme-server.target

View File

@@ -0,0 +1,6 @@
[Service]
# disabled
# we are using ldap.service
ExecStart=/usr/bin/true
ExecStartPre=
PIDFile=

View File

@@ -0,0 +1,204 @@
#!/usr/bin/perl -w
#
# $Id: directory.pm,v 1.3 2003/12/18 17:19:54 msoulier Exp $
#
package esmith::FormMagick::Panel::directory;
use strict;
use esmith::AccountsDB;
use esmith::ConfigDB;
use esmith::FormMagick;
use esmith::util;
use File::Basename;
use Exporter;
use Carp;
our @ISA = qw(esmith::FormMagick Exporter);
our @EXPORT = qw(
get_ldap_base get_value get_prop change_settings
);
our $VERSION = sprintf '%d.%03d', q$Revision: 1.3 $ =~ /: (\d+).(\d+)/;
our $db = esmith::ConfigDB->open();
# {{{ header
=pod
=head1 NAME
esmith::FormMagick::Panels::directory - useful panel functions
=head1 SYNOPSIS
use esmith::FormMagick::Panels::directory;
my $panel = esmith::FormMagick::Panel::directory->new();
$panel->display();
=head1 DESCRIPTION
=cut
# }}}
# {{{ new
=head2 new();
Exactly as for esmith::FormMagick
=begin testing
use_ok('esmith::FormMagick::Panel::directory');
use vars qw($panel);
ok($panel = esmith::FormMagick::Panel::directory->new(), "Create panel object");
isa_ok($panel, 'esmith::FormMagick::Panel::directory');
=end testing
=cut
sub new {
shift;
my $self = esmith::FormMagick->new();
$self->{calling_package} = (caller)[0];
bless $self;
return $self;
}
# }}}
# {{{ get_prop
=head2 get_prop ITEM PROP
A simple accessor for esmith::ConfigDB::Record::prop
=cut
sub get_prop {
my $fm = shift;
my $item = shift;
my $prop = shift;
my $record = $db->get($item);
if ($record) {
return $record->prop($prop);
}
else {
return '';
}
}
# }}}
=head2 get_ldap_base
Gets the LDAP base for this domain
=cut
sub get_ldap_base {
return esmith::util::ldapBase(get_value('','DomainName'));
}
# {{{ get_value
=head2 get_value ITEM
A simple accessor for esmith::ConfigDB::Record::value
=cut
sub get_value {
my $fm = shift;
my $item = shift;
my $record = $db->get($item);
if ($record) {
return $record->value();
}
else {
return '';
}
}
# }}}
=head1 ACTION
# {{{ change_settings
=head2 change_settings
If everything has been validated, properly, go ahead and set the new settings
=cut
sub change_settings {
my ($fm) = @_;
my $q = $fm->{'cgi'};
my $access = $q->param ('Access') || 'private';
my $department = $q->param ('Department') || "";
my $company = $q->param ('Company') || "";
my $street = $q->param ('Street') || "";
my $city = $q->param ('City') || "";
my $phone = $q->param ('PhoneNumber') || "";
my $existing = $q->param ('Existing') || 'leave' ;
$db->get('ldap')->set_prop('access', $access);
$db->get('ldap')->set_prop('defaultDepartment', $department);
$db->get('ldap')->set_prop('defaultCompany', $company);
$db->get('ldap')->set_prop('defaultStreet', $street);
$db->get('ldap')->set_prop('defaultCity', $city);
$db->get('ldap')->set_prop('defaultPhoneNumber', $phone);
#------------------------------------------------------------
# If requested, update the account records for all existing users.
# Don't need to signal any special events for this, since we're only
# changing LDAP information. If we were changing the user names
# or email parameters, we'd have to signal events to trigger the
# right updates.
#------------------------------------------------------------
if ($existing eq 'update') {
my $a = esmith::AccountsDB->open;
my @users = $a->users();
foreach my $user (@users) {
$user->set_prop('Phone', $phone);
$user->set_prop('Company', $company);
$user->set_prop('Dept', $department);
$user->set_prop('City', $city);
$user->set_prop('Street', $street);
}
}
#------------------------------------------------------------
# Update the system
#------------------------------------------------------------
system ("/sbin/e-smith/signal-event ldap-update") == 0
or return $fm->error('ERROR_UPDATING_CONFIGURATION');
return $fm->success('SUCCESS');
}
# }}}
1;

0
root/var/log/bdb/.gitignore vendored Normal file
View File

0
root/var/log/ldap/.gitignore vendored Normal file
View File