Changeset 740 for vendor/current/source3/printing/printing.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/printing/printing.c
r478 r740 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 extern struct current_user current_user; … … 27 39 28 40 /* Current printer interface */ 29 static bool remove_from_jobs_ changed(const char* sharename, uint32 jobid);41 static bool remove_from_jobs_added(const char* sharename, uint32 jobid); 30 42 31 43 /* … … 134 146 } 135 147 136 staticvoid rap_jobid_delete(const char* sharename, uint32 jobid)148 void rap_jobid_delete(const char* sharename, uint32 jobid) 137 149 { 138 150 TDB_DATA key, data; … … 275 287 } 276 288 289 /**************************************************************************** 290 Pack the devicemode to store it in a tdb. 291 ****************************************************************************/ 292 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen) 293 { 294 enum ndr_err_code ndr_err; 295 DATA_BLOB blob; 296 int len = 0; 297 298 if (devmode) { 299 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), 300 devmode, 301 (ndr_push_flags_fn_t) 302 ndr_push_spoolss_DeviceMode); 303 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 304 DEBUG(10, ("pack_devicemode: " 305 "error encoding spoolss_DeviceMode\n")); 306 goto done; 307 } 308 } else { 309 ZERO_STRUCT(blob); 310 } 311 312 len = tdb_pack(buf, buflen, "B", blob.length, blob.data); 313 314 if (devmode) { 315 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname)); 316 } 317 318 done: 319 return len; 320 } 321 322 /**************************************************************************** 323 Unpack the devicemode to store it in a tdb. 324 ****************************************************************************/ 325 static int unpack_devicemode(TALLOC_CTX *mem_ctx, 326 const uint8 *buf, int buflen, 327 struct spoolss_DeviceMode **devmode) 328 { 329 struct spoolss_DeviceMode *dm; 330 enum ndr_err_code ndr_err; 331 char *data = NULL; 332 int data_len = 0; 333 DATA_BLOB blob; 334 int len = 0; 335 336 *devmode = NULL; 337 338 len = tdb_unpack(buf, buflen, "B", &data_len, &data); 339 if (!data) { 340 return len; 341 } 342 343 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode); 344 if (!dm) { 345 goto done; 346 } 347 348 blob = data_blob_const(data, data_len); 349 350 ndr_err = ndr_pull_struct_blob(&blob, dm, dm, 351 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode); 352 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 353 DEBUG(10, ("unpack_devicemode: " 354 "error parsing spoolss_DeviceMode\n")); 355 goto done; 356 } 357 358 DEBUG(8, ("Unpacked devicemode [%s](%s)\n", 359 dm->devicename, dm->formname)); 360 if (dm->driverextra_data.data) { 361 DEBUG(8, ("with a private section of %d bytes\n", 362 dm->__driverextra_length)); 363 } 364 365 *devmode = dm; 366 367 done: 368 SAFE_FREE(data); 369 return len; 370 } 371 277 372 /*********************************************************************** 278 373 unpack a pjob from a tdb buffer 279 374 ***********************************************************************/ 280 375 281 int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )376 static int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob ) 282 377 { 283 378 int len = 0; … … 289 384 return -1; 290 385 291 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff ",386 len += tdb_unpack(buf+len, buflen-len, "dddddddddfffff", 292 387 &pjpid, 293 388 &pjsysjob, … … 302 397 pjob->jobname, 303 398 pjob->user, 399 pjob->clientmachine, 304 400 pjob->queuename); 305 401 … … 307 403 return -1; 308 404 309 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 ) 405 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode); 406 if (used == -1) { 310 407 return -1; 408 } 311 409 312 410 len += used; … … 352 450 } 353 451 354 if ( pjob.nt_devmode ) { 355 free_nt_devicemode( &pjob.nt_devmode ); 356 } 452 talloc_free(pjob.devmode); 357 453 358 454 ZERO_STRUCT( pjob ); … … 438 534 439 535 static const struct { 440 uint32 lpq_status;441 uint32 spoolss_status;536 uint32_t lpq_status; 537 uint32_t spoolss_status; 442 538 } lpq_to_spoolss_status_map[] = { 443 539 { LPQ_QUEUED, JOB_STATUS_QUEUED }, … … 452 548 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ }, 453 549 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION }, 454 { -1, 0 }550 { (uint32_t)-1, 0 } 455 551 }; 456 552 … … 471 567 } 472 568 473 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data, 474 struct printjob *new_data) 475 { 476 bool new_job = False; 477 478 if (!old_data) 479 new_job = True; 480 481 /* Job attributes that can't be changed. We only send 482 notification for these on a new job. */ 569 /*************************************************************************** 570 Append a jobid to the 'jobs changed' list. 571 ***************************************************************************/ 572 573 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid) 574 { 575 TDB_DATA data; 576 uint32_t store_jobid; 577 578 SIVAL(&store_jobid, 0, jobid); 579 data.dptr = (uint8 *) &store_jobid; 580 data.dsize = 4; 581 582 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid )); 583 584 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"), 585 data) == 0); 586 } 587 588 /*************************************************************************** 589 Remove a jobid from the 'jobs changed' list. 590 ***************************************************************************/ 591 592 static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid) 593 { 594 struct tdb_print_db *pdb = get_print_db_byname(sharename); 595 TDB_DATA data, key; 596 size_t job_count, i; 597 bool ret = False; 598 bool gotlock = False; 599 600 if (!pdb) { 601 return False; 602 } 603 604 ZERO_STRUCT(data); 605 606 key = string_tdb_data("INFO/jobs_changed"); 607 608 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) 609 goto out; 610 611 gotlock = True; 612 613 data = tdb_fetch(pdb->tdb, key); 614 615 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) 616 goto out; 617 618 job_count = data.dsize / 4; 619 for (i = 0; i < job_count; i++) { 620 uint32 ch_jobid; 621 622 ch_jobid = IVAL(data.dptr, i*4); 623 if (ch_jobid == jobid) { 624 if (i < job_count -1 ) 625 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 ); 626 data.dsize -= 4; 627 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1) 628 goto out; 629 break; 630 } 631 } 632 633 ret = True; 634 out: 635 636 if (gotlock) 637 tdb_chainunlock(pdb->tdb, key); 638 SAFE_FREE(data.dptr); 639 release_print_db(pdb); 640 if (ret) 641 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid )); 642 else 643 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid )); 644 return ret; 645 } 646 647 static void pjob_store_notify(struct tevent_context *ev, 648 struct messaging_context *msg_ctx, 649 const char* sharename, uint32 jobid, 650 struct printjob *old_data, 651 struct printjob *new_data, 652 bool *pchanged) 653 { 654 bool new_job = false; 655 bool changed = false; 656 657 if (old_data == NULL) { 658 new_job = true; 659 } 483 660 484 661 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the … … 490 667 491 668 if (new_job) { 492 notify_job_submitted(sharename, jobid, new_data->starttime); 493 notify_job_username(sharename, jobid, new_data->user); 494 } 495 496 if (new_job || !strequal(old_data->jobname, new_data->jobname)) 497 notify_job_name(sharename, jobid, new_data->jobname); 498 499 /* Job attributes of a new job or attributes that can be 500 modified. */ 501 502 if (new_job || !strequal(old_data->jobname, new_data->jobname)) 503 notify_job_name(sharename, jobid, new_data->jobname); 504 505 if (new_job || old_data->status != new_data->status) 506 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status)); 507 508 if (new_job || old_data->size != new_data->size) 509 notify_job_total_bytes(sharename, jobid, new_data->size); 510 511 if (new_job || old_data->page_count != new_data->page_count) 512 notify_job_total_pages(sharename, jobid, new_data->page_count); 669 notify_job_submitted(ev, msg_ctx, 670 sharename, jobid, new_data->starttime); 671 notify_job_username(ev, msg_ctx, 672 sharename, jobid, new_data->user); 673 notify_job_name(ev, msg_ctx, 674 sharename, jobid, new_data->jobname); 675 notify_job_status(ev, msg_ctx, 676 sharename, jobid, map_to_spoolss_status(new_data->status)); 677 notify_job_total_bytes(ev, msg_ctx, 678 sharename, jobid, new_data->size); 679 notify_job_total_pages(ev, msg_ctx, 680 sharename, jobid, new_data->page_count); 681 } else { 682 if (!strequal(old_data->jobname, new_data->jobname)) { 683 notify_job_name(ev, msg_ctx, sharename, 684 jobid, new_data->jobname); 685 changed = true; 686 } 687 688 if (old_data->status != new_data->status) { 689 notify_job_status(ev, msg_ctx, 690 sharename, jobid, 691 map_to_spoolss_status(new_data->status)); 692 } 693 694 if (old_data->size != new_data->size) { 695 notify_job_total_bytes(ev, msg_ctx, 696 sharename, jobid, new_data->size); 697 } 698 699 if (old_data->page_count != new_data->page_count) { 700 notify_job_total_pages(ev, msg_ctx, 701 sharename, jobid, 702 new_data->page_count); 703 } 704 } 705 706 *pchanged = changed; 513 707 } 514 708 … … 517 711 ****************************************************************************/ 518 712 519 static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob) 713 static bool pjob_store(struct tevent_context *ev, 714 struct messaging_context *msg_ctx, 715 const char* sharename, uint32 jobid, 716 struct printjob *pjob) 520 717 { 521 718 uint32_t tmp; … … 541 738 len = 0; 542 739 buflen = newlen; 543 len += tdb_pack(buf+len, buflen-len, "dddddddddffff ",740 len += tdb_pack(buf+len, buflen-len, "dddddddddfffff", 544 741 (uint32)pjob->pid, 545 742 (uint32)pjob->sysjob, … … 554 751 pjob->jobname, 555 752 pjob->user, 753 pjob->clientmachine, 556 754 pjob->queuename); 557 755 558 len += pack_devicemode(pjob-> nt_devmode, buf+len, buflen-len);756 len += pack_devicemode(pjob->devmode, buf+len, buflen-len); 559 757 560 758 if (buflen != len) { … … 576 774 TDB_REPLACE) == 0); 577 775 578 release_print_db(pdb);579 580 776 /* Send notify updates for what has changed */ 581 777 582 778 if ( ret ) { 779 bool changed = false; 583 780 struct printjob old_pjob; 584 781 … … 587 784 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 ) 588 785 { 589 pjob_store_notify( sharename, jobid, &old_pjob , pjob ); 590 free_nt_devicemode( &old_pjob.nt_devmode ); 786 pjob_store_notify(server_event_context(), 787 msg_ctx, 788 sharename, jobid, &old_pjob, 789 pjob, 790 &changed); 791 talloc_free(old_pjob.devmode); 792 793 if (changed) { 794 add_to_jobs_changed(pdb, jobid); 795 } 591 796 } 797 592 798 } 593 799 else { 594 800 /* new job */ 595 pjob_store_notify( sharename, jobid, NULL, pjob ); 596 } 597 } 598 801 pjob_store_notify(server_event_context(), msg_ctx, 802 sharename, jobid, NULL, pjob, 803 &changed); 804 } 805 } 806 807 release_print_db(pdb); 599 808 done: 600 809 SAFE_FREE( old_data.dptr ); … … 608 817 ****************************************************************************/ 609 818 610 void pjob_delete(const char* sharename, uint32 jobid) 819 static void pjob_delete(struct tevent_context *ev, 820 struct messaging_context *msg_ctx, 821 const char* sharename, uint32 jobid) 611 822 { 612 823 uint32_t tmp; … … 634 845 635 846 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED; 636 notify_job_status( sharename, jobid, job_status);847 notify_job_status(ev, msg_ctx, sharename, jobid, job_status); 637 848 638 849 /* Remove from printing.tdb */ 639 850 640 851 tdb_delete(pdb->tdb, print_key(jobid, &tmp)); 641 remove_from_jobs_ changed(sharename, jobid);852 remove_from_jobs_added(sharename, jobid); 642 853 release_print_db( pdb ); 643 854 rap_jobid_delete(sharename, jobid); … … 648 859 ****************************************************************************/ 649 860 650 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid) 861 static void print_unix_job(struct tevent_context *ev, 862 struct messaging_context *msg_ctx, 863 const char *sharename, print_queue_struct *q, 864 uint32 jobid) 651 865 { 652 866 struct printjob pj, *old_pj; … … 679 893 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename ); 680 894 681 pjob_store( sharename, jobid, &pj);895 pjob_store(ev, msg_ctx, sharename, jobid, &pj); 682 896 } 683 897 … … 690 904 const char *lprm_command; 691 905 struct printif *print_if; 906 struct tevent_context *ev; 907 struct messaging_context *msg_ctx; 692 908 }; 693 909 … … 709 925 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) 710 926 return 0; 711 free_nt_devicemode( &pjob.nt_devmode);927 talloc_free(pjob.devmode); 712 928 713 929 … … 723 939 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n", 724 940 (unsigned int)jobid )); 725 pjob_delete(ts->sharename, jobid); 941 pjob_delete(ts->ev, ts->msg_ctx, 942 ts->sharename, jobid); 726 943 return 0; 727 944 } … … 739 956 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n", 740 957 (unsigned int)jobid, (unsigned int)pjob.pid )); 741 pjob_delete(ts->sharename, jobid); 958 pjob_delete(ts->ev, ts->msg_ctx, 959 ts->sharename, jobid); 742 960 } else 743 961 ts->total_jobs++; … … 769 987 /* if we can't delete, then reset the job status */ 770 988 pjob.status = LPQ_QUEUED; 771 pjob_store(ts->sharename, jobid, &pjob); 989 pjob_store(ts->ev, ts->msg_ctx, 990 ts->sharename, jobid, &pjob); 772 991 } 773 992 else { 774 993 /* if we deleted the job, the remove the tdb record */ 775 pjob_delete(ts->sharename, jobid); 994 pjob_delete(ts->ev, 995 ts->msg_ctx, 996 ts->sharename, jobid); 776 997 pjob.status = LPQ_DELETED; 777 998 } … … 801 1022 (unsigned int)pjob.starttime, 802 1023 (unsigned int)ts->lpq_time )); 803 pjob_delete(ts->sharename, jobid); 1024 pjob_delete(ts->ev, ts->msg_ctx, 1025 ts->sharename, jobid); 804 1026 } else 805 1027 ts->total_jobs++; … … 998 1220 } 999 1221 1000 static TDB_DATA get_jobs_ changed_data(struct tdb_print_db *pdb)1222 static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb) 1001 1223 { 1002 1224 TDB_DATA data; … … 1004 1226 ZERO_STRUCT(data); 1005 1227 1006 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_ changed"));1228 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added")); 1007 1229 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) { 1008 1230 SAFE_FREE(data.dptr); … … 1013 1235 } 1014 1236 1015 static void check_job_ changed(const char *sharename, TDB_DATA data, uint32 jobid)1237 static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid) 1016 1238 { 1017 1239 unsigned int i; … … 1023 1245 ch_jobid = IVAL(data.dptr, i*4); 1024 1246 if (ch_jobid == jobid) 1025 remove_from_jobs_ changed(sharename, jobid);1247 remove_from_jobs_added(sharename, jobid); 1026 1248 } 1027 1249 } … … 1093 1315 1094 1316 /**************************************************************************** 1095 main work for updating the lpq cahe for a printer queue 1096 ****************************************************************************/ 1097 1098 static void print_queue_update_internal( const char *sharename, 1317 main work for updating the lpq cache for a printer queue 1318 ****************************************************************************/ 1319 1320 static void print_queue_update_internal( struct tevent_context *ev, 1321 struct messaging_context *msg_ctx, 1322 const char *sharename, 1099 1323 struct printif *current_printif, 1100 1324 char *lpq_command, char *lprm_command ) … … 1140 1364 in hash order. */ 1141 1365 1142 qsort(queue, qcount, sizeof(print_queue_struct), 1143 QSORT_CAST(printjob_comp)); 1366 TYPESAFE_QSORT(queue, qcount, printjob_comp); 1144 1367 1145 1368 /* … … 1154 1377 */ 1155 1378 1156 jcdata = get_jobs_ changed_data(pdb);1379 jcdata = get_jobs_added_data(pdb); 1157 1380 1158 1381 for (i=0; i<qcount; i++) { … … 1161 1384 if (jobid == (uint32)-1) { 1162 1385 /* assume its a unix print job */ 1163 print_unix_job(sharename, &queue[i], jobid); 1386 print_unix_job(ev, msg_ctx, 1387 sharename, &queue[i], jobid); 1164 1388 continue; 1165 1389 } … … 1171 1395 with jobs in the queue. All we can do is treat them 1172 1396 like unix jobs. Pity. */ 1173 print_unix_job(sharename, &queue[i], jobid); 1397 print_unix_job(ev, msg_ctx, 1398 sharename, &queue[i], jobid); 1174 1399 continue; 1175 1400 } … … 1182 1407 pjob->status = queue[i].status; 1183 1408 1184 pjob_store( sharename, jobid, pjob);1185 1186 check_job_ changed(sharename, jcdata, jobid);1409 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 1410 1411 check_job_added(sharename, jcdata, jobid); 1187 1412 } 1188 1413 … … 1199 1424 tstruct.lprm_command = lprm_command; 1200 1425 tstruct.print_if = current_printif; 1426 tstruct.ev = ev; 1427 tstruct.msg_ctx = msg_ctx; 1201 1428 1202 1429 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct); … … 1256 1483 ****************************************************************************/ 1257 1484 1258 static void print_queue_update_with_lock( const char *sharename, 1485 static void print_queue_update_with_lock( struct tevent_context *ev, 1486 struct messaging_context *msg_ctx, 1487 const char *sharename, 1259 1488 struct printif *current_printif, 1260 1489 char *lpq_command, char *lprm_command ) … … 1325 1554 /* do the main work now */ 1326 1555 1327 print_queue_update_internal( sharename, current_printif, 1328 lpq_command, lprm_command ); 1556 print_queue_update_internal(ev, msg_ctx, 1557 sharename, current_printif, 1558 lpq_command, lprm_command); 1329 1559 1330 1560 /* Delete our pid from the db. */ … … 1336 1566 this is the receive function of the background lpq updater 1337 1567 ****************************************************************************/ 1338 staticvoid print_queue_receive(struct messaging_context *msg,1568 void print_queue_receive(struct messaging_context *msg, 1339 1569 void *private_data, 1340 1570 uint32_t msg_type, … … 1360 1590 } 1361 1591 1362 print_queue_update_with_lock(s harename,1592 print_queue_update_with_lock(server_event_context(), msg, sharename, 1363 1593 get_printer_fns_from_type((enum printing_types)printing_type), 1364 1594 lpqcommand, lprmcommand ); … … 1381 1611 } 1382 1612 1613 extern struct child_pid *children; 1614 extern int num_children; 1615 1383 1616 static void add_child_pid(pid_t pid) 1384 1617 { 1385 extern struct child_pid *children;1386 1618 struct child_pid *child; 1387 extern int num_children;1388 1619 1389 1620 child = SMB_MALLOC_P(struct child_pid); … … 1402 1633 main thread of the background lpq updater 1403 1634 ****************************************************************************/ 1404 void start_background_queue(void) 1635 void start_background_queue(struct tevent_context *ev, 1636 struct messaging_context *msg_ctx) 1405 1637 { 1406 1638 /* Use local variables for this as we don't … … 1430 1662 struct tevent_fd *fde; 1431 1663 int ret; 1664 NTSTATUS status; 1432 1665 1433 1666 /* Child. */ … … 1437 1670 pause_pipe[0] = -1; 1438 1671 1439 if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),1440 smbd_event_context(), 1441 true))) {1672 status = reinit_after_fork(msg_ctx, ev, procid_self(), true); 1673 1674 if (!NT_STATUS_IS_OK(status)) { 1442 1675 DEBUG(0,("reinit_after_fork() failed\n")); 1443 1676 smb_panic("reinit_after_fork() failed"); … … 1445 1678 1446 1679 smbd_setup_sig_term_handler(); 1447 smbd_setup_sig_hup_handler(); 1448 1449 claim_connection( NULL, "smbd lpq backend", 1450 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); 1680 smbd_setup_sig_hup_handler(ev, msg_ctx); 1681 1682 if (!serverid_register(procid_self(), 1683 FLAG_MSG_GENERAL|FLAG_MSG_SMBD 1684 |FLAG_MSG_PRINT_GENERAL)) { 1685 exit(1); 1686 } 1451 1687 1452 1688 if (!locking_init()) { … … 1454 1690 } 1455 1691 1456 messaging_register(smbd_messaging_context(), NULL, 1457 MSG_PRINTER_UPDATE, print_queue_receive); 1458 1459 fde = tevent_add_fd(smbd_event_context(), smbd_event_context(), 1460 pause_pipe[1], TEVENT_FD_READ, 1692 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE, 1693 print_queue_receive); 1694 1695 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ, 1461 1696 printing_pause_fd_handler, 1462 1697 NULL); … … 1467 1702 1468 1703 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); 1469 ret = tevent_loop_wait( smbd_event_context());1704 ret = tevent_loop_wait(ev); 1470 1705 /* should not be reached */ 1471 1706 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n", … … 1481 1716 ****************************************************************************/ 1482 1717 1483 static void print_queue_update(int snum, bool force) 1718 static void print_queue_update(struct messaging_context *msg_ctx, 1719 int snum, bool force) 1484 1720 { 1485 1721 fstring key; … … 1502 1738 lp_lpqcommand(snum), 1503 1739 "%p", 1504 PRINTERNAME(snum),1740 lp_printername(snum), 1505 1741 false, false, false); 1506 1742 if (!lpqcommand) { … … 1522 1758 lp_lprmcommand(snum), 1523 1759 "%p", 1524 PRINTERNAME(snum),1760 lp_printername(snum), 1525 1761 false, false, false); 1526 1762 if (!lprmcommand) { … … 1547 1783 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename)); 1548 1784 current_printif = get_printer_fns( snum ); 1549 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand ); 1785 print_queue_update_with_lock(server_event_context(), msg_ctx, 1786 sharename, current_printif, 1787 lpqcommand, lprmcommand); 1550 1788 1551 1789 return; … … 1600 1838 /* finally send the message */ 1601 1839 1602 messaging_send_buf(smbd_messaging_context(), 1603 pid_to_procid(background_lpq_updater_pid), 1840 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid), 1604 1841 MSG_PRINTER_UPDATE, (uint8 *)buffer, len); 1605 1842 … … 1808 2045 1809 2046 /**************************************************************************** 1810 Give the fd used for a jobid.1811 ****************************************************************************/1812 1813 int print_job_fd(const char* sharename, uint32 jobid)1814 {1815 struct printjob *pjob = print_job_find(sharename, jobid);1816 if (!pjob)1817 return -1;1818 /* don't allow another process to get this info - it is meaningless */1819 if (pjob->pid != sys_getpid())1820 return -1;1821 return pjob->fd;1822 }1823 1824 /****************************************************************************1825 2047 Give the filename used for a jobid. 1826 2048 Only valid for the process doing the spooling and when the job … … 1843 2065 ****************************************************************************/ 1844 2066 1845 NT_DEVICEMODE*print_job_devmode(const char* sharename, uint32 jobid)2067 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid) 1846 2068 { 1847 2069 struct printjob *pjob = print_job_find(sharename, jobid); … … 1850 2072 return NULL; 1851 2073 1852 return pjob->nt_devmode; 1853 } 1854 1855 /**************************************************************************** 1856 Set the place in the queue for a job. 1857 ****************************************************************************/ 1858 1859 bool print_job_set_place(const char *sharename, uint32 jobid, int place) 1860 { 1861 DEBUG(2,("print_job_set_place not implemented yet\n")); 1862 return False; 2074 return pjob->devmode; 1863 2075 } 1864 2076 … … 1867 2079 ****************************************************************************/ 1868 2080 1869 bool print_job_set_name(const char *sharename, uint32 jobid, char *name) 2081 bool print_job_set_name(struct tevent_context *ev, 2082 struct messaging_context *msg_ctx, 2083 const char *sharename, uint32 jobid, const char *name) 1870 2084 { 1871 2085 struct printjob *pjob; … … 1876 2090 1877 2091 fstrcpy(pjob->jobname, name); 1878 return pjob_store(sharename, jobid, pjob); 1879 } 2092 return pjob_store(ev, msg_ctx, sharename, jobid, pjob); 2093 } 2094 2095 /**************************************************************************** 2096 Get the name of a job. Only possible for owner. 2097 ****************************************************************************/ 2098 2099 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name) 2100 { 2101 struct printjob *pjob; 2102 2103 pjob = print_job_find(sharename, jobid); 2104 if (!pjob || pjob->pid != sys_getpid()) { 2105 return false; 2106 } 2107 2108 *name = talloc_strdup(mem_ctx, pjob->jobname); 2109 if (!*name) { 2110 return false; 2111 } 2112 2113 return true; 2114 } 2115 1880 2116 1881 2117 /*************************************************************************** 1882 Remove a jobid from the 'jobs changed' list.2118 Remove a jobid from the 'jobs added' list. 1883 2119 ***************************************************************************/ 1884 2120 1885 static bool remove_from_jobs_ changed(const char* sharename, uint32 jobid)2121 static bool remove_from_jobs_added(const char* sharename, uint32 jobid) 1886 2122 { 1887 2123 struct tdb_print_db *pdb = get_print_db_byname(sharename); … … 1897 2133 ZERO_STRUCT(data); 1898 2134 1899 key = string_tdb_data("INFO/jobs_ changed");2135 key = string_tdb_data("INFO/jobs_added"); 1900 2136 1901 2137 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) … … 1932 2168 release_print_db(pdb); 1933 2169 if (ret) 1934 DEBUG(10,("remove_from_jobs_ changed: removed jobid %u\n", (unsigned int)jobid ));2170 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid )); 1935 2171 else 1936 DEBUG(10,("remove_from_jobs_ changed: Failed to remove jobid %u\n", (unsigned int)jobid ));2172 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid )); 1937 2173 return ret; 1938 2174 } … … 1942 2178 ****************************************************************************/ 1943 2179 1944 static bool print_job_delete1(int snum, uint32 jobid) 2180 static bool print_job_delete1(struct tevent_context *ev, 2181 struct messaging_context *msg_ctx, 2182 int snum, uint32 jobid) 1945 2183 { 1946 2184 const char* sharename = lp_const_servicename(snum); … … 1971 2209 1972 2210 pjob->status = LPQ_DELETING; 1973 pjob_store( sharename, jobid, pjob);2211 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 1974 2212 1975 2213 if (pjob->spooled && pjob->sysjob != -1) 1976 2214 { 1977 2215 result = (*(current_printif->job_delete))( 1978 PRINTERNAME(snum),2216 lp_printername(snum), 1979 2217 lp_lprmcommand(snum), 1980 2218 pjob); … … 1989 2227 if (!pdb) 1990 2228 return False; 1991 pjob_delete( sharename, jobid);2229 pjob_delete(ev, msg_ctx, sharename, jobid); 1992 2230 /* Ensure we keep a rough count of the number of total jobs... */ 1993 2231 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1); … … 1996 2234 } 1997 2235 1998 remove_from_jobs_ changed( sharename, jobid );2236 remove_from_jobs_added( sharename, jobid ); 1999 2237 2000 2238 return (result == 0); … … 2005 2243 ****************************************************************************/ 2006 2244 2007 static bool is_owner( struct auth_serversupplied_info *server_info,2245 static bool is_owner(const struct auth_serversupplied_info *server_info, 2008 2246 const char *servicename, 2009 2247 uint32 jobid) … … 2021 2259 ****************************************************************************/ 2022 2260 2023 bool print_job_delete(struct auth_serversupplied_info *server_info, int snum, 2024 uint32 jobid, WERROR *errcode) 2025 { 2026 const char* sharename = lp_const_servicename( snum ); 2261 WERROR print_job_delete(const struct auth_serversupplied_info *server_info, 2262 struct messaging_context *msg_ctx, 2263 int snum, uint32_t jobid) 2264 { 2265 const char* sharename = lp_const_servicename(snum); 2027 2266 struct printjob *pjob; 2028 2267 bool owner; 2029 2268 char *fname; 2030 2269 2031 *errcode = WERR_OK;2032 2033 2270 owner = is_owner(server_info, lp_const_servicename(snum), jobid); 2034 2271 … … 2037 2274 2038 2275 if (!owner && 2039 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2276 !print_access_check(server_info, msg_ctx, snum, 2277 JOB_ACCESS_ADMINISTER)) { 2040 2278 DEBUG(3, ("delete denied by security descriptor\n")); 2041 *errcode = WERR_ACCESS_DENIED;2042 2279 2043 2280 /* BEGIN_ADMIN_LOG */ … … 2046 2283 pause, or resume print job. User name: %s. Printer name: %s.", 2047 2284 uidtoname(server_info->utok.uid), 2048 PRINTERNAME(snum) );2285 lp_printername(snum) ); 2049 2286 /* END_ADMIN_LOG */ 2050 2287 2051 return False;2288 return WERR_ACCESS_DENIED; 2052 2289 } 2053 2290 … … 2059 2296 */ 2060 2297 2061 if ( (fname = print_job_fname( sharename, jobid )) != NULL )2062 {2298 fname = print_job_fname(sharename, jobid); 2299 if (fname != NULL) { 2063 2300 /* remove the spool file */ 2064 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname )); 2065 if ( unlink( fname ) == -1 ) { 2066 *errcode = map_werror_from_unix(errno); 2067 return False; 2068 } 2069 } 2070 2071 if (!print_job_delete1(snum, jobid)) { 2072 *errcode = WERR_ACCESS_DENIED; 2073 return False; 2301 DEBUG(10, ("print_job_delete: " 2302 "Removing spool file [%s]\n", fname)); 2303 if (unlink(fname) == -1) { 2304 return map_werror_from_unix(errno); 2305 } 2306 } 2307 2308 if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) { 2309 return WERR_ACCESS_DENIED; 2074 2310 } 2075 2311 … … 2077 2313 job still exists */ 2078 2314 2079 print_queue_update( snum, True);2315 print_queue_update(msg_ctx, snum, True); 2080 2316 2081 2317 pjob = print_job_find(sharename, jobid); 2082 if ( pjob && (pjob->status != LPQ_DELETING) ) 2083 *errcode = WERR_ACCESS_DENIED; 2084 2085 return (pjob == NULL ); 2318 if (pjob && (pjob->status != LPQ_DELETING)) { 2319 return WERR_ACCESS_DENIED; 2320 } 2321 2322 return WERR_PRINTER_HAS_JOBS_QUEUED; 2086 2323 } 2087 2324 … … 2090 2327 ****************************************************************************/ 2091 2328 2092 bool print_job_pause(struct auth_serversupplied_info *server_info, int snum, 2093 uint32 jobid, WERROR *errcode) 2329 bool print_job_pause(const struct auth_serversupplied_info *server_info, 2330 struct messaging_context *msg_ctx, 2331 int snum, uint32 jobid, WERROR *errcode) 2094 2332 { 2095 2333 const char* sharename = lp_const_servicename(snum); … … 2113 2351 2114 2352 if (!is_owner(server_info, lp_const_servicename(snum), jobid) && 2115 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2353 !print_access_check(server_info, msg_ctx, snum, 2354 JOB_ACCESS_ADMINISTER)) { 2116 2355 DEBUG(3, ("pause denied by security descriptor\n")); 2117 2356 … … 2121 2360 pause, or resume print job. User name: %s. Printer name: %s.", 2122 2361 uidtoname(server_info->utok.uid), 2123 PRINTERNAME(snum) );2362 lp_printername(snum) ); 2124 2363 /* END_ADMIN_LOG */ 2125 2364 … … 2141 2380 /* Send a printer notify message */ 2142 2381 2143 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED); 2382 notify_job_status(server_event_context(), msg_ctx, sharename, jobid, 2383 JOB_STATUS_PAUSED); 2144 2384 2145 2385 /* how do we tell if this succeeded? */ … … 2152 2392 ****************************************************************************/ 2153 2393 2154 bool print_job_resume(struct auth_serversupplied_info *server_info, int snum, 2155 uint32 jobid, WERROR *errcode) 2394 bool print_job_resume(const struct auth_serversupplied_info *server_info, 2395 struct messaging_context *msg_ctx, 2396 int snum, uint32 jobid, WERROR *errcode) 2156 2397 { 2157 2398 const char *sharename = lp_const_servicename(snum); … … 2175 2416 2176 2417 if (!is_owner(server_info, lp_const_servicename(snum), jobid) && 2177 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2418 !print_access_check(server_info, msg_ctx, snum, 2419 JOB_ACCESS_ADMINISTER)) { 2178 2420 DEBUG(3, ("resume denied by security descriptor\n")); 2179 2421 *errcode = WERR_ACCESS_DENIED; … … 2184 2426 pause, or resume print job. User name: %s. Printer name: %s.", 2185 2427 uidtoname(server_info->utok.uid), 2186 PRINTERNAME(snum) );2428 lp_printername(snum) ); 2187 2429 /* END_ADMIN_LOG */ 2188 2430 return False; … … 2201 2443 /* Send a printer notify message */ 2202 2444 2203 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED); 2445 notify_job_status(server_event_context(), msg_ctx, sharename, jobid, 2446 JOB_STATUS_QUEUED); 2204 2447 2205 2448 return True; … … 2210 2453 ****************************************************************************/ 2211 2454 2212 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size) 2455 ssize_t print_job_write(struct tevent_context *ev, 2456 struct messaging_context *msg_ctx, 2457 int snum, uint32 jobid, const char *buf, size_t size) 2213 2458 { 2214 2459 const char* sharename = lp_const_servicename(snum); 2215 int return_code;2460 ssize_t return_code; 2216 2461 struct printjob *pjob; 2217 2462 … … 2224 2469 return -1; 2225 2470 2226 return_code = write_data_at_offset(pjob->fd, buf, size, pos); 2471 /* if SMBD is spooling this can't be allowed */ 2472 if (pjob->status == PJOB_SMBD_SPOOLING) { 2473 return -1; 2474 } 2475 2476 return_code = write_data(pjob->fd, buf, size); 2227 2477 2228 2478 if (return_code>0) { 2229 2479 pjob->size += size; 2230 pjob_store( sharename, jobid, pjob);2480 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 2231 2481 } 2232 2482 return return_code; … … 2271 2521 ****************************************************************************/ 2272 2522 2273 int print_queue_length(int snum, print_status_struct *pstatus) 2523 int print_queue_length(struct messaging_context *msg_ctx, int snum, 2524 print_status_struct *pstatus) 2274 2525 { 2275 2526 const char* sharename = lp_const_servicename( snum ); … … 2281 2532 /* make sure the database is up to date */ 2282 2533 if (print_cache_expired(lp_const_servicename(snum), True)) 2283 print_queue_update( snum, False);2534 print_queue_update(msg_ctx, snum, False); 2284 2535 2285 2536 /* also fetch the queue status */ … … 2297 2548 ***************************************************************************/ 2298 2549 2299 static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid) 2550 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum, 2551 const char *sharename, uint32 *pjobid) 2300 2552 { 2301 2553 int i; 2302 2554 uint32 jobid; 2555 enum TDB_ERROR terr; 2556 int ret; 2303 2557 2304 2558 *pjobid = (uint32)-1; … … 2306 2560 for (i = 0; i < 3; i++) { 2307 2561 /* Lock the database - only wait 20 seconds. */ 2308 if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) { 2309 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename)); 2310 return False; 2562 ret = tdb_lock_bystring_with_timeout(pdb->tdb, 2563 "INFO/nextjob", 20); 2564 if (ret == -1) { 2565 DEBUG(0, ("allocate_print_jobid: " 2566 "Failed to lock printing database %s\n", 2567 sharename)); 2568 terr = tdb_error(pdb->tdb); 2569 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2311 2570 } 2312 2571 2313 2572 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) { 2314 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) { 2315 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n", 2316 sharename)); 2573 terr = tdb_error(pdb->tdb); 2574 if (terr != TDB_ERR_NOEXIST) { 2575 DEBUG(0, ("allocate_print_jobid: " 2576 "Failed to fetch INFO/nextjob " 2577 "for print queue %s\n", sharename)); 2317 2578 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); 2318 return False;2579 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2319 2580 } 2320 DEBUG(10,("allocate_print_jobid: no existing jobid in %s\n", sharename)); 2581 DEBUG(10, ("allocate_print_jobid: " 2582 "No existing jobid in %s\n", sharename)); 2321 2583 jobid = 0; 2322 2584 } 2323 2585 2324 DEBUG(10,("allocate_print_jobid: read jobid %u from %s\n", jobid, sharename)); 2586 DEBUG(10, ("allocate_print_jobid: " 2587 "Read jobid %u from %s\n", jobid, sharename)); 2325 2588 2326 2589 jobid = NEXT_JOBID(jobid); 2327 2590 2328 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) { 2329 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n")); 2591 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid); 2592 if (ret == -1) { 2593 terr = tdb_error(pdb->tdb); 2594 DEBUG(3, ("allocate_print_jobid: " 2595 "Failed to store INFO/nextjob.\n")); 2330 2596 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); 2331 return False;2597 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2332 2598 } 2333 2599 … … 2338 2604 break; 2339 2605 } 2340 DEBUG(10,("allocate_print_jobid: found jobid %u in %s\n", jobid, sharename)); 2606 DEBUG(10, ("allocate_print_jobid: " 2607 "Found jobid %u in %s\n", jobid, sharename)); 2341 2608 } 2342 2609 2343 2610 if (i > 2) { 2344 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n", 2345 sharename)); 2611 DEBUG(0, ("allocate_print_jobid: " 2612 "Failed to allocate a print job for queue %s\n", 2613 sharename)); 2346 2614 /* Probably full... */ 2347 errno = ENOSPC; 2348 return False; 2615 return WERR_NO_SPOOL_SPACE; 2349 2616 } 2350 2617 … … 2357 2624 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum, 2358 2625 TDB_INSERT) == -1) { 2359 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n", 2360 jobid )); 2361 return False; 2626 DEBUG(3, ("allocate_print_jobid: " 2627 "jobid (%d) failed to store placeholder.\n", 2628 jobid )); 2629 terr = tdb_error(pdb->tdb); 2630 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2362 2631 } 2363 2632 } 2364 2633 2365 2634 *pjobid = jobid; 2366 return True;2635 return WERR_OK; 2367 2636 } 2368 2637 2369 2638 /*************************************************************************** 2370 Append a jobid to the 'jobs changed' list.2639 Append a jobid to the 'jobs added' list. 2371 2640 ***************************************************************************/ 2372 2641 2373 static bool add_to_jobs_ changed(struct tdb_print_db *pdb, uint32 jobid)2642 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid) 2374 2643 { 2375 2644 TDB_DATA data; … … 2380 2649 data.dsize = 4; 2381 2650 2382 DEBUG(10,("add_to_jobs_ changed: Added jobid %u\n", (unsigned int)jobid ));2383 2384 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_ changed"),2651 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid )); 2652 2653 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"), 2385 2654 data) == 0); 2655 } 2656 2657 2658 /*************************************************************************** 2659 Do all checks needed to determine if we can start a job. 2660 ***************************************************************************/ 2661 2662 static WERROR print_job_checks(const struct auth_serversupplied_info *server_info, 2663 struct messaging_context *msg_ctx, 2664 int snum, int *njobs) 2665 { 2666 const char *sharename = lp_const_servicename(snum); 2667 uint64_t dspace, dsize; 2668 uint64_t minspace; 2669 int ret; 2670 2671 if (!print_access_check(server_info, msg_ctx, snum, 2672 PRINTER_ACCESS_USE)) { 2673 DEBUG(3, ("print_job_checks: " 2674 "job start denied by security descriptor\n")); 2675 return WERR_ACCESS_DENIED; 2676 } 2677 2678 if (!print_time_access_check(server_info, msg_ctx, sharename)) { 2679 DEBUG(3, ("print_job_checks: " 2680 "job start denied by time check\n")); 2681 return WERR_ACCESS_DENIED; 2682 } 2683 2684 /* see if we have sufficient disk space */ 2685 if (lp_minprintspace(snum)) { 2686 minspace = lp_minprintspace(snum); 2687 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize); 2688 if (ret == 0 && dspace < 2*minspace) { 2689 DEBUG(3, ("print_job_checks: " 2690 "disk space check failed.\n")); 2691 return WERR_NO_SPOOL_SPACE; 2692 } 2693 } 2694 2695 /* for autoloaded printers, check that the printcap entry still exists */ 2696 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) { 2697 DEBUG(3, ("print_job_checks: printer name %s check failed.\n", 2698 sharename)); 2699 return WERR_ACCESS_DENIED; 2700 } 2701 2702 /* Insure the maximum queue size is not violated */ 2703 *njobs = print_queue_length(msg_ctx, snum, NULL); 2704 if (*njobs > lp_maxprintjobs(snum)) { 2705 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) " 2706 "larger than max printjobs per queue (%d).\n", 2707 sharename, *njobs, lp_maxprintjobs(snum))); 2708 return WERR_NO_SPOOL_SPACE; 2709 } 2710 2711 return WERR_OK; 2712 } 2713 2714 /*************************************************************************** 2715 Create a job file. 2716 ***************************************************************************/ 2717 2718 static WERROR print_job_spool_file(int snum, uint32_t jobid, 2719 const char *output_file, 2720 struct printjob *pjob) 2721 { 2722 WERROR werr; 2723 SMB_STRUCT_STAT st; 2724 const char *path; 2725 int len; 2726 2727 /* if this file is within the printer path, it means that smbd 2728 * is spooling it and will pass us control when it is finished. 2729 * Verify that the file name is ok, within path, and it is 2730 * already already there */ 2731 if (output_file) { 2732 path = lp_pathname(snum); 2733 len = strlen(path); 2734 if (strncmp(output_file, path, len) == 0 && 2735 (output_file[len - 1] == '/' || output_file[len] == '/')) { 2736 2737 /* verify path is not too long */ 2738 if (strlen(output_file) >= sizeof(pjob->filename)) { 2739 return WERR_INVALID_NAME; 2740 } 2741 2742 /* verify that the file exists */ 2743 if (sys_stat(output_file, &st, false) != 0) { 2744 return WERR_INVALID_NAME; 2745 } 2746 2747 fstrcpy(pjob->filename, output_file); 2748 2749 DEBUG(3, ("print_job_spool_file:" 2750 "External spooling activated")); 2751 2752 /* we do not open the file until spooling is done */ 2753 pjob->fd = -1; 2754 pjob->status = PJOB_SMBD_SPOOLING; 2755 2756 return WERR_OK; 2757 } 2758 } 2759 2760 slprintf(pjob->filename, sizeof(pjob->filename)-1, 2761 "%s/%s%.8u.XXXXXX", lp_pathname(snum), 2762 PRINT_SPOOL_PREFIX, (unsigned int)jobid); 2763 pjob->fd = mkstemp(pjob->filename); 2764 2765 if (pjob->fd == -1) { 2766 werr = map_werror_from_unix(errno); 2767 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) { 2768 /* Common setup error, force a report. */ 2769 DEBUG(0, ("print_job_spool_file: " 2770 "insufficient permissions to open spool " 2771 "file %s.\n", pjob->filename)); 2772 } else { 2773 /* Normal case, report at level 3 and above. */ 2774 DEBUG(3, ("print_job_spool_file: " 2775 "can't open spool file %s\n", 2776 pjob->filename)); 2777 } 2778 return werr; 2779 } 2780 2781 return WERR_OK; 2386 2782 } 2387 2783 … … 2390 2786 ***************************************************************************/ 2391 2787 2392 uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, 2393 const char *jobname, NT_DEVICEMODE *nt_devmode ) 2394 { 2395 uint32 jobid; 2788 WERROR print_job_start(const struct auth_serversupplied_info *server_info, 2789 struct messaging_context *msg_ctx, 2790 const char *clientmachine, 2791 int snum, const char *docname, const char *filename, 2792 struct spoolss_DeviceMode *devmode, uint32_t *_jobid) 2793 { 2794 uint32_t jobid; 2396 2795 char *path; 2397 2796 struct printjob pjob; … … 2399 2798 struct tdb_print_db *pdb = get_print_db_byname(sharename); 2400 2799 int njobs; 2401 2402 errno = 0; 2403 2404 if (!pdb) 2405 return (uint32)-1; 2406 2407 if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) { 2408 DEBUG(3, ("print_job_start: job start denied by security descriptor\n")); 2800 WERROR werr; 2801 2802 if (!pdb) { 2803 return WERR_INTERNAL_DB_CORRUPTION; 2804 } 2805 2806 path = lp_pathname(snum); 2807 2808 werr = print_job_checks(server_info, msg_ctx, snum, &njobs); 2809 if (!W_ERROR_IS_OK(werr)) { 2409 2810 release_print_db(pdb); 2410 return (uint32)-1; 2411 } 2412 2413 if (!print_time_access_check(lp_servicename(snum))) { 2414 DEBUG(3, ("print_job_start: job start denied by time check\n")); 2415 release_print_db(pdb); 2416 return (uint32)-1; 2417 } 2418 2419 path = lp_pathname(snum); 2420 2421 /* see if we have sufficient disk space */ 2422 if (lp_minprintspace(snum)) { 2423 uint64_t dspace, dsize; 2424 if (sys_fsusage(path, &dspace, &dsize) == 0 && 2425 dspace < 2*(uint64_t)lp_minprintspace(snum)) { 2426 DEBUG(3, ("print_job_start: disk space check failed.\n")); 2427 release_print_db(pdb); 2428 errno = ENOSPC; 2429 return (uint32)-1; 2430 } 2431 } 2432 2433 /* for autoloaded printers, check that the printcap entry still exists */ 2434 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) { 2435 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) )); 2436 release_print_db(pdb); 2437 errno = ENOENT; 2438 return (uint32)-1; 2439 } 2440 2441 /* Insure the maximum queue size is not violated */ 2442 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { 2443 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n", 2444 sharename, njobs, lp_maxprintjobs(snum) )); 2445 release_print_db(pdb); 2446 errno = ENOSPC; 2447 return (uint32)-1; 2448 } 2449 2450 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n", 2451 sharename, njobs, lp_maxprintjobs(snum) )); 2452 2453 if (!allocate_print_jobid(pdb, snum, sharename, &jobid)) 2811 return werr; 2812 } 2813 2814 DEBUG(10, ("print_job_start: " 2815 "Queue %s number of jobs (%d), max printjobs = %d\n", 2816 sharename, njobs, lp_maxprintjobs(snum))); 2817 2818 werr = allocate_print_jobid(pdb, snum, sharename, &jobid); 2819 if (!W_ERROR_IS_OK(werr)) { 2454 2820 goto fail; 2821 } 2455 2822 2456 2823 /* create the database entry */ … … 2466 2833 pjob.spooled = False; 2467 2834 pjob.smbjob = True; 2468 pjob.nt_devmode = nt_devmode; 2469 2470 fstrcpy(pjob.jobname, jobname); 2835 pjob.devmode = devmode; 2836 2837 fstrcpy(pjob.jobname, docname); 2838 2839 fstrcpy(pjob.clientmachine, clientmachine); 2471 2840 2472 2841 fstrcpy(pjob.user, lp_printjob_username(snum)); … … 2474 2843 path, server_info->utok.gid, 2475 2844 server_info->sanitized_username, 2476 pdb_get_domain(server_info->sam_account),2845 server_info->info3->base.domain.string, 2477 2846 pjob.user, sizeof(pjob.user)-1); 2478 2847 /* ensure NULL termination */ … … 2482 2851 2483 2852 /* we have a job entry - now create the spool file */ 2484 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 2485 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid); 2486 pjob.fd = mkstemp(pjob.filename); 2487 2488 if (pjob.fd == -1) { 2489 if (errno == EACCES) { 2490 /* Common setup error, force a report. */ 2491 DEBUG(0, ("print_job_start: insufficient permissions \ 2492 to open spool file %s.\n", pjob.filename)); 2493 } else { 2494 /* Normal case, report at level 3 and above. */ 2495 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename)); 2496 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno))); 2497 } 2853 werr = print_job_spool_file(snum, jobid, filename, &pjob); 2854 if (!W_ERROR_IS_OK(werr)) { 2498 2855 goto fail; 2499 2856 } 2500 2857 2501 pjob_store(s harename, jobid, &pjob);2502 2503 /* Update the 'jobs changed' entry used by print_queue_status. */2504 add_to_jobs_ changed(pdb, jobid);2858 pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob); 2859 2860 /* Update the 'jobs added' entry used by print_queue_status. */ 2861 add_to_jobs_added(pdb, jobid); 2505 2862 2506 2863 /* Ensure we keep a rough count of the number of total jobs... */ … … 2509 2866 release_print_db(pdb); 2510 2867 2511 return jobid; 2512 2513 fail: 2514 if (jobid != -1) 2515 pjob_delete(sharename, jobid); 2868 *_jobid = jobid; 2869 return WERR_OK; 2870 2871 fail: 2872 if (jobid != -1) { 2873 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 2874 } 2516 2875 2517 2876 release_print_db(pdb); 2518 2877 2519 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); 2520 return (uint32)-1; 2878 DEBUG(3, ("print_job_start: returning fail. " 2879 "Error = %s\n", win_errstr(werr))); 2880 return werr; 2521 2881 } 2522 2882 … … 2525 2885 ****************************************************************************/ 2526 2886 2527 void print_job_endpage(int snum, uint32 jobid) 2887 void print_job_endpage(struct messaging_context *msg_ctx, 2888 int snum, uint32 jobid) 2528 2889 { 2529 2890 const char* sharename = lp_const_servicename(snum); … … 2538 2899 2539 2900 pjob->page_count++; 2540 pjob_store(s harename, jobid, pjob);2901 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob); 2541 2902 } 2542 2903 … … 2547 2908 ****************************************************************************/ 2548 2909 2549 bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type) 2910 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum, 2911 uint32 jobid, enum file_close_type close_type) 2550 2912 { 2551 2913 const char* sharename = lp_const_servicename(snum); … … 2554 2916 SMB_STRUCT_STAT sbuf; 2555 2917 struct printif *current_printif = get_printer_fns( snum ); 2918 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 2556 2919 2557 2920 pjob = print_job_find(sharename, jobid); 2558 2921 2559 if (!pjob) 2560 return False; 2561 2562 if (pjob->spooled || pjob->pid != sys_getpid()) 2563 return False; 2564 2565 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && 2566 (sys_fstat(pjob->fd, &sbuf, false) == 0)) { 2922 if (!pjob) { 2923 return NT_STATUS_PRINT_CANCELLED; 2924 } 2925 2926 if (pjob->spooled || pjob->pid != sys_getpid()) { 2927 return NT_STATUS_ACCESS_DENIED; 2928 } 2929 2930 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) { 2931 if (pjob->status == PJOB_SMBD_SPOOLING) { 2932 /* take over the file now, smbd is done */ 2933 if (sys_stat(pjob->filename, &sbuf, false) != 0) { 2934 status = map_nt_error_from_unix(errno); 2935 DEBUG(3, ("print_job_end: " 2936 "stat file failed for jobid %d\n", 2937 jobid)); 2938 goto fail; 2939 } 2940 2941 pjob->status = LPQ_SPOOLING; 2942 2943 } else { 2944 2945 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) { 2946 status = map_nt_error_from_unix(errno); 2947 close(pjob->fd); 2948 DEBUG(3, ("print_job_end: " 2949 "stat file failed for jobid %d\n", 2950 jobid)); 2951 goto fail; 2952 } 2953 2954 close(pjob->fd); 2955 } 2956 2567 2957 pjob->size = sbuf.st_ex_size; 2568 close(pjob->fd);2569 pjob->fd = -1;2570 2958 } else { 2571 2959 2572 2960 /* 2573 * Not a normal close or we couldn't stat the job file, 2574 * so something has gone wrong. Cleanup. 2961 * Not a normal close, something has gone wrong. Cleanup. 2575 2962 */ 2576 close(pjob->fd);2577 pjob->fd = -1;2578 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));2963 if (pjob->fd != -1) { 2964 close(pjob->fd); 2965 } 2579 2966 goto fail; 2580 2967 } … … 2588 2975 pjob->filename, pjob->size ? "deleted" : "zero length" )); 2589 2976 unlink(pjob->filename); 2590 pjob_delete(s harename, jobid);2591 return True;2977 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 2978 return NT_STATUS_OK; 2592 2979 } 2593 2980 2594 2981 ret = (*(current_printif->job_submit))(snum, pjob); 2595 2982 2596 if (ret) 2983 if (ret) { 2984 status = NT_STATUS_PRINT_CANCELLED; 2597 2985 goto fail; 2986 } 2598 2987 2599 2988 /* The print job has been successfully handed over to the back-end */ … … 2601 2990 pjob->spooled = True; 2602 2991 pjob->status = LPQ_QUEUED; 2603 pjob_store(s harename, jobid, pjob);2992 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob); 2604 2993 2605 2994 /* make sure the database is up to date */ 2606 2995 if (print_cache_expired(lp_const_servicename(snum), True)) 2607 print_queue_update( snum, False);2608 2609 return True;2996 print_queue_update(msg_ctx, snum, False); 2997 2998 return NT_STATUS_OK; 2610 2999 2611 3000 fail: … … 2613 3002 /* The print job was not successfully started. Cleanup */ 2614 3003 /* Still need to add proper error return propagation! 010122:JRR */ 3004 pjob->fd = -1; 2615 3005 unlink(pjob->filename); 2616 pjob_delete(s harename, jobid);2617 return False;3006 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 3007 return status; 2618 3008 } 2619 3009 … … 2622 3012 ****************************************************************************/ 2623 3013 2624 static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue) 2625 { 2626 TDB_DATA data, cgdata; 3014 static bool get_stored_queue_info(struct messaging_context *msg_ctx, 3015 struct tdb_print_db *pdb, int snum, 3016 int *pcount, print_queue_struct **ppqueue) 3017 { 3018 TDB_DATA data, cgdata, jcdata; 2627 3019 print_queue_struct *queue = NULL; 2628 3020 uint32 qcount = 0; 2629 3021 uint32 extra_count = 0; 3022 uint32_t changed_count = 0; 2630 3023 int total_count = 0; 2631 3024 size_t len = 0; … … 2637 3030 /* make sure the database is up to date */ 2638 3031 if (print_cache_expired(lp_const_servicename(snum), True)) 2639 print_queue_update( snum, False);3032 print_queue_update(msg_ctx, snum, False); 2640 3033 2641 3034 *pcount = 0; … … 2651 3044 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount); 2652 3045 2653 /* Get the changed jobs list. */2654 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_ changed"));3046 /* Get the added jobs list. */ 3047 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added")); 2655 3048 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0)) 2656 3049 extra_count = cgdata.dsize/4; 3050 3051 /* Get the changed jobs list. */ 3052 jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed")); 3053 if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0)) 3054 changed_count = jcdata.dsize / 4; 2657 3055 2658 3056 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count)); … … 2688 3086 total_count = qcount; 2689 3087 2690 /* Add in the changed jobids. */3088 /* Add new jobids to the queue. */ 2691 3089 for( i = 0; i < extra_count; i++) { 2692 3090 uint32 jobid; … … 2694 3092 2695 3093 jobid = IVAL(cgdata.dptr, i*4); 2696 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));3094 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid)); 2697 3095 pjob = print_job_find(lp_const_servicename(snum), jobid); 2698 3096 if (!pjob) { 2699 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));2700 remove_from_jobs_ changed(sharename, jobid);3097 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid)); 3098 remove_from_jobs_added(sharename, jobid); 2701 3099 continue; 2702 3100 } … … 2713 3111 } 2714 3112 3113 /* Update the changed jobids. */ 3114 for (i = 0; i < changed_count; i++) { 3115 uint32_t jobid = IVAL(jcdata.dptr, i * 4); 3116 uint32_t j; 3117 bool found = false; 3118 3119 for (j = 0; j < total_count; j++) { 3120 if (queue[j].job == jobid) { 3121 found = true; 3122 break; 3123 } 3124 } 3125 3126 if (found) { 3127 struct printjob *pjob; 3128 3129 DEBUG(5,("get_stored_queue_info: changed job: %u\n", 3130 (unsigned int) jobid)); 3131 3132 pjob = print_job_find(sharename, jobid); 3133 if (pjob == NULL) { 3134 DEBUG(5,("get_stored_queue_info: failed to find " 3135 "changed job = %u\n", 3136 (unsigned int) jobid)); 3137 remove_from_jobs_changed(sharename, jobid); 3138 continue; 3139 } 3140 3141 queue[j].job = jobid; 3142 queue[j].size = pjob->size; 3143 queue[j].page_count = pjob->page_count; 3144 queue[j].status = pjob->status; 3145 queue[j].priority = 1; 3146 queue[j].time = pjob->starttime; 3147 fstrcpy(queue[j].fs_user, pjob->user); 3148 fstrcpy(queue[j].fs_file, pjob->jobname); 3149 3150 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n", 3151 (unsigned int) j, (unsigned int) jobid, pjob->jobname)); 3152 } 3153 3154 remove_from_jobs_changed(sharename, jobid); 3155 } 3156 2715 3157 /* Sort the queue by submission time otherwise they are displayed 2716 3158 in hash order. */ 2717 3159 2718 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));3160 TYPESAFE_QSORT(queue, total_count, printjob_comp); 2719 3161 2720 3162 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count)); … … 2740 3182 ****************************************************************************/ 2741 3183 2742 int print_queue_status( int snum,3184 int print_queue_status(struct messaging_context *msg_ctx, int snum, 2743 3185 print_queue_struct **ppqueue, 2744 3186 print_status_struct *status) … … 2753 3195 2754 3196 if (print_cache_expired(lp_const_servicename(snum), True)) 2755 print_queue_update( snum, False);3197 print_queue_update(msg_ctx, snum, False); 2756 3198 2757 3199 /* return if we are done */ … … 2790 3232 */ 2791 3233 2792 if (!get_stored_queue_info( pdb, snum, &count, ppqueue)) {3234 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) { 2793 3235 release_print_db(pdb); 2794 3236 return 0; … … 2803 3245 ****************************************************************************/ 2804 3246 2805 WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum) 3247 WERROR print_queue_pause(const struct auth_serversupplied_info *server_info, 3248 struct messaging_context *msg_ctx, int snum) 2806 3249 { 2807 3250 int ret; 2808 3251 struct printif *current_printif = get_printer_fns( snum ); 2809 3252 2810 if (!print_access_check(server_info, snum,3253 if (!print_access_check(server_info, msg_ctx, snum, 2811 3254 PRINTER_ACCESS_ADMINISTER)) { 2812 3255 return WERR_ACCESS_DENIED; … … 2829 3272 /* Send a printer notify message */ 2830 3273 2831 notify_printer_status(snum, PRINTER_STATUS_PAUSED); 3274 notify_printer_status(server_event_context(), msg_ctx, snum, 3275 PRINTER_STATUS_PAUSED); 2832 3276 2833 3277 return WERR_OK; … … 2838 3282 ****************************************************************************/ 2839 3283 2840 WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum) 3284 WERROR print_queue_resume(const struct auth_serversupplied_info *server_info, 3285 struct messaging_context *msg_ctx, int snum) 2841 3286 { 2842 3287 int ret; 2843 3288 struct printif *current_printif = get_printer_fns( snum ); 2844 3289 2845 if (!print_access_check(server_info, snum,3290 if (!print_access_check(server_info, msg_ctx, snum, 2846 3291 PRINTER_ACCESS_ADMINISTER)) { 2847 3292 return WERR_ACCESS_DENIED; … … 2860 3305 /* make sure the database is up to date */ 2861 3306 if (print_cache_expired(lp_const_servicename(snum), True)) 2862 print_queue_update( snum, True);3307 print_queue_update(msg_ctx, snum, True); 2863 3308 2864 3309 /* Send a printer notify message */ 2865 3310 2866 notify_printer_status(snum, PRINTER_STATUS_OK); 3311 notify_printer_status(server_event_context(), msg_ctx, snum, 3312 PRINTER_STATUS_OK); 2867 3313 2868 3314 return WERR_OK; … … 2873 3319 ****************************************************************************/ 2874 3320 2875 WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum) 3321 WERROR print_queue_purge(const struct auth_serversupplied_info *server_info, 3322 struct messaging_context *msg_ctx, int snum) 2876 3323 { 2877 3324 print_queue_struct *queue; … … 2881 3328 2882 3329 /* Force and update so the count is accurate (i.e. not a cached count) */ 2883 print_queue_update(snum, True); 2884 2885 can_job_admin = print_access_check(server_info, snum, 3330 print_queue_update(msg_ctx, snum, True); 3331 3332 can_job_admin = print_access_check(server_info, 3333 msg_ctx, 3334 snum, 2886 3335 JOB_ACCESS_ADMINISTER); 2887 njobs = print_queue_status( snum, &queue, &status);3336 njobs = print_queue_status(msg_ctx, snum, &queue, &status); 2888 3337 2889 3338 if ( can_job_admin ) … … 2895 3344 2896 3345 if (owner || can_job_admin) { 2897 print_job_delete1(snum, queue[i].job); 3346 print_job_delete1(server_event_context(), msg_ctx, 3347 snum, queue[i].job); 2898 3348 } 2899 3349 } … … 2903 3353 2904 3354 /* update the cache */ 2905 print_queue_update( snum, True);3355 print_queue_update(msg_ctx, snum, True); 2906 3356 2907 3357 SAFE_FREE(queue);
Note:
See TracChangeset
for help on using the changeset viewer.