Further work on LDAP passwords (working on an ldap-adduser).
Sergey V Kovalyov <sqk0316@SCIRES.ACF.NYU.EDU> writes:
> It is a package in potato.
Ahh. Though I imagine that this doesn't really help in the ldap case.
When using ldap, you can't use adduser if you really want ldap to be
serving a number of machines. You need to have some script that adds
entries to the ldap server after determining what the next valid user
id is, then runs some commands to create user directores everywhere
that is appropriate (in our case it'll be creating a coda volume), but
in many cases, you might want to use cfengine or something to create
new directories on many machines.
So my-ldap-adduser should look something like this:
1) acquire a global (across all the involved machines) lock (or just
presume that only one machine will ever be used to add users and
acquire a local lock). [1]
2) get the next user id (how?). [1]
3) generate a new entry for the new user (I guess you'll have to
make sure you compute the encrypted password in a way that's
consistent with the current /etc/login.defs so technically you
should parse that to see what types of encryption are allowed --
messy...)
4) add that entry into the current ldap database using ldap_add (or
the perl LDAP module).
5) Run a script to do whatever's needed to create the user's home
directory in all the right places [1].
[1] Each of these steps should probably look up what script to run to
get the required value or do the required job in a config file or an
environment variable (sort of like adduser.local). That way different
sites could handle these issues different ways.
If I just assume that md5 passwords are allowed, and I assume that no
one will ever run this script on two machines simultaneously (avoiding
the unique ID/name problem), then I think I can see how to do this.
However, right now I'm stuck on step 4. I wrote a simple perl script
to add a trivial user, but slapd's not cooperating. From the logs, it
seems to be an authentication issue, but I'm not sure why.
When I installed openldapd, it set up the admin user with a password,
and in /etc/openldapd/slapd.conf I can see that that user's allowed to
do anything:
access to * by dn="cn=admin, ou=People, dc=localnet" write
The perl script I'm running looks like this:
#!/usr/bin/perl -w
use strict;
use English;
use Net::LDAP;
STDOUT->autoflush(1);
STDERR->autoflush(1);
my $server = Net::LDAP->new('localhost') or die "$@";
my $result = $server->bind('dn' => 'cn=admin,ou=people,dc=localnet',
'password' => 'some-password');
$result->code && die "result [" . $result->error . "]\n";
my %new_user = ('dn' => 'cn=faust,ou=people,dc=localnet',
'attr' => [ 'cn' => 'admin' ]);
$result = $server->add(%new_user);
$result->code && warn "failed to add entry: [" . $result->error . "]";
$server->unbind;
And the result looks like this:
failed to add entry: [] at ./rlab-add-user line 36.
And the relevant bit of the log (loglevel 2279) looks like this (you
can see that it does successfully authenticate admin at the start, but
then it prints the "denied by default" bit after it tries the regex
match. Anyone know what's going on?):
slapd[24000]: do_bind
slapd[24000]: do_bind: version 2 dn (cn=admin,ou=people,dc=localnet) method 128
slapd[24000]: ==> ldbm_back_bind: dn: CN=ADMIN,OU=PEOPLE,DC=LOCALNET
slapd[24000]: dn2entry_r: dn: "CN=ADMIN,OU=PEOPLE,DC=LOCALNET"
slapd[24000]: => dn2id( "CN=ADMIN,OU=PEOPLE,DC=LOCALNET" )
slapd[24000]: ====> cache_find_entry_dn2id: found dn: CN=ADMIN,OU=PEOPLE,DC=LOCALNET
slapd[24000]: <= dn2id 3 (in cache)
slapd[24000]: => id2entry_r( 3 )
slapd[24000]: ====> cache_find_entry_dn2id: found id: 3 rw: 0
slapd[24000]: entry_rdwr_rtrylock: ID: 3
slapd[24000]: <= id2entry_r 0x8088dc0 (cache)
slapd[24000]: ====> cache_return_entry_r
slapd[24000]: entry_rdwr_runlock: ID: 3
slapd[24000]: do_bind: bound "cn=admin,ou=people,dc=localnet" to "cn=admin, ou=People, dc=localnet"
slapd[24000]: send_ldap_result 0::
slapd[24001]: do_add
slapd[24001]: do_add: ndn (CN=FAUST,OU=PEOPLE,DC=LOCALNET)
slapd[24001]: ==> ldbm_back_add: cn=faust,ou=people,dc=localnet
slapd[24001]: => dn2id( "CN=FAUST,OU=PEOPLE,DC=LOCALNET" )
slapd[24001]: => ldbm_cache_open( "/var/lib/openldap/dn2id.dbb", 66, 600 )
slapd[24001]: <= ldbm_cache_open (cache 0)
slapd[24001]: <= dn2id NOID
slapd[24001]: dn2entry_w: dn: "OU=PEOPLE,DC=LOCALNET"
slapd[24001]: => dn2id( "OU=PEOPLE,DC=LOCALNET" )
slapd[24001]: ====> cache_find_entry_dn2id: found dn: OU=PEOPLE,DC=LOCALNET
slapd[24001]: <= dn2id 2 (in cache)
slapd[24001]: => id2entry_w( 2 )
slapd[24001]: ====> cache_find_entry_dn2id: found id: 2 rw: 1
slapd[24001]: entry_rdwr_wtrylock: ID: 2
slapd[24001]: <= id2entry_w 0x808ca30 (cache)
slapd[24001]: => access_allowed: entry (ou=People, dc=localnet) attr (children)
slapd[24001]: => acl_get: entry (ou=People, dc=localnet) attr (children)
slapd[24001]: => acl_get: edn OU=PEOPLE,DC=LOCALNET
slapd[24001]: => acl_get: [1] check attr children
slapd[24001]: => dnpat: [2] .* nsub: 0
slapd[24001]: => acl_get:[2] backend ACL match
slapd[24001]: => acl_get: [2] check attr children
slapd[24001]: <= acl_get: [2] backend acl ou=People, dc=localnet attr: children
slapd[24001]: => acl_access_allowed: write access to entry "ou=People, dc=localnet"
slapd[24001]: => acl_access_allowed: write access to value "any" by "CN=ADMIN,OU=PEOPLE,DC=LOCALNET"
slapd[24001]: <= check a_dnpat: CN=ADMIN, OU=PEOPLE, DC=LOCALNET
slapd[24001]: => string_expand: pattern: CN=ADMIN, OU=PEOPLE, DC=LOCALNET
slapd[24001]: => string_expand: expanded: CN=ADMIN, OU=PEOPLE, DC=LOCALNET
slapd[24001]: => regex_matches: string: CN=ADMIN,OU=PEOPLE,DC=LOCALNET
slapd[24001]: => regex_matches: rc: 1 no matches
slapd[24001]: <= acl_access_allowed: denied by default (no matching by)
slapd[24001]: => access_allowed: exit (ou=People, dc=localnet) attr (children)
slapd[24001]: no access to parent
slapd[24001]: send_ldap_result 50::
slapd[24001]: ====> cache_return_entry_w
slapd[24001]: entry_rdwr_wunlock: ID: 2
slapd[24002]: do_unbind
Thanks
--
Rob Browning <rlb@cs.utexas.edu> PGP=E80E0D04F521A094 532B97F5D64E3930
Reply to: