[SCM] Samba Shared Repository - branch master updated
Andreas Schneider
asn at samba.org
Fri Sep 10 08:12:14 MDT 2010
The branch, master has been updated
via fc1a5db s3-spoolss: Don't leak memory on the session counter list.
via ed2c06f s3-spoolss: Allow multiple client backchannels.
via a736385 s3-spoolss: Split function to send notification.
via 9db2be2 s3-spoolss: Use a single structure for all the back channel data.
via 433ac75 s3-spoolss: Rename Printer_entry to struct printer_handle.
via 4a8d042 s3-spoolss: Move Printer_entry to srv_spoolss_nt.c
via e257e68 s3-spoolss: Allocate printer entries on the pipe struct.
via 0e5b1a6 s3-spoolss: Rename session counter structure and use talloc.
from c59961d s3-dsgetdcname: cleanup receive_getdc_response a little.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit fc1a5dbffb1330bba0e4deebdf18b812ccc1a823
Author: Andreas Schneider <asn at samba.org>
Date: Fri Sep 10 16:06:24 2010 +0200
s3-spoolss: Don't leak memory on the session counter list.
Thanks Günther, please check.
commit ed2c06f9da0401fb95dcc16b4d3a3bd4f27b09f2
Author: Simo Sorce <idra at samba.org>
Date: Thu Jul 1 19:39:57 2010 -0400
s3-spoolss: Allow multiple client backchannels.
When we run spoolssd we need to support multiple clients connecting.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit a736385b9749fe127411348ff3e0d1cc4405e47f
Author: Simo Sorce <idra at samba.org>
Date: Wed Jun 30 18:35:29 2010 -0400
s3-spoolss: Split function to send notification.
More digestible this way.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 9db2be245e89e14f4c95037f67e7092f298a74f5
Author: Simo Sorce <idra at samba.org>
Date: Wed Jun 30 14:19:43 2010 -0400
s3-spoolss: Use a single structure for all the back channel data.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 433ac757dcac5841a47db3350865771a5d7301b2
Author: Simo Sorce <idra at samba.org>
Date: Wed Jun 30 15:32:15 2010 -0400
s3-spoolss: Rename Printer_entry to struct printer_handle.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 4a8d042afa41510b557e13b2aafcff611a137f28
Author: Simo Sorce <idra at samba.org>
Date: Wed Jun 30 15:11:41 2010 -0400
s3-spoolss: Move Printer_entry to srv_spoolss_nt.c
It is used only there, and it is a good idea to make this one private and
opaque to the rest of the code.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit e257e68b4bcd49c6401b0982e71f3f3085711750
Author: Simo Sorce <idra at samba.org>
Date: Wed Jun 30 12:19:41 2010 -0400
s3-spoolss: Allocate printer entries on the pipe struct.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 0e5b1a67d26f99ae6d6f5e05f968dd3107191791
Author: Simo Sorce <idra at samba.org>
Date: Wed Jun 30 12:07:44 2010 -0400
s3-spoolss: Rename session counter structure and use talloc.
Signed-off-by: Andreas Schneider <asn at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source3/include/nt_printing.h | 40 ---
source3/include/proto.h | 1 +
source3/rpc_server/srv_spoolss_nt.c | 646 +++++++++++++++++++++--------------
source3/smbd/server.c | 9 +-
4 files changed, 399 insertions(+), 297 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h
index f56ddcb..52b11fe 100644
--- a/source3/include/nt_printing.h
+++ b/source3/include/nt_printing.h
@@ -162,46 +162,6 @@ typedef struct {
#define SPLHND_PORTMON_TCP 3
#define SPLHND_PORTMON_LOCAL 4
-/* structure to store the printer handles */
-/* and a reference to what it's pointing to */
-/* and the notify info asked about */
-/* that's the central struct */
-typedef struct _Printer{
- struct _Printer *prev, *next;
- bool document_started;
- bool page_started;
- uint32 jobid; /* jobid in printing backend */
- int printer_type;
- fstring servername;
- fstring sharename;
- uint32 type;
- uint32 access_granted;
- struct {
- uint32 flags;
- uint32 options;
- fstring localmachine;
- uint32 printerlocal;
- struct spoolss_NotifyOption *option;
- struct policy_handle client_hnd;
- bool client_connected;
- uint32 change;
- /* are we in a FindNextPrinterChangeNotify() call? */
- bool fnpcn;
- struct messaging_context *msg_ctx;
- } notify;
- struct {
- fstring machine;
- fstring user;
- } client;
-
- /* devmode sent in the OpenPrinter() call */
- struct spoolss_DeviceMode *devmode;
-
- /* TODO cache the printer info2 structure */
- struct spoolss_PrinterInfo2 *info2;
-
-} Printer_entry;
-
/*
* The printer attributes.
* I #defined all of them (grabbed form MSDN)
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 0b54932..5e2e0bf 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4386,6 +4386,7 @@ NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
bool *is_data_outstanding);
/* The following definitions come from rpc_server/srv_spoolss_nt.c */
+void srv_spoolss_cleanup(void);
void do_drv_upgrade_printer(struct messaging_context *msg,
void *private_data,
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 8978971..b5e2ddb 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -57,21 +57,76 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
-static Printer_entry *printers_list;
+#ifndef MAX_OPEN_PRINTER_EXS
+#define MAX_OPEN_PRINTER_EXS 50
+#endif
+
+struct notify_back_channel;
+
+/* structure to store the printer handles */
+/* and a reference to what it's pointing to */
+/* and the notify info asked about */
+/* that's the central struct */
+struct printer_handle {
+ struct printer_handle *prev, *next;
+ bool document_started;
+ bool page_started;
+ uint32 jobid; /* jobid in printing backend */
+ int printer_type;
+ fstring servername;
+ fstring sharename;
+ uint32 type;
+ uint32 access_granted;
+ struct {
+ uint32 flags;
+ uint32 options;
+ fstring localmachine;
+ uint32 printerlocal;
+ struct spoolss_NotifyOption *option;
+ struct policy_handle cli_hnd;
+ struct notify_back_channel *cli_chan;
+ uint32 change;
+ /* are we in a FindNextPrinterChangeNotify() call? */
+ bool fnpcn;
+ struct messaging_context *msg_ctx;
+ } notify;
+ struct {
+ fstring machine;
+ fstring user;
+ } client;
+
+ /* devmode sent in the OpenPrinter() call */
+ struct spoolss_DeviceMode *devmode;
-typedef struct _counter_printer_0 {
- struct _counter_printer_0 *next;
- struct _counter_printer_0 *prev;
+ /* TODO cache the printer info2 structure */
+ struct spoolss_PrinterInfo2 *info2;
+
+};
+
+static struct printer_handle *printers_list;
+
+struct printer_session_counter {
+ struct printer_session_counter *next;
+ struct printer_session_counter *prev;
int snum;
uint32_t counter;
-} counter_printer_0;
+};
-static counter_printer_0 *counter_list;
+static struct printer_session_counter *counter_list;
-static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
-static uint32_t smb_connections = 0;
+struct notify_back_channel {
+ struct notify_back_channel *prev, *next;
+ /* associated client */
+ struct sockaddr_storage client_address;
+
+ /* print notify back-channel pipe handle*/
+ struct rpc_pipe_client *cli_pipe;
+ uint32_t active_connections;
+};
+
+static struct notify_back_channel *back_channels;
/* Map generic permissions to printer object specific permissions */
@@ -162,9 +217,8 @@ static int nt_printq_status(int v)
Disconnect from the client
****************************************************************************/
-static void srv_spoolss_replycloseprinter(
- int snum, struct policy_handle *handle,
- struct messaging_context *msg_ctx)
+static void srv_spoolss_replycloseprinter(int snum,
+ struct printer_handle *prn_hnd)
{
WERROR result;
NTSTATUS status;
@@ -174,34 +228,40 @@ static void srv_spoolss_replycloseprinter(
* by deregistering our PID.
*/
- if (!print_notify_deregister_pid(snum))
- DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
+ if (!print_notify_deregister_pid(snum)) {
+ DEBUG(0, ("Failed to register our pid for printer %s\n",
+ lp_const_servicename(snum)));
+ }
/* weird if the test succeeds !!! */
- if (smb_connections==0) {
- DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
+ if (prn_hnd->notify.cli_chan == NULL ||
+ prn_hnd->notify.cli_chan->active_connections == 0) {
+ DEBUG(0, ("Trying to close unexisting backchannel!\n"));
+ DLIST_REMOVE(back_channels, prn_hnd->notify.cli_chan);
+ TALLOC_FREE(prn_hnd->notify.cli_chan);
return;
}
- status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
- handle,
- &result);
- if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
- DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
- win_errstr(result)));
+ status = rpccli_spoolss_ReplyClosePrinter(
+ prn_hnd->notify.cli_chan->cli_pipe,
+ talloc_tos(),
+ &prn_hnd->notify.cli_hnd,
+ &result);
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("reply_close_printer failed [%s].\n",
+ win_errstr(result)));
+ }
/* if it's the last connection, deconnect the IPC$ share */
- if (smb_connections==1) {
+ if (prn_hnd->notify.cli_chan->active_connections == 1) {
- cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
- /*
- * The above call shuts down the pipe also.
- */
- notify_cli_pipe = NULL;
+ cli_shutdown(rpc_pipe_np_smb_conn(prn_hnd->notify.cli_chan->cli_pipe));
+ DLIST_REMOVE(back_channels, prn_hnd->notify.cli_chan);
+ TALLOC_FREE(prn_hnd->notify.cli_chan);
- if (msg_ctx != NULL) {
- messaging_deregister(msg_ctx, MSG_PRINTER_NOTIFY2,
- NULL);
+ if (prn_hnd->notify.msg_ctx != NULL) {
+ messaging_deregister(prn_hnd->notify.msg_ctx,
+ MSG_PRINTER_NOTIFY2, NULL);
/*
* Tell the serverid.tdb we're no longer
@@ -209,34 +269,39 @@ static void srv_spoolss_replycloseprinter(
*/
serverid_register_msg_flags(
- messaging_server_id(msg_ctx),
+ messaging_server_id(prn_hnd->notify.msg_ctx),
false, FLAG_MSG_PRINT_NOTIFY);
}
}
- smb_connections--;
+ if (prn_hnd->notify.cli_chan) {
+ prn_hnd->notify.cli_chan->active_connections--;
+ }
}
/****************************************************************************
Functions to free a printer entry datastruct.
****************************************************************************/
-static int printer_entry_destructor(Printer_entry *Printer)
+static int printer_entry_destructor(struct printer_handle *Printer)
{
- if (Printer->notify.client_connected == true) {
+ if (Printer->notify.cli_chan != NULL &&
+ Printer->notify.cli_chan->active_connections > 0) {
int snum = -1;
- if ( Printer->printer_type == SPLHND_SERVER) {
- snum = -1;
- srv_spoolss_replycloseprinter(
- snum, &Printer->notify.client_hnd,
- Printer->notify.msg_ctx);
- } else if (Printer->printer_type == SPLHND_PRINTER) {
+ switch(Printer->printer_type) {
+ case SPLHND_SERVER:
+ srv_spoolss_replycloseprinter(snum, Printer);
+ break;
+
+ case SPLHND_PRINTER:
snum = print_queue_snum(Printer->sharename);
- if (snum != -1)
- srv_spoolss_replycloseprinter(
- snum, &Printer->notify.client_hnd,
- Printer->notify.msg_ctx);
+ if (snum != -1) {
+ srv_spoolss_replycloseprinter(snum, Printer);
+ }
+ break;
+ default:
+ break;
}
}
@@ -245,8 +310,6 @@ static int printer_entry_destructor(Printer_entry *Printer)
Printer->notify.localmachine[0]='\0';
Printer->notify.printerlocal=0;
TALLOC_FREE(Printer->notify.option);
- Printer->notify.client_connected = false;
-
TALLOC_FREE(Printer->devmode);
/* Remove from the internal list. */
@@ -258,10 +321,10 @@ static int printer_entry_destructor(Printer_entry *Printer)
find printer index by handle
****************************************************************************/
-static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
- struct policy_handle *hnd)
+static struct printer_handle *find_printer_index_by_hnd(struct pipes_struct *p,
+ struct policy_handle *hnd)
{
- Printer_entry *find_printer = NULL;
+ struct printer_handle *find_printer = NULL;
if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
@@ -277,7 +340,7 @@ static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
{
- Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
+ struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
if (!Printer) {
DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
@@ -359,7 +422,7 @@ static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
{
- Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
+ struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
WERROR result;
if (!Printer) {
@@ -409,7 +472,7 @@ static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle
static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
int *number, struct share_params **params)
{
- Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
+ struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
if (!Printer) {
DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
@@ -434,7 +497,7 @@ static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
Check if it's \\server or \\server\printer
****************************************************************************/
-static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
+static bool set_printer_hnd_printertype(struct printer_handle *Printer, const char *handlename)
{
DEBUG(3,("Setting printer type=%s\n", handlename));
@@ -473,7 +536,7 @@ static void prune_printername_cache(void)
static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
const struct auth_serversupplied_info *server_info,
struct messaging_context *msg_ctx,
- Printer_entry *Printer,
+ struct printer_handle *Printer,
const char *handlename)
{
int snum;
@@ -642,16 +705,17 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
const char *name, uint32_t access_granted)
{
- Printer_entry *new_printer;
+ struct printer_handle *new_printer;
DEBUG(10,("open_printer_hnd: name [%s]\n", name));
- new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
+ new_printer = talloc_zero(p->mem_ctx, struct printer_handle);
if (new_printer == NULL) {
return false;
}
talloc_set_destructor(new_printer, printer_entry_destructor);
+ /* This also steals the printer_handle on the policy_handle */
if (!create_policy_hnd(p, hnd, new_printer)) {
TALLOC_FREE(new_printer);
return false;
@@ -694,7 +758,7 @@ static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
return true;
}
-static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
+static bool is_monitoring_event(struct printer_handle *p, uint16_t notify_type,
uint16_t notify_field)
{
struct spoolss_NotifyOption *option = p->notify.option;
@@ -1033,168 +1097,205 @@ static void construct_info_data(struct spoolss_Notify *info_data,
back registered
**********************************************************************/
-static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
+static int build_notify2_messages(TALLOC_CTX *mem_ctx,
+ struct printer_handle *prn_hnd,
+ SPOOLSS_NOTIFY_MSG *messages,
+ uint32_t num_msgs,
+ struct spoolss_Notify **_notifies,
+ int *_count)
{
- Printer_entry *p;
- TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
- SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
- SPOOLSS_NOTIFY_MSG *messages;
- int sending_msg_count;
-
- if ( !msg_group ) {
- DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
- return;
- }
-
- messages = msg_group->msgs;
+ struct spoolss_Notify *notifies;
+ SPOOLSS_NOTIFY_MSG *msg;
+ int count = 0;
+ uint32_t id;
+ int i;
- if ( !messages ) {
- DEBUG(5,("send_notify2_changes() called with no messages!\n"));
- return;
+ notifies = talloc_zero_array(mem_ctx,
+ struct spoolss_Notify, num_msgs);
+ if (!notifies) {
+ return ENOMEM;
}
- DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
+ for (i = 0; i < num_msgs; i++) {
- /* loop over all printers */
-
- for (p = printers_list; p; p = p->next) {
- struct spoolss_Notify *notifies;
- uint32_t count = 0;
- uint32_t id;
- int i;
+ msg = &messages[i];
- /* Is there notification on this handle? */
+ /* Are we monitoring this event? */
- if ( !p->notify.client_connected )
+ if (!is_monitoring_event(prn_hnd, msg->type, msg->field)) {
continue;
+ }
- DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
+ DEBUG(10, ("Sending message type [0x%x] field [0x%2x] "
+ "for printer [%s]\n",
+ msg->type, msg->field, prn_hnd->sharename));
- /* For this printer? Print servers always receive
- notifications. */
+ /*
+ * if the is a printer notification handle and not a job
+ * notification type, then set the id to 0.
+ * Otherwise just use what was specified in the message.
+ *
+ * When registering change notification on a print server
+ * handle we always need to send back the id (snum) matching
+ * the printer for which the change took place.
+ * For change notify registered on a printer handle,
+ * this does not matter and the id should be 0.
+ *
+ * --jerry
+ */
- if ( ( p->printer_type == SPLHND_PRINTER ) &&
- ( !strequal(msg_group->printername, p->sharename) ) )
- continue;
+ if ((msg->type == PRINTER_NOTIFY_TYPE) &&
+ (prn_hnd->printer_type == SPLHND_PRINTER)) {
+ id = 0;
+ } else {
+ id = msg->id;
+ }
- DEBUG(10,("Our printer\n"));
+ /* Convert unix jobid to smb jobid */
- /* allocate the max entries possible */
+ if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
+ id = sysjob_to_jobid(msg->id);
- notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
- if (!notifies) {
- return;
+ if (id == -1) {
+ DEBUG(3, ("no such unix jobid %d\n",
+ msg->id));
+ continue;
+ }
}
- /* build the array of change notifications */
+ construct_info_data(¬ifies[count],
+ msg->type, msg->field, id);
- sending_msg_count = 0;
+ switch(msg->type) {
+ case PRINTER_NOTIFY_TYPE:
+ if (printer_notify_table[msg->field].fn) {
+ printer_notify_table[msg->field].fn(msg,
+ ¬ifies[count], mem_ctx);
+ }
+ break;
- for ( i=0; i<msg_group->num_msgs; i++ ) {
- SPOOLSS_NOTIFY_MSG *msg = &messages[i];
+ case JOB_NOTIFY_TYPE:
+ if (job_notify_table[msg->field].fn) {
+ job_notify_table[msg->field].fn(msg,
--
Samba Shared Repository
More information about the samba-cvs
mailing list