- ldapuser -> adduser /modifyuser / addgroup / modifygroup / removeuser / removegroup / addusertogroup
- secure the server using ssl
- more on the acls
- figure out how to create {crypt} passwords (done)
- let other webapps that don't use pam authenticate against this server -> egroupware supports that by default
- configure evolution to read addressbook from ldap (doesn't work in 2.0.x but worked in 2.2.2)
- openldap-servers-2.2.13-2
- openldap-clients-2.2.13-2
- nss_ldap-220-3
- openldap-devel-2.2.13-2
- openldap-2.2.13-2
- /etc/openldap/slapd.conf (server conf)
- /etc/ldap.conf (client application conf)
now after you install the packages you start by editing slapd.conf
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args
## ACL ##
access to * by * read
#######################################################################
# ldbm and/or bdb database definitions
#######################################################################
database bdb
suffix "dc=lab,dc=local"
rootdn "cn=admin,dc=lab,dc=local"
rootpw {crypt}
defaultaccess read
directory /var/lib/ldap
# Indices to maintain for this database
index objectClass eq,pres
index ou,cn,mail,surname,givenname eq,pres,sub
#index uidNumber,gidNumber,loginShell eq,pres
index uid,memberUid eq,pres,sub
#index nisMapName,nisMapEntry eq,pres,sub
now some concepts (don't rely on me for concepts), these are my 2cents notes on understanding this issue
- ldap data are stored in databse backend as objects
- ldap objects are a set of attributes
- Each object has a DN (distinguished name) attribute that identifies it uniquely
- Objects in an LDAP database are organized into a tree hierarchy, based on their DN
- the tree should start from to to bottom of your organization example: "com -> company -> OU (organisational unit) -> user"
- each application needs/understands certain attributes
example of an entry for a user (see how it has DN object to identify it and the a set of attributes for details)
dn: uid=john,ou=people,dc=example,dc=com cn: John Doe uid: john uidNumber: 1001 gidNumber: 100 homeDirectory: /home/john loginShell: /bin/bash objectClass: top objectClass: posixAccount
now the most important thing to do thetrick is to figure out what to put in that ldif file (that took a lot of time and reading, lucky for you i did my homework and you can bypass that time, i hope) here is my sample file
dn: dc=lab, dc=local
objectClass: top
objectclass: organization
objectclass: dcObject
o: Opencraft labs
dc: lab
dn: ou=users,dc=lab, dc=local
ou: users
objectClass: top
objectClass: organizationalUnit
dn: ou=groups,dc=lab, dc=local
ou: groups
objectClass: top
objectClass: organizationalUnit
dn: cn=engineering, ou=groups, dc=lab, dc=local
objectclass: top
objectclass: posixGroup
cn: engineering
gidnumber: 500
memberuid: foo
dn: cn=ramez hanna,ou=users,dc=lab, dc=local
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: ramez
userpassword: {crypt}
uidnumber: 500
gidnumber: 500
gecos:ramez zoheir hanna
loginShell:/bin/bash
homeDirectory: /home/rhanna
shadowLastChange:10877
shadowMin: 0
shadowMax: 999999
shadowWarning: 7
shadowInactive: -1
shadowExpire: -1
shadowFlag: 0
cn: ramez hanna
givenname: ramez
sn: hanna
mail: me@domain.com
title: CEO
StreetAddress: somewhere
l: cairo
postalCode: huh
telephoneNumber: 54545454
homephone: 454545454
mobile: 555555555
facsimileTelephoneNumber: 555555
references : scripts:
- crypt.pl
srand (time());
my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))";
my $salt = sprintf ("%c%c", eval $randletter, eval $randletter);
my $plaintext = <STDIN>;
my $crypttext = "{CRYPT}".crypt ($plaintext, $salt);
- ldapuser (needs the ldif file below it)
#!/usr/bin/perl
use Net::LDAP;
# configuration section
# edit the next lines to meet your environment
#
$server = "ldap.opencraft.local";
$suffix = "dc=opencraft,dc=local";
$rootdn = "cn=admin,$suffix"; #if not present the script will ask for it
$ou = "ou=People";
$gou = "ou=Group";
$homeDir = "/home/";
# end of configuration
$action = shift;
if ($action eq "useradd") {
$username = shift;
$options = shift;
$groupname = $username;
$_ = $options;
if (/^-g/) {
$groupname = $';
}
ifexist($username,"user","exit");
ifexist($groupname,"group","exit");
adduser();
addgroup($groupname,"auto");
}
elsif ($action eq "groupadd") {
$group = shift;
ifexist($group,"group","exit");
$idNumber = generate_uid_num();
addgroup($group,"user");
}
elsif ($action eq "passwd") {
$username = shift;
print "changing password for user $username";
ifexist($username,"user","continue");
`ldappasswd -x -v -S -w secret -Dcn=admin,dc=opencraft,dc=local uid=$username,ou=People,dc=opencraft,dc=local`;
}
elsif ($action eq "usermod") {
$username = shift;
$changes = shift;
ifexist($username,"user","continue");
usermod();
}
else {
die "you have to specify an action";
}
################################ sub routines ##############################
#
# connect to ldap server
sub ldapconnect {
$ldap = Net::LDAP->new( $server, version => 3 ) or die "new failed : $!";
$ldap->bind( $rootdn,password => 'secret') or die "cannot bind :$!";
}
# disconnect from the server
sub ldapdisconnect {
$ldap->unbind;
}
# add a user
sub adduser {
open(TMP,">/tmp/ldapuser.tmp") || die "cannot cache data: $1";
open(TEMPLATE,"< adduser.ldif") || die "cannot read template file: $!";
while (<TEMPLATE>) {
if (!/^#/) {
@field = split(/:/,$_);
if ($field[1,1] eq "") {
if ($field[1,0] eq "dn") {
$field[1,1] = "uid=$username,$ou,$suffix\n";
}
elsif ($field[1,0] eq "uid") {
$field[1,1] = $username."\n";
}
elsif ($field[1,0] eq "userPassword") {
print "enter value of $field[1,0]-$field[1,2]";
$crypted = generate_pass();
$field[1,1] = $crypted."\n";
}
elsif ($field[1,0] eq "uidNumber") {
$idNumber = generate_uid_num();
$field[1,1] = $idNumber."\n";
}
elsif ($field[1,0] eq "gidNumber") {
$field[1,1] = $idNumber."\n";
}
elsif ($field[1,0] eq "homeDirectory") {
$field[1,1] = $homeDir.$username."\n";
}
elsif ($field[1,0] eq "cn") {
print "enter value of $field[1,0]-$field[1,2]";
my $name = <STDIN>;
$name =~ s/\n//;
$field[1,1] = $name."\n";
}
else {
print "enter value of $field[1,0]-$field[1,2]";
$field[1,1] = <STDIN>;
}
}
print TMP "$field[1,0]:$field[1,1]";
}
}
close (TMP);
print "adding user $username to LDAP . . .";
`ldapadd -x -w secret -D"$rootdn" -f /tmp/ldapuser.tmp`;
print "user added\n";
print "creating home folder . . .";
system ("cp -Rfa /etc/skel/ $homeDir$username & chown -R $username:$username $homeDir$username");
}
# encrypt the password using {crypt}
sub generate_pass {
srand (time());
my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))";
my $salt = sprintf ("%c%c", eval $randletter, eval $randletter);
my $plaintext = <STDIN>;
my $crypttext = "{CRYPT}".crypt ($plaintext, $salt);
return $crypttext;
}
# get the latest uid/gid number to get a new uid for the user or the group
sub generate_uid_num {
ldapconnect();
$searchbase = $suffix;
my $filter = "!(uidNumber=65534)";
my $attrs = "";
my $results = $ldap->search(base=>$searchbase,filter=>$filter,attrs=>$attrs);
my $count = $results->count;
my $entry;
my $list;
for (my $i=0; $i<$count; $i++) {
$entry = $results->entry($i);
if (($entry->get_value('uidNumber')>499 and $entry->get_value('uidNumber')<65534)or($entry->get_value('gidNumber')>499 and $entry->get_value('gidNumber')<65534)) {
$list = $list.",".$entry->get_value('uidNumber').",".$entry->get_value('gidNumber');
}
}
ldapdisconnect();
my @uids = split(/,/,$list);
@uids = sort { $a <=> $b } @uids;
my $count = @uids;
my $last = $uids[$count-1];
my $newuid = $last+1;
return $newuid;
}
# add a group
sub addgroup {
my $name = @_[0];
my $mode = @_[1];
open(TMP2,">/tmp/ldapgroup.tmp") || die "cannot cache data: $1";
open(TEMPLATE2,"< addgroup.ldif") || die "cannot read template file: $!";
while (<TEMPLATE2>) {
if (!/^#/) {
@field = split(/:/,$_);
if ($field[1,1] eq "") {
if ($field[1,0] eq "dn") {
$field[1,1] = "cn=$name,$gou,$suffix\n";
print TMP2 "$field[1,0]:$field[1,1]";
}
elsif ($field[1,0] eq "gidNumber") {
$field[1,1] = $idNumber."\n";
print TMP2 "$field[1,0]:$field[1,1]";
}
elsif ($field[1,0] eq "cn") {
$field[1,1] = $name."\n";
print TMP2 "$field[1,0]:$field[1,1]";
}
elsif ($field[1,0] eq "memberUid") {
if ($mode eq "user") {
print "enter value of $field[1,0]-$field[1,2]";
my $input = <STDIN>;
chomp ($input);
my @members = split(/,/,$input);
ldapconnect();
foreach $member (@members) {
$searchbase = $ou.",".$suffix;
my $filter = "uid=$member";
my $attrs = "uidNumber";
my $results = $ldap->search(base=>$searchbase,filter=>$filter,attrs=>$attrs);
my $entry = $results->entry(0);
my $memberUid = $entry->get_value('uidNumber');
$field[1,1] ="$memberUid\n";
print TMP2 "$field[1,0]:$field[1,1]";
}
ldapdisconnect();
}
elsif ($mode eq "auto") {
$field[1,1] = $idNumber;
print TMP2 "$field[1,0]:$field[1,1]";
}
}
}
else { print TMP2 "$field[1,0]:$field[1,1]"; }
}
}
close (TMP);
print "adding group $group to LDAP . . .";
`ldapadd -x -w secret -D"$rootdn" -f /tmp/ldapgroup.tmp`;
print "group added\n";
}
# modify the users attributes
sub usermod {
my %ReplaceHash = ( keyword => "x", proxy => "x" );
my $result = LDAPmodifyUsingHash ( $ldap, $dn, \%ReplaceHash );
my $result = $ldap->modify ( $dn,replace => { %$whatToChange } );
return $result;
}
# check if user/group exists
sub ifexist {
ldapconnect();
my ($attrib,$entity,$action) = @_;
my $searchbas,$filter,$attrs;
if ($entity eq "group") {
$searchbase = $gou.",".$suffix;
$filter = "cn=$attrib";
$attrs = "gidNumber";
}
else {
$searchbase = $ou.",".$suffix;
$filter = "uid=$attrib";
$attrs = "uidNumber";
}
my $results = $ldap->search(base=>$searchbase,filter=>$filter,attrs=>$attrs);
my $count = $results->count;
if ($count > 0) {
if ($action eq "exit") {
print STDOUT "dependency failure ( user/group exists\nin case you are adding new user you can use -g with useradd to assign another default group)\n";
exit;
}
}
ldapdisconnect();
}
#adduser.ldif the template for new users #this is the template for creating users #syntax: #attr:value:comment #only missing values will be prompted by the scrip #note that even if you won't have comments you need to add the ":" dn::identifier usually the full name or the username objectClass:top objectClass:person objectClass:posixAccount objectClass:shadowAccount objectClass:organizationalPerson objectClass:inetOrgPerson uid::username userPassword::password not less than 5 char uidNumber:: gidNumber:: gecos::more information divided by commas loginShell:/bin/bash homeDirectory::home folder shadowLastChange:10877 shadowMin:0 shadowMax:999999 shadowWarning:7 shadowInactive:-1 shadowExpire:-1 shadowFlag:0 cn:: givenname::surname sn::full name mail::user's email title::job title StreetAddress::home address l::city telephoneNumber::home phone number mobile::mobile number
Comments
Contribution
LDAP stands for Lightweight Directory Access Protocol.
Thanks
this is a wiki page you could contribute direct through the edit tab on the top of the document.
so you can place them(contribution)on the suitable place of the document.
Diaa Radwan
confused
so, Ramez can structure it well.