1/* 2 Unix SMB/Netbios implementation. 3 Version 3.0 4 printing backend routines 5 Copyright (C) Andrew Tridgell 1992-2000 6 Copyright (C) Jeremy Allison 2002 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21*/ 22 23#include "includes.h" 24#include "printing.h" 25 26extern SIG_ATOMIC_T got_sig_term; 27extern SIG_ATOMIC_T reload_after_sighup; 28 29/* Current printer interface */ 30static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid); 31 32/* 33 the printing backend revolves around a tdb database that stores the 34 SMB view of the print queue 35 36 The key for this database is a jobid - a internally generated number that 37 uniquely identifies a print job 38 39 reading the print queue involves two steps: 40 - possibly running lpq and updating the internal database from that 41 - reading entries from the database 42 43 jobids are assigned when a job starts spooling. 44*/ 45 46struct print_queue_update_context { 47 char* sharename; 48 enum printing_types printing_type; 49 char* lpqcommand; 50}; 51 52 53static TDB_CONTEXT *rap_tdb; 54static uint16 next_rap_jobid; 55struct rap_jobid_key { 56 fstring sharename; 57 uint32 jobid; 58}; 59 60/*************************************************************************** 61 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32 62 bit RPC jobids.... JRA. 63***************************************************************************/ 64 65uint16 pjobid_to_rap(const char* sharename, uint32 jobid) 66{ 67 uint16 rap_jobid; 68 TDB_DATA data, key; 69 struct rap_jobid_key jinfo; 70 71 DEBUG(10,("pjobid_to_rap: called.\n")); 72 73 if (!rap_tdb) { 74 /* Create the in-memory tdb. */ 75 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644); 76 if (!rap_tdb) 77 return 0; 78 } 79 80 ZERO_STRUCT( jinfo ); 81 fstrcpy( jinfo.sharename, sharename ); 82 jinfo.jobid = jobid; 83 key.dptr = (char*)&jinfo; 84 key.dsize = sizeof(jinfo); 85 86 data = tdb_fetch(rap_tdb, key); 87 if (data.dptr && data.dsize == sizeof(uint16)) { 88 rap_jobid = SVAL(data.dptr, 0); 89 SAFE_FREE(data.dptr); 90 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n", 91 (unsigned int)jobid, (unsigned int)rap_jobid)); 92 return rap_jobid; 93 } 94 SAFE_FREE(data.dptr); 95 /* Not found - create and store mapping. */ 96 rap_jobid = ++next_rap_jobid; 97 if (rap_jobid == 0) 98 rap_jobid = ++next_rap_jobid; 99 data.dptr = (char *)&rap_jobid; 100 data.dsize = sizeof(rap_jobid); 101 tdb_store(rap_tdb, key, data, TDB_REPLACE); 102 tdb_store(rap_tdb, data, key, TDB_REPLACE); 103 104 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n", 105 (unsigned int)jobid, (unsigned int)rap_jobid)); 106 return rap_jobid; 107} 108 109BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid) 110{ 111 TDB_DATA data, key; 112 113 DEBUG(10,("rap_to_pjobid called.\n")); 114 115 if (!rap_tdb) 116 return False; 117 118 key.dptr = (char *)&rap_jobid; 119 key.dsize = sizeof(rap_jobid); 120 data = tdb_fetch(rap_tdb, key); 121 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) 122 { 123 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr; 124 fstrcpy( sharename, jinfo->sharename ); 125 *pjobid = jinfo->jobid; 126 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n", 127 (unsigned int)*pjobid, (unsigned int)rap_jobid)); 128 SAFE_FREE(data.dptr); 129 return True; 130 } 131 132 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n", 133 (unsigned int)rap_jobid)); 134 SAFE_FREE(data.dptr); 135 return False; 136} 137 138static void rap_jobid_delete(const char* sharename, uint32 jobid) 139{ 140 TDB_DATA key, data; 141 uint16 rap_jobid; 142 struct rap_jobid_key jinfo; 143 144 DEBUG(10,("rap_jobid_delete: called.\n")); 145 146 if (!rap_tdb) 147 return; 148 149 ZERO_STRUCT( jinfo ); 150 fstrcpy( jinfo.sharename, sharename ); 151 jinfo.jobid = jobid; 152 key.dptr = (char*)&jinfo; 153 key.dsize = sizeof(jinfo); 154 155 data = tdb_fetch(rap_tdb, key); 156 if (!data.dptr || (data.dsize != sizeof(uint16))) { 157 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n", 158 (unsigned int)jobid )); 159 SAFE_FREE(data.dptr); 160 return; 161 } 162 163 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n", 164 (unsigned int)jobid )); 165 166 rap_jobid = SVAL(data.dptr, 0); 167 SAFE_FREE(data.dptr); 168 data.dptr = (char *)&rap_jobid; 169 data.dsize = sizeof(rap_jobid); 170 tdb_delete(rap_tdb, key); 171 tdb_delete(rap_tdb, data); 172} 173 174static int get_queue_status(const char* sharename, print_status_struct *); 175 176/**************************************************************************** 177 Initialise the printing backend. Called once at startup before the fork(). 178****************************************************************************/ 179 180BOOL print_backend_init(void) 181{ 182 const char *sversion = "INFO/version"; 183 pstring printing_path; 184 int services = lp_numservices(); 185 int snum; 186 187 unlink(lock_path("printing.tdb")); 188 pstrcpy(printing_path,lock_path("printing")); 189 mkdir(printing_path,0755); 190 191 /* handle a Samba upgrade */ 192 193 for (snum = 0; snum < services; snum++) { 194 struct tdb_print_db *pdb; 195 if (!lp_print_ok(snum)) 196 continue; 197 198 pdb = get_print_db_byname(lp_const_servicename(snum)); 199 if (!pdb) 200 continue; 201 if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) { 202 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) )); 203 release_print_db(pdb); 204 return False; 205 } 206 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) { 207 tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL); 208 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION); 209 } 210 tdb_unlock_bystring(pdb->tdb, sversion); 211 release_print_db(pdb); 212 } 213 214 close_all_print_db(); /* Don't leave any open. */ 215 216 /* do NT print initialization... */ 217 return nt_printing_init(); 218} 219 220/**************************************************************************** 221 Shut down printing backend. Called once at shutdown to close the tdb. 222****************************************************************************/ 223 224void printing_end(void) 225{ 226 close_all_print_db(); /* Don't leave any open. */ 227} 228 229/**************************************************************************** 230 Retrieve the set of printing functions for a given service. This allows 231 us to set the printer function table based on the value of the 'printing' 232 service parameter. 233 234 Use the generic interface as the default and only use cups interface only 235 when asked for (and only when supported) 236****************************************************************************/ 237 238static struct printif *get_printer_fns_from_type( enum printing_types type ) 239{ 240 struct printif *printer_fns = &generic_printif; 241 242#ifdef HAVE_CUPS 243 if ( type == PRINT_CUPS ) { 244 printer_fns = &cups_printif; 245 } 246#endif /* HAVE_CUPS */ 247 248 printer_fns->type = type; 249 250 return printer_fns; 251} 252 253static struct printif *get_printer_fns( int snum ) 254{ 255 return get_printer_fns_from_type( lp_printing(snum) ); 256} 257 258 259/**************************************************************************** 260 Useful function to generate a tdb key. 261****************************************************************************/ 262 263static TDB_DATA print_key(uint32 jobid) 264{ 265 static uint32 j; 266 TDB_DATA ret; 267 268 SIVAL(&j, 0, jobid); 269 ret.dptr = (void *)&j; 270 ret.dsize = sizeof(j); 271 return ret; 272} 273 274/*********************************************************************** 275 unpack a pjob from a tdb buffer 276***********************************************************************/ 277 278int unpack_pjob( char* buf, int buflen, struct printjob *pjob ) 279{ 280 int len = 0; 281 int used; 282 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus; 283 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob; 284 285 if ( !buf || !pjob ) 286 return -1; 287 288 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff", 289 &pjpid, 290 &pjsysjob, 291 &pjfd, 292 &pjstarttime, 293 &pjstatus, 294 &pjsize, 295 &pjpage_count, 296 &pjspooled, 297 &pjsmbjob, 298 pjob->filename, 299 pjob->jobname, 300 pjob->user, 301 pjob->queuename); 302 303 if ( len == -1 ) 304 return -1; 305 306 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 ) 307 return -1; 308 309 len += used; 310 311 pjob->pid = pjpid; 312 pjob->sysjob = pjsysjob; 313 pjob->fd = pjfd; 314 pjob->starttime = pjstarttime; 315 pjob->status = pjstatus; 316 pjob->size = pjsize; 317 pjob->page_count = pjpage_count; 318 pjob->spooled = pjspooled; 319 pjob->smbjob = pjsmbjob; 320 321 return len; 322 323} 324 325/**************************************************************************** 326 Useful function to find a print job in the database. 327****************************************************************************/ 328 329static struct printjob *print_job_find(const char *sharename, uint32 jobid) 330{ 331 static struct printjob pjob; 332 TDB_DATA ret; 333 struct tdb_print_db *pdb = get_print_db_byname(sharename); 334 335 336 if (!pdb) 337 return NULL; 338 339 ret = tdb_fetch(pdb->tdb, print_key(jobid)); 340 release_print_db(pdb); 341 342 if (!ret.dptr) 343 return NULL; 344 345 if ( pjob.nt_devmode ) 346 free_nt_devicemode( &pjob.nt_devmode ); 347 348 ZERO_STRUCT( pjob ); 349 350 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) { 351 SAFE_FREE(ret.dptr); 352 return NULL; 353 } 354 355 SAFE_FREE(ret.dptr); 356 return &pjob; 357} 358 359/* Convert a unix jobid to a smb jobid */ 360 361static uint32 sysjob_to_jobid_value; 362 363static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, 364 TDB_DATA data, void *state) 365{ 366 struct printjob *pjob; 367 int *sysjob = (int *)state; 368 369 if (!data.dptr || data.dsize == 0) 370 return 0; 371 372 pjob = (struct printjob *)data.dptr; 373 if (key.dsize != sizeof(uint32)) 374 return 0; 375 376 if (*sysjob == pjob->sysjob) { 377 uint32 jobid = IVAL(key.dptr,0); 378 379 sysjob_to_jobid_value = jobid; 380 return 1; 381 } 382 383 return 0; 384} 385 386/**************************************************************************** 387 This is a *horribly expensive call as we have to iterate through all the 388 current printer tdb's. Don't do this often ! JRA. 389****************************************************************************/ 390 391uint32 sysjob_to_jobid(int unix_jobid) 392{ 393 int services = lp_numservices(); 394 int snum; 395 396 sysjob_to_jobid_value = (uint32)-1; 397 398 for (snum = 0; snum < services; snum++) { 399 struct tdb_print_db *pdb; 400 if (!lp_print_ok(snum)) 401 continue; 402 pdb = get_print_db_byname(lp_const_servicename(snum)); 403 if (pdb) 404 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid); 405 release_print_db(pdb); 406 if (sysjob_to_jobid_value != (uint32)-1) 407 return sysjob_to_jobid_value; 408 } 409 return (uint32)-1; 410} 411 412/**************************************************************************** 413 Send notifications based on what has changed after a pjob_store. 414****************************************************************************/ 415 416static struct { 417 uint32 lpq_status; 418 uint32 spoolss_status; 419} lpq_to_spoolss_status_map[] = { 420 { LPQ_QUEUED, JOB_STATUS_QUEUED }, 421 { LPQ_PAUSED, JOB_STATUS_PAUSED }, 422 { LPQ_SPOOLING, JOB_STATUS_SPOOLING }, 423 { LPQ_PRINTING, JOB_STATUS_PRINTING }, 424 { LPQ_DELETING, JOB_STATUS_DELETING }, 425 { LPQ_OFFLINE, JOB_STATUS_OFFLINE }, 426 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT }, 427 { LPQ_PRINTED, JOB_STATUS_PRINTED }, 428 { LPQ_DELETED, JOB_STATUS_DELETED }, 429 { LPQ_BLOCKED, JOB_STATUS_BLOCKED }, 430 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION }, 431 { -1, 0 } 432}; 433 434/* Convert a lpq status value stored in printing.tdb into the 435 appropriate win32 API constant. */ 436 437static uint32 map_to_spoolss_status(uint32 lpq_status) 438{ 439 int i = 0; 440 441 while (lpq_to_spoolss_status_map[i].lpq_status != -1) { 442 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status) 443 return lpq_to_spoolss_status_map[i].spoolss_status; 444 i++; 445 } 446 447 return 0; 448} 449 450static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data, 451 struct printjob *new_data) 452{ 453 BOOL new_job = False; 454 455 if (!old_data) 456 new_job = True; 457 458 /* Job attributes that can't be changed. We only send 459 notification for these on a new job. */ 460 461 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the 462 NOTIFY_INFO_DATA buffer, we *have* to send the job submission 463 time first or else we'll end up with potential alignment 464 errors. I don't think the systemtime should be spooled as 465 a string, but this gets us around that error. 466 --jerry (i'll feel dirty for this) */ 467 468 if (new_job) { 469 notify_job_submitted(sharename, jobid, new_data->starttime); 470 notify_job_username(sharename, jobid, new_data->user); 471 } 472 473 if (new_job || !strequal(old_data->jobname, new_data->jobname)) 474 notify_job_name(sharename, jobid, new_data->jobname); 475 476 /* Job attributes of a new job or attributes that can be 477 modified. */ 478 479 if (new_job || !strequal(old_data->jobname, new_data->jobname)) 480 notify_job_name(sharename, jobid, new_data->jobname); 481 482 if (new_job || old_data->status != new_data->status) 483 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status)); 484 485 if (new_job || old_data->size != new_data->size) 486 notify_job_total_bytes(sharename, jobid, new_data->size); 487 488 if (new_job || old_data->page_count != new_data->page_count) 489 notify_job_total_pages(sharename, jobid, new_data->page_count); 490} 491 492/**************************************************************************** 493 Store a job structure back to the database. 494****************************************************************************/ 495 496static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob) 497{ 498 TDB_DATA old_data, new_data; 499 BOOL ret = False; 500 struct tdb_print_db *pdb = get_print_db_byname(sharename); 501 char *buf = NULL; 502 int len, newlen, buflen; 503 504 505 if (!pdb) 506 return False; 507 508 /* Get old data */ 509 510 old_data = tdb_fetch(pdb->tdb, print_key(jobid)); 511 512 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */ 513 514 newlen = 0; 515 516 do { 517 len = 0; 518 buflen = newlen; 519 len += tdb_pack(buf+len, buflen-len, "dddddddddffff", 520 (uint32)pjob->pid, 521 (uint32)pjob->sysjob, 522 (uint32)pjob->fd, 523 (uint32)pjob->starttime, 524 (uint32)pjob->status, 525 (uint32)pjob->size, 526 (uint32)pjob->page_count, 527 (uint32)pjob->spooled, 528 (uint32)pjob->smbjob, 529 pjob->filename, 530 pjob->jobname, 531 pjob->user, 532 pjob->queuename); 533 534 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len); 535 536 if (buflen != len) { 537 char *tb; 538 539 tb = (char *)SMB_REALLOC(buf, len); 540 if (!tb) { 541 DEBUG(0,("pjob_store: failed to enlarge buffer!\n")); 542 goto done; 543 } 544 else 545 buf = tb; 546 newlen = len; 547 } 548 } while ( buflen != len ); 549 550 551 /* Store new data */ 552 553 new_data.dptr = buf; 554 new_data.dsize = len; 555 ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0); 556 557 release_print_db(pdb); 558 559 /* Send notify updates for what has changed */ 560 561 if ( ret ) { 562 struct printjob old_pjob; 563 564 if ( old_data.dsize ) 565 { 566 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 ) 567 { 568 pjob_store_notify( sharename, jobid, &old_pjob , pjob ); 569 free_nt_devicemode( &old_pjob.nt_devmode ); 570 } 571 } 572 else { 573 /* new job */ 574 pjob_store_notify( sharename, jobid, NULL, pjob ); 575 } 576 } 577 578done: 579 SAFE_FREE( old_data.dptr ); 580 SAFE_FREE( buf ); 581 582 return ret; 583} 584 585/**************************************************************************** 586 Remove a job structure from the database. 587****************************************************************************/ 588 589void pjob_delete(const char* sharename, uint32 jobid) 590{ 591 struct printjob *pjob; 592 uint32 job_status = 0; 593 struct tdb_print_db *pdb; 594 595 pdb = get_print_db_byname( sharename ); 596 597 if (!pdb) 598 return; 599 600 pjob = print_job_find( sharename, jobid ); 601 602 if (!pjob) { 603 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n", 604 (unsigned int)jobid)); 605 release_print_db(pdb); 606 return; 607 } 608 609 /* We must cycle through JOB_STATUS_DELETING and 610 JOB_STATUS_DELETED for the port monitor to delete the job 611 properly. */ 612 613 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED; 614 notify_job_status(sharename, jobid, job_status); 615 616 /* Remove from printing.tdb */ 617 618 tdb_delete(pdb->tdb, print_key(jobid)); 619 remove_from_jobs_changed(sharename, jobid); 620 release_print_db( pdb ); 621 rap_jobid_delete(sharename, jobid); 622} 623 624/**************************************************************************** 625 Parse a file name from the system spooler to generate a jobid. 626****************************************************************************/ 627 628static uint32 print_parse_jobid(char *fname) 629{ 630 int jobid; 631 632 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) 633 return (uint32)-1; 634 fname += strlen(PRINT_SPOOL_PREFIX); 635 636 jobid = atoi(fname); 637 if (jobid <= 0) 638 return (uint32)-1; 639 640 return (uint32)jobid; 641} 642 643/**************************************************************************** 644 List a unix job in the print database. 645****************************************************************************/ 646 647static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid) 648{ 649 struct printjob pj, *old_pj; 650 651 if (jobid == (uint32)-1) 652 jobid = q->job + UNIX_JOB_START; 653 654 /* Preserve the timestamp on an existing unix print job */ 655 656 old_pj = print_job_find(sharename, jobid); 657 658 ZERO_STRUCT(pj); 659 660 pj.pid = (pid_t)-1; 661 pj.sysjob = q->job; 662 pj.fd = -1; 663 pj.starttime = old_pj ? old_pj->starttime : q->time; 664 pj.status = q->status; 665 pj.size = q->size; 666 pj.spooled = True; 667 fstrcpy(pj.filename, old_pj ? old_pj->filename : ""); 668 if (jobid < UNIX_JOB_START) { 669 pj.smbjob = True; 670 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document"); 671 } else { 672 pj.smbjob = False; 673 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file); 674 } 675 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user); 676 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename ); 677 678 pjob_store(sharename, jobid, &pj); 679} 680 681 682struct traverse_struct { 683 print_queue_struct *queue; 684 int qcount, snum, maxcount, total_jobs; 685 const char *sharename; 686 time_t lpq_time; 687}; 688 689/**************************************************************************** 690 Utility fn to delete any jobs that are no longer active. 691****************************************************************************/ 692 693static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) 694{ 695 struct traverse_struct *ts = (struct traverse_struct *)state; 696 struct printjob pjob; 697 uint32 jobid; 698 int i = 0; 699 700 if ( key.dsize != sizeof(jobid) ) 701 return 0; 702 703 jobid = IVAL(key.dptr, 0); 704 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) 705 return 0; 706 free_nt_devicemode( &pjob.nt_devmode ); 707 708 709 if (!pjob.smbjob) { 710 /* remove a unix job if it isn't in the system queue any more */ 711 712 for (i=0;i<ts->qcount;i++) { 713 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START); 714 if (jobid == u_jobid) 715 break; 716 } 717 if (i == ts->qcount) { 718 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n", 719 (unsigned int)jobid )); 720 pjob_delete(ts->sharename, jobid); 721 return 0; 722 } 723 724 /* need to continue the the bottom of the function to 725 save the correct attributes */ 726 } 727 728 /* maybe it hasn't been spooled yet */ 729 if (!pjob.spooled) { 730 /* if a job is not spooled and the process doesn't 731 exist then kill it. This cleans up after smbd 732 deaths */ 733 if (!process_exists(pjob.pid)) { 734 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n", 735 (unsigned int)jobid, (unsigned int)pjob.pid )); 736 pjob_delete(ts->sharename, jobid); 737 } else 738 ts->total_jobs++; 739 return 0; 740 } 741 742 /* this check only makes sense for jobs submitted from Windows clients */ 743 744 if ( pjob.smbjob ) { 745 for (i=0;i<ts->qcount;i++) { 746 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file); 747 if (jobid == curr_jobid) 748 break; 749 } 750 } 751 752 /* The job isn't in the system queue - we have to assume it has 753 completed, so delete the database entry. */ 754 755 if (i == ts->qcount) { 756 757 /* A race can occur between the time a job is spooled and 758 when it appears in the lpq output. This happens when 759 the job is added to printing.tdb when another smbd 760 running print_queue_update() has completed a lpq and 761 is currently traversing the printing tdb and deleting jobs. 762 Don't delete the job if it was submitted after the lpq_time. */ 763 764 if (pjob.starttime < ts->lpq_time) { 765 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n", 766 (unsigned int)jobid, 767 (unsigned int)pjob.starttime, 768 (unsigned int)ts->lpq_time )); 769 pjob_delete(ts->sharename, jobid); 770 } else 771 ts->total_jobs++; 772 return 0; 773 } 774 775 /* Save the pjob attributes we will store. */ 776 /* FIXME!!! This is the only place where queue->job 777 represents the SMB jobid --jerry */ 778 ts->queue[i].job = jobid; 779 ts->queue[i].size = pjob.size; 780 ts->queue[i].page_count = pjob.page_count; 781 ts->queue[i].status = pjob.status; 782 ts->queue[i].priority = 1; 783 ts->queue[i].time = pjob.starttime; 784 fstrcpy(ts->queue[i].fs_user, pjob.user); 785 fstrcpy(ts->queue[i].fs_file, pjob.jobname); 786 787 ts->total_jobs++; 788 789 return 0; 790} 791 792/**************************************************************************** 793 Check if the print queue has been updated recently enough. 794****************************************************************************/ 795 796static void print_cache_flush(int snum) 797{ 798 fstring key; 799 const char *sharename = lp_const_servicename(snum); 800 struct tdb_print_db *pdb = get_print_db_byname(sharename); 801 802 if (!pdb) 803 return; 804 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename); 805 tdb_store_int32(pdb->tdb, key, -1); 806 release_print_db(pdb); 807} 808 809/**************************************************************************** 810 Check if someone already thinks they are doing the update. 811****************************************************************************/ 812 813static pid_t get_updating_pid(const char *sharename) 814{ 815 fstring keystr; 816 TDB_DATA data, key; 817 pid_t updating_pid; 818 struct tdb_print_db *pdb = get_print_db_byname(sharename); 819 820 if (!pdb) 821 return (pid_t)-1; 822 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename); 823 key.dptr = keystr; 824 key.dsize = strlen(keystr); 825 826 data = tdb_fetch(pdb->tdb, key); 827 release_print_db(pdb); 828 if (!data.dptr || data.dsize != sizeof(pid_t)) { 829 SAFE_FREE(data.dptr); 830 return (pid_t)-1; 831 } 832 833 updating_pid = IVAL(data.dptr, 0); 834 SAFE_FREE(data.dptr); 835 836 if (process_exists(updating_pid)) 837 return updating_pid; 838 839 return (pid_t)-1; 840} 841 842/**************************************************************************** 843 Set the fact that we're doing the update, or have finished doing the update 844 in the tdb. 845****************************************************************************/ 846 847static void set_updating_pid(const fstring sharename, BOOL updating) 848{ 849 fstring keystr; 850 TDB_DATA key; 851 TDB_DATA data; 852 pid_t updating_pid = sys_getpid(); 853 uint8 buffer[4]; 854 855 struct tdb_print_db *pdb = get_print_db_byname(sharename); 856 857 if (!pdb) 858 return; 859 860 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename); 861 key.dptr = keystr; 862 key.dsize = strlen(keystr); 863 864 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n", 865 updating ? "" : "not ", 866 sharename )); 867 868 if ( !updating ) { 869 tdb_delete(pdb->tdb, key); 870 release_print_db(pdb); 871 return; 872 } 873 874 SIVAL( buffer, 0, updating_pid); 875 data.dptr = (void *)buffer; 876 data.dsize = 4; /* we always assume this is a 4 byte value */ 877 878 tdb_store(pdb->tdb, key, data, TDB_REPLACE); 879 release_print_db(pdb); 880} 881 882/**************************************************************************** 883 Sort print jobs by submittal time. 884****************************************************************************/ 885 886static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2) 887{ 888 /* Silly cases */ 889 890 if (!j1 && !j2) 891 return 0; 892 if (!j1) 893 return -1; 894 if (!j2) 895 return 1; 896 897 /* Sort on job start time */ 898 899 if (j1->time == j2->time) 900 return 0; 901 return (j1->time > j2->time) ? 1 : -1; 902} 903 904/**************************************************************************** 905 Store the sorted queue representation for later portmon retrieval. 906****************************************************************************/ 907 908static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts) 909{ 910 TDB_DATA data, key; 911 int max_reported_jobs = lp_max_reported_jobs(pts->snum); 912 print_queue_struct *queue = pts->queue; 913 size_t len; 914 size_t i; 915 uint qcount; 916 917 if (max_reported_jobs && (max_reported_jobs < pts->qcount)) 918 pts->qcount = max_reported_jobs; 919 qcount = pts->qcount; 920 921 /* Work out the size. */ 922 data.dsize = 0; 923 data.dsize += tdb_pack(NULL, 0, "d", qcount); 924 925 for (i = 0; i < pts->qcount; i++) { 926 data.dsize += tdb_pack(NULL, 0, "ddddddff", 927 (uint32)queue[i].job, 928 (uint32)queue[i].size, 929 (uint32)queue[i].page_count, 930 (uint32)queue[i].status, 931 (uint32)queue[i].priority, 932 (uint32)queue[i].time, 933 queue[i].fs_user, 934 queue[i].fs_file); 935 } 936 937 if ((data.dptr = SMB_MALLOC(data.dsize)) == NULL) 938 return; 939 940 len = 0; 941 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount); 942 for (i = 0; i < pts->qcount; i++) { 943 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff", 944 (uint32)queue[i].job, 945 (uint32)queue[i].size, 946 (uint32)queue[i].page_count, 947 (uint32)queue[i].status, 948 (uint32)queue[i].priority, 949 (uint32)queue[i].time, 950 queue[i].fs_user, 951 queue[i].fs_file); 952 } 953 954 key.dptr = "INFO/linear_queue_array"; 955 key.dsize = strlen(key.dptr); 956 tdb_store(pdb->tdb, key, data, TDB_REPLACE); 957 SAFE_FREE(data.dptr); 958 return; 959} 960 961static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb) 962{ 963 TDB_DATA data, key; 964 965 key.dptr = "INFO/jobs_changed"; 966 key.dsize = strlen(key.dptr); 967 ZERO_STRUCT(data); 968 969 data = tdb_fetch(pdb->tdb, key); 970 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) { 971 SAFE_FREE(data.dptr); 972 ZERO_STRUCT(data); 973 } 974 975 return data; 976} 977 978static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid) 979{ 980 unsigned int i; 981 unsigned int job_count = data.dsize / 4; 982 983 for (i = 0; i < job_count; i++) { 984 uint32 ch_jobid; 985 986 ch_jobid = IVAL(data.dptr, i*4); 987 if (ch_jobid == jobid) 988 remove_from_jobs_changed(sharename, jobid); 989 } 990} 991 992/**************************************************************************** 993 Check if the print queue has been updated recently enough. 994****************************************************************************/ 995 996static BOOL print_cache_expired(const char *sharename, BOOL check_pending) 997{ 998 fstring key; 999 time_t last_qscan_time, time_now = time(NULL); 1000 struct tdb_print_db *pdb = get_print_db_byname(sharename); 1001 BOOL result = False; 1002 1003 if (!pdb) 1004 return False; 1005 1006 snprintf(key, sizeof(key), "CACHE/%s", sharename); 1007 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key); 1008 1009 /* 1010 * Invalidate the queue for 3 reasons. 1011 * (1). last queue scan time == -1. 1012 * (2). Current time - last queue scan time > allowed cache time. 1013 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default). 1014 * This last test picks up machines for which the clock has been moved 1015 * forward, an lpq scan done and then the clock moved back. Otherwise 1016 * that last lpq scan would stay around for a loooong loooong time... :-). JRA. 1017 */ 1018 1019 if (last_qscan_time == ((time_t)-1) 1020 || (time_now - last_qscan_time) >= lp_lpqcachetime() 1021 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) 1022 { 1023 time_t msg_pending_time; 1024 1025 DEBUG(4, ("print_cache_expired: cache expired for queue %s " 1026 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", 1027 sharename, (int)last_qscan_time, (int)time_now, 1028 (int)lp_lpqcachetime() )); 1029 1030 /* check if another smbd has already sent a message to update the 1031 queue. Give the pending message one minute to clear and 1032 then send another message anyways. Make sure to check for 1033 clocks that have been run forward and then back again. */ 1034 1035 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename); 1036 1037 if ( check_pending 1038 && tdb_fetch_uint32( pdb->tdb, key, &msg_pending_time ) 1039 && msg_pending_time > 0 1040 && msg_pending_time <= time_now 1041 && (time_now - msg_pending_time) < 60 ) 1042 { 1043 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n", 1044 sharename)); 1045 goto done; 1046 } 1047 1048 result = True; 1049 } 1050 1051done: 1052 release_print_db(pdb); 1053 return result; 1054} 1055 1056/**************************************************************************** 1057 main work for updating the lpq cahe for a printer queue 1058****************************************************************************/ 1059 1060static void print_queue_update_internal( const char *sharename, 1061 struct printif *current_printif, 1062 char *lpq_command ) 1063{ 1064 int i, qcount; 1065 print_queue_struct *queue = NULL; 1066 print_status_struct status; 1067 print_status_struct old_status; 1068 struct printjob *pjob; 1069 struct traverse_struct tstruct; 1070 TDB_DATA data, key; 1071 TDB_DATA jcdata; 1072 fstring keystr, cachestr; 1073 struct tdb_print_db *pdb = get_print_db_byname(sharename); 1074 1075 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n", 1076 sharename, current_printif->type, lpq_command)); 1077 1078 /* 1079 * Update the cache time FIRST ! Stops others even 1080 * attempting to get the lock and doing this 1081 * if the lpq takes a long time. 1082 */ 1083 1084 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename); 1085 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL)); 1086 1087 /* get the current queue using the appropriate interface */ 1088 ZERO_STRUCT(status); 1089 1090 qcount = (*(current_printif->queue_get))(sharename, 1091 current_printif->type, 1092 lpq_command, &queue, &status); 1093 1094 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n", 1095 qcount, (qcount != 1) ? "s" : "", sharename)); 1096 1097 /* Sort the queue by submission time otherwise they are displayed 1098 in hash order. */ 1099 1100 qsort(queue, qcount, sizeof(print_queue_struct), 1101 QSORT_CAST(printjob_comp)); 1102 1103 /* 1104 any job in the internal database that is marked as spooled 1105 and doesn't exist in the system queue is considered finished 1106 and removed from the database 1107 1108 any job in the system database but not in the internal database 1109 is added as a unix job 1110 1111 fill in any system job numbers as we go 1112 */ 1113 1114 jcdata = get_jobs_changed_data(pdb); 1115 1116 for (i=0; i<qcount; i++) { 1117 uint32 jobid = print_parse_jobid(queue[i].fs_file); 1118 1119 if (jobid == (uint32)-1) { 1120 /* assume its a unix print job */ 1121 print_unix_job(sharename, &queue[i], jobid); 1122 continue; 1123 } 1124 1125 /* we have an active SMB print job - update its status */ 1126 pjob = print_job_find(sharename, jobid); 1127 if (!pjob) { 1128 /* err, somethings wrong. Probably smbd was restarted 1129 with jobs in the queue. All we can do is treat them 1130 like unix jobs. Pity. */ 1131 print_unix_job(sharename, &queue[i], jobid); 1132 continue; 1133 } 1134 1135 pjob->sysjob = queue[i].job; 1136 pjob->status = queue[i].status; 1137 pjob_store(sharename, jobid, pjob); 1138 check_job_changed(sharename, jcdata, jobid); 1139 } 1140 1141 SAFE_FREE(jcdata.dptr); 1142 1143 /* now delete any queued entries that don't appear in the 1144 system queue */ 1145 tstruct.queue = queue; 1146 tstruct.qcount = qcount; 1147 tstruct.snum = -1; 1148 tstruct.total_jobs = 0; 1149 tstruct.lpq_time = time(NULL); 1150 tstruct.sharename = sharename; 1151 1152 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct); 1153 1154 /* Store the linearised queue, max jobs only. */ 1155 store_queue_struct(pdb, &tstruct); 1156 1157 SAFE_FREE(tstruct.queue); 1158 1159 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n", 1160 sharename, tstruct.total_jobs )); 1161 1162 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs); 1163 1164 get_queue_status(sharename, &old_status); 1165 if (old_status.qcount != qcount) 1166 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n", 1167 old_status.qcount, qcount, sharename)); 1168 1169 /* store the new queue status structure */ 1170 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename); 1171 key.dptr = keystr; 1172 key.dsize = strlen(keystr); 1173 1174 status.qcount = qcount; 1175 data.dptr = (void *)&status; 1176 data.dsize = sizeof(status); 1177 tdb_store(pdb->tdb, key, data, TDB_REPLACE); 1178 1179 /* 1180 * Update the cache time again. We want to do this call 1181 * as little as possible... 1182 */ 1183 1184 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename); 1185 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL)); 1186 1187 /* clear the msg pending record for this queue */ 1188 1189 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename); 1190 1191 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) { 1192 /* log a message but continue on */ 1193 1194 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n", 1195 sharename)); 1196 } 1197 1198 release_print_db( pdb ); 1199 1200 return; 1201} 1202 1203/**************************************************************************** 1204 Update the internal database from the system print queue for a queue. 1205 obtain a lock on the print queue before proceeding (needed when mutiple 1206 smbd processes maytry to update the lpq cache concurrently). 1207****************************************************************************/ 1208 1209static void print_queue_update_with_lock( const char *sharename, 1210 struct printif *current_printif, 1211 char *lpq_command ) 1212{ 1213 fstring keystr; 1214 struct tdb_print_db *pdb; 1215 1216 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename)); 1217 pdb = get_print_db_byname(sharename); 1218 if (!pdb) 1219 return; 1220 1221 if ( !print_cache_expired(sharename, False) ) { 1222 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename)); 1223 release_print_db(pdb); 1224 return; 1225 } 1226 1227 /* 1228 * Check to see if someone else is doing this update. 1229 * This is essentially a mutex on the update. 1230 */ 1231 1232 if (get_updating_pid(sharename) != -1) { 1233 release_print_db(pdb); 1234 return; 1235 } 1236 1237 /* Lock the queue for the database update */ 1238 1239 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename); 1240 /* Only wait 10 seconds for this. */ 1241 if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) { 1242 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename)); 1243 release_print_db(pdb); 1244 return; 1245 } 1246 1247 /* 1248 * Ensure that no one else got in here. 1249 * If the updating pid is still -1 then we are 1250 * the winner. 1251 */ 1252 1253 if (get_updating_pid(sharename) != -1) { 1254 /* 1255 * Someone else is doing the update, exit. 1256 */ 1257 tdb_unlock_bystring(pdb->tdb, keystr); 1258 release_print_db(pdb); 1259 return; 1260 } 1261 1262 /* 1263 * We're going to do the update ourselves. 1264 */ 1265 1266 /* Tell others we're doing the update. */ 1267 set_updating_pid(sharename, True); 1268 1269 /* 1270 * Allow others to enter and notice we're doing 1271 * the update. 1272 */ 1273 1274 tdb_unlock_bystring(pdb->tdb, keystr); 1275 1276 /* do the main work now */ 1277 1278 print_queue_update_internal( sharename, current_printif, lpq_command ); 1279 1280 /* Delete our pid from the db. */ 1281 set_updating_pid(sharename, False); 1282 release_print_db(pdb); 1283} 1284 1285/**************************************************************************** 1286this is the receive function of the background lpq updater 1287****************************************************************************/ 1288static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen) 1289{ 1290 struct print_queue_update_context ctx; 1291 fstring sharename; 1292 pstring lpqcommand; 1293 size_t len; 1294 1295 len = tdb_unpack( buf, msglen, "fdP", 1296 sharename, 1297 &ctx.printing_type, 1298 lpqcommand ); 1299 1300 if ( len == -1 ) { 1301 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n")); 1302 return; 1303 } 1304 1305 ctx.sharename = sharename; 1306 ctx.lpqcommand = lpqcommand; 1307 1308 print_queue_update_with_lock(ctx.sharename, 1309 get_printer_fns_from_type(ctx.printing_type), 1310 ctx.lpqcommand ); 1311 1312 return; 1313} 1314 1315static pid_t background_lpq_updater_pid = -1; 1316 1317/**************************************************************************** 1318main thread of the background lpq updater 1319****************************************************************************/ 1320void start_background_queue(void) 1321{ 1322 DEBUG(3,("start_background_queue: Starting background LPQ thread\n")); 1323 background_lpq_updater_pid = sys_fork(); 1324 1325 if (background_lpq_updater_pid == -1) { 1326 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) )); 1327 exit(1); 1328 } 1329 1330 if(background_lpq_updater_pid == 0) { 1331 /* Child. */ 1332 DEBUG(5,("start_background_queue: background LPQ thread started\n")); 1333 1334 claim_connection( NULL, "smbd lpq backend", 0, False, 1335 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); 1336 1337 if (!locking_init(0)) { 1338 exit(1); 1339 } 1340 1341 message_register(MSG_PRINTER_UPDATE, print_queue_receive); 1342 1343 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); 1344 while (1) { 1345 pause(); 1346 1347 /* check for some essential signals first */ 1348 1349 if (got_sig_term) { 1350 exit_server("Caught TERM signal"); 1351 } 1352 1353 if (reload_after_sighup) { 1354 change_to_root_user(); 1355 DEBUG(1,("Reloading services after SIGHUP\n")); 1356 reload_services(False); 1357 reload_after_sighup = 0; 1358 } 1359 1360 /* now check for messages */ 1361 1362 DEBUG(10,("start_background_queue: background LPQ thread got a message\n")); 1363 message_dispatch(); 1364 1365 /* process any pending print change notify messages */ 1366 1367 print_notify_send_messages(0); 1368 } 1369 } 1370} 1371 1372/**************************************************************************** 1373update the internal database from the system print queue for a queue 1374****************************************************************************/ 1375 1376static void print_queue_update(int snum, BOOL force) 1377{ 1378 fstring key; 1379 fstring sharename; 1380 pstring lpqcommand; 1381 char *buffer = NULL; 1382 size_t len = 0; 1383 size_t newlen; 1384 struct tdb_print_db *pdb; 1385 enum printing_types type; 1386 struct printif *current_printif; 1387 1388 fstrcpy( sharename, lp_const_servicename(snum)); 1389 1390 pstrcpy( lpqcommand, lp_lpqcommand(snum)); 1391 pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) ); 1392 standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) ); 1393 1394 /* 1395 * Make sure that the background queue process exists. 1396 * Otherwise just do the update ourselves 1397 */ 1398 1399 if ( force || background_lpq_updater_pid == -1 ) { 1400 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename)); 1401 current_printif = get_printer_fns( snum ); 1402 print_queue_update_with_lock( sharename, current_printif, lpqcommand ); 1403 1404 return; 1405 } 1406 1407 type = lp_printing(snum); 1408 1409 /* get the length */ 1410 1411 len = tdb_pack( buffer, len, "fdP", 1412 sharename, 1413 type, 1414 lpqcommand ); 1415 1416 buffer = SMB_XMALLOC_ARRAY( char, len ); 1417 1418 /* now pack the buffer */ 1419 newlen = tdb_pack( buffer, len, "fdP", 1420 sharename, 1421 type, 1422 lpqcommand ); 1423 1424 SMB_ASSERT( newlen == len ); 1425 1426 DEBUG(10,("print_queue_update: Sending message -> printer = %s, " 1427 "type = %d, lpq command = [%s]\n", sharename, type, lpqcommand )); 1428 1429 /* here we set a msg pending record for other smbd processes 1430 to throttle the number of duplicate print_queue_update msgs 1431 sent. */ 1432 1433 pdb = get_print_db_byname(sharename); 1434 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename); 1435 1436 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) { 1437 /* log a message but continue on */ 1438 1439 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n", 1440 sharename)); 1441 } 1442 1443 release_print_db( pdb ); 1444 1445 /* finally send the message */ 1446 1447 become_root(); 1448 message_send_pid(background_lpq_updater_pid, 1449 MSG_PRINTER_UPDATE, buffer, len, False); 1450 unbecome_root(); 1451 1452 SAFE_FREE( buffer ); 1453 1454 return; 1455} 1456 1457/**************************************************************************** 1458 Create/Update an entry in the print tdb that will allow us to send notify 1459 updates only to interested smbd's. 1460****************************************************************************/ 1461 1462BOOL print_notify_register_pid(int snum) 1463{ 1464 TDB_DATA data; 1465 struct tdb_print_db *pdb = NULL; 1466 TDB_CONTEXT *tdb = NULL; 1467 const char *printername; 1468 uint32 mypid = (uint32)sys_getpid(); 1469 BOOL ret = False; 1470 size_t i; 1471 1472 /* if (snum == -1), then the change notify request was 1473 on a print server handle and we need to register on 1474 all print queus */ 1475 1476 if (snum == -1) 1477 { 1478 int num_services = lp_numservices(); 1479 int idx; 1480 1481 for ( idx=0; idx<num_services; idx++ ) { 1482 if (lp_snum_ok(idx) && lp_print_ok(idx) ) 1483 print_notify_register_pid(idx); 1484 } 1485 1486 return True; 1487 } 1488 else /* register for a specific printer */ 1489 { 1490 printername = lp_const_servicename(snum); 1491 pdb = get_print_db_byname(printername); 1492 if (!pdb) 1493 return False; 1494 tdb = pdb->tdb; 1495 } 1496 1497 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { 1498 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n", 1499 printername)); 1500 if (pdb) 1501 release_print_db(pdb); 1502 return False; 1503 } 1504 1505 data = get_printer_notify_pid_list( tdb, printername, True ); 1506 1507 /* Add ourselves and increase the refcount. */ 1508 1509 for (i = 0; i < data.dsize; i += 8) { 1510 if (IVAL(data.dptr,i) == mypid) { 1511 uint32 new_refcount = IVAL(data.dptr, i+4) + 1; 1512 SIVAL(data.dptr, i+4, new_refcount); 1513 break; 1514 } 1515 } 1516 1517 if (i == data.dsize) { 1518 /* We weren't in the list. Realloc. */ 1519 data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8); 1520 if (!data.dptr) { 1521 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n", 1522 printername)); 1523 goto done; 1524 } 1525 data.dsize += 8; 1526 SIVAL(data.dptr,data.dsize - 8,mypid); 1527 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */ 1528 } 1529 1530 /* Store back the record. */ 1531 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { 1532 DEBUG(0,("print_notify_register_pid: Failed to update pid \ 1533list for printer %s\n", printername)); 1534 goto done; 1535 } 1536 1537 ret = True; 1538 1539 done: 1540 1541 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY); 1542 if (pdb) 1543 release_print_db(pdb); 1544 SAFE_FREE(data.dptr); 1545 return ret; 1546} 1547 1548/**************************************************************************** 1549 Update an entry in the print tdb that will allow us to send notify 1550 updates only to interested smbd's. 1551****************************************************************************/ 1552 1553BOOL print_notify_deregister_pid(int snum) 1554{ 1555 TDB_DATA data; 1556 struct tdb_print_db *pdb = NULL; 1557 TDB_CONTEXT *tdb = NULL; 1558 const char *printername; 1559 uint32 mypid = (uint32)sys_getpid(); 1560 size_t i; 1561 BOOL ret = False; 1562 1563 /* if ( snum == -1 ), we are deregister a print server handle 1564 which means to deregister on all print queues */ 1565 1566 if (snum == -1) 1567 { 1568 int num_services = lp_numservices(); 1569 int idx; 1570 1571 for ( idx=0; idx<num_services; idx++ ) { 1572 if ( lp_snum_ok(idx) && lp_print_ok(idx) ) 1573 print_notify_deregister_pid(idx); 1574 } 1575 1576 return True; 1577 } 1578 else /* deregister a specific printer */ 1579 { 1580 printername = lp_const_servicename(snum); 1581 pdb = get_print_db_byname(printername); 1582 if (!pdb) 1583 return False; 1584 tdb = pdb->tdb; 1585 } 1586 1587 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) { 1588 DEBUG(0,("print_notify_register_pid: Failed to lock \ 1589printer %s database\n", printername)); 1590 if (pdb) 1591 release_print_db(pdb); 1592 return False; 1593 } 1594 1595 data = get_printer_notify_pid_list( tdb, printername, True ); 1596 1597 /* Reduce refcount. Remove ourselves if zero. */ 1598 1599 for (i = 0; i < data.dsize; ) { 1600 if (IVAL(data.dptr,i) == mypid) { 1601 uint32 refcount = IVAL(data.dptr, i+4); 1602 1603 refcount--; 1604 1605 if (refcount == 0) { 1606 if (data.dsize - i > 8) 1607 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8); 1608 data.dsize -= 8; 1609 continue; 1610 } 1611 SIVAL(data.dptr, i+4, refcount); 1612 } 1613 1614 i += 8; 1615 } 1616 1617 if (data.dsize == 0) 1618 SAFE_FREE(data.dptr); 1619 1620 /* Store back the record. */ 1621 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) { 1622 DEBUG(0,("print_notify_register_pid: Failed to update pid \ 1623list for printer %s\n", printername)); 1624 goto done; 1625 } 1626 1627 ret = True; 1628 1629 done: 1630 1631 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY); 1632 if (pdb) 1633 release_print_db(pdb); 1634 SAFE_FREE(data.dptr); 1635 return ret; 1636} 1637 1638/**************************************************************************** 1639 Check if a jobid is valid. It is valid if it exists in the database. 1640****************************************************************************/ 1641 1642BOOL print_job_exists(const char* sharename, uint32 jobid) 1643{ 1644 struct tdb_print_db *pdb = get_print_db_byname(sharename); 1645 BOOL ret; 1646 1647 if (!pdb) 1648 return False; 1649 ret = tdb_exists(pdb->tdb, print_key(jobid)); 1650 release_print_db(pdb); 1651 return ret; 1652} 1653 1654/**************************************************************************** 1655 Give the fd used for a jobid. 1656****************************************************************************/ 1657 1658int print_job_fd(const char* sharename, uint32 jobid) 1659{ 1660 struct printjob *pjob = print_job_find(sharename, jobid); 1661 if (!pjob) 1662 return -1; 1663 /* don't allow another process to get this info - it is meaningless */ 1664 if (pjob->pid != sys_getpid()) 1665 return -1; 1666 return pjob->fd; 1667} 1668 1669/**************************************************************************** 1670 Give the filename used for a jobid. 1671 Only valid for the process doing the spooling and when the job 1672 has not been spooled. 1673****************************************************************************/ 1674 1675char *print_job_fname(const char* sharename, uint32 jobid) 1676{ 1677 struct printjob *pjob = print_job_find(sharename, jobid); 1678 if (!pjob || pjob->spooled || pjob->pid != sys_getpid()) 1679 return NULL; 1680 return pjob->filename; 1681} 1682 1683 1684/**************************************************************************** 1685 Give the filename used for a jobid. 1686 Only valid for the process doing the spooling and when the job 1687 has not been spooled. 1688****************************************************************************/ 1689 1690NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid) 1691{ 1692 struct printjob *pjob = print_job_find(sharename, jobid); 1693 1694 if ( !pjob ) 1695 return NULL; 1696 1697 return pjob->nt_devmode; 1698} 1699 1700/**************************************************************************** 1701 Set the place in the queue for a job. 1702****************************************************************************/ 1703 1704BOOL print_job_set_place(int snum, uint32 jobid, int place) 1705{ 1706 DEBUG(2,("print_job_set_place not implemented yet\n")); 1707 return False; 1708} 1709 1710/**************************************************************************** 1711 Set the name of a job. Only possible for owner. 1712****************************************************************************/ 1713 1714BOOL print_job_set_name(int snum, uint32 jobid, char *name) 1715{ 1716 const char* sharename = lp_const_servicename(snum); 1717 struct printjob *pjob; 1718 1719 pjob = print_job_find(sharename, jobid); 1720 if (!pjob || pjob->pid != sys_getpid()) 1721 return False; 1722 1723 fstrcpy(pjob->jobname, name); 1724 return pjob_store(sharename, jobid, pjob); 1725} 1726 1727/*************************************************************************** 1728 Remove a jobid from the 'jobs changed' list. 1729***************************************************************************/ 1730 1731static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid) 1732{ 1733 struct tdb_print_db *pdb = get_print_db_byname(sharename); 1734 TDB_DATA data, key; 1735 size_t job_count, i; 1736 BOOL ret = False; 1737 BOOL gotlock = False; 1738 1739 key.dptr = "INFO/jobs_changed"; 1740 key.dsize = strlen(key.dptr); 1741 ZERO_STRUCT(data); 1742 1743 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) 1744 goto out; 1745 1746 gotlock = True; 1747 1748 data = tdb_fetch(pdb->tdb, key); 1749 1750 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) 1751 goto out; 1752 1753 job_count = data.dsize / 4; 1754 for (i = 0; i < job_count; i++) { 1755 uint32 ch_jobid; 1756 1757 ch_jobid = IVAL(data.dptr, i*4); 1758 if (ch_jobid == jobid) { 1759 if (i < job_count -1 ) 1760 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 ); 1761 data.dsize -= 4; 1762 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1) 1763 goto out; 1764 break; 1765 } 1766 } 1767 1768 ret = True; 1769 out: 1770 1771 if (gotlock) 1772 tdb_chainunlock(pdb->tdb, key); 1773 SAFE_FREE(data.dptr); 1774 release_print_db(pdb); 1775 if (ret) 1776 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid )); 1777 else 1778 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid )); 1779 return ret; 1780} 1781 1782/**************************************************************************** 1783 Delete a print job - don't update queue. 1784****************************************************************************/ 1785 1786static BOOL print_job_delete1(int snum, uint32 jobid) 1787{ 1788 const char* sharename = lp_const_servicename(snum); 1789 struct printjob *pjob = print_job_find(sharename, jobid); 1790 int result = 0; 1791 struct printif *current_printif = get_printer_fns( snum ); 1792 1793 pjob = print_job_find(sharename, jobid); 1794 1795 if (!pjob) 1796 return False; 1797 1798 /* 1799 * If already deleting just return. 1800 */ 1801 1802 if (pjob->status == LPQ_DELETING) 1803 return True; 1804 1805 /* Hrm - we need to be able to cope with deleting a job before it 1806 has reached the spooler. */ 1807 1808 if (pjob->sysjob == -1) { 1809 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid)); 1810 } 1811 1812 /* Set the tdb entry to be deleting. */ 1813 1814 pjob->status = LPQ_DELETING; 1815 pjob_store(sharename, jobid, pjob); 1816 1817 if (pjob->spooled && pjob->sysjob != -1) 1818 result = (*(current_printif->job_delete))(snum, pjob); 1819 1820 /* Delete the tdb entry if the delete succeeded or the job hasn't 1821 been spooled. */ 1822 1823 if (result == 0) { 1824 struct tdb_print_db *pdb = get_print_db_byname(sharename); 1825 int njobs = 1; 1826 1827 if (!pdb) 1828 return False; 1829 pjob_delete(sharename, jobid); 1830 /* Ensure we keep a rough count of the number of total jobs... */ 1831 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1); 1832 release_print_db(pdb); 1833 } 1834 1835 return (result == 0); 1836} 1837 1838/**************************************************************************** 1839 Return true if the current user owns the print job. 1840****************************************************************************/ 1841 1842static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) 1843{ 1844 struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid); 1845 user_struct *vuser; 1846 1847 if (!pjob || !user) 1848 return False; 1849 1850 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { 1851 return strequal(pjob->user, vuser->user.smb_name); 1852 } else { 1853 return strequal(pjob->user, uidtoname(user->uid)); 1854 } 1855} 1856 1857/**************************************************************************** 1858 Delete a print job. 1859****************************************************************************/ 1860 1861BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) 1862{ 1863 const char* sharename = lp_const_servicename( snum ); 1864 BOOL owner, deleted; 1865 char *fname; 1866 1867 *errcode = WERR_OK; 1868 1869 owner = is_owner(user, snum, jobid); 1870 1871 /* Check access against security descriptor or whether the user 1872 owns their job. */ 1873 1874 if (!owner && 1875 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { 1876 DEBUG(3, ("delete denied by security descriptor\n")); 1877 *errcode = WERR_ACCESS_DENIED; 1878 1879 /* BEGIN_ADMIN_LOG */ 1880 sys_adminlog( LOG_ERR, 1881 "Permission denied-- user not allowed to delete, \ 1882pause, or resume print job. User name: %s. Printer name: %s.", 1883 uidtoname(user->uid), PRINTERNAME(snum) ); 1884 /* END_ADMIN_LOG */ 1885 1886 return False; 1887 } 1888 1889 /* 1890 * get the spooled filename of the print job 1891 * if this works, then the file has not been spooled 1892 * to the underlying print system. Just delete the 1893 * spool file & return. 1894 */ 1895 1896 if ( (fname = print_job_fname( sharename, jobid )) != NULL ) 1897 { 1898 /* remove the spool file */ 1899 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname )); 1900 if ( unlink( fname ) == -1 ) { 1901 *errcode = map_werror_from_unix(errno); 1902 return False; 1903 } 1904 } 1905 1906 if (!print_job_delete1(snum, jobid)) { 1907 *errcode = WERR_ACCESS_DENIED; 1908 return False; 1909 } 1910 1911 /* force update the database and say the delete failed if the 1912 job still exists */ 1913 1914 print_queue_update(snum, True); 1915 1916 deleted = !print_job_exists(sharename, jobid); 1917 if ( !deleted ) 1918 *errcode = WERR_ACCESS_DENIED; 1919 1920 return deleted; 1921} 1922 1923/**************************************************************************** 1924 Pause a job. 1925****************************************************************************/ 1926 1927BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) 1928{ 1929 const char* sharename = lp_const_servicename(snum); 1930 struct printjob *pjob; 1931 int ret = -1; 1932 struct printif *current_printif = get_printer_fns( snum ); 1933 1934 pjob = print_job_find(sharename, jobid); 1935 1936 if (!pjob || !user) 1937 return False; 1938 1939 if (!pjob->spooled || pjob->sysjob == -1) 1940 return False; 1941 1942 if (!is_owner(user, snum, jobid) && 1943 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { 1944 DEBUG(3, ("pause denied by security descriptor\n")); 1945 1946 /* BEGIN_ADMIN_LOG */ 1947 sys_adminlog( LOG_ERR, 1948 "Permission denied-- user not allowed to delete, \ 1949pause, or resume print job. User name: %s. Printer name: %s.", 1950 uidtoname(user->uid), PRINTERNAME(snum) ); 1951 /* END_ADMIN_LOG */ 1952 1953 *errcode = WERR_ACCESS_DENIED; 1954 return False; 1955 } 1956 1957 /* need to pause the spooled entry */ 1958 ret = (*(current_printif->job_pause))(snum, pjob); 1959 1960 if (ret != 0) { 1961 *errcode = WERR_INVALID_PARAM; 1962 return False; 1963 } 1964 1965 /* force update the database */ 1966 print_cache_flush(snum); 1967 1968 /* Send a printer notify message */ 1969 1970 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED); 1971 1972 /* how do we tell if this succeeded? */ 1973 1974 return True; 1975} 1976 1977/**************************************************************************** 1978 Resume a job. 1979****************************************************************************/ 1980 1981BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) 1982{ 1983 const char *sharename = lp_const_servicename(snum); 1984 struct printjob *pjob; 1985 int ret; 1986 struct printif *current_printif = get_printer_fns( snum ); 1987 1988 pjob = print_job_find(sharename, jobid); 1989 1990 if (!pjob || !user) 1991 return False; 1992 1993 if (!pjob->spooled || pjob->sysjob == -1) 1994 return False; 1995 1996 if (!is_owner(user, snum, jobid) && 1997 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { 1998 DEBUG(3, ("resume denied by security descriptor\n")); 1999 *errcode = WERR_ACCESS_DENIED; 2000 2001 /* BEGIN_ADMIN_LOG */ 2002 sys_adminlog( LOG_ERR, 2003 "Permission denied-- user not allowed to delete, \ 2004pause, or resume print job. User name: %s. Printer name: %s.", 2005 uidtoname(user->uid), PRINTERNAME(snum) ); 2006 /* END_ADMIN_LOG */ 2007 return False; 2008 } 2009 2010 ret = (*(current_printif->job_resume))(snum, pjob); 2011 2012 if (ret != 0) { 2013 *errcode = WERR_INVALID_PARAM; 2014 return False; 2015 } 2016 2017 /* force update the database */ 2018 print_cache_flush(snum); 2019 2020 /* Send a printer notify message */ 2021 2022 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED); 2023 2024 return True; 2025} 2026 2027/**************************************************************************** 2028 Write to a print file. 2029****************************************************************************/ 2030 2031int print_job_write(int snum, uint32 jobid, const char *buf, int size) 2032{ 2033 const char* sharename = lp_const_servicename(snum); 2034 int return_code; 2035 struct printjob *pjob; 2036 2037 pjob = print_job_find(sharename, jobid); 2038 2039 if (!pjob) 2040 return -1; 2041 /* don't allow another process to get this info - it is meaningless */ 2042 if (pjob->pid != sys_getpid()) 2043 return -1; 2044 2045 return_code = write(pjob->fd, buf, size); 2046 if (return_code>0) { 2047 pjob->size += size; 2048 pjob_store(sharename, jobid, pjob); 2049 } 2050 return return_code; 2051} 2052 2053/**************************************************************************** 2054 Get the queue status - do not update if db is out of date. 2055****************************************************************************/ 2056 2057static int get_queue_status(const char* sharename, print_status_struct *status) 2058{ 2059 fstring keystr; 2060 TDB_DATA data, key; 2061 struct tdb_print_db *pdb = get_print_db_byname(sharename); 2062 int len; 2063 2064 if (!pdb) 2065 return 0; 2066 2067 if (status) { 2068 ZERO_STRUCTP(status); 2069 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename); 2070 key.dptr = keystr; 2071 key.dsize = strlen(keystr); 2072 data = tdb_fetch(pdb->tdb, key); 2073 if (data.dptr) { 2074 if (data.dsize == sizeof(print_status_struct)) 2075 /* this memcpy is ok since the status struct was 2076 not packed before storing it in the tdb */ 2077 memcpy(status, data.dptr, sizeof(print_status_struct)); 2078 SAFE_FREE(data.dptr); 2079 } 2080 } 2081 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs"); 2082 release_print_db(pdb); 2083 return (len == -1 ? 0 : len); 2084} 2085 2086/**************************************************************************** 2087 Determine the number of jobs in a queue. 2088****************************************************************************/ 2089 2090int print_queue_length(int snum, print_status_struct *pstatus) 2091{ 2092 const char* sharename = lp_const_servicename( snum ); 2093 print_status_struct status; 2094 int len; 2095 2096 /* make sure the database is up to date */ 2097 if (print_cache_expired(lp_const_servicename(snum), True)) 2098 print_queue_update(snum, False); 2099 2100 /* also fetch the queue status */ 2101 memset(&status, 0, sizeof(status)); 2102 len = get_queue_status(sharename, &status); 2103 2104 if (pstatus) 2105 *pstatus = status; 2106 2107 return len; 2108} 2109 2110/*************************************************************************** 2111 Allocate a jobid. Hold the lock for as short a time as possible. 2112***************************************************************************/ 2113 2114static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid) 2115{ 2116 int i; 2117 uint32 jobid; 2118 2119 *pjobid = (uint32)-1; 2120 2121 for (i = 0; i < 3; i++) { 2122 /* Lock the database - only wait 20 seconds. */ 2123 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) { 2124 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename)); 2125 return False; 2126 } 2127 2128 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) { 2129 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) { 2130 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n", 2131 sharename)); 2132 return False; 2133 } 2134 jobid = 0; 2135 } 2136 2137 jobid = NEXT_JOBID(jobid); 2138 2139 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) { 2140 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n")); 2141 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); 2142 return False; 2143 } 2144 2145 /* We've finished with the INFO/nextjob lock. */ 2146 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); 2147 2148 if (!print_job_exists(sharename, jobid)) 2149 break; 2150 } 2151 2152 if (i > 2) { 2153 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n", 2154 sharename)); 2155 /* Probably full... */ 2156 errno = ENOSPC; 2157 return False; 2158 } 2159 2160 /* Store a dummy placeholder. */ 2161 { 2162 TDB_DATA dum; 2163 dum.dptr = NULL; 2164 dum.dsize = 0; 2165 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) { 2166 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n", 2167 jobid )); 2168 return False; 2169 } 2170 } 2171 2172 *pjobid = jobid; 2173 return True; 2174} 2175 2176/*************************************************************************** 2177 Append a jobid to the 'jobs changed' list. 2178***************************************************************************/ 2179 2180static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) 2181{ 2182 TDB_DATA data, key; 2183 uint32 store_jobid; 2184 2185 key.dptr = "INFO/jobs_changed"; 2186 key.dsize = strlen(key.dptr); 2187 SIVAL(&store_jobid, 0, jobid); 2188 data.dptr = (char *)&store_jobid; 2189 data.dsize = 4; 2190 2191 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid )); 2192 2193 return (tdb_append(pdb->tdb, key, data) == 0); 2194} 2195 2196/*************************************************************************** 2197 Start spooling a job - return the jobid. 2198***************************************************************************/ 2199 2200uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode ) 2201{ 2202 uint32 jobid; 2203 char *path; 2204 struct printjob pjob; 2205 user_struct *vuser; 2206 const char *sharename = lp_const_servicename(snum); 2207 struct tdb_print_db *pdb = get_print_db_byname(sharename); 2208 int njobs; 2209 2210 errno = 0; 2211 2212 if (!pdb) 2213 return (uint32)-1; 2214 2215 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) { 2216 DEBUG(3, ("print_job_start: job start denied by security descriptor\n")); 2217 release_print_db(pdb); 2218 return (uint32)-1; 2219 } 2220 2221 if (!print_time_access_check(snum)) { 2222 DEBUG(3, ("print_job_start: job start denied by time check\n")); 2223 release_print_db(pdb); 2224 return (uint32)-1; 2225 } 2226 2227 path = lp_pathname(snum); 2228 2229 /* see if we have sufficient disk space */ 2230 if (lp_minprintspace(snum)) { 2231 SMB_BIG_UINT dspace, dsize; 2232 if (sys_fsusage(path, &dspace, &dsize) == 0 && 2233 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) { 2234 DEBUG(3, ("print_job_start: disk space check failed.\n")); 2235 release_print_db(pdb); 2236 errno = ENOSPC; 2237 return (uint32)-1; 2238 } 2239 } 2240 2241 /* for autoloaded printers, check that the printcap entry still exists */ 2242 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) { 2243 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) )); 2244 release_print_db(pdb); 2245 errno = ENOENT; 2246 return (uint32)-1; 2247 } 2248 2249 /* Insure the maximum queue size is not violated */ 2250 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { 2251 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n", 2252 sharename, njobs, lp_maxprintjobs(snum) )); 2253 release_print_db(pdb); 2254 errno = ENOSPC; 2255 return (uint32)-1; 2256 } 2257 2258 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n", 2259 sharename, njobs, lp_maxprintjobs(snum) )); 2260 2261 if (!allocate_print_jobid(pdb, snum, sharename, &jobid)) 2262 goto fail; 2263 2264 /* create the database entry */ 2265 2266 ZERO_STRUCT(pjob); 2267 2268 pjob.pid = sys_getpid(); 2269 pjob.sysjob = -1; 2270 pjob.fd = -1; 2271 pjob.starttime = time(NULL); 2272 pjob.status = LPQ_SPOOLING; 2273 pjob.size = 0; 2274 pjob.spooled = False; 2275 pjob.smbjob = True; 2276 pjob.nt_devmode = nt_devmode; 2277 2278 fstrcpy(pjob.jobname, jobname); 2279 2280 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) { 2281 fstrcpy(pjob.user, vuser->user.smb_name); 2282 } else { 2283 fstrcpy(pjob.user, uidtoname(user->uid)); 2284 } 2285 2286 fstrcpy(pjob.queuename, lp_const_servicename(snum)); 2287 2288 /* we have a job entry - now create the spool file */ 2289 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 2290 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid); 2291 pjob.fd = smb_mkstemp(pjob.filename); 2292 2293 if (pjob.fd == -1) { 2294 if (errno == EACCES) { 2295 /* Common setup error, force a report. */ 2296 DEBUG(0, ("print_job_start: insufficient permissions \ 2297to open spool file %s.\n", pjob.filename)); 2298 } else { 2299 /* Normal case, report at level 3 and above. */ 2300 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename)); 2301 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno))); 2302 } 2303 goto fail; 2304 } 2305 2306 pjob_store(sharename, jobid, &pjob); 2307 2308 /* Update the 'jobs changed' entry used by print_queue_status. */ 2309 add_to_jobs_changed(pdb, jobid); 2310 2311 /* Ensure we keep a rough count of the number of total jobs... */ 2312 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1); 2313 2314 release_print_db(pdb); 2315 2316 return jobid; 2317 2318 fail: 2319 if (jobid != -1) 2320 pjob_delete(sharename, jobid); 2321 2322 release_print_db(pdb); 2323 2324 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); 2325 return (uint32)-1; 2326} 2327 2328/**************************************************************************** 2329 Update the number of pages spooled to jobid 2330****************************************************************************/ 2331 2332void print_job_endpage(int snum, uint32 jobid) 2333{ 2334 const char* sharename = lp_const_servicename(snum); 2335 struct printjob *pjob; 2336 2337 pjob = print_job_find(sharename, jobid); 2338 if (!pjob) 2339 return; 2340 /* don't allow another process to get this info - it is meaningless */ 2341 if (pjob->pid != sys_getpid()) 2342 return; 2343 2344 pjob->page_count++; 2345 pjob_store(sharename, jobid, pjob); 2346} 2347 2348/**************************************************************************** 2349 Print a file - called on closing the file. This spools the job. 2350 If normal close is false then we're tearing down the jobs - treat as an 2351 error. 2352****************************************************************************/ 2353 2354BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) 2355{ 2356 const char* sharename = lp_const_servicename(snum); 2357 struct printjob *pjob; 2358 int ret; 2359 SMB_STRUCT_STAT sbuf; 2360 struct printif *current_printif = get_printer_fns( snum ); 2361 2362 pjob = print_job_find(sharename, jobid); 2363 2364 if (!pjob) 2365 return False; 2366 2367 if (pjob->spooled || pjob->pid != sys_getpid()) 2368 return False; 2369 2370 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) { 2371 pjob->size = sbuf.st_size; 2372 close(pjob->fd); 2373 pjob->fd = -1; 2374 } else { 2375 2376 /* 2377 * Not a normal close or we couldn't stat the job file, 2378 * so something has gone wrong. Cleanup. 2379 */ 2380 close(pjob->fd); 2381 pjob->fd = -1; 2382 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid )); 2383 goto fail; 2384 } 2385 2386 /* Technically, this is not quite right. If the printer has a separator 2387 * page turned on, the NT spooler prints the separator page even if the 2388 * print job is 0 bytes. 010215 JRR */ 2389 if (pjob->size == 0 || pjob->status == LPQ_DELETING) { 2390 /* don't bother spooling empty files or something being deleted. */ 2391 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n", 2392 pjob->filename, pjob->size ? "deleted" : "zero length" )); 2393 unlink(pjob->filename); 2394 pjob_delete(sharename, jobid); 2395 return True; 2396 } 2397 2398 pjob->smbjob = jobid; 2399 2400 ret = (*(current_printif->job_submit))(snum, pjob); 2401 2402 if (ret) 2403 goto fail; 2404 2405 /* The print job has been sucessfully handed over to the back-end */ 2406 2407 pjob->spooled = True; 2408 pjob->status = LPQ_QUEUED; 2409 pjob_store(sharename, jobid, pjob); 2410 2411 /* make sure the database is up to date */ 2412 if (print_cache_expired(lp_const_servicename(snum), True)) 2413 print_queue_update(snum, False); 2414 2415 return True; 2416 2417fail: 2418 2419 /* The print job was not succesfully started. Cleanup */ 2420 /* Still need to add proper error return propagation! 010122:JRR */ 2421 unlink(pjob->filename); 2422 pjob_delete(sharename, jobid); 2423 return False; 2424} 2425 2426/**************************************************************************** 2427 Get a snapshot of jobs in the system without traversing. 2428****************************************************************************/ 2429 2430static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue) 2431{ 2432 TDB_DATA data, key, cgdata; 2433 print_queue_struct *queue = NULL; 2434 uint32 qcount = 0; 2435 uint32 extra_count = 0; 2436 int total_count = 0; 2437 size_t len = 0; 2438 uint32 i; 2439 int max_reported_jobs = lp_max_reported_jobs(snum); 2440 BOOL ret = False; 2441 const char* sharename = lp_servicename(snum); 2442 2443 /* make sure the database is up to date */ 2444 if (print_cache_expired(lp_const_servicename(snum), True)) 2445 print_queue_update(snum, False); 2446 2447 *pcount = 0; 2448 *ppqueue = NULL; 2449 2450 ZERO_STRUCT(data); 2451 ZERO_STRUCT(cgdata); 2452 key.dptr = "INFO/linear_queue_array"; 2453 key.dsize = strlen(key.dptr); 2454 2455 /* Get the stored queue data. */ 2456 data = tdb_fetch(pdb->tdb, key); 2457 2458 if (data.dptr && data.dsize >= sizeof(qcount)) 2459 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount); 2460 2461 /* Get the changed jobs list. */ 2462 key.dptr = "INFO/jobs_changed"; 2463 key.dsize = strlen(key.dptr); 2464 2465 cgdata = tdb_fetch(pdb->tdb, key); 2466 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0)) 2467 extra_count = cgdata.dsize/4; 2468 2469 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count)); 2470 2471 /* Allocate the queue size. */ 2472 if (qcount == 0 && extra_count == 0) 2473 goto out; 2474 2475 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL) 2476 goto out; 2477 2478 /* Retrieve the linearised queue data. */ 2479 2480 for( i = 0; i < qcount; i++) { 2481 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime; 2482 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff", 2483 &qjob, 2484 &qsize, 2485 &qpage_count, 2486 &qstatus, 2487 &qpriority, 2488 &qtime, 2489 queue[i].fs_user, 2490 queue[i].fs_file); 2491 queue[i].job = qjob; 2492 queue[i].size = qsize; 2493 queue[i].page_count = qpage_count; 2494 queue[i].status = qstatus; 2495 queue[i].priority = qpriority; 2496 queue[i].time = qtime; 2497 } 2498 2499 total_count = qcount; 2500 2501 /* Add in the changed jobids. */ 2502 for( i = 0; i < extra_count; i++) { 2503 uint32 jobid; 2504 struct printjob *pjob; 2505 2506 jobid = IVAL(cgdata.dptr, i*4); 2507 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid)); 2508 pjob = print_job_find(lp_const_servicename(snum), jobid); 2509 if (!pjob) { 2510 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid)); 2511 remove_from_jobs_changed(sharename, jobid); 2512 continue; 2513 } 2514 2515 queue[total_count].job = jobid; 2516 queue[total_count].size = pjob->size; 2517 queue[total_count].page_count = pjob->page_count; 2518 queue[total_count].status = pjob->status; 2519 queue[total_count].priority = 1; 2520 queue[total_count].time = pjob->starttime; 2521 fstrcpy(queue[total_count].fs_user, pjob->user); 2522 fstrcpy(queue[total_count].fs_file, pjob->jobname); 2523 total_count++; 2524 } 2525 2526 /* Sort the queue by submission time otherwise they are displayed 2527 in hash order. */ 2528 2529 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp)); 2530 2531 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count)); 2532 2533 if (max_reported_jobs && total_count > max_reported_jobs) 2534 total_count = max_reported_jobs; 2535 2536 *ppqueue = queue; 2537 *pcount = total_count; 2538 2539 ret = True; 2540 2541 out: 2542 2543 SAFE_FREE(data.dptr); 2544 SAFE_FREE(cgdata.dptr); 2545 return ret; 2546} 2547 2548/**************************************************************************** 2549 Get a printer queue listing. 2550 set queue = NULL and status = NULL if you just want to update the cache 2551****************************************************************************/ 2552 2553int print_queue_status(int snum, 2554 print_queue_struct **ppqueue, 2555 print_status_struct *status) 2556{ 2557 fstring keystr; 2558 TDB_DATA data, key; 2559 const char *sharename; 2560 struct tdb_print_db *pdb; 2561 int count = 0; 2562 2563 /* make sure the database is up to date */ 2564 2565 if (print_cache_expired(lp_const_servicename(snum), True)) 2566 print_queue_update(snum, False); 2567 2568 /* return if we are done */ 2569 if ( !ppqueue || !status ) 2570 return 0; 2571 2572 *ppqueue = NULL; 2573 sharename = lp_const_servicename(snum); 2574 pdb = get_print_db_byname(sharename); 2575 2576 if (!pdb) 2577 return 0; 2578 2579 /* 2580 * Fetch the queue status. We must do this first, as there may 2581 * be no jobs in the queue. 2582 */ 2583 2584 ZERO_STRUCTP(status); 2585 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename); 2586 key.dptr = keystr; 2587 key.dsize = strlen(keystr); 2588 data = tdb_fetch(pdb->tdb, key); 2589 if (data.dptr) { 2590 if (data.dsize == sizeof(*status)) { 2591 /* this memcpy is ok since the status struct was 2592 not packed before storing it in the tdb */ 2593 memcpy(status, data.dptr, sizeof(*status)); 2594 } 2595 SAFE_FREE(data.dptr); 2596 } 2597 2598 /* 2599 * Now, fetch the print queue information. We first count the number 2600 * of entries, and then only retrieve the queue if necessary. 2601 */ 2602 2603 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) { 2604 release_print_db(pdb); 2605 return 0; 2606 } 2607 2608 release_print_db(pdb); 2609 return count; 2610} 2611 2612/**************************************************************************** 2613 Pause a queue. 2614****************************************************************************/ 2615 2616BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) 2617{ 2618 int ret; 2619 struct printif *current_printif = get_printer_fns( snum ); 2620 2621 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { 2622 *errcode = WERR_ACCESS_DENIED; 2623 return False; 2624 } 2625 2626 2627 become_root(); 2628 2629 ret = (*(current_printif->queue_pause))(snum); 2630 2631 unbecome_root(); 2632 2633 if (ret != 0) { 2634 *errcode = WERR_INVALID_PARAM; 2635 return False; 2636 } 2637 2638 /* force update the database */ 2639 print_cache_flush(snum); 2640 2641 /* Send a printer notify message */ 2642 2643 notify_printer_status(snum, PRINTER_STATUS_PAUSED); 2644 2645 return True; 2646} 2647 2648/**************************************************************************** 2649 Resume a queue. 2650****************************************************************************/ 2651 2652BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) 2653{ 2654 int ret; 2655 struct printif *current_printif = get_printer_fns( snum ); 2656 2657 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { 2658 *errcode = WERR_ACCESS_DENIED; 2659 return False; 2660 } 2661 2662 become_root(); 2663 2664 ret = (*(current_printif->queue_resume))(snum); 2665 2666 unbecome_root(); 2667 2668 if (ret != 0) { 2669 *errcode = WERR_INVALID_PARAM; 2670 return False; 2671 } 2672 2673 /* make sure the database is up to date */ 2674 if (print_cache_expired(lp_const_servicename(snum), True)) 2675 print_queue_update(snum, True); 2676 2677 /* Send a printer notify message */ 2678 2679 notify_printer_status(snum, PRINTER_STATUS_OK); 2680 2681 return True; 2682} 2683 2684/**************************************************************************** 2685 Purge a queue - implemented by deleting all jobs that we can delete. 2686****************************************************************************/ 2687 2688BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) 2689{ 2690 print_queue_struct *queue; 2691 print_status_struct status; 2692 int njobs, i; 2693 BOOL can_job_admin; 2694 2695 /* Force and update so the count is accurate (i.e. not a cached count) */ 2696 print_queue_update(snum, True); 2697 2698 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER); 2699 njobs = print_queue_status(snum, &queue, &status); 2700 2701 if ( can_job_admin ) 2702 become_root(); 2703 2704 for (i=0;i<njobs;i++) { 2705 BOOL owner = is_owner(user, snum, queue[i].job); 2706 2707 if (owner || can_job_admin) { 2708 print_job_delete1(snum, queue[i].job); 2709 } 2710 } 2711 2712 if ( can_job_admin ) 2713 unbecome_root(); 2714 2715 /* update the cache */ 2716 print_queue_update( snum, True ); 2717 2718 SAFE_FREE(queue); 2719 2720 return True; 2721} 2722