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

master 5.6.0
Brian Read 10 months ago
parent a24f2abb0c
commit ae371ebfe0

4
.gitignore vendored

@ -0,0 +1,4 @@
*.rpm
*.log
*spec-20*
*.tar.xz

@ -0,0 +1,21 @@
# Makefile for source rpm: e-smith-ldap
# $Id: Makefile,v 1.1 2016/02/05 16:04:52 stephdl Exp $
NAME := e-smith-ldap
SPECFILE = $(firstword $(wildcard *.spec))
define find-makefile-common
for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
endef
MAKEFILE_COMMON := $(shell $(find-makefile-common))
ifeq ($(MAKEFILE_COMMON),)
# attept a checkout
define checkout-makefile-common
test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2
endef
MAKEFILE_COMMON := $(shell $(checkout-makefile-common))
endif
include $(MAKEFILE_COMMON)

@ -1,3 +1,17 @@
# e-smith-ldap
# <img src="https://www.koozali.org/images/koozali/Logo/Png/Koozali_logo_2016.png" width="25%" vertical="auto" style="vertical-align:bottom"> e-smith-ldap
SMEServer Koozali developed git repo for e-smith-ldap smeserver
SMEServer Koozali developed git repo for e-smith-ldap smeserver
## Wiki
<br />https://wiki.koozali.org/
## Bugzilla
Show list of outstanding bugs: [here](https://bugs.koozali.org/buglist.cgi?component=e-smith-ldap&product=SME%20Server%2010.X&query_format=advanced&limit=0&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=CONFIRMED)
## Description
<br />*This description has been generated by an LLM AI system and cannot be relied on to be fully correct.*
*Once it has been checked, then this comment will be deleted*
<br />
e-smith-ldap is an open source, Linux-based software package that provides a secure directory service for enterprises. It is based on an LDAP (Lightweight Directory Access Protocol) server and provides an intuitive web-based administration interface for managing users, groups, policies, and permissions. It also allows for connection to external LDAP servers, providing inter-company synchronization of user accounts. e-smith-ldap is a reliable and secure solution for organizations needing to efficiently manage user access to resources without sacrificing control. It is also a cost-effective, scalable, and easy to use solution for managing large user populations.

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

@ -0,0 +1 @@
sme10

@ -0,0 +1,75 @@
#!/usr/bin/perl -w
use esmith::Build::CreateLinks qw(:all);
panel_link("directory", "manager");
foreach (qw(ldap.conf slapd.conf))
{
templates2events("/etc/openldap/$_",
qw(
bootstrap-console-save
console-save
ldap-update
e-smith-ldap-update
));
}
templates2events("/etc/sysconfig/slapd",
qw(
bootstrap-console-save
console-save
ldap-update
e-smith-ldap-update
));
event_link("ldap-update-simple", "group-create", "95");
event_link("ldap-update-simple", "group-modify", "95");
event_link("ldap-delete", "group-delete", "55");
event_link("ldap-update-simple", "user-create", "95");
event_link("ldap-update-simple", "user-modify", "95");
event_link("ldap-update-simple", "user-modify-admin", "95");
event_link("ldap-delete", "user-delete", "55");
event_link("ldap-update-simple", "password-modify", "95");
event_link("ldap-update-simple", "user-lock", "55");
event_link("ldap-update-simple", "ibay-create", "95");
event_link("ldap-update-simple", "ibay-modify", "95");
event_link("ldap-delete", "ibay-delete", "55");
event_link("ldap-update-simple", "machine-account-create", "95");
event_link("ldap-update", "bootstrap-ldap-save", "80");
event_link("cleanup-unix-user-group", "bootstrap-ldap-save", "98");
event_link("ldap-dump", "pre-backup", "30");
event_link("ldap-update", "ldap-update", "80");
templates2events("/etc/rc.d/init.d/masq", "ldap-update");
templates2events("/etc/hosts.allow", "ldap-update");
templates2events("/etc/openldap/ssl/slapd.pem", qw(ssl-update e-smith-ldap-update bootstrap-console-save) );
safe_symlink("restart", "root/etc/e-smith/events/ldap-update/services2adjust/ldap");
safe_symlink("restart", "root/etc/e-smith/events/ssl-update/services2adjust/ldap");
safe_symlink("reload", "root/etc/e-smith/events/ldap-update/services2adjust/masq");
safe_symlink("reload", "root/etc/e-smith/events/ldap-update/services2adjust/httpd-e-smith");
event_link("ldap-delete-dumps", "pre-restore", "25");
event_link("set-ldap-bootstrap", "bootstrap-console-save", "95");
event_link("reset-ldap-bootstrap", "bootstrap-ldap-save", "95");
my $event="e-smith-ldap-update";
# systemd-specific action mandatory for this package-update event
event_link("systemd-reload", $event, "89");
event_link("systemd-default", $event, "88");
safe_symlink("restart", "root/etc/e-smith/events/$event/services2adjust/ldap");
event_link("ldap-update", $event , "80");
templates2events("/etc/rsyslog.conf", $event);
safe_symlink("restart", "root/etc/e-smith/events/$event/services2adjust/rsyslog");
exit 0;

File diff suppressed because it is too large Load Diff

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

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

@ -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

@ -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);

@ -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);

@ -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;

@ -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;

@ -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

@ -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);

@ -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

@ -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,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>

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

@ -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"

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

@ -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

@ -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

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

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

@ -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

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

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

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

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

@ -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

@ -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

@ -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

@ -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 .= '';
}

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

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

@ -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
}
}

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

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

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

@ -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:///"

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

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

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

@ -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,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>

@ -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
}

@ -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 ) )

@ -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 )

@ -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,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,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);
}
}

@ -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

@ -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

@ -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

@ -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

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

@ -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;
Loading…
Cancel
Save