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