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