1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
27
28 #include "dispatch.h"
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <syslog.h>
32
33 static char *reqpath(char *, char **);
34 static int mv_file(RSTATUS *, char *);
35
36
37 RSTATUS *NewRequest;
38
39 /*
40 * s_alloc_files()
41 */
42
43 void
s_alloc_files(char * m,MESG * md)44 s_alloc_files(char *m, MESG *md) /* funcdef */
45 {
46 char *file_prefix;
47 ushort_t count;
48 mode_t old_msk;
49
50
51 /*
52 * Bugid 4140311
53 * Set umask to 0 before creating files.
54 */
55 old_msk = umask((mode_t)0);
56
57 getmessage(m, S_ALLOC_FILES, &count);
58 syslog(LOG_DEBUG, "s_alloc_files(%d)", count);
59
60 if ((file_prefix = _alloc_files(count, (char *)0, md->uid, md->gid))) {
61 mputm(md, R_ALLOC_FILES, MOK, file_prefix);
62 add_flt_act(md, FLT_FILES, file_prefix, count);
63 } else if (errno == EEXIST)
64 mputm(md, R_ALLOC_FILES, MERRDEST, "");
65 else
66 mputm(md, R_ALLOC_FILES, MNOMEM, "");
67
68 (void) umask(old_msk);
69
70 }
71
72 /*
73 * s_print_request()
74 */
75
76 void
s_print_request(char * m,MESG * md)77 s_print_request(char *m, MESG *md)
78 {
79 extern char *Local_System;
80 char *file;
81 char *idno;
82 char *path;
83 char *req_file;
84 char *req_id = 0;
85 RSTATUS *rp;
86 REQUEST *r;
87 SECURE *s;
88 struct passwd *pw;
89 short err;
90 short status;
91 off_t size;
92 uid_t org_uid;
93 gid_t org_gid;
94 #ifdef LP_USE_PAPI_ATTR
95 struct stat tmpBuf;
96 char tmpName[BUFSIZ];
97 #endif
98
99
100 (void) getmessage(m, S_PRINT_REQUEST, &file);
101 syslog(LOG_DEBUG, "s_print_request(%s)", (file ? file : "NULL"));
102
103 /*
104 * "NewRequest" points to a request that's not yet in the
105 * request list but is to be considered with the rest of the
106 * requests (e.g. calculating # of requests awaiting a form).
107 */
108 if ((rp = NewRequest = new_rstatus(NULL, NULL)) == NULL)
109 status = MNOMEM;
110
111 else
112 {
113 req_file = reqpath(file, &idno);
114 path = makepath(Lp_Tmp, req_file, (char *)0);
115 (void) chownmod(path, Lp_Uid, Lp_Gid, 0644);
116 Free(path);
117
118 if (!(r = Getrequest(req_file)))
119 status = MNOOPEN;
120
121 else
122 {
123 rp->req_file = Strdup(req_file);
124
125 freerequest(rp->request);
126 rp->request = r;
127
128 rp->request->outcome = 0;
129 rp->secure->uid = md->uid;
130 rp->secure->gid = md->gid;
131 if (md->slabel != NULL)
132 rp->secure->slabel = Strdup(md->slabel);
133
134 pw = getpwuid(md->uid);
135 endpwent();
136 if (pw && pw->pw_name && *pw->pw_name)
137 rp->secure->user = Strdup(pw->pw_name);
138 else {
139 rp->secure->user = Strdup(BIGGEST_NUMBER_S);
140 (void) sprintf(rp->secure->user, "%u",
141 md->uid);
142 }
143
144 if ((rp->request->actions & ACT_SPECIAL) == ACT_HOLD)
145 rp->request->outcome |= RS_HELD;
146 if ((rp->request->actions & ACT_SPECIAL) == ACT_RESUME)
147 rp->request->outcome &= ~RS_HELD;
148 if ((rp->request->actions & ACT_SPECIAL) ==
149 ACT_IMMEDIATE) {
150 if (!md->admin) {
151 status = MNOPERM;
152 goto Return;
153 }
154 rp->request->outcome |= RS_IMMEDIATE;
155 }
156
157 size = chfiles(rp->request->file_list, Lp_Uid, Lp_Gid);
158
159 if (size < 0) {
160 /*
161 * at this point, chfiles() may have
162 * failed because the file may live on
163 * an NFS mounted filesystem, under
164 * a directory of mode 700. such a
165 * directory isn't accessible even by
166 * root, according to the NFS protocol
167 * (i.e. the Stat() in chfiles() failed).
168 * this most commonly happens via the
169 * automounter, and rlogin. thus we
170 * change our euid/egid to that of the
171 * user, and try again. if *this* fails,
172 * then the file must really be
173 * inaccessible.
174 */
175 org_uid = geteuid();
176 org_gid = getegid();
177
178 if (setegid(md->gid) != 0) {
179 status = MUNKNOWN;
180 goto Return;
181 }
182
183 if (seteuid(md->uid) != 0) {
184 setgid(org_gid);
185 status = MUNKNOWN;
186 goto Return;
187 }
188
189 size = chfiles(rp->request->file_list,
190 Lp_Uid, Lp_Gid);
191
192 if (seteuid(org_uid) != 0) {
193 /* should never happen */
194 note("s_print_request(): ");
195 note("seteuid back to uid=%d "
196 "failed!!\n", org_uid);
197 size = -1;
198 }
199
200 if (setegid(org_gid) != 0) {
201 /* should never happen */
202 note("s_print_request(): ");
203 note("setegid back to uid=%d "
204 "failed!!\n", org_uid);
205 size = -1;
206 }
207
208 if (size < 0) {
209 status = MUNKNOWN;
210 goto Return;
211 }
212 }
213 if (!(rp->request->outcome & RS_HELD) && size == 0) {
214 status = MNOPERM;
215 goto Return;
216 }
217 rp->secure->size = size;
218
219 (void) time(&rp->secure->date);
220 rp->secure->req_id = NULL;
221
222 if (!rp->request->title) {
223 if (strlen(*rp->request->file_list) <
224 (size_t)24)
225 rp->request->title =
226 Strdup(*rp->request->file_list);
227 else {
228 char *r;
229 if (r = strrchr(
230 *rp->request->file_list, '/'))
231 r++;
232 else
233 r = *rp->request->file_list;
234
235 rp->request->title = malloc(25);
236 sprintf(rp->request->title,
237 "%-.24s", r);
238 }
239 }
240
241 if ((err = validate_request(rp, &req_id, 0)) != MOK)
242 status = err;
243 else {
244 /*
245 * "req_id" will be supplied if this is from a
246 * remote system.
247 */
248 if (rp->secure->req_id == NULL) {
249 req_id = makestr(req_id, "-",
250 idno, (char *)0);
251 rp->secure->req_id = req_id;
252 } else
253 req_id = rp->secure->req_id;
254
255 #ifdef LP_USE_PAPI_ATTR
256 /*
257 * Check if the PAPI job attribute file
258 * exists, if it does change the
259 * permissions and ownership of the file.
260 * This file is created when print jobs
261 * are submitted via the PAPI interface,
262 * the file pathname of this file is
263 * passed to the slow-filters and printer
264 * interface script as an environment
265 * variable when they are executed
266 */
267 snprintf(tmpName, sizeof (tmpName),
268 "%s-%s", idno, LP_PAPIATTRNAME);
269 path = makepath(Lp_Temp, tmpName, (char *)0);
270
271 if (stat(path, &tmpBuf) == 0) {
272 syslog(LOG_DEBUG,
273 "s_print_request: "\
274 "attribute file ='%s'", path);
275
276 /*
277 * IPP job attribute file exists
278 * for this job so change
279 * permissions and ownership of
280 * the file
281 */
282 (void) chownmod(path, Lp_Uid,
283 Lp_Gid, 0644);
284 Free(path);
285 }
286 else
287 {
288 syslog(LOG_DEBUG,
289 "s_print_request: "\
290 "no attribute file");
291 }
292 #endif
293
294 /*
295 * fix for bugid 1103890.
296 * use Putsecure instead.
297 */
298 if ((Putsecure(req_file, rp->secure) == -1) ||
299 (putrequest(req_file, rp->request) == -1))
300 status = MNOMEM;
301 else
302 {
303 status = MOK;
304
305 insertr(rp);
306 NewRequest = 0;
307
308 if (rp->slow)
309 schedule(EV_SLOWF, rp);
310 else
311 schedule(EV_INTERF,
312 rp->printer);
313
314 del_flt_act(md, FLT_FILES);
315 }
316 }
317 }
318 }
319
320 Return:
321 NewRequest = 0;
322 Free(req_file);
323 Free(idno);
324 if (status != MOK && rp) {
325 rmfiles(rp, 0);
326 free_rstatus(rp);
327 }
328 mputm(md, R_PRINT_REQUEST, status, NB(req_id), chkprinter_result);
329 }
330
331 /*
332 * s_start_change_request()
333 */
334
335 void
s_start_change_request(char * m,MESG * md)336 s_start_change_request(char *m, MESG *md)
337 {
338 char *req_id;
339 char *req_file = "";
340 short status;
341 RSTATUS *rp;
342 char *path;
343 char tmpName[BUFSIZ];
344 struct stat tmpBuf;
345
346 (void) getmessage(m, S_START_CHANGE_REQUEST, &req_id);
347 syslog(LOG_DEBUG, "s_start_change_request(%s)",
348 (req_id ? req_id : "NULL"));
349
350 if (!(rp = request_by_id(req_id)))
351 status = MUNKNOWN;
352 else if ((md->admin == 0) && (is_system_labeled()) &&
353 (md->slabel != NULL) && (rp->secure->slabel != NULL) &&
354 (!STREQU(md->slabel, rp->secure->slabel)))
355 status = MUNKNOWN;
356 else if (rp->request->outcome & RS_DONE)
357 status = M2LATE;
358 else if (!md->admin && md->uid != rp->secure->uid)
359 status = MNOPERM;
360 else if (rp->request->outcome & RS_CHANGING)
361 status = MNOOPEN;
362 else if (rp->request->outcome & RS_NOTIFYING)
363 status = MBUSY;
364 else {
365 status = MOK;
366
367 if (rp->request->outcome & RS_FILTERING &&
368 !(rp->request->outcome & RS_STOPPED)) {
369 rp->request->outcome |= (RS_REFILTER|RS_STOPPED);
370 terminate(rp->exec);
371 }
372
373 if (rp->request->outcome & RS_PRINTING &&
374 !(rp->request->outcome & RS_STOPPED)) {
375 rp->request->outcome |= RS_STOPPED;
376 terminate(rp->printer->exec);
377 }
378
379 rp->request->outcome |= RS_CHANGING;
380
381 /*
382 * Change the ownership of the request file to be "md->uid".
383 * Either this is identical to "rp->secure->uid", or it is
384 * "Lp_Uid" or it is root. The idea is that the
385 * person at the other end needs access, and that may not
386 * be who queued the request.
387 */
388
389 path = makepath(Lp_Tmp, rp->req_file, (char *)0);
390 (void) Chown(path, md->uid, rp->secure->gid);
391 Free(path);
392
393 #ifdef LP_USE_PAPI_ATTR
394
395 /*
396 * Check if the PAPI job attribute file exists, if it does
397 * change the ownership of the file to be "md->uid".
398 * Either this is identical to "rp->secure->uid", or it is
399 * "Lp_Uid" or it is root. The idea is that the
400 * person at the other end needs access, and that may not
401 * be who queued the request.
402 */
403
404 snprintf(tmpName, sizeof (tmpName),
405 "%s-%s", strtok(strdup(rp->req_file), "-"),
406 LP_PAPIATTRNAME);
407
408 path = makepath(Lp_Tmp, tmpName, (char *)0);
409
410 if (stat(path, &tmpBuf) == 0) {
411 syslog(LOG_DEBUG,
412 "s_start_change_request: attribute file ='%s'",
413 path);
414
415 /*
416 * IPP job attribute file exists for this job so
417 * change permissions and ownership of the file
418 */
419 (void) Chown(path, md->uid, rp->secure->gid);
420 Free(path);
421 }
422 else
423 {
424 syslog(LOG_DEBUG,
425 "s_start_change_request: no attribute file");
426 }
427 #endif
428
429 add_flt_act(md, FLT_CHANGE, rp);
430 req_file = rp->req_file;
431
432 }
433
434 mputm(md, R_START_CHANGE_REQUEST, status, req_file);
435 }
436
437 /*
438 * s_end_change_request()
439 */
440
441 void
s_end_change_request(char * m,MESG * md)442 s_end_change_request(char *m, MESG *md)
443 {
444 char *req_id;
445 RSTATUS *rp;
446 off_t size;
447 off_t osize;
448 short err;
449 short status;
450 REQUEST *r = 0;
451 REQUEST oldr;
452 int call_schedule = 0;
453 int move_ok = 0;
454 char *path;
455 char tmpName[BUFSIZ];
456 struct stat tmpBuf;
457
458 (void) getmessage(m, S_END_CHANGE_REQUEST, &req_id);
459 syslog(LOG_DEBUG, "s_end_change_request(%s)",
460 (req_id ? req_id : "NULL"));
461
462 if (!(rp = request_by_id(req_id)))
463 status = MUNKNOWN;
464 else if ((md->admin == 0) && (is_system_labeled()) &&
465 (md->slabel != NULL) && (rp->secure->slabel != NULL) &&
466 (!STREQU(md->slabel, rp->secure->slabel)))
467 status = MUNKNOWN;
468 else if (!(rp->request->outcome & RS_CHANGING))
469 status = MNOSTART;
470 else {
471 path = makepath(Lp_Tmp, rp->req_file, (char *)0);
472 (void) chownmod(path, Lp_Uid, Lp_Gid, 0644);
473 Free(path);
474
475 #ifdef LP_USE_PAPI_ATTR
476
477 /*
478 * Check if the PAPI job attribute file exists,
479 * if it does change the permission and the ownership
480 * of the file to be "Lp_Uid".
481 */
482
483 snprintf(tmpName, sizeof (tmpName),
484 "%s-%s", strtok(strdup(rp->req_file), "-"),
485 LP_PAPIATTRNAME);
486
487 path = makepath(Lp_Tmp, tmpName, (char *)0);
488
489 if (stat(path, &tmpBuf) == 0) {
490 syslog(LOG_DEBUG,
491 "s_end_change_request: attribute file ='%s'",
492 path);
493
494 /*
495 * IPP job attribute file exists for this job so
496 * change permissions and ownership of the file
497 */
498 (void) chownmod(path, Lp_Uid, Lp_Gid, 0644);
499 Free(path);
500 }
501 else
502 {
503 syslog(LOG_DEBUG,
504 "s_end_change_request: no attribute file");
505 }
506 #endif
507 rp->request->outcome &= ~(RS_CHANGING);
508 del_flt_act(md, FLT_CHANGE);
509 /*
510 * The RS_CHANGING bit may have been the only thing
511 * preventing this request from filtering or printing,
512 * so regardless of what happens below,
513 * we must check to see if the request can proceed.
514 */
515 call_schedule = 1;
516
517 if (!(r = Getrequest(rp->req_file)))
518 status = MNOOPEN;
519 else {
520 oldr = *(rp->request);
521 *(rp->request) = *r;
522
523 move_ok =
524 STREQU(oldr.destination, r->destination);
525
526 /*
527 * Preserve the current request status!
528 */
529 rp->request->outcome = oldr.outcome;
530
531 /*
532 * Here's an example of the dangers one meets
533 * when public flags are used for private
534 * purposes. ".actions" (indeed, anything in the
535 * REQUEST structure) is set by the person
536 * changing the job. However, lpsched uses
537 * ".actions" as place to indicate that a job
538 * came from a remote system and we must send
539 * back job completion--this is a strictly
540 * private flag that we must preserve.
541 */
542 rp->request->actions |=
543 (oldr.actions & ACT_NOTIFY);
544
545 if ((rp->request->actions & ACT_SPECIAL) ==
546 ACT_HOLD) {
547 rp->request->outcome |= RS_HELD;
548 /*
549 * To be here means either the user owns
550 * the request or he or she is the
551 * administrator. Since we don't want to
552 * set the RS_ADMINHELD flag if the user
553 * is the administrator, the following
554 * compare will work.
555 */
556 if (md->uid != rp->secure->uid)
557 rp->request->outcome |=
558 RS_ADMINHELD;
559 }
560
561 if ((rp->request->actions & ACT_SPECIAL) ==
562 ACT_RESUME) {
563 if ((rp->request->outcome & RS_ADMINHELD) &&
564 !md->admin) {
565 status = MNOPERM;
566 goto Return;
567 }
568 rp->request->outcome &=
569 ~(RS_ADMINHELD|RS_HELD);
570 }
571
572 if ((rp->request->actions & ACT_SPECIAL)
573 == ACT_IMMEDIATE) {
574 if (!md->admin) {
575 status = MNOPERM;
576 goto Return;
577 }
578 rp->request->outcome |= RS_IMMEDIATE;
579 }
580
581 size = chfiles(rp->request->file_list, Lp_Uid,
582 Lp_Gid);
583 if (size < 0) {
584 status = MUNKNOWN;
585 goto Return;
586 }
587 if (!(rp->request->outcome & RS_HELD) &&
588 size == 0) {
589 status = MNOPERM;
590 goto Return;
591 }
592
593 osize = rp->secure->size;
594 rp->secure->size = size;
595
596 if (move_ok == 0) {
597 char *dest = strdup(r->destination);
598 if ((status = mv_file(rp, dest)) == MOK)
599 rp->secure->size = osize;
600 free(dest);
601 } else if ((err = validate_request(rp, (char **)0,
602 move_ok)) != MOK) {
603 status = err;
604 rp->secure->size = osize;
605 } else {
606 status = MOK;
607
608 if ((rp->request->outcome & RS_IMMEDIATE) ||
609 (rp->request->priority != oldr.priority)) {
610 remover(rp);
611 insertr(rp);
612 }
613
614 freerequest(&oldr);
615 (void) putrequest(rp->req_file, rp->request);
616 /*
617 * fix for bugid 1103890.
618 * use Putsecure instead.
619 */
620 (void) Putsecure(rp->req_file, rp->secure);
621 }
622 }
623 }
624
625 Return:
626 if (status != MOK && rp) {
627 if (r) {
628 freerequest(r);
629 *(rp->request) = oldr;
630 }
631 if (status != MNOSTART)
632 (void) putrequest(rp->req_file, rp->request);
633 }
634
635 if (call_schedule)
636 maybe_schedule(rp);
637
638 mputm(md, R_END_CHANGE_REQUEST, status, chkprinter_result);
639 }
640
641 /*
642 * _cancel()
643 * user may be (host!user)
644 */
645
646 static char *
_cancel(MESG * md,char * dest,char * user,char * req_id)647 _cancel(MESG *md, char *dest, char *user, char *req_id)
648 {
649 static RSTATUS *rp;
650 static char *s_dest;
651 static char *s_user;
652 static char *s_req_id;
653 static int current;
654 RSTATUS *crp;
655 char *creq_id;
656
657 syslog(LOG_DEBUG, "_cancel(%s, %s, %s)", (dest ? dest : "NULL"),
658 (user ? user : "NULL"), (req_id ? req_id : "NULL"));
659
660 if (dest || user || req_id) {
661 s_dest = dest;
662 if (STREQU(user, "!"))
663 s_user = strdup("all!all");
664 else
665 s_user = user;
666 s_req_id = req_id;
667 rp = Request_List;
668 current = 0;
669 if (STREQU(s_req_id, CURRENT_REQ)) {
670 current = 1;
671 s_req_id = NULL;
672 }
673 }
674
675 while (rp != NULL) {
676 crp = rp;
677 rp = rp->next;
678
679 if (*s_dest && !STREQU(s_dest, crp->request->destination))
680 continue;
681
682 if (current && !(crp->request->outcome & RS_PRINTING))
683 continue;
684
685 if (s_req_id && *s_req_id &&
686 !STREQU(s_req_id, crp->secure->req_id))
687 continue;
688
689 if (*s_user && !bangequ(s_user, crp->secure->user))
690 continue;
691
692 if (!md->admin && md->uid != crp->secure->uid) {
693 errno = MNOPERM;
694 return (Strdup(crp->secure->req_id));
695 }
696
697 /*
698 * For Trusted Extensions, we need to check the
699 * sensitivity label of the
700 * connection and job before we try to cancel it.
701 */
702 if ((md->admin == 0) && (is_system_labeled()) &&
703 (md->slabel != NULL) && (crp->secure->slabel != NULL) &&
704 (!STREQU(md->slabel, crp->secure->slabel)))
705 continue;
706
707 crp->reason = MOK;
708 creq_id = Strdup(crp->secure->req_id);
709
710 syslog(LOG_DEBUG, "cancel reqid (%s) uid: %d, secureuid: %d",
711 creq_id, md->uid, crp->secure->uid);
712
713 if (cancel(crp, (md->uid != crp->secure->uid)))
714 errno = MOK;
715 else
716 errno = M2LATE;
717 return (creq_id);
718 }
719
720 errno = MUNKNOWN;
721 return (NULL);
722 }
723
724 /*
725 * s_cancel_request()
726 */
727
728 void
s_cancel_request(char * m,MESG * md)729 s_cancel_request(char *m, MESG *md)
730 {
731 char *req_id, *rid;
732 short status;
733
734 (void) getmessage(m, S_CANCEL_REQUEST, &req_id);
735 syslog(LOG_DEBUG, "s_cancel_request(%s)", (req_id ? req_id : "NULL"));
736
737 if ((rid = _cancel(md, "", "", req_id)) != NULL)
738 Free(rid);
739 status = (short)errno;
740
741 mputm(md, R_CANCEL_REQUEST, status);
742 }
743
744 /*
745 * s_cancel()
746 */
747
748 void
s_cancel(char * m,MESG * md)749 s_cancel(char *m, MESG *md)
750 {
751 char *req_id;
752 char *user;
753 char *destination;
754 char *rid;
755 char *nrid;
756 int nerrno;
757 int oerrno;
758
759 (void) getmessage(m, S_CANCEL, &destination, &user, &req_id);
760 syslog(LOG_DEBUG, "s_cancel(%s, %s, %s)",
761 (destination ? destination : "NULL"), (user ? user : "NULL"),
762 (req_id ? req_id : "NULL"));
763
764 if (STREQU(destination, NAME_ALL))
765 destination = "";
766 if (STREQU(req_id, NAME_ALL))
767 req_id = "";
768
769 if (rid = _cancel(md, destination, user, req_id)) {
770 oerrno = errno;
771
772 while ((nrid = _cancel(md, NULL, NULL, NULL)) != NULL) {
773 nerrno = errno;
774 mputm(md, R_CANCEL, MOKMORE, oerrno, rid);
775 Free(rid);
776 rid = nrid;
777 oerrno = nerrno;
778 }
779 mputm(md, R_CANCEL, MOK, oerrno, rid);
780 Free(rid);
781 return;
782 }
783
784 mputm(md, R_CANCEL, MOK, MUNKNOWN, "");
785 }
786
787 /*
788 * s_inquire_request_rank()
789 */
790
791 void
s_inquire_request_rank(char * m,MESG * md)792 s_inquire_request_rank(char *m, MESG *md)
793 {
794 char *form;
795 char *dest;
796 char *pwheel;
797 char *user;
798 char *req_id;
799 RSTATUS *rp;
800 RSTATUS *found = NULL;
801 int found_rank = 0;
802 short prop;
803 char files[BUFSIZ];
804 int i;
805
806 (void) getmessage(m, S_INQUIRE_REQUEST_RANK, &prop, &form, &dest,
807 &req_id, &user, &pwheel);
808 syslog(LOG_DEBUG, "s_inquire_request_rank(%d, %s, %s, %s, %s, %s)",
809 prop, (form ? form : "NULL"), (dest ? dest : "NULL"),
810 (req_id ? req_id : "NULL"), (user ? user : "NULL"),
811 (pwheel ? pwheel : "NULL"));
812
813 for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++)
814 PStatus[i]->nrequests = 0;
815
816 for (rp = Request_List; rp != NULL; rp = rp->next) {
817 if (rp->printer && !(rp->request->outcome & RS_DONE))
818 rp->printer->nrequests++;
819
820 if (*form && !SAME(form, rp->request->form))
821 continue;
822
823 if (*dest && !STREQU(dest, rp->request->destination)) {
824 if (!rp->printer)
825 continue;
826 if (!STREQU(dest, rp->printer->printer->name))
827 continue;
828 }
829
830 if (*req_id && !STREQU(req_id, rp->secure->req_id))
831 continue;
832
833 if (*user && !bangequ(user, rp->secure->user))
834 continue;
835
836 if (*pwheel && !SAME(pwheel, rp->pwheel_name))
837 continue;
838 /*
839 * For Trusted Extensions, we need to check the sensitivity
840 * label of the connection and job before we return it to the
841 * client.
842 */
843 if ((md->admin <= 0) && (is_system_labeled()) &&
844 (md->slabel != NULL) && (rp->secure->slabel != NULL) &&
845 (!STREQU(md->slabel, rp->secure->slabel)))
846 continue;
847
848 if (found) {
849 GetRequestFiles(found->request, files, sizeof (files));
850 mputm(md, R_INQUIRE_REQUEST_RANK,
851 MOKMORE,
852 found->secure->req_id,
853 found->request->user,
854 /* bgolden 091996, bug 1257405 */
855 found->secure->slabel,
856 found->secure->size,
857 found->secure->date,
858 found->request->outcome,
859 found->printer->printer->name,
860 (found->form? found->form->form->name : ""),
861 NB(found->pwheel_name),
862 found_rank,
863 files);
864 }
865 found = rp;
866 found_rank = found->printer->nrequests;
867 }
868
869 if (found) {
870 GetRequestFiles(found->request, files, sizeof (files));
871 mputm(md, R_INQUIRE_REQUEST_RANK,
872 MOK,
873 found->secure->req_id,
874 found->request->user, /* bgolden 091996, bug 1257405 */
875 found->secure->slabel,
876 found->secure->size,
877 found->secure->date,
878 found->request->outcome,
879 found->printer->printer->name,
880 (found->form? found->form->form->name : ""),
881 NB(found->pwheel_name),
882 found_rank,
883 files);
884 } else
885 mputm(md, R_INQUIRE_REQUEST_RANK, MNOINFO, "", "", "", 0L, 0L,
886 0, "", "", "", 0, "");
887 }
888
889 static int
mv_file(RSTATUS * rp,char * dest)890 mv_file(RSTATUS *rp, char *dest)
891 {
892 int stat;
893 char *olddest;
894 EXEC *oldexec;
895 SECURE * securep;
896 RSTATUS * prs;
897 char *reqno;
898
899 oldexec = rp->printer->exec;
900 olddest = rp->request->destination;
901 rp->request->destination = Strdup(dest);
902 if ((stat = validate_request(rp, (char **)0, 1)) == MOK) {
903 Free(olddest);
904
905 if (rp->request->outcome & RS_FILTERED) {
906 int cnt = 0;
907 char *reqno;
908 char **listp;
909 char tmp_nam[MAXPATHLEN];
910
911 reqno = getreqno(rp->secure->req_id);
912 for (listp = rp->request->file_list; *listp; listp++) {
913 cnt++;
914 snprintf(tmp_nam, sizeof (tmp_nam),
915 "%s/F%s-%d", Lp_Temp, reqno, cnt);
916 unlink(tmp_nam);
917
918 }
919 rp->request->outcome &= ~RS_FILTERED;
920 }
921
922 /* update /var/spool/lp/tmp/<host>/nnn-0 */
923 if (putrequest(rp->req_file, rp->request) < 0) {
924 note("putrequest failed\n");
925 return (MNOMEM);
926 }
927
928 /* update /var/spool/lp/requests/<host>/nnn-0 */
929 if ((securep = Getsecure(rp->req_file))) {
930 reqno = strdup(getreqno(securep->req_id));
931 (void) free(securep->req_id);
932 if ((securep->req_id = calloc(strlen(dest) + 1 +
933 strlen(reqno) +1, sizeof (char))) == NULL)
934 return (MNOMEM);
935 (void) sprintf(securep->req_id, "%s-%s", dest, reqno);
936 /* remove the old request file; save new one */
937 (void) rmsecure(rp->secure->req_id);
938 if (Putsecure(rp->req_file, securep) < 0) {
939 /* Putsecure includes note/errmessage */
940 return (MNOMEM);
941 }
942 } else {
943 note("Getsecure failed\n");
944 return (MNOMEM);
945 }
946
947 /* update internal jobs list: Request_list */
948 if (prs = request_by_id(rp->secure->req_id)) {
949 free(prs->secure->req_id);
950 prs->secure->req_id = strdup(securep->req_id);
951
952 /*
953 * We calloc'd securep->reqid earlier, now we free it
954 * here because we no longer call 'freesecure' from
955 * Putsecure() if we use a static structure
956 */
957
958 free(securep->req_id);
959 } else {
960 note("request_by_id failed\n");
961 return (MUNKNOWN);
962 }
963
964 /*
965 * If the request was being filtered or was printing,
966 * it would have been stopped in "validate_request()",
967 * but only if it has to be refiltered. Thus, the
968 * filtering has been stopped if it has to be stopped,
969 * but the printing may still be going.
970 */
971 if (rp->request->outcome & RS_PRINTING &&
972 !(rp->request->outcome & RS_STOPPED)) {
973 rp->request->outcome |= RS_STOPPED;
974 terminate(oldexec);
975 }
976
977 maybe_schedule(rp);
978 return (MOK);
979 }
980
981 Free(rp->request->destination);
982 rp->request->destination = olddest;
983 return (stat);
984 }
985
986 /*
987 * s_move_request()
988 */
989
990 void
s_move_request(char * m,MESG * md)991 s_move_request(char *m, MESG *md)
992 {
993 RSTATUS *rp;
994 short err;
995 char *req_id;
996 char *dest;
997
998 (void) getmessage(m, S_MOVE_REQUEST, &req_id, &dest);
999 syslog(LOG_DEBUG, "s_move_request(%s, %s)", (req_id ? req_id : "NULL"),
1000 (dest ? dest : "NULL"));
1001
1002
1003 if (!(search_pstatus(dest)) && !(search_cstatus(dest))) {
1004 mputm(md, R_MOVE_REQUEST, MNODEST, 0L);
1005 return;
1006 }
1007
1008 if ((rp = request_by_id(req_id))) {
1009 if (STREQU(rp->request->destination, dest)) {
1010 mputm(md, R_MOVE_REQUEST, MOK, 0L);
1011 return;
1012 }
1013 if (rp->request->outcome & (RS_DONE|RS_NOTIFYING)) {
1014 mputm(md, R_MOVE_REQUEST, M2LATE, 0L);
1015 return;
1016 }
1017 if (rp->request->outcome & RS_CHANGING) {
1018 mputm(md, R_MOVE_REQUEST, MBUSY, 0L);
1019 return;
1020 }
1021 if ((err = mv_file(rp, dest)) == MOK) {
1022 mputm(md, R_MOVE_REQUEST, MOK, 0L);
1023 return;
1024 }
1025 mputm(md, R_MOVE_REQUEST, err, chkprinter_result);
1026 return;
1027 }
1028 mputm(md, R_MOVE_REQUEST, MUNKNOWN, 0L);
1029 }
1030
1031 /*
1032 * s_move_dest()
1033 */
1034
1035 void
s_move_dest(char * m,MESG * md)1036 s_move_dest(char *m, MESG *md)
1037 {
1038 char *dest;
1039 char *fromdest;
1040 RSTATUS *rp;
1041 char *found = (char *)0;
1042 short num_ok = 0;
1043
1044 (void) getmessage(m, S_MOVE_DEST, &fromdest, &dest);
1045 syslog(LOG_DEBUG, "s_move_dest(%s, %s)", (fromdest ? fromdest : "NULL"),
1046 (dest ? dest : "NULL"));
1047
1048 if (!search_pstatus(fromdest) && !search_cstatus(fromdest)) {
1049 mputm(md, R_MOVE_DEST, MNODEST, fromdest, 0);
1050 return;
1051 }
1052
1053 if (!(search_pstatus(dest)) && !(search_cstatus(dest))) {
1054 mputm(md, R_MOVE_DEST, MNODEST, dest, 0);
1055 return;
1056 }
1057
1058 if (STREQU(dest, fromdest)) {
1059 mputm(md, R_MOVE_DEST, MOK, "", 0);
1060 return;
1061 }
1062
1063 for (rp = Request_List; rp != NULL; rp = rp->next) {
1064 if ((STREQU(rp->request->destination, fromdest)) &&
1065 (!(rp->request->outcome &
1066 (RS_DONE|RS_CHANGING|RS_NOTIFYING)))) {
1067 if (mv_file(rp, dest) == MOK) {
1068 num_ok++;
1069 continue;
1070 }
1071 }
1072
1073 if (found)
1074 mputm(md, R_MOVE_DEST, MMORERR, found, 0);
1075
1076 found = rp->secure->req_id;
1077 }
1078
1079 if (found)
1080 mputm(md, R_MOVE_DEST, MERRDEST, found, num_ok);
1081 else
1082 mputm(md, R_MOVE_DEST, MOK, "", num_ok);
1083 }
1084
1085 /*
1086 * reqpath
1087 */
1088
1089 static char *
reqpath(char * file,char ** idnumber)1090 reqpath(char *file, char **idnumber)
1091 {
1092 char *path;
1093 char *cp;
1094 char *cp2;
1095
1096 /*
1097 * /var/spool/lp/tmp/machine/123-0
1098 * /var/spool/lp/temp/123-0
1099 * /usr/spool/lp/temp/123-0
1100 * /usr/spool/lp/tmp/machine/123-0
1101 * 123-0
1102 * machine/123-0
1103 *
1104 * /var/spool/lp/tmp/machine/123-0 + 123
1105 */
1106 if (*file == '/') {
1107 /*CONSTCOND*/
1108 if (STRNEQU(file, Lp_Spooldir, strlen(Lp_Spooldir)))
1109 cp = file + strlen(Lp_Spooldir) + 1;
1110 else {
1111 if (STRNEQU(file, "/usr/spool/lp", 13))
1112 cp = file + strlen("/usr/spool/lp") + 1;
1113 else {
1114 *idnumber = NULL;
1115 return (NULL);
1116 }
1117 }
1118
1119 if (STRNEQU(cp, "temp", 4)) {
1120 cp += 5;
1121 path = makepath(Local_System, cp, NULL);
1122 }
1123 else
1124 path = Strdup(cp);
1125 }
1126 else
1127 {
1128 if (strchr(file, '/'))
1129 path = makepath(file, NULL);
1130 else
1131 path = makepath(Local_System, file, NULL);
1132 }
1133
1134 cp = strrchr(path, '/');
1135 cp++;
1136 if ((cp2 = strrchr(cp, '-')) == NULL)
1137 *idnumber = Strdup(cp);
1138 else
1139 {
1140 *cp2 = '\0';
1141 *idnumber = Strdup(cp);
1142 *cp2 = '-';
1143 }
1144
1145 return (path);
1146 }
1147
1148 /*
1149 * The client is sending a peer connection to retrieve label information
1150 * from. This is used in the event that the client is an intermediary for
1151 * the actual requestor in a Trusted environment.
1152 */
1153 void
s_pass_peer_connection(char * m,MESG * md)1154 s_pass_peer_connection(char *m, MESG *md)
1155 {
1156 short status = MTRANSMITERR;
1157 char *dest;
1158 struct strrecvfd recv_fd;
1159
1160 (void) getmessage(m, S_PASS_PEER_CONNECTION);
1161 syslog(LOG_DEBUG, "s_pass_peer_connection()");
1162
1163 memset(&recv_fd, NULL, sizeof (recv_fd));
1164 if (ioctl(md->readfd, I_RECVFD, &recv_fd) == 0) {
1165 int fd = recv_fd.fd;
1166
1167 if (get_peer_label(fd, &md->slabel) == 0) {
1168 if (md->admin == 1)
1169 md->admin = -1; /* turn off query privilege */
1170 status = MOK;
1171 }
1172
1173 close(fd);
1174 }
1175
1176 mputm(md, R_PASS_PEER_CONNECTION, status);
1177 }
1178