1
|
#!/usr/bin/perl -w
|
2
|
#======================================================
|
3
|
# Change password script for EOLE
|
4
|
#
|
5
|
# AUTHOR Clement OUDOT AT linagora DOT com
|
6
|
#======================================================
|
7
|
|
8
|
use strict;
|
9
|
use Net::LDAP;
|
10
|
use Crypt::SmbHash qw(lmhash nthash);
|
11
|
use Crypt::SaltedHash;
|
12
|
use Unicode::String qw(utf8);
|
13
|
use smbldap_tools;
|
14
|
|
15
|
## PARAMETERS
|
16
|
my ( $user, $password, $changePwd ) = splice @ARGV;
|
17
|
unless ( $user && $password ) {
|
18
|
print STDERR "Usage: $0 [user] [password] [changePwd]\n";
|
19
|
exit 1;
|
20
|
}
|
21
|
|
22
|
## CONFIG
|
23
|
# OpenLDAP/Samba (use $config from smbldap-tools)
|
24
|
my $openldap_server = "ldap://$config{masterLDAP}";
|
25
|
my $openldap_binddn = $config{masterDN};
|
26
|
my $openldap_bindpw = $config{masterPw};
|
27
|
my $openldap_base = $config{usersdn};
|
28
|
my $openldap_filter = "(&(objectClass=inetOrgPerson)(uid=$user))";
|
29
|
my $openldap_scope = "sub";
|
30
|
my $openldap_attrs = ['1.1'];
|
31
|
my $openldap_use_ssha = 1;
|
32
|
|
33
|
# Active Directory
|
34
|
my $ad_server = "$config{adserver}";
|
35
|
my $ad_binddn = "$config{aduser}";
|
36
|
my $ad_bindpw = "$config{adpassword}";
|
37
|
my $ad_base = "$config{adbase}";
|
38
|
my $ad_filter = "(&(objectClass=person)(sAMAccountName=$user))";
|
39
|
my $ad_scope = "sub";
|
40
|
my $ad_attrs = ['1.1'];
|
41
|
|
42
|
## INIT CHECKS
|
43
|
unless ( defined $openldap_server ) {
|
44
|
print STDERR "OpenLDAP configuration missing\n";
|
45
|
exit 1;
|
46
|
}
|
47
|
|
48
|
## SUBROUTINES
|
49
|
sub connect {
|
50
|
my ( $server, $binddn, $bindpw ) = splice @_;
|
51
|
|
52
|
my $ldap = Net::LDAP->new( $server, version => 3 );
|
53
|
|
54
|
if ($@) {
|
55
|
print STDERR "Unable to connect to $server ($@)\n";
|
56
|
exit 1;
|
57
|
}
|
58
|
|
59
|
my $bind = $ldap->bind( $binddn, password => $bindpw );
|
60
|
|
61
|
if ( $bind->is_error ) {
|
62
|
print STDERR "Unable to bind to $server with $binddn ("
|
63
|
. $bind->error . ")\n";
|
64
|
exit 1;
|
65
|
}
|
66
|
|
67
|
return $ldap;
|
68
|
}
|
69
|
|
70
|
sub get_user {
|
71
|
my ( $ldap, $base, $filter, $scope, $attrs ) = splice @_;
|
72
|
|
73
|
my $search = $ldap->search(
|
74
|
base => $base,
|
75
|
filter => $filter,
|
76
|
scope => $scope,
|
77
|
attrs => $attrs
|
78
|
);
|
79
|
|
80
|
if ( $search->is_error ) {
|
81
|
print STDERR "Unable to search user $user (" . $search->error . ")\n";
|
82
|
exit 1;
|
83
|
}
|
84
|
|
85
|
if ( $search->count > 1 ) {
|
86
|
print STDERR "More than one user $user found\n";
|
87
|
exit 1;
|
88
|
}
|
89
|
|
90
|
if ( $search->count < 1 ) {
|
91
|
print STDERR "User $user not found\n";
|
92
|
exit 1;
|
93
|
}
|
94
|
|
95
|
my $entry = $search->shift_entry;
|
96
|
|
97
|
return $entry;
|
98
|
}
|
99
|
|
100
|
sub modify_password {
|
101
|
my ( $ldap, $dn, $attr, $value ) = splice @_;
|
102
|
|
103
|
my $modify = $ldap->modify( $dn, replace => { $attr => $value } );
|
104
|
|
105
|
if ( $modify->is_error ) {
|
106
|
print STDERR "Unable to modify $attr for $dn ("
|
107
|
. $modify->error . ")\n";
|
108
|
exit 1;
|
109
|
}
|
110
|
|
111
|
return 1;
|
112
|
}
|
113
|
|
114
|
## MAIN
|
115
|
# Change password in OpenLDAP
|
116
|
my $openldap = &connect( $openldap_server, $openldap_binddn, $openldap_bindpw );
|
117
|
my $openldap_entry = &get_user(
|
118
|
$openldap, $openldap_base, $openldap_filter,
|
119
|
$openldap_scope, $openldap_attrs
|
120
|
);
|
121
|
|
122
|
my $userpassword = $password;
|
123
|
if ($openldap_use_ssha) {
|
124
|
my $csh = Crypt::SaltedHash->new( algorithm => 'SHA-1' );
|
125
|
$csh->add($password);
|
126
|
my $salted = $csh->generate;
|
127
|
$userpassword = $salted;
|
128
|
}
|
129
|
|
130
|
&modify_password( $openldap, $openldap_entry->dn, 'userPassword',
|
131
|
$userpassword );
|
132
|
&modify_password( $openldap, $openldap_entry->dn, 'sambaLMPassword',
|
133
|
lmhash $password );
|
134
|
&modify_password( $openldap, $openldap_entry->dn, 'sambaNTPassword',
|
135
|
nthash $password );
|
136
|
|
137
|
# Change passord in AD if configured
|
138
|
if ($ad_server) {
|
139
|
my $ad = &connect( $ad_server, $ad_binddn, $ad_bindpw );
|
140
|
my $ad_entry = &get_user( $ad, $ad_base, $ad_filter, $ad_scope, $ad_attrs );
|
141
|
&modify_password( $ad, $ad_entry->dn, 'unicodePwd', utf8( chr(34) . ${password} . chr(34) )->utf16le() );
|
142
|
if( defined $changePwd && $changePwd == 1 ) {
|
143
|
&modify_password( $ad, $ad_entry->dn, 'pwdLastSet', '0' );
|
144
|
}
|
145
|
}
|
146
|
|
147
|
## END
|
148
|
print "Password changed\n";
|
149
|
exit 0;
|