• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/samba-3.0.13/examples/LDAP/smbldap-tools-0.8.7/
1#!/usr/bin/perl -w
2
3# Created by P.Wieleba@iem.pw.edu.pl in 2004
4
5use strict;
6use Getopt::Std;
7use FindBin;
8use FindBin qw($RealBin);
9use lib "$RealBin/";
10use smbldap_tools;
11
12# function declaration
13sub exist_in_tab;
14
15my %Options;
16
17my $ok = getopts('f:r:w:h:o:s:?v', \%Options);
18if ( (!$ok) || ($Options{'?'}) ) {
19  print "Usage: $0 [-frwhosh?] username\n";
20  print "  -?|-h show this help message\n";
21  print "  -f full_name\n";
22  print "  -r room_no\n";
23  print "  -w work_ph\n";
24  print "  -h home_ph\n";
25  print "  -o other\n";
26  print "  -s shell\n";
27  print "  -v show modified user record\n";
28  exit (1);
29}
30
31
32my $user;
33my $pass;
34if ( $< != 0 ) {
35  my $current_user = getpwuid($<);
36  if ($current_user and $ARGV[0] and $current_user ne $ARGV[0] ) {
37    die "Only root can change other users inormation\n";
38  }
39} else {
40  if ( $ARGV[0] ) {
41    $user = $ARGV[0];
42  }
43  $pass = 1;
44}
45
46if (!defined($user)) {
47  $user = getpwuid($<);
48}
49
50my ($dn,$ldap_master);
51# First, connecting to the directory
52if ($< != 0) {
53  # non-root user
54  if (!defined($pass)) {
55    # prompt for password
56    print "UNIX password: ";
57    system "stty -echo" if (-t STDIN);
58    chomp($pass=<STDIN>);
59    system "stty echo" if (-t STDIN);
60    print "\n";
61
62    $config{masterDN}="uid=$user,$config{usersdn}";
63    $config{masterPw}="$pass";
64    $ldap_master=connect_ldap_master();
65    $dn=$config{masterDN};
66    if (!is_user_valid($user, $dn, $pass)) {
67      print "Authentication failure\n";
68      exit (10);
69    }
70  }
71} else {
72  # root user
73  $ldap_master=connect_ldap_master();
74  # test existence of user in LDAP
75  my $dn_line;
76  if (!defined($dn_line = get_user_dn($user))) {
77    print "$0: user $user doesn't exist\n";
78    exit (10);
79  }
80  $dn = get_dn_from_line($dn_line);
81}
82
83my %eng = (
84	   'shell'  => 'User Shell',
85	   'name'   => 'Full Name',
86	   'office' => 'Room Number',
87	   'wphone' => 'Work Phone',
88	   'hphone' => 'Home Phone',
89	   'other' => 'Other'
90	  );
91
92# obtain old values
93my $entry = read_user_entry($user);
94my $gecos = $entry->get_value('gecos');
95my %old;
96( $old{'name'},
97  $old{'office'},
98  $old{'wphone'},
99  $old{'hphone'},
100  $old{'other'}
101) = split(/,/,$gecos);
102$old{'shell'} = $entry->get_value('LoginShell');
103# unbind from LDAP
104$ldap_master->unbind();
105
106foreach my $key (keys %old) {
107  !defined($old{$key}) and $old{$key}="";
108}
109
110# read new values
111my %new;
112if ($Options{'f'}) {
113  $new{'name'} = $Options{'f'};
114}
115if ($Options{'r'}) {
116  $new{'office'} = $Options{'r'};
117}
118if ($Options{'w'}) {
119  $new{'wphone'} = $Options{'w'};
120}
121if ($Options{'h'}) {
122  $new{'hphone'} = $Options{'h'};
123}
124if ($Options{'o'}) {
125  $new{'other'} = $Options{'o'};
126}
127if ($Options{'s'}) {
128  $new{'shell'} = $Options{'s'};
129}
130if ( keys(%Options) < 1 or keys(%Options) == 1 and $Options{'v'} ) {
131  print "Changing the user information for $user\n";
132  print "Enter the new value, or press ENTER for the default\n";
133
134  print " $eng{'shell'} [$old{'shell'}]:";
135  $new{'shell'} = readline(*STDIN);
136  print " $eng{'name'} [$old{'name'}]:";
137  $new{'name'} = readline(*STDIN);
138  print " $eng{'office'} [$old{'office'}]:";
139  $new{'office'} = readline(*STDIN);
140  print " $eng{'wphone'} [$old{'wphone'}]:";
141  $new{'wphone'} = readline(*STDIN);
142  print " $eng{'hphone'} [$old{'hphone'}]:";
143  $new{'hphone'} = readline(*STDIN);
144  print " $eng{'other'} [$old{'other'}]:";
145  $new{'other'} = readline(*STDIN);
146}
147
148
149foreach my $key (keys %old) {
150  if (!$new{$key}) {
151    $new{$key} = $old{$key};
152  }
153}
154
155# simple check of new values
156foreach my $key (keys %new) {
157  chop($new{$key}) if ( $new{$key}=~/\n$/ );
158  if ($new{$key} =~ /^\s+$/ and $key ne 'shell') {
159    $new{$key} = "";
160  } elsif ($new{$key} =~ /^$/) {
161    $new{$key} = $old{$key};
162  } elsif ($key ne 'other' and $new{$key} =~ /.*,.*/) {
163    print "Comma cannot be used with $key.\n";
164    exit(6);
165  }
166  # $new{$key} eq "" 
167}
168
169# [TODO] check if shell really exists
170if ( $new{'shell'} and !($new{'shell'}=~/^\/.+\/.+/)
171     and ($old{'shell'}=~/^\/.+\/.+/)
172   ) {
173  $new{'shell'} = $old{'shell'};
174} elsif ( $new{'shell'} and !($new{'shell'}=~/^\/.+\/.+/)
175          or !$new{'shell'} and !$old{'shell'}
176        ) {
177  $new{'shell'} = '/bin/sh';
178}
179
180if ( !$new{'name'} ) {
181  $new{'name'} = $user;
182}
183
184# prepare gecos field
185$gecos = join(',',
186	      ( $new{'name'},
187		$new{'office'},
188		$new{'wphone'},
189		$new{'hphone'},
190		$new{'other'}
191	      )
192             );
193
194my @tmp = split(/\s+/,$new{'name'});
195my $sn = $tmp[$#tmp];
196pop(@tmp);
197my $givenName = join(' ',@tmp);
198
199$entry->replace( 'gecos' => $gecos );
200$entry->replace( 'cn'    => $new{'name'} );
201
202if ( exist_in_tab( [$entry->get_value('objectClass')],'inetOrgPerson') ) {
203  if ( $sn ) {
204    $entry->replace('sn' => $sn);
205  } else {
206    $entry->replace('sn' => $user);
207  }
208  if ( $givenName ) {
209    $entry->replace('givenName' => $givenName);
210  } else {
211    $entry->get_value('givenName') and $entry->delete('givenName');
212  }
213  if ( $new{'office'} ) {
214    $entry->replace('roomNumber' => $new{'office'});
215  } else {
216    $entry->get_value('roomNumber') and $entry->delete('roomNumber');
217  }
218  if ( $new{'wphone'} ) {
219    $entry->replace('telephoneNumber' => $new{'wphone'});
220  } else {
221    $entry->get_value('telephoneNumber') and $entry->delete('telephoneNumber');
222  }
223  if ( $new{'hphone'} ) {
224    $entry->replace('homePhone' => $new{'hphone'});
225  } else {
226    $entry->get_value('homePhone') and $entry->delete('homePhone');
227  }
228}				#end of inetOrgPerson
229if ( $new{'shell'} ) {
230  $entry->replace('loginShell' => $new{'shell'});
231} else {
232  $entry->get_value('loginShell') and $entry->delete('loginShell');
233}
234
235if ($Options{'v'}) {
236  $entry->dump();
237}
238# bind to LDAP and update entry
239$ldap_master = connect_ldap_master();
240my $mesg = $entry->update($ldap_master);
241if ($mesg->is_error()) {
242  print "Error: " . $mesg->error() . "\n";
243} else {
244  print "LDAP updated\n";
245}
246$ldap_master and $ldap_master->unbind;
247
248# Check if a $text element exists in @table
249# eg. exist_in_tab(\@table,$text);
250sub exist_in_tab
251  {
252    my($ref_tab,$text) = @_;
253    my @tab = @$ref_tab;
254
255    foreach my $elem (@tab) {
256      if ( lc($elem) eq lc($text) ) {
257	return 1;
258      }
259    }
260    return 0;
261  }
262
263########################################
264
265=head1 NAME
266
267smbldap-chfn - change user real name, information and shell
268
269=head1 SYNOPSIS
270
271smbldap-chfn [-f full_name] [-r room_no] [-w work_ph] [-h home_ph]
272[-o other] [-s login_shell] [-?] [-v]
273
274=head1 DESCRIPTION
275
276This command changes user gecos fields and login shell.
277The normal user can change only the fields for his own account,
278the super user may change the fiels for any account.
279
280If none of the options are selected, the command is run
281in an interactive mode for the current user account. User is
282asked for all fields. To accept a default value you should 
283just press <ENTER>, otherwise write text and press <ENTER>.
284
285posixAccount objectClasses has to be present in the modified
286entry. If inetOrgPerson objectClass is also present additional
287attributes will be changed (givenName,sn,roomNumber,telephoneNumber,
288homePhone)
289
290-f full_name
291       affected attributes: 'gecos', 'cn' (and 'givenName', 'sn'
292       if inetOrgPerson is present) 
293
294-r room_number
295       affected attributes: 'gecos' (and 'roomNumber'
296       if inetOrgPerson is present)
297
298-w work_phone
299       affected attributes: 'gecos' (and 'telephoneNumber'
300       if inetOrgPerson is present)
301
302-h home_phone
303       affected attributes: 'gecos' (and 'homePhone'
304       if inetOrgPerson is present)
305
306-o other
307       affected attributes: 'gecos'
308
309-s login_shell
310       affected attributes: 'loginShell'
311
312-?     show the help message
313
314-v     verbose - show modified user entry
315
316=cut
317
318#'
319
320# The End
321
322