3 # Hacked by Alan Stebbens <aks@sgi.com> to setuid to the username if
4 # valid on this system. Written as a secure Perl script. To enable,
6 # chown root /usr/samba/bin/sambalp
7 # chmod u+s,+x /usr/samba/bin/sambalp
9 # If setuidshells is not enabled on your system, you must also do this:
18 # This script will still work as a normal user; it will not try
19 # to setuid in this case.
21 # If the "$PSFIX" variable is set below...
23 # Workaround Win95 printer driver/Impressario bug by removing
24 # the PS check for available virtual memory. Note that this
25 # bug appears to be in all Win95 print drivers that generate
26 # PostScript; but is for certain there with a QMS-PS 810 (the
27 # printer type I configure on the Win95-side for printing with
30 # the perl script fixes 3 different bugs.
31 # 1. remove the JCL statements added by some HP printer drivers to the
32 # beginning of the postscript output.
33 # 2. Fix a bug in output from word files with long filenames. A non-printing
34 # character added to the end of the title comment by word is
36 # 3. The VM fix described above.
39 # Modified for Perl4 compatibility.
44 $PSFIX = 1; # set to 0 if you don't want to run
47 # Untaint the PATH variable
48 @PATH = split(' ',<<EOF);
49 /usr/sbin /usr/bsd /sbin /usr/bin /bin /usr/lib /usr/local/bin
51 $ENV{'PATH'} = join(':',@PATH);
54 print STDERR
"usage: $PROG printer file user system\n";
63 open(LPSTAT
,"/usr/bin/lpstat -t|") || die("Can't get printer list.\n");
66 next unless /^printer (\w+)/;
71 @printers{@printers} = @printers;
73 # Untaint the printer name
74 if (defined($prtname = $printers{$printer})) {
77 die("Unknown printer: \"$printer\"\n");
80 if ($> == 0) { # are we root?
81 # yes -- then perform a taint checks and possibly do a suid check
83 # Untaint the file and system names (pretend to filter them)
84 $file = $file =~ /^(.*)/ ?
$1 : die("Bad file: $file\n");
85 $system = $system =~ /^(.*)/ ?
$1 : die("Bad system: $system\n");
90 while (@pwe = getpwent()) {
91 $uids{$pwe[0]} = $pwe[2];
92 $users{$pwe[2]} = $pwe[0];
96 # Check out the user -- if the user is a real user on this system,
97 # then become that user so that the printer header page looks right
98 # otherwise, remain as the default user (probably "nobody").
100 if (defined($uid = $uids{$user})) {
102 # before we change UID, we must ensure that the file is still
103 # readable after the UID change.
104 chown($uid, 9, $file); # make the file owned by the user
106 # Now, go ahead and become the user
107 $name = $users{$uid};
108 $> = $uid; # become the user
110 } else { # do untaint filtering
111 $name = $user =~ /^(\w+)/ ?
$1 : die("Bad user: $user\n");
113 } else { # otherwise, just be me
114 $name = $user; # whomever that is
117 $lpcommand = "/usr/bin/lp -c -d$printer -t'$name on $system'";
119 # This code is from the original "psfix" but it has been completely
120 # rewritten for speed.
122 if ($PSFIX) { # are we running a "psfix"?
123 open(FILE
, $file) || die("Can't read $file: $!\n");
124 open(LP
, "|$lpcommand -") || die("Can't open pipe to \"lp\": $!\n");
127 $_ =~ s/^\004//; # strip any ctrl-d's
128 if (/^\e%/) { # get rid of any non-postscript commands
129 while (<FILE
>) { # remove text until next %!PS
130 s/^\001M//; # lenmark driver prefixes Ctrl-A M to %!PS
134 } elsif (/^%%Title:/) { # fix bug in long titles from MS Word
135 s/.\r$/\r/; # remove trailing character on the title
136 } elsif (/^\/VM
\?/) { # remove VM test
137 print "/VM? { pop } bind def\r\n";
138 while (<FILE
>) { last if /def\r/; }
145 } else { # we're not running psfix?
146 system("$lpcommand $file");
149 if ($file =~ m
(^/)) {
150 # $file is a fully specified path
151 # Remove the file only if it lives in a directory ending in /tmp.
152 unlink($file) if ($file =~ m
(/tmp/[^/]+$));
154 # $file is NOT a fully specified path
155 # Remove the file only if current directory ends in /tmp.
156 unlink($file) if (`pwd` =~ m
(/tmp
$));