LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Networking (https://www.linuxquestions.org/questions/linux-networking-3/)
-   -   howto change samba password remotely from a windows client? (https://www.linuxquestions.org/questions/linux-networking-3/howto-change-samba-password-remotely-from-a-windows-client-280477/)

yafrank 01-21-2005 07:50 AM

howto change samba password remotely from a windows client?
 
I recently configured a samba server to share files for roughly 60 window clients. The samba security is user mood and all clients need to provide a password to access the share. It works fine except inconvinient of change password. I used to run smbpasswd on the server to change password for them but it's tedious job. What if they can alter it themselves in their window's box? The samba-howto says if you configure the server a PDC, the password change can be automatic by specifying scripts in smb.conf. The problem is that another main working service for the company won't work well in a domain environment. I googled but failed to find useful links. Is there any alternatives I can choose?
Any suggestion will be appreciated?

rtspitz 01-24-2005 02:00 AM

hm...

your little problem has intrigued me :-)

QUITE A LOT ... now it's 05:03 am and I've got a solution - TESTED on my system...

. . .

not quite right anymore... the @§$%"§ windows carriage
return has caused my script to go mad... it is fixed now 08:45am.

it is quite demotivating to stare at the output of my code
and the computer tells me something like 2 is NOT equal 2,
just because of \r ARGH !

. . .

I assume there is PERL on your machine.

I propose the following solution:

create a share with samba called e.g. [pwchange]
that is writable for authenticated users and use
the 'postexec' and 'root postexec' options of samba.
the scripts need to be +rx for the users !

Code:

[pwchange]
      path = /shares/pwchange
      comment = use this to change your smb passwords
      create mask = 0700
      valid users = @users
      read only = no
      root postexec = /etc/samba/pw-script 1 /shares/pwchange /var/log/samba/pwchange.log >/dev/null
      postexec = /etc/samba/pw-script 0 /shares/pwchange /var/log/samba/pwchange.log >/dev/null

the 0 means: only change the password and do not create a log file (only root can do that)
the 1 means: script is run as root, only create the log file

also postexec is always executed BEFORE root postexec

I know this is a bit confusing, but if the smbpasswd is run as root there is not check for the old passwd, which MUST be done for security reasons. that's why the script is run twice, once as the user to change the password, 2nd time to create the log entry.

syntax: pw-script <0 or 1> <path to look for pw-files> <path to logfile>

logging is rudimentary at the moment. if say a user wants to hack a password and sends a change-file with somebody else's name in it the password will not be changed of course, but also, no logfile will be created as only root has access to them.

smbpasswd will use /var/log/samba/log.smbd to complain about that kind of stuff.


NOW. lets say a user named john wants to change his password.
he creates a file with the contents:

john
myoldpassword
mynewpassword
mynewpassword

and copies that to the [pwchange] share. this time my script will take
care of the conversion from dos to unix file format.
as soon as he disconnects (logs off and back on again) the scripts are executed and
his password is changed ! the file he created is deleted - ONLY his file in case other
users change their passwords at the same time (I could not test that of course)

I've checked this with Win XP + SuSE 9.2 Pro.

the perl script comes here:

Code:

#!/usr/bin/perl
# 04:56am 24-jan-2005 by robert_spitzenpfeil@yahoo.com
# free software not owned by SCO

use strict;
use Fcntl;

my $log = @ARGV[0]; # if 1 logfile will be created ( only possible if run as root )
my $pwchange_path = @ARGV[1]; # where to look for the files
my $pwchange_log  = @ARGV[2]; # logfile for pw changes by users
my $smbpasswd = "/usr/bin/smbpasswd"; # path to smbpasswd on the system
my $samba_user = $ENV{USER}; # needed to delete ONLY the users file !

if ( @ARGV[0] eq "" || @ARGV[1] eq "" || @ARGV[2] eq "" ) { print "usage as root: pw-script 1 <path to pw files> <path to logfile>\nusage as user: pw-script 0 <path to pw files> <path to logfile>\n! 3 arguments needed !\narg0: @ARGV[0]\narg1: @ARGV[1]\narg2: @ARGV[2]\n"; }

else {

  opendir(DIR,"$pwchange_path") or die("cannot open dir: $!");
    my @dir_lines = readdir DIR;
    shift @dir_lines;  # remove .
    shift @dir_lines;  # remove ..
  closedir(DIR);

  foreach my $dir_line ( @dir_lines ) {

    if ( -f "$pwchange_path/$dir_line" ) { # check if we are dealing with a file

      open(FILE,"$pwchange_path/$dir_line") or die("cannot open file: $!"); # read the file
        my @file_lines = <FILE>;
      close(FILE);

      my $username = @file_lines[0];
      $username    =~ s/\r//;  # this will EXTERMINATE THE F...... windows newline thingy
      $username    =~ s/\n//;  # this will ignore returns after a line

      my $oldpw    = @file_lines[1];
      $oldpw      =~ s/\r//;
      $oldpw      =~ s/\n//;


      my $newpw_1  = @file_lines[2];
      $newpw_1    =~ s/\r//;
      $newpw_1    =~ s/\n//;

      my $newpw_2  = @file_lines[3];
      $newpw_2    =~ s/\r//;
      $newpw_2    =~ s/\n//;


      if ( "$username" eq "$samba_user" ) { # only do something if the name in the change-fileis equal to the username connected to samba

        if ( $log eq "1" ) { &logfile($pwchange_log,$pwchange_path,$dir_line,$username,$oldpw,$newpw_1,$newpw_2,$samba_user); } # only root can create a logfile but CANNOT change the password with the "oldpassword newpassword newpassword" dialog !

        if ( $log ne "1" ) { &pwchange($smbpasswd,$username,$oldpw,$newpw_1,$newpw_2); } # only users can do this !

      } # end if


    } # end if ...

  } # end foreach ...

} # end else



sub logfile() {

  my ($pwchange_log,$pwchange_path,$dir_line,$username,$oldpw,$newpw_1,$newpw_2,$samba_user) =@_;

  sysopen(FILE, $pwchange_log, O_WRONLY|O_APPEND|O_CREAT,0700) or die("cannot open logfile: $!"); # append to logfile
      my $date = `date`;
      print FILE $date;
      print FILE "file used: $pwchange_path/$dir_line \n\n";
      print FILE "username: ",$username,"\n";
      print FILE "oldpw: ",$oldpw,"\n";
      print FILE "newpw_1: ",$newpw_1,"\n";
      print FILE "newpw_2: ",$newpw_2,"\n";
      print FILE "samba user: ",$samba_user,"\n";

      if ( "$newpw_1" ne "$newpw_2" ) { print FILE "-> new passwords don't match\n\n\n"; }

      else {
            print FILE "-> new passwords match\n\n\n";
          }

  close(FILE);

  `rm -f "$pwchange_path/$dir_line"`; # erase the file
}



sub pwchange() {

  my ($smbpasswd,$username,$oldpw,$newpw_1,$newpw_2) = @_;

  if ( "$newpw_1" eq "$newpw_2" ) {

    open (FILE, "|$smbpasswd -s") or die("cannot pipe into $smbpasswd: $!");
      print FILE qq|$oldpw\n|;
      print FILE qq|$newpw_1\n|;
      print FILE qq|$newpw_1\n|;
    close (FILE);

  } # end if

}


saifurab 02-04-2010 02:28 AM

Perl script for samba password
 
hello rtspitz,

your script helped me a lot. Infact, I want to create a webpage where users can change their samba password and before I jump to PHP code i want to write perl code that can be called in php code.

I have created two file
1. main.pl - this script actually switch user and call passwd.pl
2. passwd.pl - this is actually changes the password (based on your script)

{main.pl}

#!/usr/bin/perl

my $username = $ARGV[0];
my $oldpass = $ARGV[1];
my $newpass1 = $ARGV[2];
my $newpass2 = $ARGV[3];

open(USER, "|su - $username -c /script/passwd.pl \" $oldpass $newpass1 $newpass2\" ");
close(USER);

{passwd.pl}

#!/usr/bin/perl

my $oldpw = $ARG[0];
my $newpw_1 = $ARG[1];
my $newpw_2 = $ARG[2];
my $smbpasswd = "/usr/bin/smbpasswd";

&pw_change($smbpasswd,$username,$oldpw,$newpw_1,$newpw_2);

sub pw_change(){
my ($smbpasswd,$username,$oldpw,$newpw_1,$newpw_2) = @_;

if ( "$newpw_1" eq "$newpw_2" ) {

open (FILE, "|$smbpasswd -s") or die("cannot pipe into $smbpasswd: $!");

print FILE qq|$oldpw\n|;
print FILE qq|$newpw_1\n|;
print FILE qq|$newpw_1\n|;
close (FILE);
}
}


if I switch to user whom i want to change the password passwd.pl allows me the change the password but when i call this script from my main.pl, the arguments doesn't passes to passwd.pl

e.g. I call it as

./main.pl <user name> <old_pass> <new_pass_1> <new_pass_2>


Hope this make sense

Saif

rtspitz 02-04-2010 12:17 PM

Before you write a lot of code, you can use USERMIN to to that. It's been a while since I had to deal with samba and the windows curse, but I think you may have to activate 'password sync' (or whatever it is called nowadays).

Quote:

open(USER, "|su - $username -c /script/passwd.pl \" $oldpass $newpass1 $newpass2\" ");
close(USER);
This doesn't work, as you don't write anything into the pipe. You just open it and close it again.

This should work as you intended:

Quote:

system("sudo -u $username /script/passwd.pl $oldpass $newpass1 $newpass2");
This assumes you run your main.pl as ROOT tough. If your PHP page will be exposed to the internet, that might not be a good idea. WEBMIN/USERMIN support SSL encryption.

When I used usermin for that job, samba and unix users were always kept in sync as far as passwords were concerned.

saravananp 06-02-2010 05:38 AM

postexec is not working
 
Quote:

Originally Posted by rtspitz (Post 1426708)
hm...

your little problem has intrigued me :-)

QUITE A LOT ... now it's 05:03 am and I've got a solution - TESTED on my system...

. . .

not quite right anymore... the @§$%"§ windows carriage
return has caused my script to go mad... it is fixed now 08:45am.

it is quite demotivating to stare at the output of my code
and the computer tells me something like 2 is NOT equal 2,
just because of \r ARGH !

. . .

I assume there is PERL on your machine.

I propose the following solution:

create a share with samba called e.g. [pwchange]
that is writable for authenticated users and use
the 'postexec' and 'root postexec' options of samba.
the scripts need to be +rx for the users !

Code:

[pwchange]
      path = /shares/pwchange
      comment = use this to change your smb passwords
      create mask = 0700
      valid users = @users
      read only = no
      root postexec = /etc/samba/pw-script 1 /shares/pwchange /var/log/samba/pwchange.log >/dev/null
      postexec = /etc/samba/pw-script 0 /shares/pwchange /var/log/samba/pwchange.log >/dev/null

the 0 means: only change the password and do not create a log file (only root can do that)
the 1 means: script is run as root, only create the log file

also postexec is always executed BEFORE root postexec

I know this is a bit confusing, but if the smbpasswd is run as root there is not check for the old passwd, which MUST be done for security reasons. that's why the script is run twice, once as the user to change the password, 2nd time to create the log entry.

