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 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 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 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 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 * 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 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 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 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 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 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 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 * 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 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