I would like program to start TLS if the connections isn't already
SSL-encrypted. What is the best way to check that a connection is
SSL-encrypted? I tried using the scheme() method, but I get an error.
Here's the code:
# Connect to LDAP server
my $ldap = Net::LDAP->new(\@ldap_servers,
onerror => 'die'
) || die "Could not connect to LDAP servers.\n";
$connection_scheme = $ldap->scheme();
# Check that we have an encrypted connection. If not, start TLS
if ($connection_scheme ne 'ldaps') {
$ldap->start_tls( verify => 'require',
cafile => $tls_cacert,
capath => $tls_cacertdir
);
}
And here's the error:
Can't locate object method "scheme" via package "Net::LDAP" at
./sns_chsh.pl line 92, <LDAP_CONF> line 16.
Am I using scheme incorrectly?
I could check for the string 'ldaps' in each entry in @ldap_servers, but
I don't know in advance which server new() will connect to, and it's
possible to have this in ldap.conf:
URI ldap://ldap1.example.com ldaps:://ldap2.exmaple.com
so scheme() looks like the most reliable method.
--
Prentice Bisbal
Linux Software Support Specialist/System Administrator
School of Natural Sciences
Institute for Advanced Study
Princeton, NJ
I keep getting "Error changing password: no objectClass attribute".
I cannot find examples doing simple one-at-a-time adds like this. All I
can find are examples using arrays and hashes and cannot seem to
translate it to this. Any tips?
sub resetMacAcct($newuid,$pw,$newpw){
$time = localtime time;
$theirIP = $q->remote_addr();
# create mac account
$macldapsvr = "XXX.XXX.XXX.XXX";
$macADMdn = "uid=admin,cn=people,dc=lib-mac,dc=local";
$macadmpwd ="XXXXXXXX";
$macBind = Net::LDAP->new($macldapsvr,
port => 389,
debug => 0,
timeout => 60,
version => 3
) or die "Couldn't connect to Mac LDAP server: $@";
my $conn = $macBind->bind(dn => $macADMdn,
password => $macadmpwd);
if ($conn->code){
die 'Cannot bind:' . $conn->error . "\n";}
my $macEntry = Net::LDAP::Entry->new;
$newdn="uid=" . $username . ",cn=people,dc=lib-mac,dc=local";
$macEntry->dn($newdn);
# added sha1 hashing
$salt=XX;
$ctx = Digest::SHA1->new;
$ctx->add($newpw);
$ctx->add($salt);
$newMacpw = '{SSHA}' . encode_base64($ctx->digest . $salt ,'');
$macEntry->replace(userPassword => $newMacpw);
my $add = $macBind->add($macEntry);
die "Error changing password: " . $add->error()."\n" if
$add->code();
print LOG "$time;$cn;$theirIP;$username\n";
$macBind->unbind();
}
--
Robert Threet
Systems Manager
USI Computer Center
(812) 465-1082
Confidentiality Statement: This email message, including any
attachments, is for the sole use of the intended recipient(s) and may
contain confidential and privileged information.
I have been using Net::LDAP to create accounts one at a time for about a
year now. Based on the error you are seeing, I suspect that you are
forgetting to add the correct objectClass that contains the attribute
you want to store the attribute in.
Searching your code, I don't see you adding any objectClasses. You just
createa DN, and then add the the password to the userPassword attribute.
I don't know what schema(s) you are using, but for my OpenLDAP server, I
would need to add the objectClass 'top', and then the objectClass of
'person', 'organizationalPerson', or 'inetOrgPerson' before I can add
the userPassword attribute. You can find out exactly what you need by
inspecting your own schema.
Here's a sample of my code. I hope it's still readable after it gets
line-wrapped by our mail clients.
$entry = Net::LDAP::Entry->new($dn,
objectClass =>['top',
'posixAccount',
'shadowAccount',
'inetOrgPerson',
'inetLocalMailRecipient',
'eduPerson'
],
uid => $uid,
uidNumber => $uidnumber,
gidNumber => $gidnumber,
cn => $cn,
sn => $sn,
gecos => $gecos,
homeDirectory => $homedir,
loginShell => $loginshell,
mail => $mail,
mailHost => $mailhost,
mailRoutingAddress => $mailroutingaddress
);
--
Prentice
Give it an object class, like 'person'?
What objectClasses do your extant users have?
> --
> Robert Threet
> Systems Manager
> USI Computer Center
> (812) 465-1082
> Confidentiality Statement: This email message, including any
> attachments, is for the sole use of the intended recipient(s) and may
> contain confidential and privileged information.
--
Brian Reichert <reic...@numachi.com>
55 Crystal Ave. #286
Derry NH 03038-1725 USA BSD admin/developer at large
create the entry first and modify the password by means of password
modify extended operation, perldoc Net::LDAP::Extension::SetPassword
-Dieter
--
Dieter Klünter | Systemberatung
http://dkluenter.de
GPG Key ID:DA147B05
53°37'09,95"N
10°08'02,42"E
1. Are you sure that the entry you are trying to modify exists in LDAP?
Can you find it by doing an ldapsearch?
2. Are you sure the attribute that holds password is named 'userPassword'?
This is really a simple task, which makes me think something else is
wrong. In my perl script for changing a user's password, it's this
simple (using a different Net::LDAP function):
use Net::LDAP::Extension::SetPassword;
...
...
$mesg = $ldap->set_password(user => $ldap_user_dn,
newpasswd => $new_passwd);
--
Prentice
Robert Threet wrote:
> I injected the dn but now it complains - objectclass person requires
> surname. Tried them all - they all say that. Grr! Just want to change
> the password without knowing the old password.
> I have a working Net::LDAP::Entry program for adding users so I decided
> to gut it to create a userPassword changer.
>
> I keep getting "Error changing password: no objectClass attribute".
>
> I cannot find examples doing simple one-at-a-time adds like this. All I
> can find are examples using arrays and hashes and cannot seem to
> translate it to this. Any tips?
There's a simple example right at the top of the Net::LDAP man page :-)
Or at <http://search.cpan.org/~gbarr/perl-ldap/lib/Net/LDAP.pod> if you prefer:
---
$result = $ldap->add( 'cn=Barbara Jensen, o=University of Michigan, c=US',
attr => [
'cn' => ['Barbara Jensen', 'Barbs Jensen'],
'sn' => 'Jensen',
'mail' => 'b.je...@umich.edu',
'objectclass' => ['top', 'person',
'organizationalPerson',
'inetOrgPerson' ],
]
);
$result->code && warn "failed to add entry: ", $result->error ;
---
Chris
>
> Yeah - adds work great! I didn't get how to modify the password. It looks like you have to read in the entire entry - modify - then re-add it. Noticed that thinking in the LDAP Admin Guide Friday night.
No, that absolutely shouldn't be necessary. LDAP's modify operation primitives let you change attributes without needing to read them first.
But there's maybe some confusion here. You say you're trying to modify a password, but your "resetMacAcct" subroutine is adding an entry, *not* modifying it. You're not supplying enough attributes to add a valid entry, so the server rejects it with a reasonable-looking error.
If you want to modify a password, replace (sic) this code:
---old-code
$macEntry->replace(userPassword => $newMacpw);
my $add = $macBind->add($macEntry);
---old-code
with this:
---new-code
my $add = $macBind->modify($newdn,
replace => { 'userPassword' => $newMacpw });
---new-code
Note you don't need to create a $macEntry object, so you can delete those lines of code.
This code could still fail if the server is configured to check the "quality" of new passwords. It can't check a hashed password, so might reject the modify. It might also be configured to force the old password to be provided together with the new, and your script running as manager doesn't seem to have the old password.
The last way this could fail is if the server stores passwords in a different attribute, or encoded in some way. ActiveDirectory does both of those things, so you need to watch if you're using ActiveDirectory vs an LDAP server.
Chris
Robert Threet
Systems Manager
USI Computer Center
Confidentiality Statement: This email message, including any attachments, is for the sole use of the intended recipient(s) and may contain confidential and privileged information.
________________________________________
From: Chris Ridd [chri...@mac.com]
Sent: Saturday, February 19, 2011 5:58 AM
To: Threet, Robert A
Cc: perl...@perl.org
Subject: Re: Password modify
On 17 Feb 2011, at 17:10, Robert Threet wrote: