1#!/usr/bin/perl
2# chsh implementation for LDAP
3# Copyright (C) 2000 Tom Lear <tom@trap.mtview.ca.us>
4
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18#
19
20if($ARGV[0] eq '-s') {
21  shift;
22  $shell=shift;
23}
24
25$user=$ARGV[0];
26if($user eq '') {
27  $user=(getpwuid($<))[0];
28} else {
29  die "You can't change that user.\n" if($< and $<!=getpwnam($user));
30}
31
32# use pam_ldap's config file since this script is ldap specific and
33# is a work around for a deficiency in pam
34$CONF{'pam_login_attribute'}='uid';
35open(CONF,"/etc/ldap.conf") or die "$!\n";
36while(<CONF>) {
37  next if(m/^\s*($|#)/);
38  m/^\s*(\S+)\s+(.*?)\s*$/;
39  $CONF{$1}=$2;
40}
41close(CONF);
42open(CONF,"/etc/ldap.secret") and chomp($CONF{'rootbindpw'}=<CONF>);
43close(CONF);
44
45use Net::LDAP;
46
47$ldap=Net::LDAP->new($CONF{'host'});
48
49if($< or $CONF{'rootbinddn'} eq '') {
50  $ENV{'PATH'}='';
51  system "/bin/stty -echo";
52  print 'Password:';
53  chomp($password = <STDIN>);
54  print "\n";
55  system "/bin/stty echo";
56  %bindargs=('dn'         => "$CONF{pam_login_attribute}=$user,ou=People,$CONF{base}",
57             'password'   => $password,
58  );
59} else {
60  %bindargs=('dn'         => $CONF{'rootbinddn'},
61             'password'   => $CONF{'rootbindpw'},
62  );
63}
64$bindargs{'version'}=$CONF{'ldap_version'}?$CONF{'ldap_version'}:2;
65
66$ldap->bind(%bindargs) or die "unable to bind to ldap server: $@";
67
68# check if the old shell is valid
69$oldshell=(getpwnam($user))[8];
70open(IN,"/etc/shells");
71while(<IN>) {
72  chomp;
73  $valid=1 if($oldshell eq $_);
74}
75close(IN);
76die "can't change shell for `$user'\n" if($< and !$valid);
77
78# get the new shell if neccesary
79if($shell eq '') {
80  print "Enter the new value, or press return for the default\n\n";
81  print "\t Login Shell [$oldshell]: ";
82  $shell=<STDIN>;
83  chomp $shell;
84  $shell=$oldshell if($shell eq '');
85}
86
87# check the shells validity
88if($<) {
89  $valid=0;
90  open(IN,"/etc/shells");
91  while(<IN>) {
92    chomp;
93    $valid=1 if($shell eq $_);
94  }
95  close(IN);
96  die "$shell is an invalid shell.\n" if(!$valid);
97}
98
99# change the shell
100$ret=$ldap->modify("$CONF{pam_login_attribute}=$user,ou=People,$CONF{base}",
101        replace => {'loginShell' => $shell});
102if($ret->code) {
103  printf STDERR ("failed: %s\n",$ret->error);
104} else {
105  print "changed user `$user' shell to `$shell'\n";
106}
107
108