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