syntax: pw-script <0 or 1> <path to look for pw-files> <path to logfile>

logging is rudimentary at the moment. if say a user wants to hack a password and sends a change-file with somebody else's name in it the password will not be changed of course, but also, no logfile will be created as only root has access to them.

smbpasswd will use /var/log/samba/log.smbd to complain about that kind of stuff.


NOW. lets say a user named john wants to change his password.
he creates a file with the contents:

john
myoldpassword
mynewpassword
mynewpassword

and copies that to the [pwchange] share. this time my script will take
care of the conversion from dos to unix file format.
as soon as he disconnects (logs off and back on again) the scripts are executed and
his password is changed ! the file he created is deleted - ONLY his file in case other
users change their passwords at the same time (I could not test that of course)

I've checked this with Win XP + SuSE 9.2 Pro.

the perl script comes here:

Code:

#!/usr/bin/perl
# 04:56am 24-jan-2005 by robert_spitzenpfeil@yahoo.com
# free software not owned by SCO

use strict;
use Fcntl;

my $log = @ARGV[0]; # if 1 logfile will be created ( only possible if run as root )
my $pwchange_path = @ARGV[1]; # where to look for the files
my $pwchange_log  = @ARGV[2]; # logfile for pw changes by users
my $smbpasswd = "/usr/bin/smbpasswd"; # path to smbpasswd on the system
my $samba_user = $ENV{USER}; # needed to delete ONLY the users file !

if ( @ARGV[0] eq "" || @ARGV[1] eq "" || @ARGV[2] eq "" ) { print "usage as root: pw-script 1 <path to pw files> <path to logfile>\nusage as user: pw-script 0 <path to pw files> <path to logfile>\n! 3 arguments needed !\narg0: @ARGV[0]\narg1: @ARGV[1]\narg2: @ARGV[2]\n"; }

