static counter_printer_0 *counter_list;
-static struct cli_state notify_cli; /* print notify back-channel */
+static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
static uint32 smb_connections=0;
return;
}
- result = cli_spoolss_reply_close_printer(¬ify_cli, notify_cli.mem_ctx, handle);
+ result = rpccli_spoolss_reply_close_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, handle);
if (!W_ERROR_IS_OK(result))
DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
/* if it's the last connection, deconnect the IPC$ share */
if (smb_connections==1) {
- cli_nt_session_close(¬ify_cli);
- cli_ulogoff(¬ify_cli);
- cli_shutdown(¬ify_cli);
+ cli_shutdown(notify_cli_pipe->cli);
+ notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
message_deregister(MSG_PRINTER_NOTIFY2);
/* Tell the connections db we're no longer interested in
return find_printer;
}
-#ifdef ENABLE_PRINT_HND_OBJECT_CACHE
-/****************************************************************************
- look for a printer object cached on an open printer handle
-****************************************************************************/
-
-WERROR find_printer_in_print_hnd_cache( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 **info2,
- const char *servername, const char *printername )
-{
- Printer_entry *p;
-
- DEBUG(10,("find_printer_in_print_hnd_cache: printer [\\\\%s\\%s]\n",
- servername, printername));
-
- for ( p=printers_list; p; p=p->next )
- {
- if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER
- && p->printer_info
- && strequal( p->sharename, printername )
- && strequal( p->servername, servername ) )
- {
- DEBUG(10,("Found printer\n"));
- *info2 = dup_printer_2( ctx, p->printer_info->info_2 );
- if ( *info2 )
- return WERR_OK;
- }
- }
-
- return WERR_INVALID_PRINTER_NAME;
-}
-
-/****************************************************************************
- destroy any cached printer_info_2 structures on open handles
-****************************************************************************/
-
-void invalidate_printer_hnd_cache( char *printername )
-{
- Printer_entry *p;
-
- DEBUG(10,("invalidate_printer_hnd_cache: printer [%s]\n", printername));
-
- for ( p=printers_list; p; p=p->next )
- {
- if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER
- && p->printer_info
- && StrCaseCmp(p->sharename, printername)==0)
- {
- DEBUG(10,("invalidating printer_info cache for handl:\n"));
- free_a_printer( &p->printer_info, 2 );
- p->printer_info = NULL;
- }
- }
-
- return;
-}
-#endif
-
/****************************************************************************
Close printer index by handle.
****************************************************************************/
return;
}
- if (!prs_init(&ps, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
+ if (!prs_init(&ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
DEBUG(5, ("notify_system_time: prs_init() failed\n"));
return;
}
}
if ( sending_msg_count ) {
- cli_spoolss_rrpcn( ¬ify_cli, mem_ctx, &p->notify.client_hnd,
+ rpccli_spoolss_rrpcn( notify_cli_pipe, mem_ctx, &p->notify.client_hnd,
data_len, data, p->notify.change, 0 );
}
}
Receive a notify2 message list
********************************************************************/
-static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, size_t len)
+static void receive_notify2_message_list(int msg_type, struct process_id src,
+ void *msg, size_t len)
{
size_t msg_count, i;
char *buf = (char *)msg;
return;
}
-#ifdef ENABLE_PRINT_HND_OBJECT_CACHE
-/********************************************************************
- callback to MSG_PRINTER_CHANGED. When a printer is changed by
- one smbd, all of processes must clear their printer cache immediately.
- ********************************************************************/
-
-void receive_printer_mod_msg(int msg_type, pid_t src, void *buf, size_t len)
-{
- fstring printername;
-
- fstrcpy( printername, buf );
-
- DEBUG(10,("receive_printer_mod_msg: Printer change [%s]\n", printername ));
-
- invalidate_printer_hnd_cache( printername );
-}
-#endif
-
/********************************************************************
Send a message to ourself about new driver being installed
so we can upgrade the information for each printer bound to this
DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
drivername));
- message_send_pid(sys_getpid(), MSG_PRINTER_DRVUPGRADE, drivername, len+1, False);
+ message_send_pid(pid_to_procid(sys_getpid()),
+ MSG_PRINTER_DRVUPGRADE, drivername, len+1, False);
return True;
}
over all printers, upgrading ones as necessary
**********************************************************************/
-void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
+void do_drv_upgrade_printer(int msg_type, struct process_id src, void *buf, size_t len)
{
fstring drivername;
int snum;
DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
drivername));
- message_send_pid(sys_getpid(), MSG_PRINTERDATA_INIT_RESET, drivername, len+1, False);
+ message_send_pid(pid_to_procid(sys_getpid()),
+ MSG_PRINTERDATA_INIT_RESET, drivername, len+1, False);
return True;
}
over all printers, resetting printer data as neessary
**********************************************************************/
-void reset_all_printerdata(int msg_type, pid_t src, void *buf, size_t len)
+void reset_all_printerdata(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
fstring drivername;
int snum;
* SPOOL_Q_OPEN_PRINTER_EX structure
********************************************************************/
-static void convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q_u_ex, SPOOL_Q_OPEN_PRINTER *q_u)
+static WERROR convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q_u_ex, SPOOL_Q_OPEN_PRINTER *q_u)
{
if (!q_u_ex || !q_u)
- return;
+ return WERR_OK;
DEBUG(8,("convert_to_openprinterex\n"));
if ( q_u->printername ) {
- q_u_ex->printername = TALLOC_P( ctx, UNISTR2 );
+ q_u_ex->printername = TALLOC_ZERO_P( ctx, UNISTR2 );
+ if (q_u_ex->printername == NULL)
+ return WERR_NOMEM;
copy_unistr2(q_u_ex->printername, q_u->printername);
}
copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default);
+
+ return WERR_OK;
}
/********************************************************************
/* convert the OpenPrinter() call to OpenPrinterEx() */
- convert_to_openprinterex(p->mem_ctx, &q_u_ex, q_u);
+ r_u_ex.status = convert_to_openprinterex(p->mem_ctx, &q_u_ex, q_u);
+ if (!W_ERROR_IS_OK(r_u_ex.status))
+ return r_u_ex.status;
r_u_ex.status = _spoolss_open_printer_ex(p, &q_u_ex, &r_u_ex);
if (printer_default->access_required &
~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
- DEBUG(3, ("access DENIED for non-printserver bits"));
+ DEBUG(3, ("access DENIED for non-printserver bits\n"));
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
}
static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
- BOOL ret = True;
+ BOOL ret;
switch (level) {
case 2:
- ret = uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
- break;
- default:
- break;
+ /* allocate memory if needed. Messy because
+ convert_printer_info is used to update an existing
+ printer or build a new one */
+
+ if ( !printer->info_2 ) {
+ printer->info_2 = TALLOC_ZERO_P( printer, NT_PRINTER_INFO_LEVEL_2 );
+ if ( !printer->info_2 ) {
+ DEBUG(0,("convert_printer_info: talloc() failed!\n"));
+ return False;
+ }
+ }
+
+ ret = uni_2_asc_printer_info_2(uni->info_2, printer->info_2);
+ printer->info_2->setuptime = time(NULL);
+
+ return ret;
}
- return ret;
+ return False;
}
static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
/* this should not have failed---if it did, report to client */
if ( !W_ERROR_IS_OK(status_win2k) )
+ {
+ status = status_win2k;
goto done;
+ }
}
}
WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
uint32 type, uint8 *data, int real_len )
{
- delete_printer_data( printer->info_2, key, value );
-
+ /* the registry objects enforce uniqueness based on value name */
+
return add_printer_data( printer->info_2, key, value, type, data, real_len );
}
if (!StrCaseCmp(value, "W3SvcInstalled")) {
*type = REG_DWORD;
- if((*data = (uint8 *)TALLOC_ZERO(ctx, 4*sizeof(uint8) )) == NULL)
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
*needed = 0x4;
return WERR_OK;
if (!StrCaseCmp(value, "BeepEnabled")) {
*type = REG_DWORD;
- if((*data = (uint8 *)TALLOC(ctx, 4*sizeof(uint8) )) == NULL)
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
SIVAL(*data, 0, 0x00);
*needed = 0x4;
if (!StrCaseCmp(value, "EventLog")) {
*type = REG_DWORD;
- if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
/* formally was 0x1b */
SIVAL(*data, 0, 0x0);
if (!StrCaseCmp(value, "NetPopup")) {
*type = REG_DWORD;
- if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
SIVAL(*data, 0, 0x00);
*needed = 0x4;
if (!StrCaseCmp(value, "MajorVersion")) {
*type = REG_DWORD;
- if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
/* Windows NT 4.0 seems to not allow uploading of drivers
if (!StrCaseCmp(value, "MinorVersion")) {
*type = REG_DWORD;
- if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
SIVAL(*data, 0, 0);
*needed = 0x4;
*type = REG_BINARY;
*needed = 0x114;
- if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, *needed)) )
+ if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
return WERR_NOMEM;
SIVAL(*data, 0, *needed); /* size */
if (!StrCaseCmp(value, "DsPresent")) {
*type = REG_DWORD;
- if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
/* only show the publish check box if we are a
Connect to the client machine.
**********************************************************/
-static BOOL spoolss_connect_to_client(struct cli_state *the_cli,
+static BOOL spoolss_connect_to_client(struct cli_state *the_cli, struct rpc_pipe_client **pp_pipe,
struct in_addr *client_ip, const char *remote_machine)
{
+ NTSTATUS ret;
ZERO_STRUCTP(the_cli);
if(cli_initialise(the_cli) == NULL) {
* Now start the NT Domain stuff :-).
*/
- if(cli_nt_session_open(the_cli, PI_SPOOLSS) == False) {
- DEBUG(0,("spoolss_connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli)));
- cli_nt_session_close(the_cli);
- cli_ulogoff(the_cli);
+ *pp_pipe = cli_rpc_pipe_open_noauth(the_cli, PI_SPOOLSS, &ret);
+ if(!*pp_pipe) {
+ DEBUG(0,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
+ remote_machine, nt_errstr(ret)));
cli_shutdown(the_cli);
return False;
}
* and connect to the IPC$ share anonymously
*/
if (smb_connections==0) {
+ struct cli_state notify_cli; /* print notify back-channel */
fstring unix_printer;
fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
ZERO_STRUCT(notify_cli);
- if(!spoolss_connect_to_client(¬ify_cli, client_ip, unix_printer))
+ if(!spoolss_connect_to_client(¬ify_cli, ¬ify_cli_pipe, client_ip, unix_printer))
return False;
message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message_list);
smb_connections++;
- result = cli_spoolss_reply_open_printer(¬ify_cli, notify_cli.mem_ctx, printer, localprinter,
+ result = rpccli_spoolss_reply_open_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, printer, localprinter,
type, handle);
if (!W_ERROR_IS_OK(result))
printer->cjobs = count; /* jobs */
printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
- if((printer->devmode = construct_dev_mode(snum)) == NULL) {
+ if ( !(printer->devmode = construct_dev_mode(snum)) )
DEBUG(8, ("Returning NULL Devicemode!\n"));
- }
- if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
- /* steal the printer info sec_desc structure. [badly done]. */
- printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
- ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
- ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
- ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
- }
- else {
- printer->secdesc = NULL;
+ printer->secdesc = NULL;
+
+ if ( ntprinter->info_2->secdesc_buf
+ && ntprinter->info_2->secdesc_buf->len != 0 )
+ {
+ /* don't use talloc_steal() here unless you do a deep steal of all
+ the SEC_DESC members */
+
+ printer->secdesc = dup_sec_desc( get_talloc_ctx(),
+ ntprinter->info_2->secdesc_buf->sec );
}
free_a_printer(&ntprinter, 2);
+
return True;
}
ZERO_STRUCTP(printer);
- printer->flags = 4; /* These are the components of the SD we are returning. */
- if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
- /* steal the printer info sec_desc structure. [badly done]. */
- printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
+ /* These are the components of the SD we are returning. */
-#if 0
- /*
- * Set the flags for the components we are returning.
- */
+ printer->flags = 0x4;
- if (printer->secdesc->owner_sid)
- printer->flags |= OWNER_SECURITY_INFORMATION;
-
- if (printer->secdesc->grp_sid)
- printer->flags |= GROUP_SECURITY_INFORMATION;
-
- if (printer->secdesc->dacl)
- printer->flags |= DACL_SECURITY_INFORMATION;
-
- if (printer->secdesc->sacl)
- printer->flags |= SACL_SECURITY_INFORMATION;
-#endif
+ if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
+ /* don't use talloc_steal() here unless you do a deep steal of all
+ the SEC_DESC members */
- ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
- ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
- ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
+ printer->secdesc = dup_sec_desc( get_talloc_ctx(),
+ ntprinter->info_2->secdesc_buf->sec );
}
free_a_printer(&ntprinter, 2);
if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
- if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
- if((tp=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) == NULL) {
+ if (construct_printer_info_2(NULL, ¤t_prt, snum))
+ {
+ if ( !(tp=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
SAFE_FREE(printers);
*returned = 0;
return WERR_NOMEM;
}
- else printers = tp;
+
DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
+
+ printers = tp;
memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
+
(*returned)++;
}
}
out:
/* clear memory */
- for (i=0; i<*returned; i++) {
+
+ for (i=0; i<*returned; i++)
free_devmode(printers[i].devmode);
- }
+
SAFE_FREE(printers);
if ( !W_ERROR_IS_OK(result) )
|| !strequal(printer->info_2->portname, old_printer->info_2->portname)
|| !strequal(printer->info_2->location, old_printer->info_2->location)) )
{
+ /* add_printer_hook() will call reload_services() */
+
if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
result = WERR_ACCESS_DENIED;
goto done;
}
-
- /*
- * make sure we actually reload the services after
- * this as smb.conf could have a new section in it
- * .... shouldn't .... but could
- */
- reload_services(False);
}
/*
int i, key_index, num_values;
int name_length;
- ZERO_STRUCT( printer );
-
*out_type = 0;
*out_max_data_len = 0;
if (!W_ERROR_IS_OK(result))
return result;
- p_data = &printer->info_2->data;
+ p_data = printer->info_2->data;
key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
result = WERR_OK;
biggest_valuesize = 0;
biggest_datasize = 0;
- num_values = regval_ctr_numvals( &p_data->keys[key_index].values );
-
+ num_values = regval_ctr_numvals( p_data->keys[key_index].values );
+
for ( i=0; i<num_values; i++ )
{
- val = regval_ctr_specific_value( &p_data->keys[key_index].values, i );
+ val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
name_length = strlen(val->valuename);
if ( strlen(val->valuename) > biggest_valuesize )
*/
if ( key_index != -1 )
- val = regval_ctr_specific_value( &p_data->keys[key_index].values, idx );
+ val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
if ( !val )
{
/* data - counted in bytes */
*out_max_data_len = in_data_len;
- if ( (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
+ if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
{
result = WERR_NOMEM;
goto done;
}
data_len = regval_size(val);
- memcpy( *data_out, regval_data_p(val), data_len );
+ if ( *data_out )
+ memcpy( *data_out, regval_data_p(val), data_len );
*out_data_len = data_len;
}
goto done;
}
- if ( lookup_printerkey( &printer->info_2->data, keyname ) == -1 ) {
+ if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname ));
free_a_printer( &printer, 2 );
status = WERR_BADFILE;
/* get the list of subkey names */
unistr2_to_ascii( key, &q_u->key, sizeof(key)-1 );
- data = &printer->info_2->data;
+ data = printer->info_2->data;
num_keys = get_printer_subkeys( data, key, &keynames );
/* now look for a match on the key name */
- p_data = &printer->info_2->data;
+ p_data = printer->info_2->data;
unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
/* allocate the memory for the array of pointers -- if necessary */
- num_entries = regval_ctr_numvals( &p_data->keys[key_index].values );
+ num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
if ( num_entries )
{
if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
{
/* lookup the registry value */
- val = regval_ctr_specific_value( &p_data->keys[key_index].values, i );
+ val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
/* copy the data */