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