Mandi! Benoit Mortier
In chel di` si favelave...
> could you post them here so we could test them
Many more sent me similar request in private, i was really happy to
know that my little work can be useful!
Someone, expecially the main developer jerome, ask me directly to
commit patches to the repository: i'm a very dumb programmer,
expecially in perl, and i've so little time that i've never ''studied''
the code management system apart using the vary 'svn update *' and so
on.
So i prefere to post patches here, and let someone with good perl
skills to double check them.
Consider also that these patches are against the debian lenny version,
because i've used to build a custom version to redistriute in my
servers. Eg, probably not tyhe freshest 'sources'.
I've speaked too much, i'll attach the patches, directly as used in
debian package.
9000_gaio_smbldap-passwd.patch:
+ as stated, fix the incompatibility with samba 3.2 in lenny
9001_gaio_smbldap-useraccess.patch:
+ new script
9002_gaio_smbldap-useradd.patch:
+ fix incompatibility with samba 3.2
+ fix -T opton
+ add -W option (email expiration hack)
9003_gaio_smbldap-userexpire.patch:
+ new script
9004_gaio_smbldap-usermod.patch:
+ fix incompatibility with samba 3.2
+ fix -T opton
+ add -W option (email expiration hack)
9005_gaio_smbldap-userwarn.patch
+ new script
Some values (eg, mos notably POSIX/shadow tereshold) are hardcoded on
scripts, and clerly implementing the '-W' hack need the MTA
''collaboration''... ;-)
[i've done with exim]
--
dott. Marco Gaiarin GNUPG Key ID: 240A3D66
Associazione ``La Nostra Famiglia'' http://www.sv.lnf.it/
Polo FVG - Via della Bontà , 7 - 33078 - San Vito al Tagliamento (PN)
marco.gaiarin(at)sv.lnf.it tel +39-0434-842711 fax +39-0434-842797
Dona il 5 PER MILLE a LA NOSTRA FAMIGLIA!
http://www.lanostrafamiglia.it/chi_siamo/5xmille.php
(cf 00307430132, categoria ONLUS oppure RICERCA SANITARIA)
--- smbldap-tools-0.9.4/smbldap-passwd 2010-06-18 12:56:35.072322983 +0200
+++ dev/smbldap-passwd 2011-02-15 12:57:22.644598592 +0100
@@ -222,13 +222,13 @@
}
}
if ($force_update_samba_passwd == 1) {
- # To force a user to change his password:
- # . the attribut sambaPwdLastSet must be != 0
+ # To force a user to change his password (in samba >= 3.2):
+ # . the attribut sambaPwdLastSet must be == 0
# . the attribut sambaAcctFlags must not match the 'X' flag
my $winmagic = 2147483647;
my $valacctflags = "[U]";
push(@mods, 'sambaPwdMustChange' => 0);
- push(@mods, 'sambaPwdLastSet' => $winmagic);
+ push(@mods, 'sambaPwdLastSet' => 0);
push(@mods, 'sambaAcctFlags' => $valacctflags);
}
# Let's change nt/lm passwords
--- smbldap-tools-0.9.4/smbldap-useraccess 1970-01-01 01:00:00.000000000 +0100
+++ dev/smbldap-useraccess 2011-02-15 12:57:22.672639262 +0100
@@ -0,0 +1,135 @@
+#!/usr/bin/perl -w
+
+# This code was developped by Marco Gaiarin <[email protected]>
+# taking ideas and code from smbldap-tools script by IDEALX
+# (http://IDEALX.org/) and
+#
+# Copyright (C) 2006 Marco Gaiarin
+# Copyright (C) 2001-2002 IDEALX
+#
+# 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.
+
+# Purpose of smbldap-useraccess : update access (logon/logoff) time
+
+use strict;
+use smbldap_tools;
+
+#####################
+
+use Getopt::Std;
+my %Options;
+
+my $ok = getopts('t:nfh?', \%Options);
+if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) || ($Options{'h'}) ) {
+ print_banner;
+ print "Usage: $0 [-nft?h] username\n";
+ print "Available options are:\n";
+ print " -n write LogOn timestamp\n";
+ print " -f write LogOff timestamp\n";
+ print " -t timestamp\n";
+ print " -?|-h show this help message\n";
+ exit (1);
+}
+
+if ((! $Options{'n'}) && (! $Options{'f'})) {
+ print "At least one of -n or -f have to be specified.\n";
+ exit(1);
+}
+
+if ($< != 0) {
+ print "You must be root to modify an user\n";
+ exit (1);
+}
+# Read only first @ARGV
+my $user = $ARGV[0];
+
+# Let's connect to the directory first
+my $ldap_master=connect_ldap_master();
+
+# Read user data
+my $user_entry = read_user_entry($user);
+if (!defined($user_entry)) {
+ print "$0: user $user doesn't exist\n";
+ exit (1);
+}
+
+if (!grep ($_ =~ /^sambaSamAccount$/i, $user_entry->get_value('objectClass'))) {
+ print "$0: user $user doesn't have samba data, nothing to do.\n";
+ exit(1);
+}
+
+# get the dn of the user
+my $dn= $user_entry->dn();
+
+# some vars...
+my @mods;
+my $tmp;
+my $date;
+if (defined($tmp = $Options{'t'})) {
+ $date=int($tmp);
+} else {
+ $date=time;
+}
+
+# build data snippet...
+if ($Options{'n'}) {
+ push(@mods, 'sambaLogonTime' => $date);
+}
+if ($Options{'f'}) {
+ push(@mods, 'sambaLogoffTime' => $date);
+}
+
+# apply changes
+my $modify = $ldap_master->modify ( "$dn",
+ 'replace' => { @mods }
+ );
+$modify->code && warn "failed to modify entry: ", $modify->error ;
+
+# take down session
+$ldap_master->unbind;
+
+# there's no need to tackle with nscd...
+
+############################################################
+
+=head1 NAME
+
+smbldap-useraccess - Update user account access timestamps
+
+=head1 SYNOPSIS
+
+smbldap-useraccess [-n] [-f] [-t timestamp] login
+
+=head1 DESCRIPTION
+
+The smbldap-useraccess command update the user access timestamp field to current or specified time. The options which apply to the usermod command are
+
+-n
+ Update LogOn timestamp
+
+-f
+ Update LogOff timestamp
+
+-t timestamp
+ Use timestamp as value, otherwise use current time
+
+=head1 SEE ALSO
+
+ smbldap-usermod(1)
+
+=cut
+
+#'
--- smbldap-tools-0.9.4/smbldap-useradd 2010-06-18 12:56:34.964272421 +0200
+++ dev/smbldap-useradd 2011-02-15 12:57:22.688604036 +0100
@@ -35,7 +35,8 @@
use Getopt::Std;
my %Options;
-my $ok = getopts('o:abnmwiPG:u:g:d:s:c:k:t:A:B:C:D:E:F:H:M:N:S:T:?', \%Options);
+
+my $ok = getopts('o:abnmwiPG:u:g:d:s:c:k:t:A:B:C:D:E:F:H:M:N:S:T:W:?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
print_banner;
@@ -67,6 +68,7 @@
print " -P ends by invoking smbldap-passwd\n";
print " -S surname (Family name)\n";
print " -T mailToAddress (forward address) (comma seperated)\n";
+ print " -W forward expiration (in days from now, default unlimited)\n";
print " -? show this help message\n";
exit (1);
}
@@ -402,7 +404,12 @@
push(@adds, 'mail' => [ @mail ]);
}
if (@userMailTo) {
- push(@adds, 'mailRoutingAddress' => [ @userMailTo ]);
+ my $suserMailTo = join(',', @userMailTo);
+ if (defined($Options{'W'})) {
+ my $localtime = time/86400;
+ $suserMailTo = $suserMailTo . ':' . int($localtime + $Options{'W'});
+ }
+ push(@adds, 'mailRoutingAddress' => $suserMailTo );
}
if (@userMailLocal || @userMailTo) {
push(@adds, 'objectClass' => 'inetLocalMailRecipient');
@@ -429,10 +436,10 @@
if (defined($tmp = $Options{'B'})) {
if ($tmp != 0) {
$valpwdmustchange = "0";
- # To force a user to change his password:
- # . the attribut sambaPwdLastSet must be != 0
+ # To force a user to change his password (in samba >= 3.2):
+ # . the attribut sambaPwdLastSet must be == 0
# . the attribut sambaAcctFlags must not match the 'X' flag
- $valpwdlastset=$winmagic;
+ $valpwdlastset= 0;
$valacctflags = "[U]";
} else {
$valpwdmustchange = "$winmagic";
@@ -640,6 +647,9 @@
-T mailToAddress
Forward address (multiple addresses are seperated by spaces)
+-W days
+ Add a custom ':date' to forward address as an expiration date
+
-n
do not print banner message
--- smbldap-tools-0.9.4/smbldap-userexpire 1970-01-01 01:00:00.000000000 +0100
+++ dev/smbldap-userexpire 2011-02-15 12:57:22.712600713 +0100
@@ -0,0 +1,337 @@
+#!/usr/bin/perl -w
+
+# This code was developped by Marco Gaiarin <[email protected]>
+# taking ideas and code from smbldap-tools script by IDEALX
+# (http://IDEALX.org/) and
+#
+# Copyright (C) 2006 Marco Gaiarin
+# Copyright (C) 2001-2002 IDEALX
+#
+# 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.
+
+# Purpose of smbldap-userexpire: expire user (posix,shadow,samba) after some
+# inactivity time
+
+# CHANGELOG
+#
+# (Thu Jul 20 16:12:39 CEST 2006)
+# + added -P options, rename all POSIX options
+# + considering the case sambaLogonTime < sambaPwdLastSet
+# (Wed May 12 16:18:13 CEST 2010)
+# + some logic change in how 'change password on logon' are handled, so fixup
+# this script accordingly
+# (Tue Jun 15 11:53:18 CEST 2010)
+# + adding 'T' options to expire email forward.
+# (Mon Feb 14 15:26:20 CET 2011)
+# + some cleanup for smbldap-userwarn
+# + rewrite default value in term of $config{defaultMaxPasswordAge}) factors
+
+use strict;
+use smbldap_tools;
+
+#####################
+
+use Getopt::Std;
+my %Options;
+
+# getting some info from config file, setting some default.
+#
+my $pwdage = 90; # Samba password duration, also taken from config file
+if (defined $config{defaultMaxPasswordAge}) {
+ $pwdage = $config{defaultMaxPasswordAge};
+}
+my $acctage = $pwdage * 2; # Samba account duration
+my $pxpwdage = int($pwdage*5/4); # POSIX password duration
+my $pxacctage = int($pwdage*9/4); # POSIX account duration; NOTE that if you don't setup a pam layer for password change, via winbind, at password expiration there's no way to logon anymore.
+my $pxwarndays = 14; # POSIX warning days for password expiration
+my $hash = "SSHA";
+if (defined $config{hash_encrypt}) {
+ $hash = $config{hash_encrypt};
+}
+
+my $ok = getopts('vdfsp:a:P:A:W:Th?', \%Options);
+if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) || ($Options{'h'}) ) {
+ print_banner;
+ print "Usage: $0 [-vdfsT?h] [-p days] [-a days] [-P days] [-A days] [-W days] username\n";
+ print "Available options are:\n";
+ print " -v verbose mode\n";
+ print " -d dry-run (do all the checks but just not update)\n";
+ print " -f fix broken/impossible value\n";
+ print " -s fix also POSIX/shadow account information\n";
+ print " -p password age, default $pwdage (in days)\n";
+ print " -a account age, default $acctage (in days)\n";
+ print " -P POSIX password age, default $pxpwdage (in days)\n";
+ print " -A POSIX account age, default $pxacctage (in days)\n";
+ print " -W POSIX warning days before expiring, default $pxwarndays (in days)\n";
+ print " -T Expire mailToAddress (forward)\n";
+ print " -?|-h show this help message\n";
+ exit (1);
+}
+
+if ($< != 0) {
+ print "You must be root to modify an user\n";
+ exit (1);
+}
+# Read only first @ARGV
+my $user = $ARGV[0];
+
+# Let's connect to the directory first
+my $ldap_master=connect_ldap_master();
+
+# Read user data
+my $user_entry = read_user_entry($user);
+if (!defined($user_entry)) {
+ if ($Options{'v'}) {
+ print "$0: user $user doesn't exist\n";
+ }
+ exit (1);
+}
+my $dn = $user_entry->dn();
+
+# some vars...
+my @mods;
+my $tmp;
+my constant $max = 2147483647;
+my $retval = 0;
+my $curdate = time;
+
+# reapup account ages on commandline...
+if (defined($tmp = $Options{'p'})) {
+ $pwdage = int($tmp);
+}
+if (defined($tmp = $Options{'a'})) {
+ $acctage = int($tmp);
+}
+if (defined($tmp = $Options{'P'})) {
+ $pxpwdage = int($tmp);
+}
+if (defined($tmp = $Options{'A'})) {
+ $pxacctage = int($tmp);
+}
+if (defined($tmp = $Options{'W'})) {
+ $pxwarndays = int($tmp);
+}
+
+# no samba?
+if ( ! grep ($_ =~ /^sambaSamAccount$/i, $user_entry->get_value('objectClass'))) {
+ if ($Options{'v'}) {
+ print "$0: user $user doesn't have samba data.\n";
+ }
+} else {
+ # Password expiration are handled automatically by samba, here we do only
+ # some check... note that we use a theresold value of one day for password
+ # expiration...
+ my $pls = $user_entry->get_value('sambaPwdLastSet');
+ if (! defined($pls) ) {
+ $pls = 0;
+ }
+ my $pmc = $user_entry->get_value('sambaPwdMustChange');
+ if (! defined($pmc) ) {
+ $pmc = 0;
+ }
+ my $af = $user_entry->get_value('sambaAcctFlags');
+ if ($Options{'f'}) {
+ if ( $pls > $curdate ) {
+ $pls = $curdate;
+ if ($Options{'v'}) {
+ print "$0: user $user sambaPwdLastSet invalid, resetting to $pls\n";
+ }
+ push(@mods, 'sambaPwdLastSet' => $pls);
+ }
+
+ if ( $pmc > $curdate + (($pwdage+1)*24*60*60) ) {
+ $pmc = $curdate;
+ if ($Options{'v'}) {
+ print "$0: user $user sambaPwdMustChange too high, resetting to $pmc\n";
+ }
+ push(@mods, 'sambaPwdMustChange' => $pmc);
+ }
+
+ if ( $af =~ /X/ ) {
+ if ($Options{'v'}) {
+ print "$0: user $user sambaAcctFlags 'X' enabled, resetting it\n";
+ }
+ $af =~ s/X//;
+ push(@mods, 'sambaAcctFlags' => $af);
+ }
+ }
+
+ # account expiration/disabling...
+ my $lot = $user_entry->get_value('sambaLogonTime');
+ if (! defined($lot) ) {
+ $lot = 0;
+ }
+ if ( $lot < $pls ) {
+ # strange, this user have a logon time smaller than last pwd set, could
+ # be a real UNIX guy that use smbpasswd by hand?
+ # anyway we consider this an access...
+ if ($Options{'v'}) {
+ print "$0: user $user sambaPwdLastSet considered as an access\n";
+ }
+ $lot = $pls;
+ push(@mods, 'sambaLogonTime' => $lot);
+ }
+ if ( ($pls > 0) && ($lot < $curdate - ($acctage*24*60*60)) && ($af !~ /D/) ) {
+ if ($Options{'v'}) {
+ print "$0: user $user sambaLogonTime too low, disabling account\n";
+ }
+ $af =~ s/U/DU/;
+ push(@mods, 'sambaAcctFlags' => $af);
+ $retval += 2;
+ }
+
+ # no POSIX?
+ if ( ! grep ($_ =~ /^posixAccount$/i, $user_entry->get_value('objectClass'))) {
+ if ($Options{'v'}) {
+ print "$0: user $user doesn't have POSIX data.\n";
+ }
+ } else {
+ # Eventually adding missing shadowAccount OC
+ if ( ($Options{'s'}) && (! grep ($_ =~ /^shadowAccount$/i, $user_entry->get_value('objectClass'))) ) {
+ my @objectclass = $user_entry->get_value('objectClass');
+ push(@mods, 'objectClass' => [ @objectclass, 'shadowAccount' ]);
+ if ($Options{'v'}) {
+ print "$0: user $user shadowAccount ObjectClass missing added\n";
+ }
+ }
+
+ # if we are using shadow, this could be excessive, but better do this
+ # then risk to have and open access lying around...
+ my $up = $user_entry->get_value('userPassword');
+ if ( ($Options{'s'}) && ($lot < $curdate - ($pxacctage*24*60*60)) && ($up !~ /}!/) ) {
+ if ($Options{'v'}) {
+ print "$0: user $user sambaLogonTime really too low, disabling POSIX account\n";
+ }
+ $up = "{" . $hash . "}!x";
+ push(@mods, 'userPassword' => $up);
+ $retval += 4;
+ }
+
+ # poking POSIX shadow data...
+ if ( $Options{'s'} ) {
+ my $lc = $user_entry->get_value('shadowLastChange');
+ if ( ! defined($lc) ) {
+ $lc = 0;
+ }
+ my $slc = int ($pls/(24*60*60));
+ if ( $lc != $slc ) {
+ if ($Options{'v'}) {
+ print "$0: user $user setting up shadow data\n";
+ }
+ push(@mods, 'shadowLastChange' => $slc);
+ push(@mods, 'shadowMin' => 0);
+ push(@mods, 'shadowMax' => $pxpwdage);
+ push(@mods, 'shadowWarning' => $pxwarndays);
+ push(@mods, 'shadowInactive' => ($pxacctage - $pxpwdage) );
+ }
+ }
+ }
+}
+
+# redirection expiring
+my $mrae;
+if ( (grep ($_ =~ /^inetLocalMailRecipient$/i, $user_entry->get_value('objectClass'))) && ($Options{'T'}) && (defined($mrae = $user_entry->get_value('mailRoutingAddress'))) ) {
+ my ($mra, $mex) = split(/:/, $mrae, 2);
+ if ( (defined($mex)) && ($mex < $curdate/(60*60*24)) ) {
+ if ($Options{'v'}) {
+ print "$0: user $user expiring email forward (was $mra)\n";
+ }
+ push(@mods, 'mailRoutingAddress' => '');
+ $retval += 8;
+ }
+}
+
+# apply changes
+if ( (@mods) && (! $Options{'d'}) ) {
+ my $modify = $ldap_master->modify ( "$dn",
+ 'replace' => { @mods }
+ );
+ $modify->code && warn "failed to modify entry: ", $modify->error ;
+}
+
+# take down session
+$ldap_master->unbind;
+
+# need to tackle with nscd...
+if ( (@mods) && (! $Options{'d'}) ) {
+ my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
+ if ($nscd_status == 0) {
+ system "/etc/init.d/nscd restart > /dev/null 2>&1";
+ }
+}
+
+# we exit with a well-known exit status, so if we change something
+# important we can warn users...
+exit($retval);
+
+############################################################
+
+=head1 NAME
+
+smbldap-userexpire - Expire user account based on last access time
+
+=head1 SYNOPSIS
+
+smbldap-userexpire [-v] [-d] [-f] [-s] [-p days] [-a days] [-x days] login
+
+=head1 DESCRIPTION
+
+The smbldap-userexpire command check for account access timestamp, and update account info accordingly, typically disabling account if not used by some time.
+
+-v
+ Verbose mode, print any action taken
+
+-d
+ Dry-run, actually compute all needed modification but not apply them; usually used in conjunction with -v
+
+-f
+ Fix broken/impossible data, that can prevent an account to expire
+
+-s
+ Fix also POSIX/shadow data; note that LDAP shadow data can not be used, so this script also set the POSIX password invalid
+
+-p days
+ Password age in days (also use defaultMaxPasswordAge in smbldap.conf)
+
+-a days
+ Samba Account age in days
+
+-P days
+ POSIX password age in days
+
+-A days
+ POSIX Account age in days
+
+-W days
+ POSIX warning days before expiring; in PAM-enabled environment, the POSIX layer will warn users that password are expiring
+
+-T
+ Expire mail forward/redirection (mailRoutingAddress)
+
+=head1 RETURN VALUES
+
+This script return 0 if all goes well, 1 if something goes wrong, 2 if all goes well and a Samba account was disabled, 4 if all goes well and POSIX account was disabled and 8 if all goes well and email forward was disabled.
+Last three exit codes are bitwise combinable, so you can catch all condidion.
+
+This is intended so you can catch return value, and do something (send an email, ...) to user. For the same reason Samba account age <> POSIX account age, with the latter better to be highest then the former.
+
+=head1 SEE ALSO
+
+ smbldap-usermod(1) smbldap-useraccess(1) chage(1)
+
+=cut
+
+#'
--- smbldap-tools-0.9.4/smbldap-usermod 2010-06-18 12:56:34.836273934 +0200
+++ dev/smbldap-usermod 2011-02-15 12:57:22.716779290 +0100
@@ -56,6 +56,7 @@
"U|shadowUnlock" => \$Options{U},
"S|surname=s" => \$Options{S},
"T|mailToAddress=s" => \$Options{T},
+ "W|mailToExpDays=s" => \$Options{W},
"a|addsambaSAMAccount" => \$Options{a},
"c|gecos=s" => \$Options{c},
"d|homedir=s" => \$Options{d},
@@ -93,6 +94,7 @@
print " -P ends by invoking smbldap-passwd\n";
print " -M|--mailAddresses <mail,> mailAddresses (comma seperated)\n";
print " -T|--mailToAddress <mail,> mailToAddress (forward address) (comma seperated)\n";
+ print " -W|--mailToExpDays <days> forward expiration (in days from now, default unlimited)\n";
print " --shadowExpire <date> Shadow expiration date(like \"YYYY-MM-DD\")\n";
print " --shadowMax <n> User must change the password, at least, every 'n' days\n";
print " --shadowMin <n> user must wait 'n' days once the password has changed before changing it again\n";
@@ -398,9 +400,10 @@
$mailobj = 1;
}
-if ($tmp= $Options{'T'}) {
+if (defined($tmp = $Options{'T'})) {
my $action= '';
my @old;
+ my $suserMailTo;
# action si + or - for adding or deleting an entry
if ($tmp =~ s/^([+-])+\s*//) {
$action= $1;
@@ -414,7 +417,11 @@
} elsif ($action eq '-') {
@userMailTo = &list_minus(\@old, \@userMailTo);
}
- push(@mods, 'mailRoutingAddress', [ @userMailTo ]);
+ $suserMailTo = join(',', @userMailTo);
+ if (defined($Options{'W'})) {
+ $suserMailTo = $suserMailTo . ':' . int($localtime + $Options{'W'});
+ }
+ push(@mods, 'mailRoutingAddress' => $suserMailTo );
$mailobj = 1;
}
if ($mailobj) {
@@ -494,8 +501,8 @@
if ($samba == 1) {
if ($tmp != 0) {
$_sambaPwdMustChange=0;
- # To force a user to change his password:
- # . the attribut sambaPwdLastSet must be != 0
+ # To force a user to change his password (in samba >= 3.2):
+ # . the attribut sambaPwdLastSet must be == 0
# . the attribut sambaAcctFlags must not match the 'X' flag
my $_sambaAcctFlags;
my $flags = $user_entry->get_value('sambaAcctFlags');
@@ -509,8 +516,8 @@
push(@mods, 'sambaAcctFlags' => $_sambaAcctFlags);
}
my $_sambaPwdLastSet = $user_entry->get_value('sambaPwdLastSet');
- if ($_sambaPwdLastSet == 0) {
- push(@mods, 'sambaPwdLastSet' => $winmagic);
+ if ($_sambaPwdLastSet != 0) {
+ push(@mods, 'sambaPwdLastSet' => 0);
}
} else {
$_sambaPwdMustChange=$winmagic;
@@ -778,6 +785,9 @@
-T, --mailToAddress mail,[...]
mailToAddress (forward address) (comma seperated)
+-W, --mailToExpDays days
+ Add a custom ':date' to forward address as an expiration date
+
--shadowExpire <YYYY-MM-DD>
Set the expiration date for the user password. This only affect unix account. The date must be in the following format : YYYY-MM-DD. This option call the external 'date' command to set calculate the number of seconds from Junary 1 1970 to the specified date.
--- smbldap-tools-0.9.4/smbldap-userwarn 1970-01-01 01:00:00.000000000 +0100
+++ dev/smbldap-userwarn 2011-02-15 12:57:22.748778887 +0100
@@ -0,0 +1,268 @@
+#!/usr/bin/perl -w
+
+# This code was developped by Marco Gaiarin <[email protected]>
+# taking ideas and code from smbldap-tools script by IDEALX
+# (http://IDEALX.org/) and
+#
+# Copyright (C) 2011 Marco Gaiarin
+# Copyright (C) 2001-2002 IDEALX
+#
+# 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.
+
+# Purpose of smbldap-userwarn: check expiration theresold of an user. It is
+# meant to be executed weekly.
+
+# CHANGELOG
+#
+# (Fri Feb 11 12:42:14 CET 2011)
+# + first version.
+
+use strict;
+use smbldap_tools;
+
+#####################
+
+use Getopt::Std;
+my %Options;
+
+# Some default value
+#
+my $pwdage = 90; # Samba password duration, also taken from config file
+if (defined $config{defaultMaxPasswordAge}) {
+ $pwdage = $config{defaultMaxPasswordAge};
+}
+my $warndays = 14; # days before password expiring
+my $theresold = int($warndays/2); # theresold by last logon to prevent expire notes
+
+my $ok = getopts('vp:W:SPTh?', \%Options);
+if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) || ($Options{'h'}) ) {
+ print_banner;
+ print "Usage: $0 [-vSPT?h] [-p days] [-W days] username\n";
+ print "Available options are:\n";
+ print " -v verbose mode\n";
+ print " -p password age, default $pwdage (in days)\n";
+ print " -W Warning days before expiring, default $warndays (in days)\n";
+ print " -S Check samba account expiration status\n";
+ print " -P Check POSIX account expiration status\n";
+ print " -T Check mailToAddress (forward) expiration status\n";
+ print " -?|-h show this help message\n";
+ print "If none of '-S', '-P' or '-T' are selected, all expiration checks are performed\n";
+ exit (1);
+}
+
+if ($< != 0) {
+ print "You must be root to check an user\n";
+ exit (1);
+}
+# Read only first @ARGV
+my $user = $ARGV[0];
+
+# Let's connect to the directory first
+my $ldap_slave=connect_ldap_slave();
+
+# Read user data
+my $user_entry = read_user_entry($user);
+if (!defined($user_entry)) {
+ if ($Options{'v'}) {
+ print "$0: user $user doesn't exist\n";
+ }
+ exit (1);
+}
+my $dn = $user_entry->dn();
+
+# some vars...
+my $tmp;
+my constant $max = 2147483647;
+my $retval = 0;
+my $curdate = time;
+
+# reapup data on commandline...
+if (defined($tmp = $Options{'p'})) {
+ $pwdage = int($tmp);
+}
+if (defined($tmp = $Options{'W'})) {
+ $warndays = int($tmp);
+}
+if ( (! defined($Options{'S'})) && (! defined($Options{'P'})) && (! defined($Options{'T'})) ) {
+ $Options{'S'} = 1;
+ $Options{'P'} = 1;
+ $Options{'T'} = 1;
+}
+
+# Check samba password expiring...
+my $samba = 0;
+if ( ! grep ($_ =~ /^sambaSamAccount$/i, $user_entry->get_value('objectClass'))) {
+ if ($Options{'v'}) {
+ print "$0: user $user doesn't have samba data.\n";
+ }
+} elsif ( defined($Options{'S'}) ) {
+
+ # Account are just disabled?
+ my $af = $user_entry->get_value('sambaAcctFlags');
+ if ( $af =~ /D/ ) {
+ $samba = 1;
+ if ($Options{'v'}) {
+ print "$0: user $user, samba account just disabled.\n";
+ }
+ }
+ # Account marked 'X' (never expired)?
+ if ( ($samba == 0) && ($af =~ /X/) ) {
+ $samba = 1;
+ if ($Options{'v'}) {
+ print "$0: user $user, samba account never expire.\n";
+ }
+ }
+
+ # check if samba password will expire...
+ my $pls = $user_entry->get_value('sambaPwdLastSet');
+ if (! defined($pls) ) {
+ print "$0: user $user, samba account had no password set.\n";
+ $pls = 0;
+ }
+ $tmp = int($pwdage - ($curdate - $pls)/(24*60*60));
+ if ( ($samba == 0) && ($tmp >= 0) && ($tmp <= $warndays) ) {
+ if ($Options{'v'}) {
+ print "$0: user $user, samba password will expire in $tmp days.\n";
+ }
+ # ...but prevent signal if user successful logon.
+ my $lot = $user_entry->get_value('sambaLogonTime');
+ $tmp = int(($curdate - $lot)/(24*60*60));
+ if ( $tmp <= $theresold ) {
+ if ($Options{'v'}) {
+ print "$0: user $user, password expire but user have done a successful windows logon, ignoring.\n";
+ }
+ } else {
+ $retval += 2;
+ }
+ }
+}
+
+# Check POSIX password expiring
+my $posix = 0;
+if ( ! grep ($_ =~ /^shadowAccount$/i, $user_entry->get_value('objectClass'))) {
+ if ($Options{'v'}) {
+ print "$0: user $user doesn't have POSIX data.\n";
+ }
+} elsif ( defined($Options{'P'}) ) {
+
+ my $up = $user_entry->get_value('userPassword');
+ if ( $up =~ /}!/ ) {
+ $posix = 1;
+ if ($Options{'v'}) {
+ print "$0: user $user, POSIX account just disabled.\n";
+ }
+ }
+
+ my $slc = $user_entry->get_value('shadowLastChange');
+ my $pxpwdage = $user_entry->get_value('shadowMax');
+ my $pxwarndays = $user_entry->get_value('shadowWarning');
+ if (! defined($slc) ) {
+ if ($Options{'v'}) {
+ print "$0: user $user, POSIX account had no password set.\n";
+ }
+ $slc = 0;
+ }
+ if ( (!defined($pxpwdage)) || ($pxpwdage = 0) ) {
+ $pxpwdage = 99999;
+ }
+ if ( (!defined($pxwarndays)) || ($pxwarndays = 0) ) {
+ $pxwarndays = $warndays;
+ }
+ $tmp = int(($curdate/(24*60*60)) - ($slc + $pxpwdage));
+ if ( ($posix == 0) && ($tmp > 0) && ($tmp <= $pxwarndays) ) {
+ $retval += 4;
+ if ($Options{'v'}) {
+ print "$0: user $user, POSIX password will expire in $tmp days.\n";
+ }
+ }
+}
+
+# Check redirection expiring
+if ( ! grep ($_ =~ /^inetLocalMailRecipient$/i, $user_entry->get_value('objectClass'))) {
+ if ($Options{'v'}) {
+ print "$0: user $user doesn't have mail routing data.\n";
+ }
+} elsif ( defined($Options{'T'}) ) {
+
+ $tmp = $user_entry->get_value('mailRoutingAddress');
+ my ($mra, $mex);
+ if ( defined($tmp) ) {
+ ($mra, $mex) = split(/:/, $tmp, 2);
+ }
+ if ( !defined($mex) ) {
+ if ( $Options{'v'} ) {
+ print "$0: user $user, mail routing account have no expiration data.\n";
+ }
+ $mex = int($max/(24*60*60));
+ }
+ $tmp = int(($curdate/(24*60*60)) - $mex);
+ if ( ($tmp > 0) && ($tmp <= $warndays) ) {
+ $retval += 8;
+ if ($Options{'v'}) {
+ print "$0: user $user, mail routing will expire in $tmp days.\n";
+ }
+ }
+}
+
+# take down session
+$ldap_slave->unbind;
+
+# we exit with a well-known exit status, so if we change something
+# important we can warn users...
+exit($retval);
+
+############################################################
+
+=head1 NAME
+
+smbldap-userwarn - Warn user about password expiration
+
+=head1 SYNOPSIS
+
+smbldap-userwarn [-v] [-S] [-P] [-T] [-W days] login
+
+=head1 DESCRIPTION
+
+The smbldap-userwarn command check for account dates and warn about expiring password and services.
+
+-v
+ Verbose mode, print any check executed.
+
+-S
+ Check if samba password reached the near-expiration time, return 2 if true.
+
+-P
+ Check if POSIX password reached the near-expiration time, return 4 if true.
+
+-T
+ Check if mail routing (forward using mailRoutingAddress) reached the near-expiration time, return 8 if true.
+
+-W days
+ 'Warning days', eg days before expiring used in check above. Note that for POSIX check the native value saved in LDAP are used if exist and is > 0. Note also that for Samba check, this value are unrelated with the samna domain's one: this are stored in the domain policy.
+
+=head1 RETURN VALUES
+
+This script return 0 if all goes well, 1 of something goes wrong and and return the sum of the check's return value (eg, return 14 if all check are positive).
+
+This is intended so you can catch return value, and do something (send an email, ...) to user.
+
+=head1 SEE ALSO
+
+ smbldap-usermod(1) smbldap-useraccess(1) smbldap-userexpire(1) chage(1)
+
+=cut
+
+#'
_______________________________________________
Smbldap-tools-tech mailing list
[email protected]
https://mail.gna.org/listinfo/smbldap-tools-tech