[Samba-it] pam & cambio password(posix/win) linux-side
Marco Gaiarin
gaio at sv.lnf.it
Thu Jan 28 11:30:09 MST 2010
Mandi! Simone
In chel di` si favelave...
> Qualcuno ha già trovato una soluzione al problema? Se sì, come ha
> configurato i pam ?
Per forza, necessità di cose, occorre usare winbind e pam_winbind.
Non serve installare samba sulla macchina, basta installare winbind
e mettere la macchina in join a dominio.
La configurazione sicuramente più 'pulita' è quella di usare winbind
per tutti i contesti pam in cui ha senso e per nss; se come me sei
pazzo e paranoico (nei confronti di winbind) io sono riuscito ad
usarlo solo nel contesto password (per il cambio password).
Allego il mio profilo di auth-client-config in ubuntu e lo script che
uso per 'sincronizzare' le scadenza delle password tra samba e POSIX.
...è un po' che non ci gioco, se qualcuno ha qualche modifica che dica
pure...
--
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)
-------------- next part --------------
1) occorre che la macchina sia in join a dominio, ma non serve che ci sia
samba in esecuzione, basta samba-common e winbind.
Occorre configurare smb.conf al minimo, stile:
[global]
workgroup = SANVITO
server string = %h server (Samba, Ubuntu)
security = DOMAIN
guest account = guest
syslog = 0
log file = /var/log/samba/log.%m
max log size = 1000
dns proxy = No
wins server = 10.5.1.3
panic action = /usr/share/samba/panic-action %d
idmap domains = SANVITO
winbind use default domain = Yes
idmap config SANVITO:backend = nss
idmap config SANVITO:readonly = yes
idmap config SANVITO:default = yes
2) il mapping avviene attraverso il nome di utenti e gruppi e quindi
QUESTO DEVE COINCIDERE, ovvero nomi POSIX e Win di utenti e gruppi
devono essere gli stessi.
Per i gruppi potrebbe bastare anche un mapping locale, ma è un hack
e potrebbe smettere di funzonare di punto in bianco.
More info su:
http://lists.xsec.it/pipermail/samba-it/2008-December/007813.html
ed eventualmente tutto il thread precedente. ;)
-------------- next part --------------
#
# Configurazione mista che utilizza LDAP per i contesti password ed account
# mentre utilizza winbind per il contesto password, per permettere il
# cambiamento della pass con gli strumenti di windows.
#
# Alcune note:
# + NSS non supporta shadow,
# /usr/share/doc/libnss-ldap/LDAP-Permissions.txt.gz
# ma posso ovviare con il contesto specifico 'account'
# + onde evitare errori inutili, uso pam_localuser per identificare gli
# utenti locali.
# + la configurazione di winbind necessita solo del join e della corretta
# configurazione dell'idmap nss.
#
[ldap-wb]
nss_passwd=passwd: files ldap
nss_group=group: files ldap
nss_shadow=shadow: files
pam_auth=auth [success=ignore default=1] pam_localuser.so
auth [success=1 default=ignore] pam_unix.so nullok_secure
auth required pam_ldap.so try_first_pass
auth required pam_permit.so
pam_account=account [success=ignore default=1] pam_localuser.so
account [success=1 default=ignore] pam_unix.so
account required pam_ldap.so
account required pam_permit.so
pam_session=session required pam_unix.so
pam_password=password [success=ignore default=1] pam_localuser.so
password [success=1 default=ignore] pam_unix.so nullok obscure min=4 max=8 md5
password required pam_winbind.so try_first_pass
password required pam_permit.so
-------------- next part --------------
#!/usr/bin/perl -w
# This code was developped by Marco Gaiarin <gaio at linux.it>
# 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
use strict;
use smbldap_tools;
#####################
use Getopt::Std;
my %Options;
# getting some info from config file
#
my $pwdage = 90;
if (defined $config{defaultMaxPasswordAge}) {
$pwdage = $config{defaultMaxPasswordAge};
}
my $acctage = 180;
my $pxpwdage = 210;
my $pxacctage = 360;
my $pxwarndays = 7;
my $ok = getopts('vdfsp:a:P:A:W:h?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) || ($Options{'h'}) ) {
print_banner;
print "Usage: $0 [-vdfs?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 " -?|-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();
# no samba? no party!
if ( ! grep ($_ =~ /^sambaSamAccount$/i, $user_entry->get_value('objectClass'))) {
if ($Options{'v'}) {
print "$0: user $user doesn't have samba data, nothing to do.\n";
}
exit(1);
}
# 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);
}
# 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";
}
}
# 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');
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 ( ($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;
# 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 !~ /^{crypt}x$/) ) {
if ($Options{'v'}) {
print "$0: user $user sambaLogonTime really too low, disabling POSIX account\n";
}
$up = "{crypt}x";
push(@mods, 'userPassword' => $up);
}
}
# 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) );
}
}
# 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
=head1 RETURN VALUES
This script return 0 if all goes well, 1 if something goes wrong and 2 if all goes well and a Samba account was disabled.
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
#'
More information about the samba-it
mailing list