3 # Display details of an existing user and allow editing
5 require './ldap-useradmin-lib.pl';
8 $ldap = &ldap_connect();
9 $schema = $ldap->schema();
11 $access{'ucreate'} || &error($text{'uedit_ecreate'});
12 $pass = $mconfig{'lock_string'};
13 $shell = $mconfig{'default_shell'} if ($mconfig{'default_shell'});
14 foreach $oec (split(/\s+/, $config{'other_class'})) {
17 if ($config{'samba_def'}) {
18 $oclass{$samba_class}++;
20 if ($config{'imap_def'}) {
21 @cyrus_class_3 = split(' ',$cyrus_class);
22 $oclass{$cyrus_class_3[0]}++;
25 # Get initial values from form parameters
26 foreach $n ("user", "firstname", "lastname", "real", "home", "shell",
27 "gid", "pass", "change", "expire", "min", "max", "warn",
29 if (defined($in{$n})) {
33 &ui_print_header(undef, $text{'uedit_title2'}, "");
36 # Get values from current user
37 $rv = $ldap->search(base => $in{'dn'},
39 filter => &user_filter());
40 ($uinfo) = $rv->all_entries;
41 @users = $uinfo->get_value('uid');
43 $uid = $uinfo->get_value('uidNumber');
44 $firstname = $uinfo->get_value('givenName');
45 $lastname = $uinfo->get_value('sn');
46 $real = $uinfo->get_value('cn');
47 $home = $uinfo->get_value('homeDirectory');
48 $shell = $uinfo->get_value('loginShell');
49 $gid = $uinfo->get_value('gidNumber');
50 $pass = $uinfo->get_value('userPassword');
51 $change = $uinfo->get_value('shadowLastChange');
52 $expire = $uinfo->get_value('shadowExpire');
53 $min = $uinfo->get_value('shadowMin');
54 $max = $uinfo->get_value('shadowMax');
55 $warn = $uinfo->get_value('shadowWarning');
56 $inactive = $uinfo->get_value('shadowInactive');
57 foreach $oc ($uinfo->get_value('objectClass')) {
60 @alias = $uinfo->get_value($config{'maillocaladdress'} || 'alias');
61 %uinfo = &dn_to_hash($uinfo);
62 &can_edit_user(\%uinfo) || &error($text{'uedit_eedit'});
63 &ui_print_header(undef, $text{'uedit_title'}, "");
65 @tds = ( "width=30%" );
67 # build a list of used shells and uids
68 @shlist = ($mconfig{'default_shell'} ? ( $mconfig{'default_shell'} ) : ( ));
69 %shells = map { $_, 1 } split(/,/, $config{'shells'});
70 push(@shlist, "/bin/sh", "/bin/csh", "/bin/false") if ($shells{'fixed'});
71 if ($shells{'passwd'}) {
72 # Don't do this unless we need to, as scanning all users is slow
73 &build_user_used(undef, \@shlist);
75 if ($shells{'shells'}) {
76 open(SHELLS, "/etc/shells");
80 push(@shlist, $_) if (/\S/);
84 push(@shlist, $shell) if ($shell);
85 @shlist = &unique(@shlist);
88 print &ui_form_start("save_user.cgi", "post");
89 print &ui_hidden("new", $in{'new'});
90 print &ui_hidden("dn", $in{'dn'});
91 print &ui_table_start($text{'uedit_details'}, "width=100%", 2, \@tds);
95 print &ui_table_row($text{'uedit_dn'},
96 "<tt>$in{'dn'}</tt>", 3);
98 print &ui_table_row($text{'uedit_classes'},
99 ,join(" , ", map { "<tt>$_</tt>" }
100 $uinfo->get_value('objectClass')), 3);
103 # Show username input
104 print &ui_table_row($text{'user'},
105 @users > 1 ? &ui_textarea("user", join("\n", @users), 2, 10)
106 : &ui_textbox("user", $user, 20));
108 # Show UID input, filled in with a default for new users
110 # Find the first free UID above the base
111 $newuid = $mconfig{'base_uid'};
112 while(&check_uid_used($ldap, $newuid)) {
115 $uidfield = &ui_textbox("uid", $newuid, 10);
118 $uidfield = &ui_textbox("uid", $uid, 10);
120 print &ui_table_row($text{'uid'}, $uidfield);
122 if ($config{'given'}) {
123 # Show Full name inputs
125 if ($config{'given_order'} == 0) {
127 $onch = "onChange='form.real.value = form.firstname.value+\" \"+form.lastname.value'";
131 $onch = "onChange='form.real.value = form.lastname.value+\", \"+form.firstname.value'";
134 print &ui_table_row($text{'uedit_firstname'},
135 &ui_textbox("firstname", $firstname, 20, 0, undef, $onch));
137 print &ui_table_row($text{'uedit_lastname'},
138 &ui_textbox("lastname", $lastname, 20, 0, undef, $onch));
141 # Show real name input
142 print &ui_table_row($text{'real'},
143 &ui_textbox("real", $real, 40));
145 # Work out group name
147 $grp = $mconfig{'default_group'};
150 $grp = &all_getgrgid($gid);
153 # Show home directory input, with an 'automatic' option
154 if ($mconfig{'home_base'}) {
155 local $hb = $in{'new'} ||
156 &auto_home_dir($mconfig{'home_base'}, $user, $grp) eq $home;
157 $homefield = &ui_radio("home_base", $hb ? 1 : 0,
158 [ [ 1, $text{'uedit_auto'} ],
159 [ 0, &ui_filebox("home", $hb ? "" : $home,
160 25, 0, undef, undef, 1) ]
164 $homefield = &ui_filebox("home", $home, 25, 0, undef, undef, 1);
166 print &ui_table_row($text{'home'}, $homefield);
168 # Show shell selection menu
169 print &ui_table_row($text{'shell'},
170 &ui_select("shell", $uinfo{'shell'}, \@shlist, 1, 0, 0, 0,
171 "onChange='form.othersh.disabled = form.shell.value != \"*\"'").
172 &ui_filebox("othersh", undef, 40, 1));
174 # Generate password if needed
175 if ($in{'new'} && $mconfig{'random_password'}) {
176 $random_password = &useradmin::generate_random_password();
179 # Check if temporary locking is supported
180 if (!$in{'new'} && $pass ne $mconfig{'lock_string'} && $pass ne "") {
181 # Can disable if not already locked, or if a new account
183 if ($pass =~ /^\Q$useradmin::disable_string\E/) {
185 $pass =~ s/^\Q$useradmin::disable_string\E//;
192 # Show password field
193 $passmode = $pass eq "" && $random_password eq "" ? 0 :
194 $pass eq $mconfig{'lock_string'} && $random_password eq "" ? 1 :
195 $random_password ne "" ? 3 :
196 $pass && $pass ne $mconfig{'lock_string'} &&
197 $random_password eq "" ? 2 : -1;
198 $pffunc = $mconfig{'passwd_stars'} ? \&ui_password : \&ui_textbox;
199 print &ui_table_row($text{'pass'},
200 &ui_radio_table("passmode", $passmode,
201 [ [ 0, $mconfig{'empty_mode'} ? $text{'none1'} : $text{'none2'} ],
202 [ 1, $text{'nologin'} ],
204 &$pffunc("pass", $mconfig{'random_password'} && $n eq "" ?
205 $random_password : "", 15) ],
206 $access{'nocrypt'} ? ( [ 2, $text{'nochange'},
207 &ui_hidden("encpass", $pass) ] ) :
208 ( [ 2, $text{'encrypted'},
209 &ui_textbox("encpass", $passmode == 2 ? $pass : "", 40) ] )
211 ($can_disable ? " ".&ui_checkbox("disable", 1,
212 $text{'uedit_disabled'}, $disabled) : "")
215 print &ui_table_end();
217 # Show shadow password options
218 if (&in_schema($schema, "shadowLastChange")) {
219 print &ui_table_start($text{'uedit_passopts'}, "width=100%", 4, \@tds);
222 print &ui_table_row($text{'change'},
223 ($uinfo{'change'} ? &make_date(timelocal(
224 gmtime($change * 60*60*24)),1) :
225 $n eq "" ? $text{'uedit_never'} :
226 $text{'uedit_unknown'}));
230 $mconfig{'default_expire'} =~ /^(\d+)\/(\d+)\/(\d+)$/) {
236 @tm = localtime(timelocal(gmtime($expire * 60*60*24)));
239 $eyear = $tm[5]+1900;
241 print &ui_table_row($text{'expire'},
242 &useradmin::date_input($eday, $emon, $eyear, 'expire'));
244 # Minimum and maximum days for changing
245 print &ui_table_row($text{'min'},
246 &ui_textbox("min", $in{'new'} ? $mconfig{'default_min'}
248 print &ui_table_row($text{'max'},
249 &ui_textbox("max", $in{'new'} ? $mconfig{'default_max'}
252 # Password warning days
253 print &ui_table_row($text{'warn'},
254 &ui_textbox("warn", $in{'new'} ? $mconfig{'default_warn'}
258 print &ui_table_row($text{'inactive'},
259 &ui_textbox("inactive", $in{'new'} ?$mconfig{'default_inactive'}
262 # Force password change at next login
264 $text{'uedit_forcechange'},
265 &ui_yesno_radio("forcechange", 0));
268 print &ui_table_end();
271 # Group memberships section
272 print &ui_table_start($text{'uedit_gmem'}, "width=100%", 4, \@tds);
275 print &ui_table_row($text{'group'},
276 &ui_textbox("gid", $grp || $gid, 13).
277 " ".&group_chooser_button("gid"), 3);
279 if ($config{'secmode'} != 1) {
280 # Work out which secondary groups the user is in
281 @defsecs = &split_quoted_string($mconfig{'default_secs'});
282 $base = &get_group_base();
283 $rv = $ldap->search(base => $base,
284 filter => &group_filter());
286 foreach $g (sort { lc($a->dn()) cmp lc($b->dn()) } $rv->all_entries) {
287 $group = $g->get_value("cn");
288 @mems = $g->get_value("memberUid");
289 $desc = $g->get_value("description");
290 local $ismem = &indexof($user, @mems) >= 0;
292 $ismem = 1 if (&indexof($group, @defsecs) >= 0);
294 $ingroups{$group} = $ismem;
295 $descgroups{$group} = " ($desc)";
299 if ($config{'secmode'} == 0) {
300 # Show secondary groups with select menu
301 foreach $g (sort { lc($a->dn()) cmp lc($b->dn()) } $rv->all_entries) {
302 $group = $g->get_value("cn");
303 push(@canglist, [ $group, $group ]);
305 @ingroups = map { [ $_, $_.$descgroups{$_} ] } sort { $a cmp $b }
306 grep { $ingroups{$_} } (keys %ingroups);
307 $groupfield = &ui_multi_select("sgid", \@ingroups, \@canglist, 5, 1, 0,
308 $text{'uedit_allg'}, $text{'uedit_ing'});
310 elsif ($config{'secmode'} == 2) {
313 foreach $g (sort { lc($a->dn()) cmp lc($b->dn()) } $rv->all_entries) {
314 $group = $g->get_value("cn");
315 if ($ingroups{$group}) {
316 push(@insecs, $group);
319 $groupfield = &ui_textarea("sgid", join("\n", @insecs), 5, 20);
322 print &ui_table_row($text{'uedit_2nd'}, $groupfield, 3);
325 print &ui_table_end();
327 # Show extra fields (if any)
328 &extra_fields_input($config{'fields'}, $uinfo, \@tds);
330 # Show capabilties section
331 print &ui_table_start($text{'uedit_cap'}, "width=100%", 4, \@tds);
334 print &ui_table_row($text{'uedit_samba'},
335 &ui_yesno_radio("samba", $oclass{$samba_class} ? 1 : 0));
337 if ($config{'imap_host'}) {
339 @cyrus_class_3 = split(' ',$cyrus_class);
340 print &ui_table_row($text{'uedit_cyrus'},
341 &ui_yesno_radio("cyrus", $oclass{$cyrus_class_3[0]} ? 1 : 0));
344 if ($config{'domain'}) {
345 print &ui_table_row($text{'uedit_alias'},
346 &ui_textbox("alias", join(" ", @alias), 40), 3);
349 # Show field for changing the quota on existing users, or setting
351 if ($config{'quota_support'}) {
352 print &ui_table_row($text{'uedit_quota'},
353 $in{'new'} || !$oclass{$cyrus_class_3[0]} ?
354 &ui_textbox("quota", $config{'quota'}, 10)." kB" :
355 &ui_opt_textbox("quota", undef, 10,
356 $text{'uedit_unquota'})." Kb");
360 print &ui_hidden("cyrus", $oclass{$cyrus_class});
362 print &ui_table_end();
366 print &ui_table_start($text{'uedit_oncreate'}, "width=100%",
370 print &ui_table_row($text{'uedit_makehome'},
371 &ui_yesno_radio("makehome", 1));
373 # Create in other modules?
374 print &ui_table_row($text{'uedit_cothers'},
375 &ui_yesno_radio("others", $mconfig{'default_other'}));
377 print &ui_table_end();
381 print &ui_table_start($text{'onsave'}, "width=100%", 2, \@tds);
383 # Move home directory
384 print &ui_table_row($text{'uedit_movehome'},
385 &ui_yesno_radio("movehome", 1));
387 # Change UID on files
388 print &ui_table_row($text{'uedit_chuid'},
389 &ui_radio("chuid", 1,
390 [ [ 0, $text{'no'} ],
391 [ 1, $text{'home'} ],
392 [ 2, $text{'uedit_allfiles'} ] ]));
394 # Change GID on files
395 print &ui_table_row($text{'uedit_chgid'},
396 &ui_radio("chgid", 1,
397 [ [ 0, $text{'no'} ],
398 [ 1, $text{'home'} ],
399 [ 2, $text{'uedit_allfiles'} ] ]));
401 # Modify in other modules
402 print &ui_table_row($text{'uedit_mothers'},
403 &ui_yesno_radio("others",
404 $mconfig{'default_other'} ? 1 : 0));
406 print &ui_table_end();
409 # Build buttons for end of form
412 # Show buttons for new users
413 push(@buts, [ undef, $text{'create'} ]);
416 # Show buttons for existing users
417 push(@buts, [ undef, $text{'save'} ],
418 [ 'raw', $text{'uedit_raw'} ]);
420 if (&foreign_available("mailboxes") &&
421 &foreign_installed("mailboxes", 1)) {
422 # Link to the mailboxes module, if installed
423 push(@buts, [ 'mailboxes', $text{'uedit_mail'} ]);
426 if (&foreign_available("usermin") &&
427 &foreign_installed("usermin", 1) &&
428 (%uacl = &get_module_acl("usermin") &&
429 $uacl{'sessions'})) {
430 # Link to Usermin module for switching to some user
431 &foreign_require("usermin", "usermin-lib.pl");
433 &usermin::get_usermin_miniserv_config(\%uminiserv);
434 if ($uminiserv{'session'}) {
435 push(@buts, [ "switch", $text{'uedit_swit'} ]);
439 push(@buts, [ 'delete', $text{'delete'} ]);
441 print &ui_form_end(\@buts);
443 &ui_print_footer("", $text{'index_return'});