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