Collins, Kevin
2003-Sep-16 16:53 UTC
[Samba] Samba + LDAP + Password Expiry = Almost working...
I've got a Samba 2.2.7a domain with an LDAP backend. It's been working for nearly 3 months now without much bother. By the way: Great work and thanks for all of the effort! I have been missing one minor thing from the setup since I moved away from NT 4: Password Expiration. In the past I have posted questions about this on the list and I've gotten two answers: "Wait for 3." or "Write your own script to do it for you." Well, I sorta went the second route. By "sorta" I mean that I modified a pre-existing script to make it do what I wanted it to. What I did was this...I started with IDEALX's howto and scripts to get things going. I had Samba configured to use their "smbldap-passwd.pl" script to modify passwords. That worked, I could change any Windows account password from Windows or the command line and indeed all three passwords for that user are changed (Unix, LM and NT passwords). I later discovered the LDAP entry "pwdMustChange" while looking at a user account one day. When I set this to a date inside of 14 days from today, Windows begins to barks about "Password will expire in X days" - Great I thought I found my solution. But the default password change script wouldn't modify this value. So I modified the script to where it would. This is where my confusion starts. When I run my modified script from the command line, I get the password changes I expect and I get the pwdMustChange date changes I expect too. "Cool!" I thought - things are coming together. But when I turn to my Windows machine (Windows 2000 or XP) and change my password all I get is the password changes and the value for "pwdLastSet" being changed. HUH? If Samba is being told to run my script in its configuration file with "passwd program = /usr/local/sbin/smbldap-passwd.pl -o %u", then why doesn't it work like when I run it from the command line? To put it simply, when I run my script on the command line, it works - exactly the way I want. When Samba is told to change passwords from a Windows machine, it either doesn't use my script or is passing some other information that causes the script to perform differently. In either case, I have spent the better part of two days looking for cure to this and not been able to find a solution. So, I'm hoping that someone here will be able to help me. I have included the smb.conf file and the modified version of the IDEALX smbpasswd.pl script below. Any help is appreciated. If it comes down to it, I (think I) can create a script that will do what I need outside of the IDEALX stuff, but I would prefer not to as they seem to work so well. SMB.CONF ---------------------------------------------------------------------------- --- # **************************************************************************** * # -- Nesbitt Engineering, Inc. Stargazer Samba Configuration -- # **************************************************************************** * # This is the main Samba configuration file for Stargazer - NEI's Primary # Domain Controller and Lexington office File Server. # # This configuration file is only to be used for an LDAP enabled server that # will be acting as a PDC. Modifications will be required for member servers # and machine that will act as "BDCs". # # Any line which starts with a ; (semi-colon) or a # (hash) # is a comment and is ignored. In this file we have used a # # for commentry and a ; for parts of the config file that are # either not enabled yet, or temporarly disabled # # NOTE: Whenever you modify this file you should run the command "testparm" # to check that you have not made any basic syntactic errors. # ---------------------------------------------------------------------------- - # "Fear the Penguin!" # -- Kevin L. Collins # Systems Manager # Nesbitt Engineering, Inc. # **************************************************************************** * # Changelog: # Date - Version - Change # * Info about change # ---------------------------------------------------------------------------- - # 06/04/03 - 1.0 - Original Creation # **************************************************************************** * #============================= Global Settings ===============================[global] # Server Name and description workgroup = nesbitt.local netbios name = stargazer server string = Stargazer - Lexington File Server # Samba log information log file = /var/log/samba/%m.log max log size = 0 # Security information security = user encrypt passwords = yes smb passwd file = /etc/samba/smbpasswd unix password sync = Yes passwd program = /usr/local/sbin/smbldap-passwd.pl -o %u passwd chat = *New*Password* %n\n *Retype*New*Password* %n\n *All*authentication*tokens*updated*successfully* # To help performance socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192 # Settings for PDC setup local master = yes os level = 80 domain master = yes preferred master = yes domain logons = yes logon path # Activate these Network Services wins support = yes time server = yes # LDAP Declarations -- Needed to allow the LDAP backend to work ldap suffix = dc=nesbitt,dc=local ldap admin dn = cn=Manager,dc=nesbitt,dc=local ldap port = 389 ldap server = 127.0.0.1 ldap ssl = no add user script = /usr/local/sbin/smbldap-useradd.pl -w %m domain admin group = " @"Domain Admins" " # Oplocks settings - disable all oplocks for compatibility reasons oplocks = no level2 oplocks = no kernel oplocks = no #============================= Share Definitions ==============================[netlogon] comment = Network Logon Service path = /usr/local/samba/lib/netlogon guest ok = yes writable = no write list = @"domain admins" share modes = no [homes] comment = Home Directories browseable = no writable = yes valid users = %S create mode = 0664 directory mode = 0775 [admin] comment = Administrative Files path = /npdata/admin writable = yes create mode = 0777 directory mode = 0777 [archives] comment = Files to be Archived path = /npdata/archives writeable = yes valid users = @"domain admins" @"project management" kcollins bmcgregor create mode = 0777 directory mode = 0777 [cadfiles] comment = NEI Custom AutoCAD and Eagle Point Files path = /npdata/cadfiles writable = yes create mode = 0777 directory mode = 0777 [county maps] comment = Raster Versions of County Maps path = /images/county writeable = yes create mode = 0777 directory mode = 0777 [drivers] comment = Various Windows Drivers path = /npdata/drivers read only = yes write list = @"domain admins" kcollins bmcgregor create mode = 0777 directory mode = 0777 [finance] comment = Accounting Data path = /account/finance writable = yes valid users = @"domain admins" @"senior management" accounting create mode = 0777 directory mode = 0777 [projects] comment = Lexington Project Data path = /pdata/projects writeable = yes create mode = 0777 directory mode = 0777 [quadimages] comment = Raster Versions of USGS Quads path = /images/quads writable = yes create mode = 0777 directory mode = 0777 [timeslips] comment = Timeslips Data path = /account/timeslips writable = yes valid users = @"clerical staff" @"domain admins" accounting create mode = 0777 directory mode = 0777 ---------------------------------------------------------------------------- --- SMBLDAP-PASSWD.PL ---------------------------------------------------------------------------- --- #!/usr/bin/perl # LDAP to unix password sync script for samba # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # # 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 : # . ldap-unix passwd sync for SAMBA-2.2.2 + LDAP # . may also replace /bin/passwd use strict; use smbldap_tools; use smbldap_conf; my $user; my $oldpass; my $ret; my $arg; foreach $arg (@ARGV) { if ($< != 0) { die "Only root can specify parameters\n"; } else { if ( ($arg eq '-?') || ($arg eq '--help') ) { print "Usage: $0 [username]\n"; print " -?, --help show this help message\n"; exit (6); } elsif (substr($arg,0) ne '-') { $user = $arg; } $oldpass = 1; } } if (!defined($user)) { $user=$ENV{"USER"}; } # test existence of user in LDAP my $dn_line; if (!defined($dn_line = get_user_dn($user))) { print "$0: user $user doesn't exist\n"; exit (10); } my $dn = get_dn_from_line($dn_line); my $samba = is_samba_user($user); print "Changing password for $user\n"; # non-root user if (!defined($oldpass)) { # prompt for current password system "stty -echo"; print "(current) UNIX password: "; chomp($oldpass=<STDIN>); print "\n"; system "stty echo"; if (!is_user_valid($user, $dn, $oldpass)) { print "Authentication failure\n"; exit (10); } } # prompt for new password my $pass; my $pass2; system "stty -echo"; print "New password : "; chomp($pass=<STDIN>); print "\n"; system "stty echo"; system "stty -echo"; print "Retype new password : "; chomp($pass2=<STDIN>); print "\n"; system "stty echo"; if ($pass ne $pass2) { print "New passwords don't match!\n"; exit (10); } # only modify smb passwords if smb user if ($samba == 1) { if (!$with_smbpasswd) { # generate LanManager and NT clear text passwords # ***************************************************** # modified on 05-04-03 by Kevin Collins of NEI # ----------------------------------------------------- # Added the "$neidate" and "$winmagic" varibles so that # the "pwdMustChange" field can be set to a value of 90 # days in the future from today. # # It is hoped that by changing this field in this way, # the Windows users must change thier account passwords # every 90 days. # ***************************************************** if ($mk_ntpasswd eq '') { print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; exit(1); } my $ntpwd = `$mk_ntpasswd '$pass'`; my $neidate = `/bin/date +%s`; my $chgdate = $neidate+7776000; chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':'))); chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1)); # change nt/lm passwords # *************************************************** # Modified on 05-04-03 by kevin Collins of NEI # --------------------------------------------------- # Added the modify "pwdMustChange" field for password # changes. See Modification note above for reasons. # *************************************************** my $tmpldif "$dn_line changetype: modify replace: pwdMustChange pwdMustChange: $chgdate - changetype: modify replace: lmpassword lmpassword: $lmpassword - changetype: modify replace: ntpassword ntpassword: $ntpassword - "; die "$0: error while modifying password for $user\n" unless (do_ldapmodify($tmpldif) == 0); undef $tmpldif; } else { if ($< != 0) { my $FILE="|$smbpasswd -s >/dev/null"; open (FILE, $FILE) || die "$!\n"; print FILE <<EOF; '$oldpass' '$pass' '$pass' EOF ; close FILE; } else { my $FILE="|$smbpasswd $user -s >/dev/null"; open (FILE, $FILE) || die "$!\n"; print FILE <<EOF; '$pass' '$pass' EOF ; close FILE; } } } # change unix password $ret = system "$ldappasswd $dn -s '$pass' > /dev/null"; if ($ret == 0) { print "all authentication tokens updated successfully\n"; } else { return $ret; } exit 0; # - The End =head1 NAME smbldap-passwd.pl - change user password =head1 SYNOPSIS smbldap-passwd.pl [name] =head1 DESCRIPTION smbldap-passwd.pl changes passwords for user accounts. A normal user may only change the password for their own account, the super user may change the password for any account. Password Changes The user is first prompted for their old password, if one is present. This password is then tested against the stored password by binding to the server. The user has only one chance to enter the correct pass- word. The super user is permitted to bypass this step so that forgot- ten passwords may be changed. The user is then prompted for a replacement password. As a general guideline, passwords should consist of 6 to 8 characters including one or more from each of following sets: Lower case alphabetics Upper case alphabetics Digits 0 thru 9 Punctuation marks passwd will prompt again and compare the second entry against the first. Both entries are require to match in order for the password to be changed. =head1 SEE ALSO passwd(1) =cut #' ---------------------------------------------------------------------------- --- -- Kevin L. Collins, MCSE Systems Manager Nesbitt Engineering, Inc.
Rauno Tuul
2003-Sep-16 19:07 UTC
[Samba] Samba + LDAP + Password Expiry = Almost working...
Hi, You almost got it... Samba 2 has a weird behaviour, when using LDAP and passwd program. When you change the password from windows, thnings happen like this: 1) samba reads all the user data from LDAP to memory (doesn't read userpassword) 2) executes the "passwd program" to change userpassword. I this point your script also sets the new "pwdMustChange" valus. 3) things get tricky here, when samba writes back all the data, he got from LDAP earlier and changes password hashes. So if your script changes the "pwdMustChange" value, samba puts it back as it was before :P Workaround is to modify pdb_ldap.c and teach samba not to write back "pwdMustChange". It can be achieved with commenting out 2 lines. When samba3 calculates new "pwdMustChange" based on policy. In samba2 you must do it with scripts. btw, your perl script is way too complex. I attached one my e-mail sent to samba-technical ages ago, where this trick is described. Best regards, Rauno Tuul. -----Original Message----- From: Collins, Kevin [mailto:KCollins@nesbittengineering.com] I've got a Samba 2.2.7a domain with an LDAP backend. It's been working for nearly 3 months now without much bother. By the way: Great work and thanks for all of the effort! I have been missing one minor thing from the setup since I moved away from NT 4: Password Expiration. In the past I have posted questions about this on the list and I've gotten two answers: "Wait for 3." or "Write your own script to do it for you." Well, I sorta went the second route. By "sorta" I mean that I modified a pre-existing script to make it do what I wanted it to. What I did was this...I started with IDEALX's howto and scripts to get things going. I had Samba configured to use their "smbldap-passwd.pl" script to modify passwords. That worked, I could change any Windows account password from Windows or the command line and indeed all three passwords for that user are changed (Unix, LM and NT passwords). I later discovered the LDAP entry "pwdMustChange" while looking at a user account one day. When I set this to a date inside of 14 days from today, Windows begins to barks about "Password will expire in X days" - Great I thought I found my solution. But the default password change script wouldn't modify this value., but I would prefer not to as they seem to work so well. .................
Kristyan Osborne
2003-Sep-16 22:55 UTC
[Samba] Samba + LDAP + Password Expiry = Almost working...
Hi, Try looking at the parameter passwd chat = The man pages should help you out here. Cheers ------- Kristyan Osborne - IT Technician Longhill High School 01273 391672 -----Original Message----- From: Collins, Kevin [mailto:KCollins@nesbittengineering.com] Sent: Tue 16/09/2003 17:53 To: 'samba@lists.samba.org' Cc: Subject: [Samba] Samba + LDAP + Password Expiry = Almost working... I've got a Samba 2.2.7a domain with an LDAP backend. It's been working for nearly 3 months now without much bother. By the way: Great work and thanks for all of the effort! I have been missing one minor thing from the setup since I moved away from NT 4: Password Expiration. In the past I have posted questions about this on the list and I've gotten two answers: "Wait for 3." or "Write your own script to do it for you." Well, I sorta went the second route. By "sorta" I mean that I modified a pre-existing script to make it do what I wanted it to. What I did was this...I started with IDEALX's howto and scripts to get things going. I had Samba configured to use their "smbldap-passwd.pl" script to modify passwords. That worked, I could change any Windows account password from Windows or the command line and indeed all three passwords for that user are changed (Unix, LM and NT passwords). I later discovered the LDAP entry "pwdMustChange" while looking at a user account one day. When I set this to a date inside of 14 days from today, Windows begins to barks about "Password will expire in X days" - Great I thought I found my solution. But the default password change script wouldn't modify this value. So I modified the script to where it would. This is where my confusion starts. When I run my modified script from the command line, I get the password changes I expect and I get the pwdMustChange date changes I expect too. "Cool!" I thought - things are coming together. But when I turn to my Windows machine (Windows 2000 or XP) and change my password all I get is the password changes and the value for "pwdLastSet" being changed. HUH? If Samba is being told to run my script in its configuration file with "passwd program = /usr/local/sbin/smbldap-passwd.pl -o %u", then why doesn't it work like when I run it from the command line? To put it simply, when I run my script on the command line, it works - exactly the way I want. When Samba is told to change passwords from a Windows machine, it either doesn't use my script or is passing some other information that causes the script to perform differently. In either case, I have spent the better part of two days looking for cure to this and not been able to find a solution. So, I'm hoping that someone here will be able to help me. I have included the smb.conf file and the modified version of the IDEALX smbpasswd.pl script below. Any help is appreciated. If it comes down to it, I (think I) can create a script that will do what I need outside of the IDEALX stuff, but I would prefer not to as they seem to work so well. SMB.CONF ---------------------------------------------------------------------------- --- # **************************************************************************** * # -- Nesbitt Engineering, Inc. Stargazer Samba Configuration -- # **************************************************************************** * # This is the main Samba configuration file for Stargazer - NEI's Primary # Domain Controller and Lexington office File Server. # # This configuration file is only to be used for an LDAP enabled server that # will be acting as a PDC. Modifications will be required for member servers # and machine that will act as "BDCs". # # Any line which starts with a ; (semi-colon) or a # (hash) # is a comment and is ignored. In this file we have used a # # for commentry and a ; for parts of the config file that are # either not enabled yet, or temporarly disabled # # NOTE: Whenever you modify this file you should run the command "testparm" # to check that you have not made any basic syntactic errors. # ---------------------------------------------------------------------------- - # "Fear the Penguin!" # -- Kevin L. Collins # Systems Manager # Nesbitt Engineering, Inc. # **************************************************************************** * # Changelog: # Date - Version - Change # * Info about change # ---------------------------------------------------------------------------- - # 06/04/03 - 1.0 - Original Creation # **************************************************************************** * #============================= Global Settings =============================== [global] # Server Name and description workgroup = nesbitt.local netbios name = stargazer server string = Stargazer - Lexington File Server # Samba log information log file = /var/log/samba/%m.log max log size = 0 # Security information security = user encrypt passwords = yes smb passwd file = /etc/samba/smbpasswd unix password sync = Yes passwd program = /usr/local/sbin/smbldap-passwd.pl -o %u passwd chat = *New*Password* %n\n *Retype*New*Password* %n\n *All*authentication*tokens*updated*successfully* # To help performance socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192 # Settings for PDC setup local master = yes os level = 80 domain master = yes preferred master = yes domain logons = yes logon path # Activate these Network Services wins support = yes time server = yes # LDAP Declarations -- Needed to allow the LDAP backend to work ldap suffix = dc=nesbitt,dc=local ldap admin dn = cn=Manager,dc=nesbitt,dc=local ldap port = 389 ldap server = 127.0.0.1 ldap ssl = no add user script = /usr/local/sbin/smbldap-useradd.pl -w %m domain admin group = " @"Domain Admins" " # Oplocks settings - disable all oplocks for compatibility reasons oplocks = no level2 oplocks = no kernel oplocks = no #============================= Share Definitions ============================== [netlogon] comment = Network Logon Service path = /usr/local/samba/lib/netlogon guest ok = yes writable = no write list = @"domain admins" share modes = no [homes] comment = Home Directories browseable = no writable = yes valid users = %S create mode = 0664 directory mode = 0775 [admin] comment = Administrative Files path = /npdata/admin writable = yes create mode = 0777 directory mode = 0777 [archives] comment = Files to be Archived path = /npdata/archives writeable = yes valid users = @"domain admins" @"project management" kcollins bmcgregor create mode = 0777 directory mode = 0777 [cadfiles] comment = NEI Custom AutoCAD and Eagle Point Files path = /npdata/cadfiles writable = yes create mode = 0777 directory mode = 0777 [county maps] comment = Raster Versions of County Maps path = /images/county writeable = yes create mode = 0777 directory mode = 0777 [drivers] comment = Various Windows Drivers path = /npdata/drivers read only = yes write list = @"domain admins" kcollins bmcgregor create mode = 0777 directory mode = 0777 [finance] comment = Accounting Data path = /account/finance writable = yes valid users = @"domain admins" @"senior management" accounting create mode = 0777 directory mode = 0777 [projects] comment = Lexington Project Data path = /pdata/projects writeable = yes create mode = 0777 directory mode = 0777 [quadimages] comment = Raster Versions of USGS Quads path = /images/quads writable = yes create mode = 0777 directory mode = 0777 [timeslips] comment = Timeslips Data path = /account/timeslips writable = yes valid users = @"clerical staff" @"domain admins" accounting create mode = 0777 directory mode = 0777 ---------------------------------------------------------------------------- --- SMBLDAP-PASSWD.PL ---------------------------------------------------------------------------- --- #!/usr/bin/perl # LDAP to unix password sync script for samba # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # # 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 : # . ldap-unix passwd sync for SAMBA-2.2.2 + LDAP # . may also replace /bin/passwd use strict; use smbldap_tools; use smbldap_conf; my $user; my $oldpass; my $ret; my $arg; foreach $arg (@ARGV) { if ($< != 0) { die "Only root can specify parameters\n"; } else { if ( ($arg eq '-?') || ($arg eq '--help') ) { print "Usage: $0 [username]\n"; print " -?, --help show this help message\n"; exit (6); } elsif (substr($arg,0) ne '-') { $user = $arg; } $oldpass = 1; } } if (!defined($user)) { $user=$ENV{"USER"}; } # test existence of user in LDAP my $dn_line; if (!defined($dn_line = get_user_dn($user))) { print "$0: user $user doesn't exist\n"; exit (10); } my $dn = get_dn_from_line($dn_line); my $samba = is_samba_user($user); print "Changing password for $user\n"; # non-root user if (!defined($oldpass)) { # prompt for current password system "stty -echo"; print "(current) UNIX password: "; chomp($oldpass=<STDIN>); print "\n"; system "stty echo"; if (!is_user_valid($user, $dn, $oldpass)) { print "Authentication failure\n"; exit (10); } } # prompt for new password my $pass; my $pass2; system "stty -echo"; print "New password : "; chomp($pass=<STDIN>); print "\n"; system "stty echo"; system "stty -echo"; print "Retype new password : "; chomp($pass2=<STDIN>); print "\n"; system "stty echo"; if ($pass ne $pass2) { print "New passwords don't match!\n"; exit (10); } # only modify smb passwords if smb user if ($samba == 1) { if (!$with_smbpasswd) { # generate LanManager and NT clear text passwords # ***************************************************** # modified on 05-04-03 by Kevin Collins of NEI # ----------------------------------------------------- # Added the "$neidate" and "$winmagic" varibles so that # the "pwdMustChange" field can be set to a value of 90 # days in the future from today. # # It is hoped that by changing this field in this way, # the Windows users must change thier account passwords # every 90 days. # ***************************************************** if ($mk_ntpasswd eq '') { print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; exit(1); } my $ntpwd = `$mk_ntpasswd '$pass'`; my $neidate = `/bin/date +%s`; my $chgdate = $neidate+7776000; chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':'))); chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1)); # change nt/lm passwords # *************************************************** # Modified on 05-04-03 by kevin Collins of NEI # --------------------------------------------------- # Added the modify "pwdMustChange" field for password # changes. See Modification note above for reasons. # *************************************************** my $tmpldif "$dn_line changetype: modify replace: pwdMustChange pwdMustChange: $chgdate - changetype: modify replace: lmpassword lmpassword: $lmpassword - changetype: modify replace: ntpassword ntpassword: $ntpassword - "; die "$0: error while modifying password for $user\n" unless (do_ldapmodify($tmpldif) == 0); undef $tmpldif; } else { if ($< != 0) { my $FILE="|$smbpasswd -s >/dev/null"; open (FILE, $FILE) || die "$!\n"; print FILE <<EOF; '$oldpass' '$pass' '$pass' EOF ; close FILE; } else { my $FILE="|$smbpasswd $user -s >/dev/null"; open (FILE, $FILE) || die "$!\n"; print FILE <<EOF; '$pass' '$pass' EOF ; close FILE; } } } # change unix password $ret = system "$ldappasswd $dn -s '$pass' > /dev/null"; if ($ret == 0) { print "all authentication tokens updated successfully\n"; } else { return $ret; } exit 0; # - The End =head1 NAME smbldap-passwd.pl - change user password =head1 SYNOPSIS smbldap-passwd.pl [name] =head1 DESCRIPTION smbldap-passwd.pl changes passwords for user accounts. A normal user may only change the password for their own account, the super user may change the password for any account. Password Changes The user is first prompted for their old password, if one is present. This password is then tested against the stored password by binding to the server. The user has only one chance to enter the correct pass- word. The super user is permitted to bypass this step so that forgot- ten passwords may be changed. The user is then prompted for a replacement password. As a general guideline, passwords should consist of 6 to 8 characters including one or more from each of following sets: Lower case alphabetics Upper case alphabetics Digits 0 thru 9 Punctuation marks passwd will prompt again and compare the second entry against the first. Both entries are require to match in order for the password to be changed. =head1 SEE ALSO passwd(1) =cut #' ---------------------------------------------------------------------------- --- -- Kevin L. Collins, MCSE Systems Manager Nesbitt Engineering, Inc. -- To unsubscribe from this list go to the following URL and read the instructions: http://lists.samba.org/mailman/listinfo/samba
Collins, Kevin
2003-Sep-17 14:41 UTC
[Samba] Samba + LDAP + Password Expiry = Almost working...
Hi, I hope I'm not showing my ignorance here, but I'm not following you on this one. Could be a little more specific? Kevin -----Original Message----- From: Kristyan Osborne [mailto:kris@longhill.brighton-hove.sch.uk] Sent: Tuesday, September 16, 2003 6:56 PM To: Collins, Kevin; samba@lists.samba.org Subject: RE: [Samba] Samba + LDAP + Password Expiry = Almost working... Hi, Try looking at the parameter passwd chat = The man pages should help you out here. Cheers ------- Kristyan Osborne - IT Technician Longhill High School 01273 391672 -----Original Message----- From: Collins, Kevin [mailto:KCollins@nesbittengineering.com] Sent: Tue 16/09/2003 17:53 To: 'samba@lists.samba.org' Cc: Subject: [Samba] Samba + LDAP + Password Expiry = Almost working... I've got a Samba 2.2.7a domain with an LDAP backend. It's been working for nearly 3 months now without much bother. By the way: Great work and thanks for all of the effort! I have been missing one minor thing from the setup since I moved away from NT 4: Password Expiration. In the past I have posted questions about this on the list and I've gotten two answers: "Wait for 3." or "Write your own script to do it for you." Well, I sorta went the second route. By "sorta" I mean that I modified a pre-existing script to make it do what I wanted it to. What I did was this...I started with IDEALX's howto and scripts to get things going. I had Samba configured to use their "smbldap-passwd.pl" script to modify passwords. That worked, I could change any Windows account password from Windows or the command line and indeed all three passwords for that user are changed (Unix, LM and NT passwords). I later discovered the LDAP entry "pwdMustChange" while looking at a user account one day. When I set this to a date inside of 14 days from today, Windows begins to barks about "Password will expire in X days" - Great I thought I found my solution. But the default password change script wouldn't modify this value. So I modified the script to where it would. This is where my confusion starts. When I run my modified script from the command line, I get the password changes I expect and I get the pwdMustChange date changes I expect too. "Cool!" I thought - things are coming together. But when I turn to my Windows machine (Windows 2000 or XP) and change my password all I get is the password changes and the value for "pwdLastSet" being changed. HUH? If Samba is being told to run my script in its configuration file with "passwd program = /usr/local/sbin/smbldap-passwd.pl -o %u", then why doesn't it work like when I run it from the command line? To put it simply, when I run my script on the command line, it works - exactly the way I want. When Samba is told to change passwords from a Windows machine, it either doesn't use my script or is passing some other information that causes the script to perform differently. In either case, I have spent the better part of two days looking for cure to this and not been able to find a solution. So, I'm hoping that someone here will be able to help me. I have included the smb.conf file and the modified version of the IDEALX smbpasswd.pl script below. Any help is appreciated. If it comes down to it, I (think I) can create a script that will do what I need outside of the IDEALX stuff, but I would prefer not to as they seem to work so well. SMB.CONF ---------------------------------------------------------------------------- --- # **************************************************************************** * # -- Nesbitt Engineering, Inc. Stargazer Samba Configuration -- # **************************************************************************** * # This is the main Samba configuration file for Stargazer - NEI's Primary # Domain Controller and Lexington office File Server. # # This configuration file is only to be used for an LDAP enabled server that # will be acting as a PDC. Modifications will be required for member servers # and machine that will act as "BDCs". # # Any line which starts with a ; (semi-colon) or a # (hash) # is a comment and is ignored. In this file we have used a # # for commentry and a ; for parts of the config file that are # either not enabled yet, or temporarly disabled # # NOTE: Whenever you modify this file you should run the command "testparm" # to check that you have not made any basic syntactic errors. # ---------------------------------------------------------------------------- - # "Fear the Penguin!" # -- Kevin L. Collins # Systems Manager # Nesbitt Engineering, Inc. # **************************************************************************** * # Changelog: # Date - Version - Change # * Info about change # ---------------------------------------------------------------------------- - # 06/04/03 - 1.0 - Original Creation # **************************************************************************** * #============================= Global Settings =============================== [global] # Server Name and description workgroup = nesbitt.local netbios name = stargazer server string = Stargazer - Lexington File Server # Samba log information log file = /var/log/samba/%m.log max log size = 0 # Security information security = user encrypt passwords = yes smb passwd file = /etc/samba/smbpasswd unix password sync = Yes passwd program = /usr/local/sbin/smbldap-passwd.pl -o %u passwd chat = *New*Password* %n\n *Retype*New*Password* %n\n *All*authentication*tokens*updated*successfully* # To help performance socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192 # Settings for PDC setup local master = yes os level = 80 domain master = yes preferred master = yes domain logons = yes logon path # Activate these Network Services wins support = yes time server = yes # LDAP Declarations -- Needed to allow the LDAP backend to work ldap suffix = dc=nesbitt,dc=local ldap admin dn = cn=Manager,dc=nesbitt,dc=local ldap port = 389 ldap server = 127.0.0.1 ldap ssl = no add user script = /usr/local/sbin/smbldap-useradd.pl -w %m domain admin group = " @"Domain Admins" " # Oplocks settings - disable all oplocks for compatibility reasons oplocks = no level2 oplocks = no kernel oplocks = no #============================= Share Definitions ============================== [netlogon] comment = Network Logon Service path = /usr/local/samba/lib/netlogon guest ok = yes writable = no write list = @"domain admins" share modes = no [homes] comment = Home Directories browseable = no writable = yes valid users = %S create mode = 0664 directory mode = 0775 [admin] comment = Administrative Files path = /npdata/admin writable = yes create mode = 0777 directory mode = 0777 [archives] comment = Files to be Archived path = /npdata/archives writeable = yes valid users = @"domain admins" @"project management" kcollins bmcgregor create mode = 0777 directory mode = 0777 [cadfiles] comment = NEI Custom AutoCAD and Eagle Point Files path = /npdata/cadfiles writable = yes create mode = 0777 directory mode = 0777 [county maps] comment = Raster Versions of County Maps path = /images/county writeable = yes create mode = 0777 directory mode = 0777 [drivers] comment = Various Windows Drivers path = /npdata/drivers read only = yes write list = @"domain admins" kcollins bmcgregor create mode = 0777 directory mode = 0777 [finance] comment = Accounting Data path = /account/finance writable = yes valid users = @"domain admins" @"senior management" accounting create mode = 0777 directory mode = 0777 [projects] comment = Lexington Project Data path = /pdata/projects writeable = yes create mode = 0777 directory mode = 0777 [quadimages] comment = Raster Versions of USGS Quads path = /images/quads writable = yes create mode = 0777 directory mode = 0777 [timeslips] comment = Timeslips Data path = /account/timeslips writable = yes valid users = @"clerical staff" @"domain admins" accounting create mode = 0777 directory mode = 0777 ---------------------------------------------------------------------------- --- SMBLDAP-PASSWD.PL ---------------------------------------------------------------------------- --- #!/usr/bin/perl # LDAP to unix password sync script for samba # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # # 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 : # . ldap-unix passwd sync for SAMBA-2.2.2 + LDAP # . may also replace /bin/passwd use strict; use smbldap_tools; use smbldap_conf; my $user; my $oldpass; my $ret; my $arg; foreach $arg (@ARGV) { if ($< != 0) { die "Only root can specify parameters\n"; } else { if ( ($arg eq '-?') || ($arg eq '--help') ) { print "Usage: $0 [username]\n"; print " -?, --help show this help message\n"; exit (6); } elsif (substr($arg,0) ne '-') { $user = $arg; } $oldpass = 1; } } if (!defined($user)) { $user=$ENV{"USER"}; } # test existence of user in LDAP my $dn_line; if (!defined($dn_line = get_user_dn($user))) { print "$0: user $user doesn't exist\n"; exit (10); } my $dn = get_dn_from_line($dn_line); my $samba = is_samba_user($user); print "Changing password for $user\n"; # non-root user if (!defined($oldpass)) { # prompt for current password system "stty -echo"; print "(current) UNIX password: "; chomp($oldpass=<STDIN>); print "\n"; system "stty echo"; if (!is_user_valid($user, $dn, $oldpass)) { print "Authentication failure\n"; exit (10); } } # prompt for new password my $pass; my $pass2; system "stty -echo"; print "New password : "; chomp($pass=<STDIN>); print "\n"; system "stty echo"; system "stty -echo"; print "Retype new password : "; chomp($pass2=<STDIN>); print "\n"; system "stty echo"; if ($pass ne $pass2) { print "New passwords don't match!\n"; exit (10); } # only modify smb passwords if smb user if ($samba == 1) { if (!$with_smbpasswd) { # generate LanManager and NT clear text passwords # ***************************************************** # modified on 05-04-03 by Kevin Collins of NEI # ----------------------------------------------------- # Added the "$neidate" and "$winmagic" varibles so that # the "pwdMustChange" field can be set to a value of 90 # days in the future from today. # # It is hoped that by changing this field in this way, # the Windows users must change thier account passwords # every 90 days. # ***************************************************** if ($mk_ntpasswd eq '') { print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; exit(1); } my $ntpwd = `$mk_ntpasswd '$pass'`; my $neidate = `/bin/date +%s`; my $chgdate = $neidate+7776000; chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':'))); chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1)); # change nt/lm passwords # *************************************************** # Modified on 05-04-03 by kevin Collins of NEI # --------------------------------------------------- # Added the modify "pwdMustChange" field for password # changes. See Modification note above for reasons. # *************************************************** my $tmpldif "$dn_line changetype: modify replace: pwdMustChange pwdMustChange: $chgdate - changetype: modify replace: lmpassword lmpassword: $lmpassword - changetype: modify replace: ntpassword ntpassword: $ntpassword - "; die "$0: error while modifying password for $user\n" unless (do_ldapmodify($tmpldif) == 0); undef $tmpldif; } else { if ($< != 0) { my $FILE="|$smbpasswd -s >/dev/null"; open (FILE, $FILE) || die "$!\n"; print FILE <<EOF; '$oldpass' '$pass' '$pass' EOF ; close FILE; } else { my $FILE="|$smbpasswd $user -s >/dev/null"; open (FILE, $FILE) || die "$!\n"; print FILE <<EOF; '$pass' '$pass' EOF ; close FILE; } } } # change unix password $ret = system "$ldappasswd $dn -s '$pass' > /dev/null"; if ($ret == 0) { print "all authentication tokens updated successfully\n"; } else { return $ret; } exit 0; # - The End =head1 NAME smbldap-passwd.pl - change user password =head1 SYNOPSIS smbldap-passwd.pl [name] =head1 DESCRIPTION smbldap-passwd.pl changes passwords for user accounts. A normal user may only change the password for their own account, the super user may change the password for any account. Password Changes The user is first prompted for their old password, if one is present. This password is then tested against the stored password by binding to the server. The user has only one chance to enter the correct pass- word. The super user is permitted to bypass this step so that forgot- ten passwords may be changed. The user is then prompted for a replacement password. As a general guideline, passwords should consist of 6 to 8 characters including one or more from each of following sets: Lower case alphabetics Upper case alphabetics Digits 0 thru 9 Punctuation marks passwd will prompt again and compare the second entry against the first. Both entries are require to match in order for the password to be changed. =head1 SEE ALSO passwd(1) =cut #' ---------------------------------------------------------------------------- --- -- Kevin L. Collins, MCSE Systems Manager Nesbitt Engineering, Inc. -- To unsubscribe from this list go to the following URL and read the instructions: http://lists.samba.org/mailman/listinfo/samba
Collins, Kevin
2003-Sep-17 14:52 UTC
[Samba] Samba + LDAP + Password Expiry = Almost working...
Thanks for the info... I've got a "custom version" of 2.2.7a with your suggestions building right now on a test machine. I'm like you, I think this is a "bug" in the code and can not see any reason for it to be doing this. In fact, I think your suggestion about a smb.conf parameter setting the number of days for a password to live is the proper way to go. But I don't know everything... :) Kevin -----Original Message----- From: Rauno Tuul [mailto:rauno.tuul@haigekassa.ee] Sent: Tuesday, September 16, 2003 3:07 PM To: 'Collins, Kevin' Cc: 'samba@lists.samba.org' Subject: RE: [Samba] Samba + LDAP + Password Expiry = Almost working... Hi, You almost got it... Samba 2 has a weird behaviour, when using LDAP and passwd program. When you change the password from windows, thnings happen like this: 1) samba reads all the user data from LDAP to memory (doesn't read userpassword) 2) executes the "passwd program" to change userpassword. I this point your script also sets the new "pwdMustChange" valus. 3) things get tricky here, when samba writes back all the data, he got from LDAP earlier and changes password hashes. So if your script changes the "pwdMustChange" value, samba puts it back as it was before :P Workaround is to modify pdb_ldap.c and teach samba not to write back "pwdMustChange". It can be achieved with commenting out 2 lines. When samba3 calculates new "pwdMustChange" based on policy. In samba2 you must do it with scripts. btw, your perl script is way too complex. I attached one my e-mail sent to samba-technical ages ago, where this trick is described. Best regards, Rauno Tuul. -----Original Message----- From: Collins, Kevin [mailto:KCollins@nesbittengineering.com] I've got a Samba 2.2.7a domain with an LDAP backend. It's been working for nearly 3 months now without much bother. By the way: Great work and thanks for all of the effort! I have been missing one minor thing from the setup since I moved away from NT 4: Password Expiration. In the past I have posted questions about this on the list and I've gotten two answers: "Wait for 3." or "Write your own script to do it for you." Well, I sorta went the second route. By "sorta" I mean that I modified a pre-existing script to make it do what I wanted it to. What I did was this...I started with IDEALX's howto and scripts to get things going. I had Samba configured to use their "smbldap-passwd.pl" script to modify passwords. That worked, I could change any Windows account password from Windows or the command line and indeed all three passwords for that user are changed (Unix, LM and NT passwords). I later discovered the LDAP entry "pwdMustChange" while looking at a user account one day. When I set this to a date inside of 14 days from today, Windows begins to barks about "Password will expire in X days" - Great I thought I found my solution. But the default password change script wouldn't modify this value., but I would prefer not to as they seem to work so well. .................