else {

  opendir(DIR,"$pwchange_path") or die("cannot open dir: $!");
    my @dir_lines = readdir DIR;
    shift @dir_lines;  # remove .
    shift @dir_lines;  # remove ..
  closedir(DIR);

  foreach my $dir_line ( @dir_lines ) {

    if ( -f "$pwchange_path/$dir_line" ) { # check if we are dealing with a file

      open(FILE,"$pwchange_path/$dir_line") or die("cannot open file: $!"); # read the file
        my @file_lines = <FILE>;
      close(FILE);

      my $username = @file_lines[0];
      $username    =~ s/\r//;  # this will EXTERMINATE THE F...... windows newline thingy
      $username    =~ s/\n//;  # this will ignore returns after a line

      my $oldpw    = @file_lines[1];
      $oldpw      =~ s/\r//;
      $oldpw      =~ s/\n//;


      my $newpw_1  = @file_lines[2];
      $newpw_1    =~ s/\r//;
      $newpw_1    =~ s/\n//;

      my $newpw_2  = @file_lines[3];
      $newpw_2    =~ s/\r//;
      $newpw_2    =~ s/\n//;


      if ( "$username" eq "$samba_user" ) { # only do something if the name in the change-fileis equal to the username connected to samba

        if ( $log eq "1" ) { &logfile($pwchange_log,$pwchange_path,$dir_line,$username,$oldpw,$newpw_1,$newpw_2,$samba_user); } # only root can create a logfile but CANNOT change the password with the "oldpassword newpassword newpassword" dialog !

        if ( $log ne "1" ) { &pwchange($smbpasswd,$username,$oldpw,$newpw_1,$newpw_2); } # only users can do this !

      } # end if


    } # end if ...

  } # end foreach ...

} # end else



sub logfile() {

  my ($pwchange_log,$pwchange_path,$dir_line,$username,$oldpw,$newpw_1,$newpw_2,$samba_user) =@_;

  sysopen(FILE, $pwchange_log, O_WRONLY|O_APPEND|O_CREAT,0700) or die("cannot open logfile: $!"); # append to logfile
      my $date = `date`;
      print FILE $date;
      print FILE "file used: $pwchange_path/$dir_line \n\n";
      print FILE "username: ",$username,"\n";
      print FILE "oldpw: ",$oldpw,"\n";
      print FILE "newpw_1: ",$newpw_1,"\n";
      print FILE "newpw_2: ",$newpw_2,"\n";
      print FILE "samba user: ",$samba_user,"\n";

      if ( "$newpw_1" ne "$newpw_2" ) { print FILE "-> new passwords don't match\n\n\n"; }

      else {
            print FILE "-> new passwords match\n\n\n";
          }

  close(FILE);

  `rm -f "$pwchange_path/$dir_line"`; # erase the file
}



sub pwchange() {

  my ($smbpasswd,$username,$oldpw,$newpw_1,$newpw_2) = @_;

  if ( "$newpw_1" eq "$newpw_2" ) {

    open (FILE, "|$smbpasswd -s") or die("cannot pipe into $smbpasswd: $!");
      print FILE qq|$oldpw\n|;
      print FILE qq|$newpw_1\n|;
      print FILE qq|$newpw_1\n|;
    close (FILE);

  } # end if

}


Hi,

I have setup Linux server and windows clients as work model. I used Samba for file sharing. I tried to use the above codes using postexec for remote window samba password change. But the postexec is not working. These codes are working in local Linux server with individual user login.

Please help me to solve the problem. I spent many days to solve. Thanks.

rtspitz 06-02-2010 06:48 AM

If the script works if run in a terminal, the problem lies with samba and the way it's been configured.

First try to get something simple working, as suggested in the manpage of smb.conf, and as usual check file permissions. Try setting a test script to 0777 (temporarily, not for good) and see if that helps. You could create a new linux group and make the script executable exclusively to this group (750).

derekpock 08-04-2013 12:30 AM

Much easier approach. Use the following, simply use variables in the command.

Code:

echo -e "new_password\nnew_password" | (passwd --stdin $USER)
echo -e "new_password\nnew_password" | (smbpasswd -s $USER)

Source : http://en.kioskea.net/faq/790-changi...d-via-a-script

rtspitz 08-04-2013 05:22 AM

Dear Derek,

that works if you're on a linux machine.

As far as I can remember, it's been a while, the purpose of this effort was to change the samba password when logged in on a windows machine - without having ssh access to the server etc.

derekpock 08-04-2013 12:16 PM

Ah, ok sorry, just giving the command out to those who need it.


All times are GMT -5. The time now is 08:42 AM.