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