Changeset 745 for trunk/server/source3/printing/printing.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/printing/printing.c
r664 r745 21 21 22 22 #include "includes.h" 23 #include "system/syslog.h" 24 #include "system/filesys.h" 23 25 #include "printing.h" 26 #include "../librpc/gen_ndr/ndr_spoolss.h" 27 #include "nt_printing.h" 28 #include "../librpc/gen_ndr/netlogon.h" 29 #include "printing/notify.h" 30 #include "printing/pcap.h" 31 #include "serverid.h" 32 #include "smbd/smbd.h" 33 #include "auth.h" 34 #include "messages.h" 35 #include "util_tdb.h" 24 36 25 37 #ifdef __OS2__ … … 31 43 32 44 /* Current printer interface */ 33 static bool remove_from_jobs_ changed(const char* sharename, uint32 jobid);45 static bool remove_from_jobs_added(const char* sharename, uint32 jobid); 34 46 35 47 /* … … 138 150 } 139 151 140 staticvoid rap_jobid_delete(const char* sharename, uint32 jobid)152 void rap_jobid_delete(const char* sharename, uint32 jobid) 141 153 { 142 154 TDB_DATA key, data; … … 279 291 } 280 292 293 /**************************************************************************** 294 Pack the devicemode to store it in a tdb. 295 ****************************************************************************/ 296 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen) 297 { 298 enum ndr_err_code ndr_err; 299 DATA_BLOB blob; 300 int len = 0; 301 302 if (devmode) { 303 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), 304 devmode, 305 (ndr_push_flags_fn_t) 306 ndr_push_spoolss_DeviceMode); 307 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 308 DEBUG(10, ("pack_devicemode: " 309 "error encoding spoolss_DeviceMode\n")); 310 goto done; 311 } 312 } else { 313 ZERO_STRUCT(blob); 314 } 315 316 len = tdb_pack(buf, buflen, "B", blob.length, blob.data); 317 318 if (devmode) { 319 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname)); 320 } 321 322 done: 323 return len; 324 } 325 326 /**************************************************************************** 327 Unpack the devicemode to store it in a tdb. 328 ****************************************************************************/ 329 static int unpack_devicemode(TALLOC_CTX *mem_ctx, 330 const uint8 *buf, int buflen, 331 struct spoolss_DeviceMode **devmode) 332 { 333 struct spoolss_DeviceMode *dm; 334 enum ndr_err_code ndr_err; 335 char *data = NULL; 336 int data_len = 0; 337 DATA_BLOB blob; 338 int len = 0; 339 340 *devmode = NULL; 341 342 len = tdb_unpack(buf, buflen, "B", &data_len, &data); 343 if (!data) { 344 return len; 345 } 346 347 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode); 348 if (!dm) { 349 goto done; 350 } 351 352 blob = data_blob_const(data, data_len); 353 354 ndr_err = ndr_pull_struct_blob(&blob, dm, dm, 355 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode); 356 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 357 DEBUG(10, ("unpack_devicemode: " 358 "error parsing spoolss_DeviceMode\n")); 359 goto done; 360 } 361 362 DEBUG(8, ("Unpacked devicemode [%s](%s)\n", 363 dm->devicename, dm->formname)); 364 if (dm->driverextra_data.data) { 365 DEBUG(8, ("with a private section of %d bytes\n", 366 dm->__driverextra_length)); 367 } 368 369 *devmode = dm; 370 371 done: 372 SAFE_FREE(data); 373 return len; 374 } 375 281 376 /*********************************************************************** 282 377 unpack a pjob from a tdb buffer 283 378 ***********************************************************************/ 284 379 285 int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )380 static int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob ) 286 381 { 287 382 int len = 0; … … 293 388 return -1; 294 389 295 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff ",390 len += tdb_unpack(buf+len, buflen-len, "dddddddddfffff", 296 391 &pjpid, 297 392 &pjsysjob, … … 306 401 pjob->jobname, 307 402 pjob->user, 403 pjob->clientmachine, 308 404 pjob->queuename); 309 405 … … 311 407 return -1; 312 408 313 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 ) 409 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode); 410 if (used == -1) { 314 411 return -1; 412 } 315 413 316 414 len += used; … … 356 454 } 357 455 358 if ( pjob.nt_devmode ) { 359 free_nt_devicemode( &pjob.nt_devmode ); 360 } 456 talloc_free(pjob.devmode); 361 457 362 458 ZERO_STRUCT( pjob ); … … 442 538 443 539 static const struct { 444 uint32 lpq_status;445 uint32 spoolss_status;540 uint32_t lpq_status; 541 uint32_t spoolss_status; 446 542 } lpq_to_spoolss_status_map[] = { 447 543 { LPQ_QUEUED, JOB_STATUS_QUEUED }, … … 456 552 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ }, 457 553 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION }, 458 { -1, 0 }554 { (uint32_t)-1, 0 } 459 555 }; 460 556 … … 475 571 } 476 572 477 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data, 478 struct printjob *new_data) 479 { 480 bool new_job = False; 481 482 if (!old_data) 483 new_job = True; 484 485 /* Job attributes that can't be changed. We only send 486 notification for these on a new job. */ 573 /*************************************************************************** 574 Append a jobid to the 'jobs changed' list. 575 ***************************************************************************/ 576 577 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid) 578 { 579 TDB_DATA data; 580 uint32_t store_jobid; 581 582 SIVAL(&store_jobid, 0, jobid); 583 data.dptr = (uint8 *) &store_jobid; 584 data.dsize = 4; 585 586 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid )); 587 588 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"), 589 data) == 0); 590 } 591 592 /*************************************************************************** 593 Remove a jobid from the 'jobs changed' list. 594 ***************************************************************************/ 595 596 static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid) 597 { 598 struct tdb_print_db *pdb = get_print_db_byname(sharename); 599 TDB_DATA data, key; 600 size_t job_count, i; 601 bool ret = False; 602 bool gotlock = False; 603 604 if (!pdb) { 605 return False; 606 } 607 608 ZERO_STRUCT(data); 609 610 key = string_tdb_data("INFO/jobs_changed"); 611 612 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) 613 goto out; 614 615 gotlock = True; 616 617 data = tdb_fetch(pdb->tdb, key); 618 619 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) 620 goto out; 621 622 job_count = data.dsize / 4; 623 for (i = 0; i < job_count; i++) { 624 uint32 ch_jobid; 625 626 ch_jobid = IVAL(data.dptr, i*4); 627 if (ch_jobid == jobid) { 628 if (i < job_count -1 ) 629 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 ); 630 data.dsize -= 4; 631 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1) 632 goto out; 633 break; 634 } 635 } 636 637 ret = True; 638 out: 639 640 if (gotlock) 641 tdb_chainunlock(pdb->tdb, key); 642 SAFE_FREE(data.dptr); 643 release_print_db(pdb); 644 if (ret) 645 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid )); 646 else 647 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid )); 648 return ret; 649 } 650 651 static void pjob_store_notify(struct tevent_context *ev, 652 struct messaging_context *msg_ctx, 653 const char* sharename, uint32 jobid, 654 struct printjob *old_data, 655 struct printjob *new_data, 656 bool *pchanged) 657 { 658 bool new_job = false; 659 bool changed = false; 660 661 if (old_data == NULL) { 662 new_job = true; 663 } 487 664 488 665 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the … … 494 671 495 672 if (new_job) { 496 notify_job_submitted(sharename, jobid, new_data->starttime); 497 notify_job_username(sharename, jobid, new_data->user); 498 } 499 500 if (new_job || !strequal(old_data->jobname, new_data->jobname)) 501 notify_job_name(sharename, jobid, new_data->jobname); 502 503 /* Job attributes of a new job or attributes that can be 504 modified. */ 505 506 if (new_job || !strequal(old_data->jobname, new_data->jobname)) 507 notify_job_name(sharename, jobid, new_data->jobname); 508 509 if (new_job || old_data->status != new_data->status) 510 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status)); 511 512 if (new_job || old_data->size != new_data->size) 513 notify_job_total_bytes(sharename, jobid, new_data->size); 514 515 if (new_job || old_data->page_count != new_data->page_count) 516 notify_job_total_pages(sharename, jobid, new_data->page_count); 673 notify_job_submitted(ev, msg_ctx, 674 sharename, jobid, new_data->starttime); 675 notify_job_username(ev, msg_ctx, 676 sharename, jobid, new_data->user); 677 notify_job_name(ev, msg_ctx, 678 sharename, jobid, new_data->jobname); 679 notify_job_status(ev, msg_ctx, 680 sharename, jobid, map_to_spoolss_status(new_data->status)); 681 notify_job_total_bytes(ev, msg_ctx, 682 sharename, jobid, new_data->size); 683 notify_job_total_pages(ev, msg_ctx, 684 sharename, jobid, new_data->page_count); 685 } else { 686 if (!strequal(old_data->jobname, new_data->jobname)) { 687 notify_job_name(ev, msg_ctx, sharename, 688 jobid, new_data->jobname); 689 changed = true; 690 } 691 692 if (old_data->status != new_data->status) { 693 notify_job_status(ev, msg_ctx, 694 sharename, jobid, 695 map_to_spoolss_status(new_data->status)); 696 } 697 698 if (old_data->size != new_data->size) { 699 notify_job_total_bytes(ev, msg_ctx, 700 sharename, jobid, new_data->size); 701 } 702 703 if (old_data->page_count != new_data->page_count) { 704 notify_job_total_pages(ev, msg_ctx, 705 sharename, jobid, 706 new_data->page_count); 707 } 708 } 709 710 *pchanged = changed; 517 711 } 518 712 … … 521 715 ****************************************************************************/ 522 716 523 static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob) 717 static bool pjob_store(struct tevent_context *ev, 718 struct messaging_context *msg_ctx, 719 const char* sharename, uint32 jobid, 720 struct printjob *pjob) 524 721 { 525 722 uint32_t tmp; … … 545 742 len = 0; 546 743 buflen = newlen; 547 len += tdb_pack(buf+len, buflen-len, "dddddddddffff ",744 len += tdb_pack(buf+len, buflen-len, "dddddddddfffff", 548 745 (uint32)pjob->pid, 549 746 (uint32)pjob->sysjob, … … 558 755 pjob->jobname, 559 756 pjob->user, 757 pjob->clientmachine, 560 758 pjob->queuename); 561 759 562 len += pack_devicemode(pjob-> nt_devmode, buf+len, buflen-len);760 len += pack_devicemode(pjob->devmode, buf+len, buflen-len); 563 761 564 762 if (buflen != len) { … … 580 778 TDB_REPLACE) == 0); 581 779 582 release_print_db(pdb);583 584 780 /* Send notify updates for what has changed */ 585 781 586 782 if ( ret ) { 783 bool changed = false; 587 784 struct printjob old_pjob; 588 785 … … 591 788 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 ) 592 789 { 593 pjob_store_notify( sharename, jobid, &old_pjob , pjob ); 594 free_nt_devicemode( &old_pjob.nt_devmode ); 790 pjob_store_notify(server_event_context(), 791 msg_ctx, 792 sharename, jobid, &old_pjob, 793 pjob, 794 &changed); 795 talloc_free(old_pjob.devmode); 796 797 if (changed) { 798 add_to_jobs_changed(pdb, jobid); 799 } 595 800 } 801 596 802 } 597 803 else { 598 804 /* new job */ 599 pjob_store_notify( sharename, jobid, NULL, pjob ); 600 } 601 } 602 805 pjob_store_notify(server_event_context(), msg_ctx, 806 sharename, jobid, NULL, pjob, 807 &changed); 808 } 809 } 810 811 release_print_db(pdb); 603 812 done: 604 813 SAFE_FREE( old_data.dptr ); … … 612 821 ****************************************************************************/ 613 822 614 void pjob_delete(const char* sharename, uint32 jobid) 823 static void pjob_delete(struct tevent_context *ev, 824 struct messaging_context *msg_ctx, 825 const char* sharename, uint32 jobid) 615 826 { 616 827 uint32_t tmp; … … 638 849 639 850 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED; 640 notify_job_status( sharename, jobid, job_status);851 notify_job_status(ev, msg_ctx, sharename, jobid, job_status); 641 852 642 853 /* Remove from printing.tdb */ 643 854 644 855 tdb_delete(pdb->tdb, print_key(jobid, &tmp)); 645 remove_from_jobs_ changed(sharename, jobid);856 remove_from_jobs_added(sharename, jobid); 646 857 release_print_db( pdb ); 647 858 rap_jobid_delete(sharename, jobid); … … 652 863 ****************************************************************************/ 653 864 654 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid) 865 static void print_unix_job(struct tevent_context *ev, 866 struct messaging_context *msg_ctx, 867 const char *sharename, print_queue_struct *q, 868 uint32 jobid) 655 869 { 656 870 struct printjob pj, *old_pj; … … 683 897 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename ); 684 898 685 pjob_store( sharename, jobid, &pj);899 pjob_store(ev, msg_ctx, sharename, jobid, &pj); 686 900 } 687 901 … … 694 908 const char *lprm_command; 695 909 struct printif *print_if; 910 struct tevent_context *ev; 911 struct messaging_context *msg_ctx; 696 912 }; 697 913 … … 713 929 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) 714 930 return 0; 715 free_nt_devicemode( &pjob.nt_devmode);931 talloc_free(pjob.devmode); 716 932 717 933 … … 727 943 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n", 728 944 (unsigned int)jobid )); 729 pjob_delete(ts->sharename, jobid); 945 pjob_delete(ts->ev, ts->msg_ctx, 946 ts->sharename, jobid); 730 947 return 0; 731 948 } … … 743 960 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n", 744 961 (unsigned int)jobid, (unsigned int)pjob.pid )); 745 pjob_delete(ts->sharename, jobid); 962 pjob_delete(ts->ev, ts->msg_ctx, 963 ts->sharename, jobid); 746 964 } else 747 965 ts->total_jobs++; … … 773 991 /* if we can't delete, then reset the job status */ 774 992 pjob.status = LPQ_QUEUED; 775 pjob_store(ts->sharename, jobid, &pjob); 993 pjob_store(ts->ev, ts->msg_ctx, 994 ts->sharename, jobid, &pjob); 776 995 } 777 996 else { 778 997 /* if we deleted the job, the remove the tdb record */ 779 pjob_delete(ts->sharename, jobid); 998 pjob_delete(ts->ev, 999 ts->msg_ctx, 1000 ts->sharename, jobid); 780 1001 pjob.status = LPQ_DELETED; 781 1002 } … … 805 1026 (unsigned int)pjob.starttime, 806 1027 (unsigned int)ts->lpq_time )); 807 pjob_delete(ts->sharename, jobid); 1028 pjob_delete(ts->ev, ts->msg_ctx, 1029 ts->sharename, jobid); 808 1030 } else 809 1031 ts->total_jobs++; … … 1002 1224 } 1003 1225 1004 static TDB_DATA get_jobs_ changed_data(struct tdb_print_db *pdb)1226 static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb) 1005 1227 { 1006 1228 TDB_DATA data; … … 1008 1230 ZERO_STRUCT(data); 1009 1231 1010 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_ changed"));1232 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added")); 1011 1233 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) { 1012 1234 SAFE_FREE(data.dptr); … … 1017 1239 } 1018 1240 1019 static void check_job_ changed(const char *sharename, TDB_DATA data, uint32 jobid)1241 static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid) 1020 1242 { 1021 1243 unsigned int i; … … 1027 1249 ch_jobid = IVAL(data.dptr, i*4); 1028 1250 if (ch_jobid == jobid) 1029 remove_from_jobs_ changed(sharename, jobid);1251 remove_from_jobs_added(sharename, jobid); 1030 1252 } 1031 1253 } … … 1097 1319 1098 1320 /**************************************************************************** 1099 main work for updating the lpq cahe for a printer queue 1100 ****************************************************************************/ 1101 1102 static void print_queue_update_internal( const char *sharename, 1321 main work for updating the lpq cache for a printer queue 1322 ****************************************************************************/ 1323 1324 static void print_queue_update_internal( struct tevent_context *ev, 1325 struct messaging_context *msg_ctx, 1326 const char *sharename, 1103 1327 struct printif *current_printif, 1104 1328 char *lpq_command, char *lprm_command ) … … 1144 1368 in hash order. */ 1145 1369 1146 qsort(queue, qcount, sizeof(print_queue_struct), 1147 QSORT_CAST(printjob_comp)); 1370 TYPESAFE_QSORT(queue, qcount, printjob_comp); 1148 1371 1149 1372 /* … … 1158 1381 */ 1159 1382 1160 jcdata = get_jobs_ changed_data(pdb);1383 jcdata = get_jobs_added_data(pdb); 1161 1384 1162 1385 for (i=0; i<qcount; i++) { … … 1165 1388 if (jobid == (uint32)-1) { 1166 1389 /* assume its a unix print job */ 1167 print_unix_job(sharename, &queue[i], jobid); 1390 print_unix_job(ev, msg_ctx, 1391 sharename, &queue[i], jobid); 1168 1392 continue; 1169 1393 } … … 1175 1399 with jobs in the queue. All we can do is treat them 1176 1400 like unix jobs. Pity. */ 1177 print_unix_job(sharename, &queue[i], jobid); 1401 print_unix_job(ev, msg_ctx, 1402 sharename, &queue[i], jobid); 1178 1403 continue; 1179 1404 } … … 1186 1411 pjob->status = queue[i].status; 1187 1412 1188 pjob_store( sharename, jobid, pjob);1189 1190 check_job_ changed(sharename, jcdata, jobid);1413 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 1414 1415 check_job_added(sharename, jcdata, jobid); 1191 1416 } 1192 1417 … … 1203 1428 tstruct.lprm_command = lprm_command; 1204 1429 tstruct.print_if = current_printif; 1430 tstruct.ev = ev; 1431 tstruct.msg_ctx = msg_ctx; 1205 1432 1206 1433 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct); … … 1260 1487 ****************************************************************************/ 1261 1488 1262 static void print_queue_update_with_lock( const char *sharename, 1489 static void print_queue_update_with_lock( struct tevent_context *ev, 1490 struct messaging_context *msg_ctx, 1491 const char *sharename, 1263 1492 struct printif *current_printif, 1264 1493 char *lpq_command, char *lprm_command ) … … 1329 1558 /* do the main work now */ 1330 1559 1331 print_queue_update_internal( sharename, current_printif, 1332 lpq_command, lprm_command ); 1560 print_queue_update_internal(ev, msg_ctx, 1561 sharename, current_printif, 1562 lpq_command, lprm_command); 1333 1563 1334 1564 /* Delete our pid from the db. */ … … 1340 1570 this is the receive function of the background lpq updater 1341 1571 ****************************************************************************/ 1342 staticvoid print_queue_receive(struct messaging_context *msg,1572 void print_queue_receive(struct messaging_context *msg, 1343 1573 void *private_data, 1344 1574 uint32_t msg_type, … … 1364 1594 } 1365 1595 1366 print_queue_update_with_lock(s harename,1596 print_queue_update_with_lock(server_event_context(), msg, sharename, 1367 1597 get_printer_fns_from_type((enum printing_types)printing_type), 1368 1598 lpqcommand, lprmcommand ); … … 1385 1615 } 1386 1616 1617 extern struct child_pid *children; 1618 extern int num_children; 1619 1387 1620 static void add_child_pid(pid_t pid) 1388 1621 { 1389 extern struct child_pid *children;1390 1622 struct child_pid *child; 1391 extern int num_children;1392 1623 1393 1624 child = SMB_MALLOC_P(struct child_pid); … … 1406 1637 main thread of the background lpq updater 1407 1638 ****************************************************************************/ 1408 void start_background_queue(void) 1639 void start_background_queue(struct tevent_context *ev, 1640 struct messaging_context *msg_ctx) 1409 1641 { 1410 1642 /* Use local variables for this as we don't … … 1434 1666 struct tevent_fd *fde; 1435 1667 int ret; 1668 NTSTATUS status; 1436 1669 1437 1670 /* Child. */ … … 1441 1674 pause_pipe[0] = -1; 1442 1675 1443 if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),1444 smbd_event_context(), 1445 true))) {1676 status = reinit_after_fork(msg_ctx, ev, procid_self(), true); 1677 1678 if (!NT_STATUS_IS_OK(status)) { 1446 1679 DEBUG(0,("reinit_after_fork() failed\n")); 1447 1680 smb_panic("reinit_after_fork() failed"); … … 1449 1682 1450 1683 smbd_setup_sig_term_handler(); 1451 smbd_setup_sig_hup_handler(); 1452 1453 claim_connection( NULL, "smbd lpq backend", 1454 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); 1684 smbd_setup_sig_hup_handler(ev, msg_ctx); 1685 1686 if (!serverid_register(procid_self(), 1687 FLAG_MSG_GENERAL|FLAG_MSG_SMBD 1688 |FLAG_MSG_PRINT_GENERAL)) { 1689 exit(1); 1690 } 1455 1691 1456 1692 if (!locking_init()) { … … 1458 1694 } 1459 1695 1460 messaging_register(smbd_messaging_context(), NULL, 1461 MSG_PRINTER_UPDATE, print_queue_receive); 1462 1463 fde = tevent_add_fd(smbd_event_context(), smbd_event_context(), 1464 pause_pipe[1], TEVENT_FD_READ, 1696 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE, 1697 print_queue_receive); 1698 1699 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ, 1465 1700 printing_pause_fd_handler, 1466 1701 NULL); … … 1471 1706 1472 1707 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); 1473 ret = tevent_loop_wait( smbd_event_context());1708 ret = tevent_loop_wait(ev); 1474 1709 /* should not be reached */ 1475 1710 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n", … … 1485 1720 ****************************************************************************/ 1486 1721 1487 static void print_queue_update(int snum, bool force) 1722 static void print_queue_update(struct messaging_context *msg_ctx, 1723 int snum, bool force) 1488 1724 { 1489 1725 fstring key; … … 1506 1742 lp_lpqcommand(snum), 1507 1743 "%p", 1508 PRINTERNAME(snum),1744 lp_printername(snum), 1509 1745 false, false, false); 1510 1746 if (!lpqcommand) { … … 1526 1762 lp_lprmcommand(snum), 1527 1763 "%p", 1528 PRINTERNAME(snum),1764 lp_printername(snum), 1529 1765 false, false, false); 1530 1766 if (!lprmcommand) { … … 1551 1787 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename)); 1552 1788 current_printif = get_printer_fns( snum ); 1553 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand ); 1789 print_queue_update_with_lock(server_event_context(), msg_ctx, 1790 sharename, current_printif, 1791 lpqcommand, lprmcommand); 1554 1792 1555 1793 return; … … 1604 1842 /* finally send the message */ 1605 1843 1606 messaging_send_buf(smbd_messaging_context(), 1607 pid_to_procid(background_lpq_updater_pid), 1844 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid), 1608 1845 MSG_PRINTER_UPDATE, (uint8 *)buffer, len); 1609 1846 … … 1812 2049 1813 2050 /**************************************************************************** 1814 Give the fd used for a jobid.1815 ****************************************************************************/1816 1817 int print_job_fd(const char* sharename, uint32 jobid)1818 {1819 struct printjob *pjob = print_job_find(sharename, jobid);1820 if (!pjob)1821 return -1;1822 /* don't allow another process to get this info - it is meaningless */1823 if (pjob->pid != sys_getpid())1824 return -1;1825 return pjob->fd;1826 }1827 1828 /****************************************************************************1829 2051 Give the filename used for a jobid. 1830 2052 Only valid for the process doing the spooling and when the job … … 1847 2069 ****************************************************************************/ 1848 2070 1849 NT_DEVICEMODE*print_job_devmode(const char* sharename, uint32 jobid)2071 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid) 1850 2072 { 1851 2073 struct printjob *pjob = print_job_find(sharename, jobid); … … 1854 2076 return NULL; 1855 2077 1856 return pjob->nt_devmode; 1857 } 1858 1859 /**************************************************************************** 1860 Set the place in the queue for a job. 1861 ****************************************************************************/ 1862 1863 bool print_job_set_place(const char *sharename, uint32 jobid, int place) 1864 { 1865 DEBUG(2,("print_job_set_place not implemented yet\n")); 1866 return False; 2078 return pjob->devmode; 1867 2079 } 1868 2080 … … 1871 2083 ****************************************************************************/ 1872 2084 1873 bool print_job_set_name(const char *sharename, uint32 jobid, char *name) 2085 bool print_job_set_name(struct tevent_context *ev, 2086 struct messaging_context *msg_ctx, 2087 const char *sharename, uint32 jobid, const char *name) 1874 2088 { 1875 2089 struct printjob *pjob; … … 1880 2094 1881 2095 fstrcpy(pjob->jobname, name); 1882 return pjob_store(sharename, jobid, pjob); 1883 } 2096 return pjob_store(ev, msg_ctx, sharename, jobid, pjob); 2097 } 2098 2099 /**************************************************************************** 2100 Get the name of a job. Only possible for owner. 2101 ****************************************************************************/ 2102 2103 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name) 2104 { 2105 struct printjob *pjob; 2106 2107 pjob = print_job_find(sharename, jobid); 2108 if (!pjob || pjob->pid != sys_getpid()) { 2109 return false; 2110 } 2111 2112 *name = talloc_strdup(mem_ctx, pjob->jobname); 2113 if (!*name) { 2114 return false; 2115 } 2116 2117 return true; 2118 } 2119 1884 2120 1885 2121 /*************************************************************************** 1886 Remove a jobid from the 'jobs changed' list.2122 Remove a jobid from the 'jobs added' list. 1887 2123 ***************************************************************************/ 1888 2124 1889 static bool remove_from_jobs_ changed(const char* sharename, uint32 jobid)2125 static bool remove_from_jobs_added(const char* sharename, uint32 jobid) 1890 2126 { 1891 2127 struct tdb_print_db *pdb = get_print_db_byname(sharename); … … 1901 2137 ZERO_STRUCT(data); 1902 2138 1903 key = string_tdb_data("INFO/jobs_ changed");2139 key = string_tdb_data("INFO/jobs_added"); 1904 2140 1905 2141 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) … … 1936 2172 release_print_db(pdb); 1937 2173 if (ret) 1938 DEBUG(10,("remove_from_jobs_ changed: removed jobid %u\n", (unsigned int)jobid ));2174 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid )); 1939 2175 else 1940 DEBUG(10,("remove_from_jobs_ changed: Failed to remove jobid %u\n", (unsigned int)jobid ));2176 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid )); 1941 2177 return ret; 1942 2178 } … … 1946 2182 ****************************************************************************/ 1947 2183 1948 static bool print_job_delete1(int snum, uint32 jobid) 2184 static bool print_job_delete1(struct tevent_context *ev, 2185 struct messaging_context *msg_ctx, 2186 int snum, uint32 jobid) 1949 2187 { 1950 2188 const char* sharename = lp_const_servicename(snum); … … 1975 2213 1976 2214 pjob->status = LPQ_DELETING; 1977 pjob_store( sharename, jobid, pjob);2215 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 1978 2216 1979 2217 if (pjob->spooled && pjob->sysjob != -1) 1980 2218 { 1981 2219 result = (*(current_printif->job_delete))( 1982 PRINTERNAME(snum),2220 lp_printername(snum), 1983 2221 lp_lprmcommand(snum), 1984 2222 pjob); … … 1993 2231 if (!pdb) 1994 2232 return False; 1995 pjob_delete( sharename, jobid);2233 pjob_delete(ev, msg_ctx, sharename, jobid); 1996 2234 /* Ensure we keep a rough count of the number of total jobs... */ 1997 2235 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1); … … 2000 2238 } 2001 2239 2002 remove_from_jobs_ changed( sharename, jobid );2240 remove_from_jobs_added( sharename, jobid ); 2003 2241 2004 2242 return (result == 0); … … 2009 2247 ****************************************************************************/ 2010 2248 2011 static bool is_owner( struct auth_serversupplied_info *server_info,2249 static bool is_owner(const struct auth_serversupplied_info *server_info, 2012 2250 const char *servicename, 2013 2251 uint32 jobid) … … 2025 2263 ****************************************************************************/ 2026 2264 2027 bool print_job_delete(struct auth_serversupplied_info *server_info, int snum, 2028 uint32 jobid, WERROR *errcode) 2029 { 2030 const char* sharename = lp_const_servicename( snum ); 2265 WERROR print_job_delete(const struct auth_serversupplied_info *server_info, 2266 struct messaging_context *msg_ctx, 2267 int snum, uint32_t jobid) 2268 { 2269 const char* sharename = lp_const_servicename(snum); 2031 2270 struct printjob *pjob; 2032 2271 bool owner; 2033 2272 char *fname; 2034 2273 2035 *errcode = WERR_OK;2036 2037 2274 owner = is_owner(server_info, lp_const_servicename(snum), jobid); 2038 2275 … … 2041 2278 2042 2279 if (!owner && 2043 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2280 !print_access_check(server_info, msg_ctx, snum, 2281 JOB_ACCESS_ADMINISTER)) { 2044 2282 DEBUG(3, ("delete denied by security descriptor\n")); 2045 *errcode = WERR_ACCESS_DENIED;2046 2283 2047 2284 /* BEGIN_ADMIN_LOG */ … … 2050 2287 pause, or resume print job. User name: %s. Printer name: %s.", 2051 2288 uidtoname(server_info->utok.uid), 2052 PRINTERNAME(snum) );2289 lp_printername(snum) ); 2053 2290 /* END_ADMIN_LOG */ 2054 2291 2055 return False;2292 return WERR_ACCESS_DENIED; 2056 2293 } 2057 2294 … … 2063 2300 */ 2064 2301 2065 if ( (fname = print_job_fname( sharename, jobid )) != NULL )2066 {2302 fname = print_job_fname(sharename, jobid); 2303 if (fname != NULL) { 2067 2304 /* remove the spool file */ 2068 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname )); 2069 if ( unlink( fname ) == -1 ) { 2070 *errcode = map_werror_from_unix(errno); 2071 return False; 2072 } 2073 } 2074 2075 if (!print_job_delete1(snum, jobid)) { 2076 *errcode = WERR_ACCESS_DENIED; 2077 return False; 2305 DEBUG(10, ("print_job_delete: " 2306 "Removing spool file [%s]\n", fname)); 2307 if (unlink(fname) == -1) { 2308 return map_werror_from_unix(errno); 2309 } 2310 } 2311 2312 if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) { 2313 return WERR_ACCESS_DENIED; 2078 2314 } 2079 2315 … … 2081 2317 job still exists */ 2082 2318 2083 print_queue_update( snum, True);2319 print_queue_update(msg_ctx, snum, True); 2084 2320 2085 2321 pjob = print_job_find(sharename, jobid); 2086 if ( pjob && (pjob->status != LPQ_DELETING) ) 2087 *errcode = WERR_ACCESS_DENIED; 2088 2089 return (pjob == NULL ); 2322 if (pjob && (pjob->status != LPQ_DELETING)) { 2323 return WERR_ACCESS_DENIED; 2324 } 2325 2326 return WERR_PRINTER_HAS_JOBS_QUEUED; 2090 2327 } 2091 2328 … … 2094 2331 ****************************************************************************/ 2095 2332 2096 bool print_job_pause(struct auth_serversupplied_info *server_info, int snum, 2097 uint32 jobid, WERROR *errcode) 2333 bool print_job_pause(const struct auth_serversupplied_info *server_info, 2334 struct messaging_context *msg_ctx, 2335 int snum, uint32 jobid, WERROR *errcode) 2098 2336 { 2099 2337 const char* sharename = lp_const_servicename(snum); … … 2117 2355 2118 2356 if (!is_owner(server_info, lp_const_servicename(snum), jobid) && 2119 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2357 !print_access_check(server_info, msg_ctx, snum, 2358 JOB_ACCESS_ADMINISTER)) { 2120 2359 DEBUG(3, ("pause denied by security descriptor\n")); 2121 2360 … … 2125 2364 pause, or resume print job. User name: %s. Printer name: %s.", 2126 2365 uidtoname(server_info->utok.uid), 2127 PRINTERNAME(snum) );2366 lp_printername(snum) ); 2128 2367 /* END_ADMIN_LOG */ 2129 2368 … … 2145 2384 /* Send a printer notify message */ 2146 2385 2147 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED); 2386 notify_job_status(server_event_context(), msg_ctx, sharename, jobid, 2387 JOB_STATUS_PAUSED); 2148 2388 2149 2389 /* how do we tell if this succeeded? */ … … 2156 2396 ****************************************************************************/ 2157 2397 2158 bool print_job_resume(struct auth_serversupplied_info *server_info, int snum, 2159 uint32 jobid, WERROR *errcode) 2398 bool print_job_resume(const struct auth_serversupplied_info *server_info, 2399 struct messaging_context *msg_ctx, 2400 int snum, uint32 jobid, WERROR *errcode) 2160 2401 { 2161 2402 const char *sharename = lp_const_servicename(snum); … … 2179 2420 2180 2421 if (!is_owner(server_info, lp_const_servicename(snum), jobid) && 2181 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2422 !print_access_check(server_info, msg_ctx, snum, 2423 JOB_ACCESS_ADMINISTER)) { 2182 2424 DEBUG(3, ("resume denied by security descriptor\n")); 2183 2425 *errcode = WERR_ACCESS_DENIED; … … 2188 2430 pause, or resume print job. User name: %s. Printer name: %s.", 2189 2431 uidtoname(server_info->utok.uid), 2190 PRINTERNAME(snum) );2432 lp_printername(snum) ); 2191 2433 /* END_ADMIN_LOG */ 2192 2434 return False; … … 2205 2447 /* Send a printer notify message */ 2206 2448 2207 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED); 2449 notify_job_status(server_event_context(), msg_ctx, sharename, jobid, 2450 JOB_STATUS_QUEUED); 2208 2451 2209 2452 return True; … … 2214 2457 ****************************************************************************/ 2215 2458 2216 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size) 2459 ssize_t print_job_write(struct tevent_context *ev, 2460 struct messaging_context *msg_ctx, 2461 int snum, uint32 jobid, const char *buf, size_t size) 2217 2462 { 2218 2463 const char* sharename = lp_const_servicename(snum); 2219 int return_code;2464 ssize_t return_code; 2220 2465 struct printjob *pjob; 2221 2466 … … 2228 2473 return -1; 2229 2474 2230 return_code = write_data_at_offset(pjob->fd, buf, size, pos); 2475 /* if SMBD is spooling this can't be allowed */ 2476 if (pjob->status == PJOB_SMBD_SPOOLING) { 2477 return -1; 2478 } 2479 2480 return_code = write_data(pjob->fd, buf, size); 2231 2481 2232 2482 if (return_code>0) { 2233 2483 pjob->size += size; 2234 pjob_store( sharename, jobid, pjob);2484 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 2235 2485 } 2236 2486 return return_code; … … 2275 2525 ****************************************************************************/ 2276 2526 2277 int print_queue_length(int snum, print_status_struct *pstatus) 2527 int print_queue_length(struct messaging_context *msg_ctx, int snum, 2528 print_status_struct *pstatus) 2278 2529 { 2279 2530 const char* sharename = lp_const_servicename( snum ); … … 2285 2536 /* make sure the database is up to date */ 2286 2537 if (print_cache_expired(lp_const_servicename(snum), True)) 2287 print_queue_update( snum, False);2538 print_queue_update(msg_ctx, snum, False); 2288 2539 2289 2540 /* also fetch the queue status */ … … 2301 2552 ***************************************************************************/ 2302 2553 2303 static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid) 2554 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum, 2555 const char *sharename, uint32 *pjobid) 2304 2556 { 2305 2557 int i; 2306 2558 uint32 jobid; 2559 enum TDB_ERROR terr; 2560 int ret; 2307 2561 2308 2562 *pjobid = (uint32)-1; … … 2310 2564 for (i = 0; i < 3; i++) { 2311 2565 /* Lock the database - only wait 20 seconds. */ 2312 if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) { 2313 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename)); 2314 return False; 2566 ret = tdb_lock_bystring_with_timeout(pdb->tdb, 2567 "INFO/nextjob", 20); 2568 if (ret == -1) { 2569 DEBUG(0, ("allocate_print_jobid: " 2570 "Failed to lock printing database %s\n", 2571 sharename)); 2572 terr = tdb_error(pdb->tdb); 2573 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2315 2574 } 2316 2575 2317 2576 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) { 2318 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) { 2319 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n", 2320 sharename)); 2577 terr = tdb_error(pdb->tdb); 2578 if (terr != TDB_ERR_NOEXIST) { 2579 DEBUG(0, ("allocate_print_jobid: " 2580 "Failed to fetch INFO/nextjob " 2581 "for print queue %s\n", sharename)); 2321 2582 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); 2322 return False;2583 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2323 2584 } 2324 DEBUG(10,("allocate_print_jobid: no existing jobid in %s\n", sharename)); 2585 DEBUG(10, ("allocate_print_jobid: " 2586 "No existing jobid in %s\n", sharename)); 2325 2587 jobid = 0; 2326 2588 } 2327 2589 2328 DEBUG(10,("allocate_print_jobid: read jobid %u from %s\n", jobid, sharename)); 2590 DEBUG(10, ("allocate_print_jobid: " 2591 "Read jobid %u from %s\n", jobid, sharename)); 2329 2592 2330 2593 jobid = NEXT_JOBID(jobid); 2331 2594 2332 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) { 2333 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n")); 2595 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid); 2596 if (ret == -1) { 2597 terr = tdb_error(pdb->tdb); 2598 DEBUG(3, ("allocate_print_jobid: " 2599 "Failed to store INFO/nextjob.\n")); 2334 2600 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); 2335 return False;2601 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2336 2602 } 2337 2603 … … 2342 2608 break; 2343 2609 } 2344 DEBUG(10,("allocate_print_jobid: found jobid %u in %s\n", jobid, sharename)); 2610 DEBUG(10, ("allocate_print_jobid: " 2611 "Found jobid %u in %s\n", jobid, sharename)); 2345 2612 } 2346 2613 2347 2614 if (i > 2) { 2348 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n", 2349 sharename)); 2615 DEBUG(0, ("allocate_print_jobid: " 2616 "Failed to allocate a print job for queue %s\n", 2617 sharename)); 2350 2618 /* Probably full... */ 2351 errno = ENOSPC; 2352 return False; 2619 return WERR_NO_SPOOL_SPACE; 2353 2620 } 2354 2621 … … 2361 2628 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum, 2362 2629 TDB_INSERT) == -1) { 2363 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n", 2364 jobid )); 2365 return False; 2630 DEBUG(3, ("allocate_print_jobid: " 2631 "jobid (%d) failed to store placeholder.\n", 2632 jobid )); 2633 terr = tdb_error(pdb->tdb); 2634 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2366 2635 } 2367 2636 } 2368 2637 2369 2638 *pjobid = jobid; 2370 return True;2639 return WERR_OK; 2371 2640 } 2372 2641 2373 2642 /*************************************************************************** 2374 Append a jobid to the 'jobs changed' list.2643 Append a jobid to the 'jobs added' list. 2375 2644 ***************************************************************************/ 2376 2645 2377 static bool add_to_jobs_ changed(struct tdb_print_db *pdb, uint32 jobid)2646 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid) 2378 2647 { 2379 2648 TDB_DATA data; … … 2384 2653 data.dsize = 4; 2385 2654 2386 DEBUG(10,("add_to_jobs_ changed: Added jobid %u\n", (unsigned int)jobid ));2387 2388 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_ changed"),2655 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid )); 2656 2657 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"), 2389 2658 data) == 0); 2659 } 2660 2661 2662 /*************************************************************************** 2663 Do all checks needed to determine if we can start a job. 2664 ***************************************************************************/ 2665 2666 static WERROR print_job_checks(const struct auth_serversupplied_info *server_info, 2667 struct messaging_context *msg_ctx, 2668 int snum, int *njobs) 2669 { 2670 const char *sharename = lp_const_servicename(snum); 2671 uint64_t dspace, dsize; 2672 uint64_t minspace; 2673 int ret; 2674 2675 if (!print_access_check(server_info, msg_ctx, snum, 2676 PRINTER_ACCESS_USE)) { 2677 DEBUG(3, ("print_job_checks: " 2678 "job start denied by security descriptor\n")); 2679 return WERR_ACCESS_DENIED; 2680 } 2681 2682 if (!print_time_access_check(server_info, msg_ctx, sharename)) { 2683 DEBUG(3, ("print_job_checks: " 2684 "job start denied by time check\n")); 2685 return WERR_ACCESS_DENIED; 2686 } 2687 2688 /* see if we have sufficient disk space */ 2689 if (lp_minprintspace(snum)) { 2690 minspace = lp_minprintspace(snum); 2691 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize); 2692 if (ret == 0 && dspace < 2*minspace) { 2693 DEBUG(3, ("print_job_checks: " 2694 "disk space check failed.\n")); 2695 return WERR_NO_SPOOL_SPACE; 2696 } 2697 } 2698 2699 /* for autoloaded printers, check that the printcap entry still exists */ 2700 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) { 2701 DEBUG(3, ("print_job_checks: printer name %s check failed.\n", 2702 sharename)); 2703 return WERR_ACCESS_DENIED; 2704 } 2705 2706 /* Insure the maximum queue size is not violated */ 2707 *njobs = print_queue_length(msg_ctx, snum, NULL); 2708 if (*njobs > lp_maxprintjobs(snum)) { 2709 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) " 2710 "larger than max printjobs per queue (%d).\n", 2711 sharename, *njobs, lp_maxprintjobs(snum))); 2712 return WERR_NO_SPOOL_SPACE; 2713 } 2714 2715 return WERR_OK; 2716 } 2717 2718 /*************************************************************************** 2719 Create a job file. 2720 ***************************************************************************/ 2721 2722 static WERROR print_job_spool_file(int snum, uint32_t jobid, 2723 const char *output_file, 2724 struct printjob *pjob) 2725 { 2726 WERROR werr; 2727 SMB_STRUCT_STAT st; 2728 const char *path; 2729 int len; 2730 2731 /* if this file is within the printer path, it means that smbd 2732 * is spooling it and will pass us control when it is finished. 2733 * Verify that the file name is ok, within path, and it is 2734 * already already there */ 2735 if (output_file) { 2736 path = lp_pathname(snum); 2737 len = strlen(path); 2738 if (strncmp(output_file, path, len) == 0 && 2739 (output_file[len - 1] == '/' || output_file[len] == '/')) { 2740 2741 /* verify path is not too long */ 2742 if (strlen(output_file) >= sizeof(pjob->filename)) { 2743 return WERR_INVALID_NAME; 2744 } 2745 2746 /* verify that the file exists */ 2747 if (sys_stat(output_file, &st, false) != 0) { 2748 return WERR_INVALID_NAME; 2749 } 2750 2751 fstrcpy(pjob->filename, output_file); 2752 2753 DEBUG(3, ("print_job_spool_file:" 2754 "External spooling activated")); 2755 2756 /* we do not open the file until spooling is done */ 2757 pjob->fd = -1; 2758 pjob->status = PJOB_SMBD_SPOOLING; 2759 2760 return WERR_OK; 2761 } 2762 } 2763 2764 slprintf(pjob->filename, sizeof(pjob->filename)-1, 2765 "%s/%s%.8u.XXXXXX", lp_pathname(snum), 2766 PRINT_SPOOL_PREFIX, (unsigned int)jobid); 2767 pjob->fd = mkstemp(pjob->filename); 2768 2769 if (pjob->fd == -1) { 2770 werr = map_werror_from_unix(errno); 2771 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) { 2772 /* Common setup error, force a report. */ 2773 DEBUG(0, ("print_job_spool_file: " 2774 "insufficient permissions to open spool " 2775 "file %s.\n", pjob->filename)); 2776 } else { 2777 /* Normal case, report at level 3 and above. */ 2778 DEBUG(3, ("print_job_spool_file: " 2779 "can't open spool file %s\n", 2780 pjob->filename)); 2781 } 2782 return werr; 2783 } 2784 2785 return WERR_OK; 2390 2786 } 2391 2787 … … 2394 2790 ***************************************************************************/ 2395 2791 2396 uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, 2397 const char *jobname, NT_DEVICEMODE *nt_devmode ) 2398 { 2399 uint32 jobid; 2792 WERROR print_job_start(const struct auth_serversupplied_info *server_info, 2793 struct messaging_context *msg_ctx, 2794 const char *clientmachine, 2795 int snum, const char *docname, const char *filename, 2796 struct spoolss_DeviceMode *devmode, uint32_t *_jobid) 2797 { 2798 uint32_t jobid; 2400 2799 char *path; 2401 2800 struct printjob pjob; … … 2403 2802 struct tdb_print_db *pdb = get_print_db_byname(sharename); 2404 2803 int njobs; 2405 2406 errno = 0; 2407 2408 if (!pdb) 2409 return (uint32)-1; 2410 2411 if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) { 2412 DEBUG(3, ("print_job_start: job start denied by security descriptor\n")); 2804 WERROR werr; 2805 2806 if (!pdb) { 2807 return WERR_INTERNAL_DB_CORRUPTION; 2808 } 2809 2810 path = lp_pathname(snum); 2811 2812 werr = print_job_checks(server_info, msg_ctx, snum, &njobs); 2813 if (!W_ERROR_IS_OK(werr)) { 2413 2814 release_print_db(pdb); 2414 return (uint32)-1; 2415 } 2416 2417 if (!print_time_access_check(lp_servicename(snum))) { 2418 DEBUG(3, ("print_job_start: job start denied by time check\n")); 2419 release_print_db(pdb); 2420 return (uint32)-1; 2421 } 2422 2423 path = lp_pathname(snum); 2424 2425 /* see if we have sufficient disk space */ 2426 if (lp_minprintspace(snum)) { 2427 uint64_t dspace, dsize; 2428 if (sys_fsusage(path, &dspace, &dsize) == 0 && 2429 dspace < 2*(uint64_t)lp_minprintspace(snum)) { 2430 DEBUG(3, ("print_job_start: disk space check failed.\n")); 2431 release_print_db(pdb); 2432 errno = ENOSPC; 2433 return (uint32)-1; 2434 } 2435 } 2436 2437 /* for autoloaded printers, check that the printcap entry still exists */ 2438 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) { 2439 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) )); 2440 release_print_db(pdb); 2441 errno = ENOENT; 2442 return (uint32)-1; 2443 } 2444 2445 /* Insure the maximum queue size is not violated */ 2446 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { 2447 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n", 2448 sharename, njobs, lp_maxprintjobs(snum) )); 2449 release_print_db(pdb); 2450 errno = ENOSPC; 2451 return (uint32)-1; 2452 } 2453 2454 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n", 2455 sharename, njobs, lp_maxprintjobs(snum) )); 2456 2457 if (!allocate_print_jobid(pdb, snum, sharename, &jobid)) 2815 return werr; 2816 } 2817 2818 DEBUG(10, ("print_job_start: " 2819 "Queue %s number of jobs (%d), max printjobs = %d\n", 2820 sharename, njobs, lp_maxprintjobs(snum))); 2821 2822 werr = allocate_print_jobid(pdb, snum, sharename, &jobid); 2823 if (!W_ERROR_IS_OK(werr)) { 2458 2824 goto fail; 2825 } 2459 2826 2460 2827 /* create the database entry */ … … 2470 2837 pjob.spooled = False; 2471 2838 pjob.smbjob = True; 2472 pjob.nt_devmode = nt_devmode; 2473 2474 fstrcpy(pjob.jobname, jobname); 2839 pjob.devmode = devmode; 2840 2841 fstrcpy(pjob.jobname, docname); 2842 2843 fstrcpy(pjob.clientmachine, clientmachine); 2475 2844 2476 2845 fstrcpy(pjob.user, lp_printjob_username(snum)); … … 2478 2847 path, server_info->utok.gid, 2479 2848 server_info->sanitized_username, 2480 pdb_get_domain(server_info->sam_account),2849 server_info->info3->base.domain.string, 2481 2850 pjob.user, sizeof(pjob.user)-1); 2482 2851 /* ensure NULL termination */ … … 2486 2855 2487 2856 /* we have a job entry - now create the spool file */ 2488 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 2489 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid); 2490 pjob.fd = mkstemp(pjob.filename); 2491 2492 if (pjob.fd == -1) { 2493 if (errno == EACCES) { 2494 /* Common setup error, force a report. */ 2495 DEBUG(0, ("print_job_start: insufficient permissions \ 2496 to open spool file %s.\n", pjob.filename)); 2497 } else { 2498 /* Normal case, report at level 3 and above. */ 2499 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename)); 2500 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno))); 2501 } 2857 werr = print_job_spool_file(snum, jobid, filename, &pjob); 2858 if (!W_ERROR_IS_OK(werr)) { 2502 2859 goto fail; 2503 2860 } 2504 2861 2505 pjob_store(s harename, jobid, &pjob);2506 2507 /* Update the 'jobs changed' entry used by print_queue_status. */2508 add_to_jobs_ changed(pdb, jobid);2862 pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob); 2863 2864 /* Update the 'jobs added' entry used by print_queue_status. */ 2865 add_to_jobs_added(pdb, jobid); 2509 2866 2510 2867 /* Ensure we keep a rough count of the number of total jobs... */ … … 2513 2870 release_print_db(pdb); 2514 2871 2515 return jobid; 2516 2517 fail: 2518 if (jobid != -1) 2519 pjob_delete(sharename, jobid); 2872 *_jobid = jobid; 2873 return WERR_OK; 2874 2875 fail: 2876 if (jobid != -1) { 2877 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 2878 } 2520 2879 2521 2880 release_print_db(pdb); 2522 2881 2523 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); 2524 return (uint32)-1; 2882 DEBUG(3, ("print_job_start: returning fail. " 2883 "Error = %s\n", win_errstr(werr))); 2884 return werr; 2525 2885 } 2526 2886 … … 2529 2889 ****************************************************************************/ 2530 2890 2531 void print_job_endpage(int snum, uint32 jobid) 2891 void print_job_endpage(struct messaging_context *msg_ctx, 2892 int snum, uint32 jobid) 2532 2893 { 2533 2894 const char* sharename = lp_const_servicename(snum); … … 2542 2903 2543 2904 pjob->page_count++; 2544 pjob_store(s harename, jobid, pjob);2905 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob); 2545 2906 } 2546 2907 … … 2551 2912 ****************************************************************************/ 2552 2913 2553 bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type) 2914 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum, 2915 uint32 jobid, enum file_close_type close_type) 2554 2916 { 2555 2917 const char* sharename = lp_const_servicename(snum); … … 2558 2920 SMB_STRUCT_STAT sbuf; 2559 2921 struct printif *current_printif = get_printer_fns( snum ); 2922 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 2560 2923 2561 2924 pjob = print_job_find(sharename, jobid); 2562 2925 2563 if (!pjob) 2564 return False; 2565 2566 if (pjob->spooled || pjob->pid != sys_getpid()) 2567 return False; 2568 2569 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && 2570 (sys_fstat(pjob->fd, &sbuf, false) == 0)) { 2926 if (!pjob) { 2927 return NT_STATUS_PRINT_CANCELLED; 2928 } 2929 2930 if (pjob->spooled || pjob->pid != sys_getpid()) { 2931 return NT_STATUS_ACCESS_DENIED; 2932 } 2933 2934 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) { 2935 if (pjob->status == PJOB_SMBD_SPOOLING) { 2936 /* take over the file now, smbd is done */ 2937 if (sys_stat(pjob->filename, &sbuf, false) != 0) { 2938 status = map_nt_error_from_unix(errno); 2939 DEBUG(3, ("print_job_end: " 2940 "stat file failed for jobid %d\n", 2941 jobid)); 2942 goto fail; 2943 } 2944 2945 pjob->status = LPQ_SPOOLING; 2946 2947 } else { 2948 2949 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) { 2950 status = map_nt_error_from_unix(errno); 2951 close(pjob->fd); 2952 DEBUG(3, ("print_job_end: " 2953 "stat file failed for jobid %d\n", 2954 jobid)); 2955 goto fail; 2956 } 2957 2958 close(pjob->fd); 2959 } 2960 2571 2961 pjob->size = sbuf.st_ex_size; 2572 close(pjob->fd);2573 pjob->fd = -1;2574 2962 } else { 2575 2963 2576 2964 /* 2577 * Not a normal close or we couldn't stat the job file, 2578 * so something has gone wrong. Cleanup. 2965 * Not a normal close, something has gone wrong. Cleanup. 2579 2966 */ 2580 close(pjob->fd);2581 pjob->fd = -1;2582 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));2967 if (pjob->fd != -1) { 2968 close(pjob->fd); 2969 } 2583 2970 goto fail; 2584 2971 } … … 2592 2979 pjob->filename, pjob->size ? "deleted" : "zero length" )); 2593 2980 unlink(pjob->filename); 2594 pjob_delete(s harename, jobid);2595 return True;2981 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 2982 return NT_STATUS_OK; 2596 2983 } 2597 2984 2598 2985 ret = (*(current_printif->job_submit))(snum, pjob); 2599 2986 2600 if (ret) 2987 if (ret) { 2988 status = NT_STATUS_PRINT_CANCELLED; 2601 2989 goto fail; 2990 } 2602 2991 2603 2992 /* The print job has been successfully handed over to the back-end */ … … 2605 2994 pjob->spooled = True; 2606 2995 pjob->status = LPQ_QUEUED; 2607 pjob_store(s harename, jobid, pjob);2996 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob); 2608 2997 2609 2998 /* make sure the database is up to date */ 2610 2999 if (print_cache_expired(lp_const_servicename(snum), True)) 2611 print_queue_update( snum, False);2612 2613 return True;3000 print_queue_update(msg_ctx, snum, False); 3001 3002 return NT_STATUS_OK; 2614 3003 2615 3004 fail: … … 2617 3006 /* The print job was not successfully started. Cleanup */ 2618 3007 /* Still need to add proper error return propagation! 010122:JRR */ 3008 pjob->fd = -1; 2619 3009 unlink(pjob->filename); 2620 pjob_delete(s harename, jobid);2621 return False;3010 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 3011 return status; 2622 3012 } 2623 3013 … … 2626 3016 ****************************************************************************/ 2627 3017 2628 static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue) 2629 { 2630 TDB_DATA data, cgdata; 3018 static bool get_stored_queue_info(struct messaging_context *msg_ctx, 3019 struct tdb_print_db *pdb, int snum, 3020 int *pcount, print_queue_struct **ppqueue) 3021 { 3022 TDB_DATA data, cgdata, jcdata; 2631 3023 print_queue_struct *queue = NULL; 2632 3024 uint32 qcount = 0; 2633 3025 uint32 extra_count = 0; 3026 uint32_t changed_count = 0; 2634 3027 int total_count = 0; 2635 3028 size_t len = 0; … … 2641 3034 /* make sure the database is up to date */ 2642 3035 if (print_cache_expired(lp_const_servicename(snum), True)) 2643 print_queue_update( snum, False);3036 print_queue_update(msg_ctx, snum, False); 2644 3037 2645 3038 *pcount = 0; … … 2655 3048 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount); 2656 3049 2657 /* Get the changed jobs list. */2658 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_ changed"));3050 /* Get the added jobs list. */ 3051 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added")); 2659 3052 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0)) 2660 3053 extra_count = cgdata.dsize/4; 3054 3055 /* Get the changed jobs list. */ 3056 jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed")); 3057 if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0)) 3058 changed_count = jcdata.dsize / 4; 2661 3059 2662 3060 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count)); … … 2692 3090 total_count = qcount; 2693 3091 2694 /* Add in the changed jobids. */3092 /* Add new jobids to the queue. */ 2695 3093 for( i = 0; i < extra_count; i++) { 2696 3094 uint32 jobid; … … 2698 3096 2699 3097 jobid = IVAL(cgdata.dptr, i*4); 2700 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));3098 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid)); 2701 3099 pjob = print_job_find(lp_const_servicename(snum), jobid); 2702 3100 if (!pjob) { 2703 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));2704 remove_from_jobs_ changed(sharename, jobid);3101 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid)); 3102 remove_from_jobs_added(sharename, jobid); 2705 3103 continue; 2706 3104 } … … 2717 3115 } 2718 3116 3117 /* Update the changed jobids. */ 3118 for (i = 0; i < changed_count; i++) { 3119 uint32_t jobid = IVAL(jcdata.dptr, i * 4); 3120 uint32_t j; 3121 bool found = false; 3122 3123 for (j = 0; j < total_count; j++) { 3124 if (queue[j].job == jobid) { 3125 found = true; 3126 break; 3127 } 3128 } 3129 3130 if (found) { 3131 struct printjob *pjob; 3132 3133 DEBUG(5,("get_stored_queue_info: changed job: %u\n", 3134 (unsigned int) jobid)); 3135 3136 pjob = print_job_find(sharename, jobid); 3137 if (pjob == NULL) { 3138 DEBUG(5,("get_stored_queue_info: failed to find " 3139 "changed job = %u\n", 3140 (unsigned int) jobid)); 3141 remove_from_jobs_changed(sharename, jobid); 3142 continue; 3143 } 3144 3145 queue[j].job = jobid; 3146 queue[j].size = pjob->size; 3147 queue[j].page_count = pjob->page_count; 3148 queue[j].status = pjob->status; 3149 queue[j].priority = 1; 3150 queue[j].time = pjob->starttime; 3151 fstrcpy(queue[j].fs_user, pjob->user); 3152 fstrcpy(queue[j].fs_file, pjob->jobname); 3153 3154 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n", 3155 (unsigned int) j, (unsigned int) jobid, pjob->jobname)); 3156 } 3157 3158 remove_from_jobs_changed(sharename, jobid); 3159 } 3160 2719 3161 /* Sort the queue by submission time otherwise they are displayed 2720 3162 in hash order. */ 2721 3163 2722 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));3164 TYPESAFE_QSORT(queue, total_count, printjob_comp); 2723 3165 2724 3166 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count)); … … 2744 3186 ****************************************************************************/ 2745 3187 2746 int print_queue_status( int snum,3188 int print_queue_status(struct messaging_context *msg_ctx, int snum, 2747 3189 print_queue_struct **ppqueue, 2748 3190 print_status_struct *status) … … 2757 3199 2758 3200 if (print_cache_expired(lp_const_servicename(snum), True)) 2759 print_queue_update( snum, False);3201 print_queue_update(msg_ctx, snum, False); 2760 3202 2761 3203 /* return if we are done */ … … 2794 3236 */ 2795 3237 2796 if (!get_stored_queue_info( pdb, snum, &count, ppqueue)) {3238 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) { 2797 3239 release_print_db(pdb); 2798 3240 return 0; … … 2807 3249 ****************************************************************************/ 2808 3250 2809 WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum) 3251 WERROR print_queue_pause(const struct auth_serversupplied_info *server_info, 3252 struct messaging_context *msg_ctx, int snum) 2810 3253 { 2811 3254 int ret; 2812 3255 struct printif *current_printif = get_printer_fns( snum ); 2813 3256 2814 if (!print_access_check(server_info, snum,3257 if (!print_access_check(server_info, msg_ctx, snum, 2815 3258 PRINTER_ACCESS_ADMINISTER)) { 2816 3259 return WERR_ACCESS_DENIED; … … 2833 3276 /* Send a printer notify message */ 2834 3277 2835 notify_printer_status(snum, PRINTER_STATUS_PAUSED); 3278 notify_printer_status(server_event_context(), msg_ctx, snum, 3279 PRINTER_STATUS_PAUSED); 2836 3280 2837 3281 return WERR_OK; … … 2842 3286 ****************************************************************************/ 2843 3287 2844 WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum) 3288 WERROR print_queue_resume(const struct auth_serversupplied_info *server_info, 3289 struct messaging_context *msg_ctx, int snum) 2845 3290 { 2846 3291 int ret; 2847 3292 struct printif *current_printif = get_printer_fns( snum ); 2848 3293 2849 if (!print_access_check(server_info, snum,3294 if (!print_access_check(server_info, msg_ctx, snum, 2850 3295 PRINTER_ACCESS_ADMINISTER)) { 2851 3296 return WERR_ACCESS_DENIED; … … 2864 3309 /* make sure the database is up to date */ 2865 3310 if (print_cache_expired(lp_const_servicename(snum), True)) 2866 print_queue_update( snum, True);3311 print_queue_update(msg_ctx, snum, True); 2867 3312 2868 3313 /* Send a printer notify message */ 2869 3314 2870 notify_printer_status(snum, PRINTER_STATUS_OK); 3315 notify_printer_status(server_event_context(), msg_ctx, snum, 3316 PRINTER_STATUS_OK); 2871 3317 2872 3318 return WERR_OK; … … 2877 3323 ****************************************************************************/ 2878 3324 2879 WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum) 3325 WERROR print_queue_purge(const struct auth_serversupplied_info *server_info, 3326 struct messaging_context *msg_ctx, int snum) 2880 3327 { 2881 3328 print_queue_struct *queue; … … 2885 3332 2886 3333 /* Force and update so the count is accurate (i.e. not a cached count) */ 2887 print_queue_update(snum, True); 2888 2889 can_job_admin = print_access_check(server_info, snum, 3334 print_queue_update(msg_ctx, snum, True); 3335 3336 can_job_admin = print_access_check(server_info, 3337 msg_ctx, 3338 snum, 2890 3339 JOB_ACCESS_ADMINISTER); 2891 njobs = print_queue_status( snum, &queue, &status);3340 njobs = print_queue_status(msg_ctx, snum, &queue, &status); 2892 3341 2893 3342 if ( can_job_admin ) … … 2899 3348 2900 3349 if (owner || can_job_admin) { 2901 print_job_delete1(snum, queue[i].job); 3350 print_job_delete1(server_event_context(), msg_ctx, 3351 snum, queue[i].job); 2902 3352 } 2903 3353 } … … 2907 3357 2908 3358 /* update the cache */ 2909 print_queue_update( snum, True);3359 print_queue_update(msg_ctx, snum, True); 2910 3360 2911 3361 SAFE_FREE(queue);
Note:
See TracChangeset
for help on using the changeset viewer.