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