1 /*	$OpenBSD: lprm.c,v 1.16 2003/06/02 23:36:53 millert Exp $	*/
2 /*	$$NetBSD: lprm.c,v 1.9 1999/08/16 03:12:32 simonb Exp $	*/
3 
4 /*
5  * Copyright (c) 1983, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #ifndef lint
35 static const char copyright[] =
36 "@(#) Copyright (c) 1983, 1993\n\
37 	The Regents of the University of California.  All rights reserved.\n";
38 #endif /* not lint */
39 
40 #ifndef lint
41 #if 0
42 static const char sccsid[] = "@(#)lprm.c	8.1 (Berkeley) 6/6/93";
43 #else
44 static const char rcsid[] = "$OpenBSD: lprm.c,v 1.16 2003/06/02 23:36:53 millert Exp $";
45 #endif
46 #endif /* not lint */
47 
48 /*
49  * lprm - remove the current user's spool entry
50  *
51  * lprm [-] [[job #] [user] ...]
52  *
53  * Using information in the lock file, lprm will kill the
54  * currently active daemon (if necessary), remove the associated files,
55  * and startup a new daemon.  Privileged users may remove anyone's spool
56  * entries, otherwise one can only remove their own.
57  */
58 
59 #include <sys/param.h>
60 
61 #include <ctype.h>
62 #include <dirent.h>
63 #include <err.h>
64 #include <errno.h>
65 #include <pwd.h>
66 #include <stdlib.h>
67 #include <stdio.h>
68 #include <string.h>
69 #include <syslog.h>
70 #include <unistd.h>
71 
72 #include "lp.h"
73 #include "lp.local.h"
74 
75 /*
76  * Stuff for handling job specifications
77  */
78 char	*person;		/* name of person doing lprm */
79 int	 requ[MAXREQUESTS];	/* job number of spool entries */
80 int	 requests;		/* # of spool requests */
81 char	*user[MAXUSERS];	/* users to process */
82 int	 users;			/* # of users in user array */
83 volatile sig_atomic_t gotintr;	/* set when we receive SIGINT */
84 static char luser[MAXLOGNAME];	/* buffer for person */
85 
86 static __dead void usage(void);
87 
88 int
main(int argc,char ** argv)89 main(int argc, char **argv)
90 {
91 	struct passwd *pw;
92 	char *cp;
93 	long l;
94 	int ch;
95 
96 	/*
97 	 * Simulate setuid daemon w/ PRIV_END called.
98 	 * We don't want lpr to actually be setuid daemon since that
99 	 * requires that the lpr binary be owned by user daemon, which
100 	 * is potentially unsafe.
101 	 */
102 	if ((pw = getpwuid(DEFUID)) == NULL)
103 		errx(1, "daemon uid (%u) not in password file", DEFUID);
104 	effective_uid = pw->pw_uid;
105 	real_uid = getuid();
106 	effective_gid = pw->pw_gid;
107 	real_gid = getgid();
108 	setresgid(real_gid, real_gid, effective_gid);
109 	setresuid(real_uid, real_uid, effective_uid);
110 
111 	gethostname(host, sizeof(host));
112 	openlog("lprm", 0, LOG_LPR);
113 	if ((pw = getpwuid(real_uid)) == NULL)
114 		fatal("Who are you?");
115 	if (strlen(pw->pw_name) >= sizeof(luser))
116 		fatal("Your name is too long");
117 	strlcpy(luser, pw->pw_name, sizeof(luser));
118 	person = luser;
119 	while ((ch = getopt(argc, argv, "P:w:-")) != -1) {
120 		switch (ch) {
121 		case '-':
122 			users = -1;
123 			break;
124 		case 'P':
125 			printer = optarg;
126 			break;
127 		case 'w':
128 			l = strtol(optarg, &cp, 10);
129 			if (*cp != '\0' || l < 0 || l >= INT_MAX)
130 				errx(1, "wait time must be postive integer: %s",
131 				    optarg);
132 			wait_time = (u_int)l;
133 			if (wait_time < 30)
134 				warnx("warning: wait time less than 30 seconds");
135 			break;
136 		default:
137 			usage();
138 		}
139 	}
140 	argc -= optind;
141 	argv += optind;
142 
143 	if (printer == NULL && (printer = getenv("PRINTER")) == NULL)
144 		printer = DEFLP;
145 	if (users < 0 && argc != 0)
146 		usage();
147 	while (argc > 0) {
148 		if (isdigit(*argv[0])) {
149 			if (requests >= MAXREQUESTS)
150 				fatal("Too many requests");
151 			requ[requests++] = atoi(argv[0]);
152 		} else {
153 			if (users >= MAXUSERS)
154 				fatal("Too many users");
155 			user[users++] = argv[0];
156 		}
157 		argc--;
158 		argv++;
159 	}
160 
161 	rmjob();
162 	exit(0);
163 }
164 
165 static __dead void
usage(void)166 usage(void)
167 {
168 	extern char *__progname;
169 
170 	fprintf(stderr, "usage: %s [-] [-Pprinter] [[job #] [user] ...]\n",
171 	    __progname);
172 	exit(2);
173 }
174