Handle hostnames with upper-case letters
[webmin.git] / lpadmin / save_printer.cgi
1 #!/usr/local/bin/perl
2 # save_printer.cgi
3 # Create or modify a printer
4
5 require './lpadmin-lib.pl';
6 &ReadParse();
7 &error_setup($text{'save_err'});
8
9 # Check ACL
10 if ($in{'new'}) {
11         $access{'add'} || &error($text{'save_eadd'});
12         }
13 else {
14         &can_edit_printer($in{'name'}) ||
15                 &error($text{'save_eedit'});
16         }
17
18 # validate and store printer details
19 $in{'name'} =~ /^[A-z0-9\-\_\.]+$/ ||
20         &error(&text('save_ename', $in{'name'}));
21 if ($in{'new'} && &get_printer($in{'name'})) {
22         &error(&text('save_edup', $in{'name'}));
23         }
24 $prn{'name'} = $in{'name'};
25 $prn{'accepting'} = $in{'accepting'};
26 if (!$prn{'accepting'}) { $prn{'accepting_why'} = $in{'accepting_why'}; }
27 $prn{'enabled'} = $in{'enabled'};
28 if (!$prn{'enabled'}) { $prn{'enabled_why'} = $in{'enabled_why'}; }
29 $prn{'desc'} = $in{'desc'};
30 if (&printer_support('allow')) {
31         @ul = split(/\s+/, $in{'users'});
32         if ($in{'access'} == 0) { $prn{'allow_all'}++; }
33         elsif ($in{'access'} == 1) { $prn{'deny_all'}++; }
34         else {
35                 $w = $in{'access'} == 2 ? "allow" : "deny";
36                 if (!@ul) { &error($text{"save_e$w"}); }
37                 foreach $u (@ul) {
38                         if ($u !~ /^\S+\!\S+$/ && !(@dummy=getpwnam($u))) {
39                                 &error(&text('save_euser', $u));
40                                 }
41                         }
42                 $prn{$w} = \@ul;
43                 }
44         }
45 if (&printer_support('banner')) {
46         $prn{'banner'} = $in{'prbanner'};
47         }
48 if (&printer_support('ctype')) {
49         if ($in{'ctype_simple'}) { push(@ctype, "simple"); }
50         if ($in{'ctype_postscript'}) { push(@ctype, "postscript"); }
51         if ($in{'ctype_other'}) {
52                 push(@ctype, split(/\s+/, $in{'ctype_olist'}));
53                 }
54         &error($text{'save_etype'}) if (!@ctype && $in{'dest'} != 2);
55         $prn{'ctype'} = \@ctype;
56         }
57 $prn{'default'} = $in{'default'};
58 if (&printer_support('msize')) {
59         if ($in{'msize_def'} == 2) {
60                 $prn{'msize'} = 0;
61                 }
62         elsif ($in{'msize_def'} == 0) {
63                 $in{'msize'} =~ /^\d+$/ ||
64                         &error($text{'save_emax'});
65                 $prn{'msize'} = $in{'msize'};
66                 }
67         }
68 if (&printer_support('alias')) {
69         @alias = split(/\s+/, $in{'alias'});
70         $prn{'alias'} = \@alias;
71         }
72
73 if ($in{'new'} || &printer_support('editdest')) {
74         if ($in{'webmin'}) {
75                 $drv = &parse_webmin_driver();
76                 $dfunc = \&create_webmin_driver;
77                 }
78         else {
79                 $drv = &parse_driver();
80                 $dfunc = \&create_driver;
81                 }
82
83         # validate and store destination section
84         $SIG{'ALRM'} = \&connect_time_out;
85         if ($in{'dest'} == 0) {
86                 # printing to some device
87                 $prn{'dev'} = $in{'dev'};
88                 $prn{'iface'} = &$dfunc(\%prn, $drv);
89                 }
90         elsif ($in{'dest'} == 1) {
91                 # printing to some file
92                 (-r $in{'file'}) || ($in{'file'} =~ /^\|(.*)/ && -r $1) ||
93                         &error(&text('save_efile', $in{'file'}));
94                 $prn{'dev'} = $in{'file'};
95                 $prn{'iface'} = &$dfunc(\%prn, $drv);
96                 }
97         elsif ($in{'dest'} == 2) {
98                 # printing to a unix host
99                 local ($rhost, $rport);
100                 if ($in{'rhost'} =~ /^(\S+):(\d+)$/) {
101                         $rhost = $1;
102                         $rport = $2;
103                         }
104                 else {
105                         $rhost = $in{'rhost'};
106                         $rport = 515;
107                         }
108                 &to_ipaddress($rhost) || &to_ip6address($rhost) ||
109                         &error(&text('save_erhost', $rhost));
110                 $rport =~ /^\d+$/ || &error(&text('save_erport', $rport));
111                 $in{'rqueue'} =~ /^[A-z0-9\-\_\.\/]+$/ ||
112                         (!$in{'rqueue'} && &printer_support('rnoqueue')) ||
113                         &error(&text('save_erqueue', $in{'rqueue'}));
114                 $prn{'rhost'} = $in{'rhost'};
115                 $prn{'rqueue'} = $in{'rqueue'};
116                 $prn{'rtype'} = $in{'rtype'};
117                 if ($drv->{'mode'} && !&printer_support('riface')) {
118                         &error($text{'save_eremote'});
119                         }
120                 if ($in{'check'} && (!$in{'rtype'} || $in{'rtype'} eq 'bsd')) {
121                         # Try connecting to the LPR port
122                         alarm(10);
123                         &open_socket($rhost, 515, TEST);
124                         close(TEST);
125                         alarm(0);
126                         }
127                 $prn{'iface'} = &$dfunc(\%prn, $drv);
128                 }
129         elsif ($in{'dest'} == 3) {
130                 # printing to windows
131                 $sdrv = { 'server' => $in{'server'},
132                          'share' => $in{'share'},
133                          'user' => $in{'suser'},
134                          'pass' => $in{'spass'},
135                          'workgroup' => $in{'wgroup'},
136                          'program' => &$dfunc(\%prn, $drv) };
137                 $prn{'dev'} = "/dev/null";
138                 $prn{'iface'} = $in{'webmin'} ? 
139                         &create_webmin_windows_driver(\%prn, $sdrv) :
140                         &create_windows_driver(\%prn, $sdrv);
141                 if ($in{'check'}) {
142                         # Try connecting to the SMB port
143                         alarm(10);
144                         &open_socket($sdrv->{'server'}, 139, TEST);
145                         close(TEST);
146                         alarm(0);
147                         }
148                 }
149         elsif ($in{'dest'} == 4) {
150                 # printing to hpnp server
151                 $hdrv = { 'server' => $in{'hpnp'},
152                           'port' => $in{'port'},
153                           'program' => &$dfunc(\%prn, $drv) };
154                 $prn{'iface'} = &create_hpnp_driver(\%prn, $hdrv);
155                 $prn{'dev'} = "/dev/null";
156                 }
157         elsif ($in{'dest'} == 5) {
158                 # direct connection printing
159                 &to_ipaddress($in{'dhost'}) || &to_ip6address($in{'dhost'}) ||
160                         &error(&text('save_edhost', $in{'dhost'}));
161                 $in{'dport'} =~ /^\d+$/ || &error($text{'save_edport'});
162                 $prn{'dhost'} = $in{'dhost'};
163                 $prn{'dport'} = $in{'dport'};
164                 $prn{'iface'} = &$dfunc(\%prn, $drv);
165                 if ($in{'check'}) {
166                         # Try connecting to the port
167                         alarm(10);
168                         &open_socket($prn{'dhost'}, $prn{'dport'}, TEST);
169                         close(TEST);
170                         alarm(0);
171                         }
172                 }
173         }
174
175 # Call os-specific validation function
176 if (defined(&validate_printer)) {
177         $err = &validate_printer(\%prn);
178         &error($err) if ($err);
179         }
180
181 # Create the printer
182 if ($in{'new'}) {
183         &create_printer(\%prn);
184         &system_logged("$config{'apply_cmd'} >/dev/null 2>&1 </dev/null")
185                 if ($config{'apply_cmd'});
186         &webmin_log("create", "printer", $prn{'name'}, &log_info(\%prn));
187         }
188 else {
189         &modify_printer(\%prn);
190         &system_logged("$config{'apply_cmd'} >/dev/null 2>&1 </dev/null")
191                 if ($config{'apply_cmd'});
192         &webmin_log("modify", "printer", $prn{'name'}, &log_info(\%prn));
193         }
194
195 # Update ACL
196 if ($in{'new'} && $access{'printers'} ne '*') {
197         $access{'printers'} .= " ".$in{'name'};
198         &save_module_acl(\%access);
199         }
200
201 # Create on cluster
202 @slaveerrs = &save_on_cluster($in{'new'}, \%prn, $drv, $sdrv || $hdrv,
203                               $in{'webmin'}, $in{'dest'});
204 if (@slaveerrs) {
205         &error(&text('save_errslave',
206              "<p>".join("<br>", map { "$_->[0]->{'host'} : $_->[1]" }
207                                     @slaveerrs)));
208         }
209
210 &redirect("");
211
212 sub connect_time_out
213 {
214 $connect_timed_out++;
215 }
216