2 # Core proftpd directives
4 # mod_core_directives(version)
5 # Returns a directive structure, like the one user by Apache. Types are :
13 sub mod_core_directives
16 [ 'AccessDenyMsg', 0, 3, 'virtual anon global', 1.202 ],
17 [ 'AccessGrantMsg', 0, 3, 'virtual anon global', 0.99 ],
18 [ 'Allow Deny Order', 1, 3, 'limit', 0.99 ],
19 [ 'AllowAll DenyAll', 0, 3, 'directory anon limit ftpaccess', 0.99 ],
20 [ 'AllowFilter', 0, 3, 'virtual anon global', 1.20 ],
21 [ 'AllowForeignAddress', 0, 0, 'virtual anon global', 1.17 ],
22 [ 'AllowGroup', 1, 3, 'limit', 1.11 ],
23 [ 'AllowOverwrite', 0, 3, 'virtual anon directory ftpaccess global', 0.99 ],
24 [ 'AllowUser', 1, 3, 'limit', 1.17 ],
25 [ 'AllowRetrieveRestart', 0, 0, 'virtual anon directory global ftpaccess', 0.99 ],
26 [ 'AllowStoreRestart', 0, 0, 'virtual anon directory global ftpaccess', 0.99 ],
27 [ 'AnonRequirePassword', 0, 6, 'anon', 0.99 ],
28 [ 'AnonymousGroup', 0, 6, 'virtual global', 1.13 ],
29 [ 'AuthAliasOnly', 0, 6, 'virtual anon global', 1.13 ],
30 [ 'AuthUsingAlias', 0, 6, 'anon', 1.20 ],
31 [ 'Bind', 0, 0, 'virtual', '1.16-1.27' ],
32 [ 'DefaultAddress', 0, 0, 'virtual', '1.27' ],
33 [ 'CDPath', 1, 2, 'virtual anon global', 1.20 ],
34 [ 'Class Classes', 1, 3, 'virtual', 1.20 ],
35 [ 'CommandBufferSize', 0, 0, 'virtual global', 1.20 ],
36 [ 'DefaultServer', 0, 0, 'virtual', undef, 0.99, 8 ],
37 [ 'DefaultTransferMode', 0, 0, 'virtual global', 1.20 ],
38 [ 'DeferWelcome', 0, 0, 'virtual global', 0.99 ],
39 [ 'DeleteAbortedStores', 0, 2, 'virtual directory anon global ftpaccess', 1.20 ],
40 [ 'DenyFilter', 0, 3, 'virtual anon global', 1.20 ],
41 [ 'DenyGroup', 1, 3, 'limit', 1.11 ],
42 [ 'DenyUser', 1, 3, 'limit', 1.17 ],
43 [ 'DisplayConnect', 0, 6, 'virtual global', 1.20 ],
44 [ 'DisplayFirstChdir', 0, 2, 'virtual anon directory global', '0.99-1.31' ],
45 [ 'DisplayChdir', 0, 2, 'virtual anon directory global', 1.31 ],
46 [ 'DisplayGoAway', 0, 6, 'virtual anon global', 1.20 ],
47 [ 'DisplayLogin', 0, 6, 'virtual anon global', 0.99 ],
48 [ 'DisplayQuit', 0, 6, 'virtual anon global', 1.20 ],
49 [ 'Group', 0, 5, 'virtual anon', undef, 0.99, 9 ],
50 [ 'GroupOwner', 0, 5, 'anon directory ftpaccess', 0.99 ],
51 [ 'GroupPassword', 1, 6, 'virtual anon global', 0.99 ],
52 [ 'HiddenStor', 0, 2, 'virtual anon directory global', '1.20-1.31' ],
53 [ 'HiddenStores', 0, 2, 'virtual anon directory global', 1.31 ],
54 [ 'HideGroup', 1, 2, 'directory anon', 0.99 ],
55 [ 'HideNoAccess', 0, 2, 'directory anon', 0.99 ],
56 [ 'HideUser', 1, 2, 'directory anon', 0.99 ],
57 [ 'IdentLookups', 0, 0, 'virtual global', 1.15 ],
58 [ 'IgnoreHidden', 0, 2, 'limit', 0.99 ],
59 [ 'MasqueradeAddress', 0, 0, 'virtual', 1.202 ],
60 [ 'MaxClients', 0, 0, 'virtual anon global', 0.99 ],
61 [ 'MaxClientsPerHost', 0, 0, 'virtual anon global', 1.17 ],
62 # [ 'MaxClientsPerUser', 0, 0, 'virtual anon global', 1.20 ],
63 [ 'MaxInstances', 0, 0, 'root', undef, 1.16, 8 ],
64 [ 'MaxLoginAttempts', 0, 6, 'virtual global', 0.99 ],
65 [ 'MultilineRFC2228', 0, 0, 'root', 1.20 ],
66 [ 'PassivePorts', 0, 0, 'virtual global', 1.20 ],
67 [ 'PathAllowFilter', 0, 2, 'virtual anon global', 1.17 ],
68 [ 'PathDenyFilter', 0, 2, 'virtual anon global', 1.17 ],
69 [ 'PidFile', 0, 4, 'root', 1.20 ],
70 [ 'Port', 0, 0, 'virtual', 0.99 ],
71 [ 'RequireValidShell', 0, 6, 'virtual anon global', 0.99 ],
72 [ 'RLimitCPU', 0, 4, 'root', 1.202 ],
73 [ 'RLimitMemory', 0, 4, 'root', 1.202 ],
74 [ 'RLimitOpenFiles', 0, 4, 'root', 1.202 ],
75 [ 'ScoreboardPath', 0, 4, 'root', 1.16 ],
76 [ 'ServerAdmin', 0, 4, 'virtual', 0.99 ],
77 [ 'ServerIdent', 0, 0, 'virtual global', 1.20 ],
78 [ 'ServerName', 0, 4, 'virtual', undef, 0.99, 11 ],
79 [ 'ServerType', 0, 0, 'root', undef, 0.99, 10 ],
80 [ 'ShowSymlinks', 0, 2, 'virtual anon global', 0.99 ],
81 [ 'SocketBindTight', 0, 0, 'root', 0.99 ],
82 [ 'SyslogFacility', 0, 1, 'root', 1.16 ],
83 [ 'SyslogLevel', 0, 1, 'virtual anon global', 1.20 ],
84 [ 'tcpBackLog', 0, 0, 'root', 0.99 ],
85 [ 'tcpNoDelay', 0, 0, 'virtual global', 1.20 ],
86 [ 'tcpReceiveWindow', 0, 0, 'virtual', 0.99 ],
87 [ 'tcpSendWindow', 0, 0, 'virtual', 0.99 ],
88 [ 'TimesGMT', 0, 4, 'root', 1.20 ],
89 [ 'TimeoutIdle', 0, 0, 'root', 0.99 ],
90 [ 'TimeoutLogin', 0, 0, 'root', 0.99 ],
91 [ 'TimeoutNoTransfer', 0, 0, 'root', 0.99 ],
92 [ 'TimeoutStalled', 0, 0, 'root', 1.16 ],
93 [ 'TransferLog', 0, 1, 'virtual anon global', undef, 1.14, 10 ],
94 [ 'Umask', 0, 2, 'virtual directory ftpaccess', undef, 0.99, 3 ],
95 [ 'UseFtpUsers', 0, 6, 'virtual anon global', 0.99 ],
96 [ 'UseHostsAllowFile', 0, 3, 'virtual anon', 1.20 ],
97 [ 'UseHostsDenyFile', 0, 3, 'virtual anon', 1.20 ],
98 [ 'UseReverseDNS', 0, 0, 'root', 1.17 ],
99 [ 'User', 0, 5, 'virtual anon', undef, 0.99, 10 ],
100 [ 'UserDirRoot', 0, 2, 'anon', 1.20 ],
101 [ 'UserAlias', 1, 6, 'virtual anon global', 0.99 ],
102 [ 'UserOwner', 0, 5, 'anon directory', 1.20 ],
103 [ 'UserPassword', 1, 6, 'virtual anon global', 0.99 ],
104 [ 'WtmpLog', 0, 4, 'virtual anon global', 1.17 ],
106 return &make_directives($rv, $_[0], "mod_core");
109 sub edit_AccessDenyMsg
111 return (1, $text{'mod_core_accessdeny'},
112 &opt_input($_[0]->{'words'}->[0], "AccessDenyMsg", $text{'default'}, 20));
114 sub save_AccessDenyMsg
116 return &parse_opt("AccessDenyMsg");
119 sub edit_AccessGrantMsg
121 return (1, $text{'mod_core_accessgrant'},
122 &opt_input($_[0]->{'words'}->[0], "AccessGrantMsg", $text{'default'}, 20));
124 sub save_AccessGrantMsg
126 return &parse_opt("AccessGrantMsg");
129 sub edit_Allow_Deny_Order
131 local (@type, @what, @mode, $i);
132 foreach $d (@{$_[0]}, @{$_[1]}) {
133 local @w = @{$d->{'words'}};
134 shift(@w) if (lc($w[0]) eq 'from');
135 for($i=0; $i<@w; $i++) {
136 push(@type, lc($d->{'name'}) eq "allow" ? 1 : 2);
137 push(@what, $w[$i] eq 'all' || $w[$i] eq 'none' ? undef
139 if ($w[$i] eq 'all') { push(@mode, 0); }
140 elsif ($w[$i] eq 'none') { push(@mode, 1); }
141 elsif ($w[$i] =~ /^\d+\.\d+\.\d+\.\d+$/) { push(@mode, 2); }
142 elsif ($w[$i] =~ /^[0-9\.\/]+$/) { push(@mode, 3); }
143 else { push(@mode, 4); }
146 push(@type, ""); push(@what, ""); push(@mode, 0);
147 $rv = "<i>$text{'mod_core_order'}</i>\n".
148 &choice_input($_[2]->[0]->{'value'}, "order", "",
149 "$text{'mod_core_denyallow'},deny,allow",
150 "$text{'mod_core_allowdeny'},allow,deny",
151 "$text{'default'},")."<br>\n";
152 $rv .= "<table border>\n".
153 "<tr $tb> <td><b>$text{'mod_core_action'}</b></td> ".
154 "<td><b>$text{'mod_core_cond'}</b></td> </tr>\n";
155 @sels = map { $text{"mod_core_mode_$_"}.','.$_ } (0 .. 4);
156 for($i=0; $i<@type; $i++) {
157 $rv .= "<tr $cb> <td>".&select_input($type[$i], "allow_type_$i", "0",
158 " ,0", "$text{'mod_core_allow'},1",
159 "$text{'mod_core_deny'},2")."</td>\n";
160 $rv .= "<td>".&select_input($mode[$i], "allow_mode_$i", "0", @sels);
161 $rv .= sprintf "<input name=allow_what_$i size=20 value=\"%s\"></td>\n",
162 $mode[$i] ? $what[$i] : "";
166 return (2, $text{'mod_core_allow_deny'}, $rv);
168 sub save_Allow_Deny_Order
170 local ($i, $type, $mode, $what, @allow, @deny);
171 for($i=0; defined($type = $in{"allow_type_$i"}); $i++) {
172 $mode = $in{"allow_mode_$i"}; $what = $in{"allow_what_$i"};
174 if ($mode == 0) { $what = "all"; }
175 elsif ($mode == 1) { $what = "none"; }
177 &check_ipaddress($what) || &check_ip6address($what) ||
178 &error(&text('mod_core_eip', $what));
181 $what =~ /^[0-9\.]+\.$/ ||
182 $what =~ /^([0-9\.]+)\/\d+$/ && &check_ipaddress("$1") ||
183 $what =~ /^([a-f0-9:]+)\/\d+$/ && &check_ip6address("$1") ||
184 &error(&text('mod_core_enet', $what));
187 $what =~ /^[A-Za-z0-9\.\-]+$/ ||
188 &error(&text('mod_core_ehost', $what));
190 if ($type == 1) { push(@allow, $what); }
191 else { push(@deny, $what); }
193 return ( \@allow, \@deny, &parse_choice("order", ""));
196 sub edit_AllowAll_DenyAll
198 #local $a = @{$_[0]}, $d = @{$_[1]};
199 local $a = $_[0], $d = $_[1];
200 local $rv = sprintf "<input type=radio name=AllowAll value=0 %s> %s\n",
201 $a || $d ? "" : "checked", $text{'mod_core_addefault'};
202 $rv .= sprintf "<input type=radio name=AllowAll value=1 %s> %s\n",
203 $a ? "checked" : "", $text{'mod_core_allowall'};
204 $rv .= sprintf "<input type=radio name=AllowAll value=2 %s> %s\n",
205 $d ? "checked" : "", $text{'mod_core_denyall'};
206 return (1, $text{'mod_core_adall'}, $rv);
208 sub save_AllowAll_DenyAll
210 return $in{'AllowAll'} == 0 ? ( [ ], [ ] ) :
211 $in{'AllowAll'} == 1 ? ( [ "" ], [ ] ) : ( [ ], [ "" ] );
216 return (1, $text{'mod_core_filter'},
217 &opt_input($_[0]->{'value'}, "AllowFilter", $text{'default'}, 15));
221 return &parse_opt("AllowFilter");
224 sub edit_AllowForeignAddress
226 return (1, $text{'mod_core_foreign'},
227 &choice_input($_[0]->{'value'}, "AllowForeignAddress", "",
228 "$text{'yes'},on", "$text{'no'},off",
229 "$text{'default'},"));
231 sub save_AllowForeignAddress
233 return &parse_choice("AllowForeignAddress", "");
238 local $v = @{$_[0]} ? join(" ", (map { $_->{'value'} } @{$_[0]})) : undef;
239 return (2, $text{'mod_core_agroup'},
240 &opt_input($v, "AllowGroup", $text{'mod_core_all'}, 50));
244 return ( $in{'AllowGroup_def'} ? [ ] : [ split(/\s+/, $in{'AllowGroup'}) ] );
247 sub edit_AllowOverwrite
249 return (1, $text{'mod_core_overwrite'},
250 &choice_input($_[0]->{'value'}, "AllowOverwrite", "",
251 "$text{'yes'},on", "$text{'no'},off",
252 "$text{'default'},"));
254 sub save_AllowOverwrite
256 return &parse_choice("AllowOverwrite", "");
259 sub edit_AllowRetrieveRestart
261 return (1, $text{'mod_core_restart'},
262 &choice_input($_[0]->{'value'}, "AllowRetrieveRestart", "",
263 "$text{'yes'},on", "$text{'no'},off",
264 "$text{'default'},"));
266 sub save_AllowRetrieveRestart
268 return &parse_choice("AllowRetrieveRestart", "");
271 sub edit_AllowStoreRestart
273 return (1, $text{'mod_core_restart2'},
274 &choice_input($_[0]->{'value'}, "AllowStoreRestart", "",
275 "$text{'yes'},on", "$text{'no'},off",
276 "$text{'default'},"));
278 sub save_AllowStoreRestart
280 return &parse_choice("AllowStoreRestart", "");
285 local $v = @{$_[0]} ? join(" ", (map { $_->{'value'} } @{$_[0]})) : undef;
286 return (2, $text{'mod_core_auser'},
287 &opt_input($v, "AllowUser", $text{'mod_core_all'}, 50));
291 return ( $in{'AllowUser_def'} ? [ ] : [ split(/\s+/, $in{'AllowUser'}) ] );
294 sub edit_AnonRequirePassword
296 return (1, $text{'mod_core_require'},
297 &choice_input($_[0]->{'value'}, "AnonRequirePassword", "",
298 "$text{'yes'},on", "$text{'no'},off",
299 "$text{'default'},"));
301 sub save_AnonRequirePassword
303 return &parse_choice("AnonRequirePassword", "");
306 sub edit_AnonymousGroup
308 return (2, $text{'mod_core_anongroup'},
309 &opt_input($_[0]->{'value'}, "AnonymousGroup", $text{'default'}, 50));
312 sub save_AnonymousGroup
314 return &parse_opt("AnonymousGroup", '\S', $text{'mod_core_eanongroup'});
317 sub edit_AuthAliasOnly
319 return (1, $text{'mod_core_authalias'},
320 &choice_input($_[0]->{'value'}, "AuthAliasOnly", "",
321 "$text{'yes'},on", "$text{'no'},off",
322 "$text{'default'},"));
324 sub save_AuthAliasOnly
326 return &parse_choice("AuthAliasOnly", "");
329 sub edit_AuthUsingAlias
331 return (1, $text{'mod_core_authusingalias'},
332 &choice_input($_[0]->{'value'}, "AuthUsingAlias", "",
333 "$text{'yes'},on", "$text{'no'},off",
334 "$text{'default'},"));
336 sub save_AuthUsingAlias
338 return &parse_choice("AuthUsingAlias", "");
343 return (1, $text{'mod_core_bind'},
344 &opt_input($_[0]->{'value'}, "Bind", $text{'mod_core_bind_all'}, 15));
348 return &parse_opt("Bind", '^(\d+)\.(\d+)\.(\d+)\.(\d+)|([0-9:]+)$',
349 $text{'mod_core_ebind'});
352 sub edit_DefaultAddress
354 return (1, $text{'mod_core_bind'},
355 &opt_input($_[0]->{'value'}, "DefaultAddress", $text{'mod_core_bind_all'}, 15));
357 sub save_DefaultAddress
359 $in{'DefaultAddress_def'} || &to_ipaddress($in{'DefaultAddress'}) ||
360 &to_ip6address($in{'DefaultAddress'}) ||
361 &error(text{'mod_core_ebind'});
362 return &parse_opt("DefaultAddress", '^\S+$',
363 $text{'mod_core_ebind'});
368 local $rv = "<textarea rows=3 cols=50 name=CDPath>";
369 foreach $p (@{$_[0]}) {
370 $rv .= "$p->{'value'}\n";
372 $rv .= "</textarea>\n";
373 return (2, $text{'mod_core_cdpath'}, $rv);
377 $in{'CDPath'} =~ s/\r//g;
378 return ( [ split(/\s+/, $in{'CDPath'}) ] );
381 sub edit_Class_Classes
383 local $rv = $text{'mod_core_classes'}.
384 &choice_input($_[1]->[0]->{'value'}, "Classes", "",
385 "$text{'yes'},on", "$text{'no'},off",
386 "$text{'default'},")."<br>\n";
387 $rv .= "<table border>\n".
388 "<tr $tb> <td><b>$text{'mod_core_cname'}</b></td> ".
389 "<td><b>$text{'mod_core_ctype'}</b></td> </tr>\n";
391 foreach $c (@{$_[0]}, { }) {
392 local @w = @{$c->{'words'}};
394 $rv .= "<td><input name=Class_n_$i size=10 value='$w[0]'></td>\n";
395 $rv .= "<td><select name=Class_t_$i>\n";
396 $rv .= sprintf "<option value=limit %s>%s\n",
397 $w[1] eq 'limit' ? 'selected' : '', $text{'mod_core_climit'};
398 $rv .= sprintf "<option value=regex %s>%s\n",
399 $w[1] eq 'regex' ? 'selected' : '', $text{'mod_core_cregex'};
400 $rv .= sprintf "<option value=ip %s>%s\n",
401 $w[1] eq 'ip' ? 'selected' : '', $text{'mod_core_cip'};
402 $rv .= "</select>\n";
403 $rv .= "<input name=Class_v_$i size=20 value='$w[2]'></td>\n";
408 return (2, $text{'mod_core_cls'}, $rv);
410 sub save_Class_Classes
413 for($i=0; defined($in{"Class_n_$i"}); $i++) {
414 next if (!$in{"Class_n_$i"});
415 $in{"Class_t_$i"} ne 'limit' ||
416 $in{"Class_v_$i"} =~ /^\d+$/ ||
417 &error($text{'mod_core_eclimit'});
418 $in{"Class_t_$i"} ne 'regex' ||
419 $in{"Class_v_$i"} =~ /\S/ ||
420 &error($text{'mod_core_ecregex'});
421 $in{"Class_t_$i"} ne 'ip' ||
422 $in{"Class_v_$i"} =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)$/ ||
423 &error($text{'mod_core_ecip'});
424 push(@rv, join(" ", $in{"Class_n_$i"}, $in{"Class_t_$i"},
427 return ( \@rv, $in{'Classes'} eq 'on' ? [ 'on' ] :
428 $in{'Classes'} eq 'off' ? [ 'off' ] : [ ] );
431 sub edit_CommandBufferSize
433 return (1, $text{'mod_core_buffer'},
434 &opt_input($_[0]->{'value'}, "CommandBufferSize", $text{'default'}, 5));
436 sub save_CommandBufferSize
438 return &parse_opt("CommandBufferSize", '^\d+$', $text{'mod_core_ebuffer'});
441 sub edit_DefaultServer
443 return (1, $text{'mod_core_defaultserver'},
444 &choice_input($_[0]->{'value'}, "DefaultServer", "off",
448 sub save_DefaultServer
450 return &parse_choice("DefaultServer", "off");
453 sub edit_DefaultTransferMode
455 return (1, $text{'mod_core_transfer'},
456 &select_input($_[0]->{'value'}, "DefaultTransferMode", "",
457 "$text{'mod_core_ascii'},ascii",
458 "$text{'mod_core_binary'},binary",
459 "$text{'default'},"));
461 sub save_DefaultTransferMode
463 return &parse_choice("DefaultTransferMode", "");
466 sub edit_DeferWelcome
468 return (1, $text{'mod_core_defer'},
469 &choice_input($_[0]->{'value'}, "DeferWelcome", "",
470 "$text{'yes'},on", "$text{'no'},off",
471 "$text{'default'},"));
473 sub save_DeferWelcome
475 return &parse_choice("DeferWelcome", "");
478 sub edit_DeleteAbortedStores
480 return (1, $text{'mod_core_aborted'},
481 &choice_input($_[0]->{'value'}, "DeleteAbortedStores", "",
482 "$text{'yes'},on", "$text{'no'},off",
483 "$text{'default'},"));
485 sub save_DeleteAbortedStores
487 return &parse_choice("DeleteAbortedStores", "");
492 return (1, $text{'mod_core_dfilter'},
493 &opt_input($_[0]->{'value'}, "DenyFilter", $text{'default'}, 15));
497 return &parse_opt("DenyFilter");
502 local $v = @{$_[0]} ? join(" ", (map { $_->{'value'} } @{$_[0]})) : undef;
503 return (2, $text{'mod_core_dgroup'},
504 &opt_input($v, "DenyGroup", $text{'mod_core_none'}, 50));
508 return ( $in{'DenyGroup_def'} ? [ ] : [ split(/\s+/, $in{'DenyGroup'}) ] );
513 local $v = @{$_[0]} ? join(" ", (map { $_->{'value'} } @{$_[0]})) : undef;
514 return (2, $text{'mod_core_duser'},
515 &opt_input($v, "DenyUser", $text{'mod_core_none'}, 50));
519 return ( $in{'DenyUser_def'} ? [ ] : [ split(/\s+/, $in{'DenyUser'}) ] );
522 sub edit_DisplayConnect
524 return (2, $text{'mod_core_display'},
525 &opt_input($_[0]->{'value'}, "DisplayConnect",
526 $text{'mod_core_none'}, 50));
528 sub save_DisplayConnect
530 return &parse_opt("DisplayConnect", '\S', $text{'mod_core_edisplay'});
533 sub edit_DisplayFirstChdir
535 return (1, $text{'mod_core_firstcd'},
536 &opt_input($_[0]->{'value'}, "DisplayFirstChdir",
537 $text{'mod_core_none'}, 15));
539 sub save_DisplayFirstChdir
541 return &parse_opt("DisplayFirstChdir", '^\S+$', $text{'mod_core_efirstcd'});
544 sub edit_DisplayChdir
546 return (1, $text{'mod_core_firstcd'},
547 &opt_input($_[0]->{'words'}->[0], "DisplayChdir",
548 $text{'mod_core_none'}, 15).
549 &ui_checkbox("DisplayChdir_always", 'true', $text{'mod_core_firstcdt'},
550 $_[0]->{'words'}->[1] eq 'true'));
552 sub save_DisplayChdir
554 local @rv = &parse_opt("DisplayChdir", '^\S+$', $text{'mod_core_efirstcd'});
555 if ($in{'DisplayChdir_always'}) {
556 $rv[0]->[0] .= ' true';
561 sub edit_DisplayGoAway
563 return (2, $text{'mod_core_goaway'},
564 &opt_input($_[0]->{'value'}, "DisplayGoAway",
565 $text{'mod_core_none'}, 50));
567 sub save_DisplayGoAway
569 return &parse_opt("DisplayGoAway", '\S', $text{'mod_core_egoaway'});
572 sub edit_DisplayLogin
574 return (2, $text{'mod_core_login'},
575 &opt_input($_[0]->{'value'}, "DisplayLogin",
576 $text{'mod_core_none'}, 50));
578 sub save_DisplayLogin
580 return &parse_opt("DisplayLogin", '\S', $text{'mod_core_elogin'});
585 return (2, $text{'mod_core_quit'},
586 &opt_input($_[0]->{'value'}, "DisplayQuit",
587 $text{'mod_core_none'}, 50));
591 return &parse_opt("DisplayQuit", '\S', $text{'mod_core_equit'});
597 $rv = sprintf "<input type=radio name=Group value=0 %s> $text{'default'}\n",
598 $_[0] ? "" : "checked";
599 $rv .= sprintf "<input type=radio name=Group value=1 %s> %s\n",
600 $_[0] && $_[0]->{'value'} !~ /^#/ ? "checked" : "",
601 $text{'mod_core_gname'};
602 $rv .= sprintf "<input name=Group_name size=8 value=\"%s\"> %s\n",
603 $_[0]->{'value'} !~ /^#/ ? $_[0]->{'value'} : "",
604 &group_chooser_button("Group_name", 0);
605 $rv .= sprintf "<input type=radio name=Group value=2 %s> %s\n",
606 $_[0]->{'value'} =~ /^#/ ? "checked" : "",
607 $text{'mod_core_gid'};
608 $rv .= sprintf "<input name=Group_id size=6 value=\"%s\">\n",
609 $_[0]->{'value'} =~ /^#(.*)$/ ? $1 : "";
610 return (2, $text{'mod_core_group'}, $rv);
614 if ($in{'Group'} == 0) { return ( [ ] ); }
615 elsif ($in{'Group'} == 1) { return ( [ $in{'Group_name'} ] ); }
616 elsif ($in{'Group_id'} !~ /^\-?\d+$/) {
617 &error(&text('core_euid', $in{'Group_id'}));
619 else { return ( [ "#$in{'Group_id'}" ] ); }
624 return (1, $text{'mod_core_gowner'},
625 &opt_input($_[0]->{'value'}, "GroupOwner", $text{'default'}, 13,
626 &group_chooser_button("GroupOwner")));
630 if ($in{'GroupOwner_def'}) { return ( [ ] ); }
632 defined(getgrnam($in{'GroupOwner'})) || &error($text{'mod_core_egowner'});
633 return ( [ $in{'GroupOwner'} ] );
637 sub edit_GroupPassword
639 local $rv = "<table border>\n";
640 $rv .= "<tr $tb> <td><b>$text{'mod_core_gpname'}</b></td> ".
641 "<td><b>$text{'mod_core_gppass'}</b></td> </tr>\n";
643 foreach $g (@{$_[0]}) {
644 local @v = @{$g->{'words'}};
646 $rv .= "<td><input name=GroupPassword_n_$i size=13 value='$v[0]'></td>\n";
647 $rv .= "<td><input type=radio name=GroupPassword_d_$i value='$v[1]' checked> $text{'mod_core_gpdef'}\n";
648 $rv .= "<input type=radio name=GroupPassword_d_$i value=0>\n";
649 $rv .= "<input name=GroupPassword_p_$i size=25></td> </tr>\n";
653 "<td><input name=GroupPassword_n_$i size=13></td>\n".
654 "<td><input name=GroupPassword_p_$i size=35></td>\n".
656 return (2, $text{'mod_core_grouppassword'}, $rv);
658 sub save_GroupPassword
661 for($i=0; defined($in{"GroupPassword_n_$i"}); $i++) {
662 next if (!$in{"GroupPassword_n_$i"});
663 scalar(getgrnam($in{"GroupPassword_n_$i"})) ||
664 &error($text{'mod_core_egpname'});
665 if ($in{"GroupPassword_d_$i"}) {
666 push(@rv, $in{"GroupPassword_n_$i"}.' '.
667 $in{"GroupPassword_d_$i"});
670 $salt = substr(time(), 0, 2);
671 push(@rv, $in{"GroupPassword_n_$i"}.' '.
672 &unix_crypt($in{"GroupPassword_p_$i"}, $salt));
680 return (1, $text{'mod_core_hstor'},
681 &choice_input($_[0]->{'value'}, "HiddenStor", "",
682 "$text{'yes'},on", "$text{'no'},off",
683 "$text{'default'},"));
687 return &parse_choice("HiddenStor", "");
690 sub edit_HiddenStores
692 return (1, $text{'mod_core_hstor'},
693 &choice_input($_[0]->{'value'}, "HiddenStores", "",
694 "$text{'yes'},on", "$text{'no'},off",
695 "$text{'default'},"));
697 sub save_HiddenStores
699 return &parse_choice("HiddenStores", "");
704 return (2, $text{'mod_core_hgroup'},
705 sprintf "<input name=HideGroup size=50 value='%s'>",
706 join(" ", map { $_->{'value'} } @{$_[0]}));
710 local @hg = split(/\s+/, $in{'HideGroup'});
712 scalar(getgrnam($g)) || &error($text{'mod_core_ehgroup'});
717 sub edit_HideNoAccess
719 return (1, $text{'mod_core_hnoaccess'},
720 &choice_input($_[0]->{'value'}, "HideNoAccess", "",
721 "$text{'yes'},on", "$text{'no'},off",
722 "$text{'default'},"));
724 sub save_HideNoAccess
726 return &parse_choice("HideNoAccess", "");
731 return (2, $text{'mod_core_huser'},
732 sprintf "<input name=HideUser size=50 value='%s'>",
733 join(" ", map { $_->{'value'} } @{$_[0]}));
737 local @hu = split(/\s+/, $in{'HideUser'});
739 defined(getpwnam($u)) || &error($text{'mod_core_ehuser'});
744 sub edit_IdentLookups
746 return (1, $text{'mod_core_ident'},
747 &choice_input($_[0]->{'value'}, "IdentLookups", "",
748 "$text{'yes'},on", "$text{'no'},off",
749 "$text{'default'},"));
751 sub save_IdentLookups
753 return &parse_choice("IdentLookups", "");
756 sub edit_IgnoreHidden
758 return (1, $text{'mod_core_ihidden'},
759 &choice_input($_[0]->{'value'}, "IgnoreHidden", "off",
760 "$text{'yes'},on", "$text{'no'},off"));
762 sub save_IgnoreHidden
764 return &parse_choice("IgnoreHidden", "off");
767 sub edit_MasqueradeAddress
769 return (2, $text{'mod_core_masq'},
770 &opt_input($_[0]->{'value'}, "MasqueradeAddress",
771 $text{'mod_core_masq_def'}, 30));
773 sub save_MasqueradeAddress
775 $in{'MasqueradeAddress_def'} || &to_ipaddress($in{'MasqueradeAddress'}) ||
776 &error($text{'mod_core_emasq'});
777 return &parse_opt("MasqueradeAddress");
782 return (2, $text{'mod_core_maxc'}, &edit_max($_[0], "MaxClients"));
786 return &save_max("MaxClients");
789 sub edit_MaxClientsPerHost
791 return (2, $text{'mod_core_maxch'}, &edit_max($_[0], "MaxClientsPerHost"));
793 sub save_MaxClientsPerHost
795 return &save_max("MaxClientsPerHost");
798 sub edit_MaxClientsPerUser
800 return (2, $text{'mod_core_maxcu'}, &edit_max($_[0], "MaxClientsPerUser"));
802 sub save_MaxClientsPerUser
804 return &save_max("MaxClientsPerUser");
809 local $m = !$_[0] ? 0 :
810 $_[0]->{'words'}->[0] eq 'none' ? 1 : 2;
811 local $rv = sprintf "<input type=radio name=$_[1]_m value=0 %s> %s\n",
812 $m == 0 ? "checked" : "", $text{'default'};
813 $rv .= sprintf "<input type=radio name=$_[1]_m value=1 %s> %s\n",
814 $m == 1 ? "checked" : "", $text{'mod_core_maxc1'};
815 $rv .= sprintf "<input type=radio name=$_[1]_m value=2 %s>\n",
816 $m == 2 ? "checked" : "";
817 $rv .= sprintf "<input name=$_[1] size=6 value='%s'><br>\n",
818 $m == 2 ? $_[0]->{'words'}->[0] : "";
819 $rv .= sprintf "%s <input name=$_[1]_t size=40 value='%s'>\n",
820 $text{'mod_core_maxcmsg'}, $_[0]->{'words'}->[1];
825 if ($in{"$_[0]_m"} == 0) {
830 if ($in{"$_[0]_m"} == 1) {
834 $in{$_[0]} =~ /^\d+$/ || &error($text{'mod_core_emaxc'});
837 if ($in{"$_[0]_t"}) {
838 return ( [ "$n \"".$in{"$_[0]_t"}."\"" ] );
846 sub edit_MaxInstances
848 return (1, $text{'mod_core_instances'},
849 &opt_input($_[0]->{'value'}, "MaxInstances", $text{'default'}, 4));
851 sub save_MaxInstances
853 return &parse_opt("MaxInstances", '^\d+$', $text{'mod_core_einstances'});
856 sub edit_MaxLoginAttempts
858 return (1, $text{'mod_core_logins'},
859 &opt_input($_[0]->{'value'}, "MaxLoginAttempts", $text{'default'}, 4));
861 sub save_MaxLoginAttempts
863 return &parse_opt("MaxLoginAttempts", '^\d+$', $text{'mod_core_elogins'});
866 sub edit_MultilineRFC2228
868 return (1, $text{'mod_core_rfc2228'},
869 &choice_input($_[0]->{'value'}, "MultilineRFC2228", "",
870 "$text{'yes'},on", "$text{'no'},off",
871 "$text{'default'},"));
873 sub save_MultilineRFC2228
875 return &parse_choice("MultilineRFC2228", "");
878 sub edit_PassivePorts
880 local $rv = sprintf "<input type=radio name=PassivePorts_def value=1 %s> %s\n",
881 $_[0] ? "" : "checked", $text{'default'};
882 $rv .= sprintf "<input type=radio name=PassivePorts_def value=0 %s> %s\n",
883 $_[0] ? "checked" : "", $text{'mod_core_pasvr'};
884 $rv .= sprintf "<input name=PassivePorts_f size=5 value='%s'> -\n",
885 $_[0]->{'words'}->[0];
886 $rv .= sprintf "<input name=PassivePorts_t size=5 value='%s'>\n",
887 $_[0]->{'words'}->[1];
888 return (1, $text{'mod_core_pasv'}, $rv);
890 sub save_PassivePorts
892 if ($in{'PassivePorts_def'}) {
896 $in{'PassivePorts_f'} =~ /^\d+$/ || &error($text{'mod_core_epasv'});
897 $in{'PassivePorts_t'} =~ /^\d+$/ || &error($text{'mod_core_epasv'});
898 return ( [ "$in{'PassivePorts_f'} $in{'PassivePorts_t'}" ] );
902 sub edit_PathAllowFilter
904 return (1, $text{'mod_core_pathallow'},
905 &opt_input($_[0]->{'words'}->[0], "PathAllowFilter",
906 $text{'mod_core_any'}, 20));
908 sub save_PathAllowFilter
910 return &parse_opt("PathAllowFilter");
913 sub edit_PathDenyFilter
915 return (1, $text{'mod_core_pathdeny'},
916 &opt_input($_[0]->{'words'}->[0], "PathDenyFilter",
917 $text{'mod_core_none'}, 20));
919 sub save_PathDenyFilter
921 return &parse_opt("PathDenyFilter");
926 return (2, $text{'mod_core_pidfile'},
927 &opt_input($_[0]->{'words'}->[0], "PidFile", $text{'default'}, 50,
928 &file_chooser_button("PidFile")));
932 return &parse_opt("PidFile", '^\/\S+$', $text{'mod_core_epidfile'});
937 return (1, $text{'mod_core_port'},
938 &opt_input($_[0]->{'value'}, "Port", $text{'default'}, 6));
942 return &parse_opt("Port", '^\d+$', $text{'mod_core_eport'});
945 sub edit_RequireValidShell
947 return (1, $text{'mod_core_shell'},
948 &choice_input($_[0]->{'value'}, "RequireValidShell", "",
949 "$text{'yes'},on", "$text{'no'},off",
950 "$text{'default'},"));
952 sub save_RequireValidShell
954 return &parse_choice("RequireValidShell", "");
959 return &rlimit_input("RLimitCPU", $text{'mod_core_cpulimit'}, $_[0]);
963 return &parse_rlimit("RLimitCPU", $text{'mod_core_ecpulimit'});
966 sub edit_RLimitMemory
968 return &rlimit_input("RLimitMemory", $text{'mod_core_memlimit'}, $_[0]);
970 sub save_RLimitMemory
972 return &parse_rlimit("RLimitMemory", $text{'mod_core_ememlimit'});
975 sub edit_RLimitOpenFiles
977 return &rlimit_input("RLimitOpenFiles", $text{'mod_core_filelimit'}, $_[0]);
979 sub save_RLimitOpenFiles
981 return &parse_rlimit("RLimitOpenFiles", $text{'mod_core_efilelimit'});
984 # rlimit_input(name, desc, value)
987 local @w = @{$_[2]->{'words'}};
989 $rv .= sprintf "<b>%s</b> <input type=radio name=%s_smax value=2 %s> %s\n",
990 $text{'mod_core_soft'}, $_[0], $w[0] ? "" : "checked",
992 $rv .= sprintf "<input type=radio name=%s_smax value=1 %s> %s\n",
993 $_[0], $w[0] eq 'max' ? "checked" : "", $text{'mod_core_max'};
994 $rv .= sprintf "<input type=radio name=%s_smax value=0 %s>\n",
995 $_[0], !$w[0] || $w[0] eq 'max' ? "" : "checked";
996 $rv .= sprintf "<input name=%s_soft size=6 value='%s'>\n",
997 $_[0], $w[0] eq 'max' ? '' : $w[0];
998 $rv .= " ";
1000 $rv .= sprintf "<b>%s</b> <input type=radio name=%s_hmax value=2 %s> %s\n",
1001 $text{'mod_core_hard'}, $_[0], $w[1] ? "" : "checked",
1003 $rv .= sprintf "<input type=radio name=%s_hmax value=1 %s> %s\n",
1004 $_[0], $w[1] eq 'max' ? "checked" : "", $text{'mod_core_max'};
1005 $rv .= sprintf "<input type=radio name=%s_hmax value=0 %s>\n",
1006 $_[0], !$w[1] || $w[1] eq 'max' ? "" : "checked";
1007 $rv .= sprintf "<input name=%s_hard size=6 value='%s'>\n",
1008 $_[0], $w[1] eq 'max' ? '' : $w[1];
1009 return (2, $_[1], $rv);
1012 # parse_rlimit(name, desc)
1015 if ($in{"$_[0]_smax"} == 2) {
1019 if ($in{"$_[0]_smax"} == 1) {
1023 $in{"$_[0]_soft"} =~ /^(\d+)(G|M|K|B)?$/i ||
1024 &error(&text('mod_core_esoft', $_[1]));
1025 push(@v, $in{"$_[0]_soft"});
1027 if ($in{"$_[0]_hmax"} == 1) {
1030 elsif ($in{"$_[0]_hmax"} == 0) {
1031 $in{"$_[0]_hard"} =~ /^(\d+)(G|M|K|B)?$/i ||
1032 &error(&text('mod_core_ehard', $_[1]));
1033 push(@v, $in{"$_[0]_hard"});
1035 return ( [ join(" ", @v) ] );
1038 sub edit_ScoreboardPath
1040 return (2, $text{'mod_core_score'},
1041 &opt_input($_[0]->{'words'}->[0], "ScoreboardPath", $text{'default'},
1042 50, &file_chooser_button("ScoreboardPath")));
1044 sub save_ScoreboardPath
1046 return &parse_opt("ScoreboardPath", '^\/\S+$', $text{'mod_core_escore'});
1049 sub edit_ServerAdmin
1051 return (2, $text{'mod_core_admin'},
1052 &opt_input($_[0]->{'words'}->[0], "ServerAdmin", $text{'default'}, 40));
1054 sub save_ServerAdmin
1056 return &parse_opt("ServerAdmin", '^\S+\@\S+$', $text{'mod_core_eadmin'});
1059 sub edit_ServerIdent
1061 local @w = @{$_[0]->{'words'}};
1062 local $rv = sprintf "<input type=radio name=ServerIdent_m value=0 %s> %s\n",
1063 $_[0] ? "" : "checked", $text{'default'};
1064 $rv .= sprintf "<input type=radio name=ServerIdent_m value=1 %s> %s\n",
1065 lc($w[0]) eq 'off' ? "checked" : "", $text{'mod_core_none'};
1066 $rv .= sprintf "<input type=radio name=ServerIdent_m value=2 %s> %s\n",
1067 lc($w[0]) eq 'on' && !$w[1] ? "checked" : "",
1068 $text{'mod_core_identmsg_def'};
1069 $rv .= sprintf "<input type=radio name=ServerIdent_m value=3 %s>\n",
1070 lc($w[0]) eq 'on' && $w[1] ? "checked" : "";
1071 $rv .= sprintf "<input name=ServerIdent size=30 value='%s'>\n",
1072 lc($w[0]) eq 'on' ? $w[1] : "";
1073 return (2, $text{'mod_core_identmsg'}, $rv);
1075 sub save_ServerIdent
1077 if ($in{'ServerIdent_m'} == 0) {
1080 elsif ($in{'ServerIdent_m'} == 1) {
1081 return ( [ "off" ] );
1083 elsif ($in{'ServerIdent_m'} == 2) {
1084 return ( [ "on" ] );
1087 return ( [ "on \"$in{'ServerIdent'}\"" ] );
1093 return (2, $text{'mod_core_servername'},
1094 &opt_input($_[0]->{'words'}->[0], "ServerName", $text{'default'}, 50));
1098 return &parse_opt("ServerName", '\S', $text{'mod_core_eservername'});
1103 return (1, $text{'mod_core_type'},
1104 &select_input($_[0]->{'value'}, "ServerType", "",
1105 "$text{'mod_core_inetd'},inetd",
1106 "$text{'mod_core_stand'},standalone",
1107 "$text{'default'},"));
1111 return &parse_choice("ServerType", "");
1114 sub edit_ShowSymlinks
1116 return (1, $text{'mod_core_links'},
1117 &choice_input($_[0]->{'value'}, "ShowSymlinks", "",
1118 "$text{'yes'},on", "$text{'no'},off",
1119 "$text{'default'},"));
1121 sub save_ShowSymlinks
1123 return &parse_choice("ShowSymlinks", "");
1126 sub edit_SocketBindTight
1128 return (1, $text{'mod_core_tight'},
1129 &choice_input($_[0]->{'value'}, "SocketBindTight", "",
1130 "$text{'yes'},on", "$text{'no'},off",
1131 "$text{'default'},"));
1133 sub save_SocketBindTight
1135 return &parse_choice("SocketBindTight", "");
1138 sub edit_SyslogFacility
1140 local @facils = map { "$_,$_" } ( 'auth', 'authpriv', 'cron', 'daemon', 'kern', 'lpr', 'mail', 'news', 'user', 'uucp', 'local0', 'local1', 'local2', 'local3', 'local4', 'local5', 'local6', 'local7' );
1141 return (1, $text{'mod_core_facility'},
1142 &select_input($_[0]->{'value'}, "SyslogFacility", "",
1143 "$text{'default'},", @facils));
1145 sub save_SyslogFacility
1147 return &parse_select("SyslogFacility", "");
1150 sub edit_SyslogLevel
1152 local @levels = map { "$_,$_" } ( 'emerg', 'alert', 'crit', 'error', 'warn', 'notice', 'info', 'debug' );
1153 return (1, $text{'mod_core_level'},
1154 &select_input($_[0]->{'value'}, "SyslogLevel", "",
1155 "$text{'default'},", @levels));
1157 sub save_SyslogLevel
1159 return &parse_select("SyslogLevel", "");
1162 sub edit_TransferLog
1164 local $mode = $_[0]->{'value'} eq 'NONE' ? 2 :
1165 $_[0]->{'value'} ? 0 : 1;
1166 local $rv = sprintf "<input type=radio name=TransferLog_def value=1 %s> %s\n",
1167 $mode == 1 ? "checked" : "", $text{'default'};
1168 if ($_[1]->{'version'} >= 1.17) {
1169 $rv .= sprintf"<input type=radio name=TransferLog_def value=2 %s> %s\n",
1170 $mode == 2 ? "checked" : "", $text{'mod_core_nowhere'};
1172 $rv .= sprintf "<input type=radio name=TransferLog_def value=0 %s>\n",
1173 $mode == 0 ? "checked" : "";
1174 $rv .= sprintf "<input name=TransferLog size=50 value='%s'>\n",
1175 $mode == 0 ? $_[0]->{'value'} : "";
1176 return (2, $text{'mod_core_tlog'}, $rv);
1178 sub save_TransferLog
1180 if ($in{'TransferLog_def'} == 1) {
1183 elsif ($in{'TransferLog_def'} == 2) {
1184 return ( [ 'NONE' ] );
1187 $in{'TransferLog'} =~ /^\/\S+$/ || &error($text{'mod_core_etlog'});
1188 return ( [ $in{'TransferLog'} ] );
1194 return (1, $text{'mod_core_backlog'},
1195 &opt_input($_[0]->{'value'}, "tcpBackLog", $text{'default'}, 6));
1199 return &parse_opt("tcpBackLog", '^\d+$', $text{'mod_core_ebacklog'});
1204 return (1, $text{'mod_core_nodelay'},
1205 &choice_input($_[0]->{'value'}, "tcpNoDelay", "",
1206 "$text{'yes'},on", "$text{'no'},off",
1207 "$text{'default'},"));
1211 return &parse_choice("tcpNoDelay", "");
1214 sub edit_tcpReceiveWindow
1216 return (1, $text{'mod_core_rwindow'},
1217 &opt_input($_[0]->{'value'}, "tcpReceiveWindow", $text{'default'}, 6));
1219 sub save_tcpReceiveWindow
1221 return &parse_opt("tcpReceiveWindow", '^\d+$', $text{'mod_core_erwindow'});
1224 sub edit_tcpSendWindow
1226 return (1, $text{'mod_core_swindow'},
1227 &opt_input($_[0]->{'value'}, "tcpSendWindow", $text{'default'}, 6));
1229 sub save_tcpSendWindow
1231 return &parse_opt("tcpSendWindow", '^\d+$', $text{'mod_core_eswindow'});
1236 return (1, $text{'mod_core_gmt'},
1237 &choice_input($_[0]->{'value'}, "TimesGMT", "",
1238 "$text{'yes'},on", "$text{'no'},off",
1239 "$text{'default'},"));
1243 return &parse_choice("TimesGMT", "");
1246 sub edit_TimeoutIdle
1248 return (1, $text{'mod_core_tidle'},
1249 &opt_input($_[0]->{'value'}, "TimeoutIdle", $text{'default'}, 6,
1250 $text{'mod_core_secs'}));
1252 sub save_TimeoutIdle
1254 return &parse_opt("TimeoutIdle", '^\d+$', $text{'mod_core_etidle'});
1257 sub edit_TimeoutLogin
1259 return (1, $text{'mod_core_tlogin'},
1260 &opt_input($_[0]->{'value'}, "TimeoutLogin", $text{'default'}, 6,
1261 $text{'mod_core_secs'}));
1263 sub save_TimeoutLogin
1265 return &parse_opt("TimeoutLogin", '^\d+$', $text{'mod_core_etlogin'});
1268 sub edit_TimeoutNoTransfer
1270 return (1, $text{'mod_core_ttransfer'},
1271 &opt_input($_[0]->{'value'}, "TimeoutNoTransfer", $text{'default'}, 6,
1272 $text{'mod_core_secs'}));
1274 sub save_TimeoutNoTransfer
1276 return &parse_opt("TimeoutNoTransfer", '^\d+$', $text{'mod_core_ettransfer'});
1279 sub edit_TimeoutStalled
1281 return (1, $text{'mod_core_tstalled'},
1282 &opt_input($_[0]->{'value'}, "TimeoutStalled", $text{'default'}, 6,
1283 $text{'mod_core_secs'}));
1285 sub save_TimeoutStalled
1287 return &parse_opt("TimeoutStalled", '^\d+$', $text{'mod_core_etstalled'});
1293 $rv .= sprintf "<input type=radio name=Umask_def value=1 %s> %s\n",
1294 $_[0]->{'words'}->[0] ? "" : "checked", $text{'default'};
1295 $rv .= sprintf "<input type=radio name=Umask_def value=0 %s> %s\n",
1296 $_[0]->{'words'}->[0] ? "checked" : "", $text{'mod_core_octal'};
1297 $rv .= sprintf "<input name=Umask size=5 value='%s'>\n",
1298 $_[0]->{'words'}->[0];
1300 $rv .= " <b>$text{'mod_core_umask_d'}</b>\n";
1301 $rv .= sprintf "<input type=radio name=Umask_d_def value=1 %s> %s\n",
1302 $_[0]->{'words'}->[1] ? "" : "checked", $text{'default'};
1303 $rv .= sprintf "<input type=radio name=Umask_d_def value=0 %s> %s\n",
1304 $_[0]->{'words'}->[1] ? "checked" : "", $text{'mod_core_octal'};
1305 $rv .= sprintf "<input name=Umask_d size=5 value='%s'>\n",
1306 $_[0]->{'words'}->[1];
1308 return (2, $text{'mod_core_umask'}, $rv);
1312 if ($in{'Umask_def'}) {
1316 $in{'Umask'} =~ /^[0-7]{3}$/ || &error($text{'mod_core_eumask'});
1317 if ($in{'Umask_d_def'}) {
1318 return ( [ $in{'Umask'} ] );
1321 $in{'Umask_d'} =~ /^[0-7]{3}$/ || &error($text{'mod_core_eumask'});
1322 return ( [ $in{'Umask'}." ".$in{'Umask_d'} ] );
1327 sub edit_UseFtpUsers
1329 return (1, $text{'mod_core_ftpusers'},
1330 &choice_input($_[0]->{'value'}, "UseFtpUsers", "",
1331 "$text{'yes'},on", "$text{'no'},off",
1332 "$text{'default'},"));
1334 sub save_UseFtpUsers
1336 return &parse_choice("UseFtpUsers", "");
1339 sub edit_UseHostsAllowFile
1341 return (2, $text{'mod_core_hostsallow'},
1342 &opt_input($_[0]->{'value'}, "UseHostsAllowFile", $text{'default'}, 50,
1343 &file_chooser_button("UseHostsAllowFile")));
1345 sub save_UseHostsAllowFile
1347 $in{'UseHostsAllowFile_def'} || -r $in{'UseHostsAllowFile'} ||
1348 &error($text{'mod_core_ehostsallow'});
1349 return &parse_opt("UseHostsAllowFile");
1352 sub edit_UseHostsDenyFile
1354 return (2, $text{'mod_core_hostsdeny'},
1355 &opt_input($_[0]->{'value'}, "UseHostsDenyFile", $text{'default'}, 50,
1356 &file_chooser_button("UseHostsDenyFile")));
1358 sub save_UseHostsDenyFile
1360 $in{'UseHostsDenyFile_def'} || -r $in{'UseHostsDenyFile'} ||
1361 &error($text{'mod_core_ehostsdeny'});
1362 return &parse_opt("UseHostsDenyFile");
1365 sub edit_UseReverseDNS
1367 return (1, $text{'mod_core_revdns'},
1368 &choice_input($_[0]->{'value'}, "UseReverseDNS", "",
1369 "$text{'yes'},on", "$text{'no'},off",
1370 "$text{'default'},"));
1372 sub save_UseReverseDNS
1374 return &parse_choice("UseReverseDNS", "");
1377 sub edit_UserDirRoot
1379 return (1, $text{'mod_core_userdir'},
1380 &choice_input($_[0]->{'value'}, "UserDirRoot", "",
1381 "$text{'yes'},on", "$text{'no'},off",
1382 "$text{'default'},"));
1384 sub save_UserDirRoot
1386 return &parse_choice("UserDirRoot", "");
1392 $rv = sprintf "<input type=radio name=User value=0 %s> $text{'default'}\n",
1393 $_[0] ? "" : "checked";
1394 $rv .= sprintf "<input type=radio name=User value=1 %s> %s\n",
1395 $_[0] && $_[0]->{'value'} !~ /^#/ ? "checked" : "",
1396 $text{'mod_core_uname'};
1397 $rv .= sprintf "<input name=User_name size=8 value=\"%s\"> %s \n",
1398 $_[0]->{'value'} !~ /^#/ ? $_[0]->{'value'} : "",
1399 &user_chooser_button("User_name", 0);
1400 $rv .= sprintf "<input type=radio name=User value=2 %s> %s\n",
1401 $_[0]->{'value'} =~ /^#/ ? "checked" : "",
1402 $text{'mod_core_uid'};
1403 $rv .= sprintf "<input name=User_id size=6 value=\"%s\">\n",
1404 $_[0]->{'value'} =~ /^#(.*)$/ ? $1 : "";
1405 return (2, $text{'mod_core_user'}, $rv);
1409 if ($in{'User'} == 0) { return ( [ ] ); }
1410 elsif ($in{'User'} == 1) { return ( [ $in{'User_name'} ] ); }
1411 elsif ($in{'User_id'} !~ /^\-?\d+$/) {
1412 &error(&text('core_egid', $in{'User_id'}));
1414 else { return ( [ "#$in{'User_id'}" ] ); }
1419 local $rv = "<table border>\n".
1420 "<tr $tb> <td><b>$text{'mod_core_afrom'}</b></td> ".
1421 "<td><b>$text{'mod_core_ato'}</b></td> </tr>\n";
1423 foreach $u (@{$_[0]}, { }) {
1424 local @w = @{$u->{'words'}};
1425 $rv .= "<tr $cb>\n";
1426 $rv .= "<td><input name=UserAlias_f_$i size=15 value='$w[0]'></td>\n";
1427 $rv .= "<td><input name=UserAlias_t_$i size=15 value='$w[1]'></td>\n";
1431 $rv .= "</table>\n";
1432 return (2, $text{'mod_core_ualias'}, $rv);
1437 for($i=0; defined($in{"UserAlias_f_$i"}); $i++) {
1438 next if (!$in{"UserAlias_f_$i"});
1439 $in{"UserAlias_f_$i"} =~ /^\S+$/ || &error($text{'mod_core_eafrom'});
1440 $in{"UserAlias_t_$i"} =~ /^\S+$/ || &error($text{'mod_core_eato'});
1441 push(@rv, $in{"UserAlias_f_$i"}.' '.$in{"UserAlias_t_$i"});
1448 return (1, $text{'mod_core_uowner'},
1449 &opt_input($_[0]->{'value'}, "UserOwner", $text{'default'}, 13,
1450 &user_chooser_button("UserOwner")));
1454 if ($in{'UserOwner_def'}) { return ( [ ] ); }
1456 getpwnam($in{'UserOwner'}) || &error($text{'mod_core_euowner'});
1457 return ( [ $in{'UserOwner'} ] );
1461 sub edit_UserPassword
1463 local $rv = "<table border>\n";
1464 $rv .= "<tr $tb> <td><b>$text{'mod_core_upname'}</b></td> ".
1465 "<td><b>$text{'mod_core_uppass'}</b></td> </tr>\n";
1467 foreach $u (@{$_[0]}) {
1468 local @v = @{$u->{'words'}};
1469 $rv .= "<tr $cb>\n";
1470 $rv .= "<td><input name=UserPassword_n_$i size=13 value='$v[0]'></td>\n";
1471 $rv .= "<td><input type=radio name=UserPassword_d_$i value='$v[1]' checked> $text{'mod_core_updef'}\n";
1472 $rv .= "<input type=radio name=UserPassword_d_$i value=0>\n";
1473 $rv .= "<input name=UserPassword_p_$i size=25></td> </tr>\n";
1476 $rv .= "<tr $cb>\n".
1477 "<td><input name=UserPassword_n_$i size=13></td>\n".
1478 "<td><input name=UserPassword_p_$i size=35></td>\n".
1480 return (2, $text{'mod_core_userpassword'}, $rv);
1482 sub save_UserPassword
1485 for($i=0; defined($in{"UserPassword_n_$i"}); $i++) {
1486 next if (!$in{"UserPassword_n_$i"});
1487 scalar(getpwnam($in{"UserPassword_n_$i"})) ||
1488 &error($text{'mod_core_eupname'});
1489 if ($in{"UserPassword_d_$i"}) {
1490 push(@rv, $in{"UserPassword_n_$i"}.' '.
1491 $in{"UserPassword_d_$i"});
1494 $salt = substr(time(), 0, 2);
1495 push(@rv, $in{"UserPassword_n_$i"}.' '.
1496 &unix_crypt($in{"UserPassword_p_$i"}, $salt));
1504 return (1, $text{'mod_core_wtmp'},
1505 &choice_input($_[0]->{'value'}, "WtmpLog", "",
1506 "$text{'yes'},on", "$text{'no'},off",
1507 "$text{'mod_core_none'},NONE", "$text{'default'},"));
1511 return &parse_choice("WtmpLog", "");