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