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