* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
- * Copyright (C) Jean François Micouleau 1998-2000,
+ * Copyright (C) Jean François Micouleau 1998-2000,
* Copyright (C) Jeremy Allison 2001-2002,
- * Copyright (C) Gerald Carter 2000-2003,
+ * Copyright (C) Gerald Carter 2000-2004,
* Copyright (C) Tim Potter 2001-2002.
*
* This program is free software; you can redistribute it and/or modify
#include "includes.h"
+extern userdom_struct current_user_info;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
static Printer_entry *printers_list;
typedef struct _counter_printer_0 {
- ubi_dlNode Next;
- ubi_dlNode Prev;
+ struct _counter_printer_0 *next;
+ struct _counter_printer_0 *prev;
int snum;
uint32 counter;
} counter_printer_0;
-static ubi_dlList counter_list;
+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
* printer notify messages. */
- register_message_flags( False, FLAG_MSG_PRINTING );
+ register_message_flags( False, FLAG_MSG_PRINT_NOTIFY );
}
smb_connections--;
snum = -1;
srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
} else if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) {
- snum = print_queue_snum(Printer->dev.handlename);
+ snum = print_queue_snum(Printer->sharename);
if (snum != -1)
srv_spoolss_replycloseprinter(snum,
&Printer->notify.client_hnd);
if (!sp)
return NULL;
- new_sp = (SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION));
+ new_sp = SMB_MALLOC_P(SPOOL_NOTIFY_OPTION);
if (!new_sp)
return NULL;
return find_printer;
}
-/****************************************************************************
- 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 *printername )
-{
- Printer_entry *p;
-
- DEBUG(10,("find_printer_in_print_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->dev.handlename, printername) == 0 )
- {
- 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
- && StrCaseCmp(p->dev.handlename, printername)==0)
- {
- DEBUG(10,("invalidating printer_info cache for handl:\n"));
- free_a_printer( &p->printer_info, 2 );
- p->printer_info = NULL;
- }
- }
-
- return;
-}
/****************************************************************************
Close printer index by handle.
****************************************************************************/
return True;
}
+/****************************************************************************
+ Delete a printer given a handle.
+****************************************************************************/
+WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename )
+{
+ char *cmd = lp_deleteprinter_cmd();
+ pstring command;
+ int ret;
+ SE_PRIV se_printop = SE_PRINT_OPERATOR;
+ BOOL is_print_op = False;
+
+ /* can't fail if we don't try */
+
+ if ( !*cmd )
+ return WERR_OK;
+
+ pstr_sprintf(command, "%s \"%s\"", cmd, sharename);
+
+ if ( token )
+ is_print_op = user_has_privileges( token, &se_printop );
+
+ DEBUG(10,("Running [%s]\n", command));
+
+ /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
+
+ if ( is_print_op )
+ become_root();
+
+ if ( (ret = smbrun(command, NULL)) == 0 ) {
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
+ }
+
+ if ( is_print_op )
+ unbecome_root();
+
+ /********** END SePrintOperatorPrivlege BLOCK **********/
+
+ DEBUGADD(10,("returned [%d]\n", ret));
+
+ if (ret != 0)
+ return WERR_BADFID; /* What to return here? */
+
+ /* go ahead and re-read the services immediately */
+ reload_services( False );
+
+ if ( lp_servicenumber( sharename ) < 0 )
+ return WERR_ACCESS_DENIED;
+
+ return WERR_OK;
+}
+
/****************************************************************************
Delete a printer given a handle.
****************************************************************************/
DEBUG(3, ("delete_printer_handle: denied by handle\n"));
return WERR_ACCESS_DENIED;
}
-
-#if 0
- /* Check calling user has permission to delete printer. Note that
- since we set the snum parameter to -1 only administrators can
- delete the printer. This stops people with the Full Control
- permission from deleting the printer. */
-
- if (!print_access_check(NULL, -1, PRINTER_ACCESS_ADMINISTER)) {
- DEBUG(3, ("printer delete denied by security descriptor\n"));
- return WERR_ACCESS_DENIED;
- }
-#endif
-
- if (del_a_printer(Printer->dev.handlename) != 0) {
- DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
+
+ /* this does not need a become root since the access check has been
+ done on the handle already */
+
+ if (del_a_printer( Printer->sharename ) != 0) {
+ DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
return WERR_BADFID;
}
- if (*lp_deleteprinter_cmd()) {
-
- char *cmd = lp_deleteprinter_cmd();
- pstring command;
- int ret;
-
- /* Printer->dev.handlename equals portname equals sharename */
- slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd,
- Printer->dev.handlename);
-
- DEBUG(10,("Running [%s]\n", command));
- ret = smbrun(command, NULL);
- if (ret != 0) {
- return WERR_BADFID; /* What to return here? */
- }
- DEBUGADD(10,("returned [%d]\n", ret));
-
- /* Send SIGHUP to process group... is there a better way? */
- kill(0, SIGHUP);
-
- /* go ahead and re-read the services immediately */
- reload_services( False );
-
- if ( lp_servicenumber( Printer->dev.handlename ) < 0 )
- return WERR_ACCESS_DENIED;
- }
-
- return WERR_OK;
+ return delete_printer_hook( p->pipe_user.nt_user_token, Printer->sharename );
}
/****************************************************************************
}
switch (Printer->printer_type) {
- case PRINTER_HANDLE_IS_PRINTER:
- DEBUG(4,("short name:%s\n", Printer->dev.handlename));
- *number = print_queue_snum(Printer->dev.handlename);
- return (*number != -1);
- case PRINTER_HANDLE_IS_PRINTSERVER:
- return False;
- default:
- return False;
+ case PRINTER_HANDLE_IS_PRINTER:
+ DEBUG(4,("short name:%s\n", Printer->sharename));
+ *number = print_queue_snum(Printer->sharename);
+ return (*number != -1);
+ case PRINTER_HANDLE_IS_PRINTSERVER:
+ return False;
+ default:
+ return False;
}
}
{
int snum;
int n_services=lp_numservices();
- char *aprinter;
+ char *aprinter, *printername;
+ const char *servername;
fstring sname;
BOOL found=False;
+ NT_PRINTER_INFO_LEVEL *printer;
+ WERROR result;
DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
- if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
- ZERO_STRUCT(Printer->dev.printerservername);
- strncpy(Printer->dev.printerservername, handlename, strlen(handlename));
- return True;
+ aprinter = handlename;
+ if ( *handlename == '\\' ) {
+ servername = handlename + 2;
+ if ( (aprinter = strchr_m( handlename+2, '\\' )) != NULL ) {
+ *aprinter = '\0';
+ aprinter++;
+ }
+ }
+ else {
+ servername = "";
}
+
+ /* save the servername to fill in replies on this handle */
+
+ if ( !is_myname_or_ipaddr( servername ) )
+ return False;
+
+ fstrcpy( Printer->servername, servername );
+
+ if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER )
+ return True;
- if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
+ if ( Printer->printer_type != PRINTER_HANDLE_IS_PRINTER )
return False;
+
+ DEBUGADD(5, ("searching for [%s]\n", aprinter ));
+
+ /* Search all sharenames first as this is easier than pulling
+ the printer_info_2 off of disk */
- if (*handlename=='\\') {
- aprinter=strchr_m(handlename+2, '\\');
- aprinter++;
- }
- else {
- aprinter=handlename;
+ snum = find_service(aprinter);
+
+ if ( lp_snum_ok(snum) && lp_print_ok(snum) ) {
+ found = True;
+ fstrcpy( sname, aprinter );
}
- DEBUGADD(5,("searching for [%s] (len=%lu)\n", aprinter, (unsigned long)strlen(aprinter)));
-
- /*
- * The original code allowed smbd to store a printer name that
- * was different from the share name. This is not possible
- * anymore, so I've simplified this loop greatly. Here
- * we are just verifying that the printer name is a valid
- * printer service defined in smb.conf
- * --jerry [Fri Feb 15 11:17:46 CST 2002]
- */
+ /* do another loop to look for printernames */
+
+ for (snum=0; !found && snum<n_services; snum++) {
- for (snum=0; snum<n_services; snum++) {
+ /* no point in checking if this is not a printer or
+ we aren't allowing printername != sharename */
- if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
+ if ( !(lp_snum_ok(snum)
+ && lp_print_ok(snum)
+ && !lp_force_printername(snum)) )
+ {
continue;
+ }
fstrcpy(sname, lp_servicename(snum));
- DEBUGADD(5,("share:%s\n",sname));
+ printer = NULL;
+ result = get_a_printer( NULL, &printer, 2, sname );
+ if ( !W_ERROR_IS_OK(result) ) {
+ DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
+ sname, dos_errstr(result)));
+ continue;
+ }
+
+ /* printername is always returned as \\server\printername */
+ if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
+ DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
+ printer->info_2->printername));
+ free_a_printer( &printer, 2);
+ continue;
+ }
+
+ printername++;
- if (! StrCaseCmp(sname, aprinter)) {
+ if ( strequal(printername, aprinter) ) {
found = True;
- break;
}
-
+
+ DEBUGADD(10, ("printername: %s\n", printername));
+
+ free_a_printer( &printer, 2);
}
-
- if (!found) {
+ if ( !found ) {
DEBUGADD(4,("Printer not found\n"));
return False;
}
DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
- ZERO_STRUCT(Printer->dev.handlename);
- fstrcpy(Printer->dev.handlename, sname);
+ fstrcpy(Printer->sharename, sname);
return True;
}
DEBUG(10,("open_printer_hnd: name [%s]\n", name));
- if((new_printer=(Printer_entry *)malloc(sizeof(Printer_entry))) == NULL)
+ if((new_printer=SMB_MALLOC_P(Printer_entry)) == NULL)
return False;
ZERO_STRUCTP(new_printer);
return True;
}
-/****************************************************************************
- Allocate more memory for a BUFFER.
-****************************************************************************/
-
-static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
-{
- prs_struct *ps;
- uint32 extra_space;
- uint32 old_offset;
-
- ps= &buffer->prs;
-
- /* damn, I'm doing the reverse operation of prs_grow() :) */
- if (buffer_size < prs_data_size(ps))
- extra_space=0;
- else
- extra_space = buffer_size - prs_data_size(ps);
-
- /*
- * save the offset and move to the end of the buffer
- * prs_grow() checks the extra_space against the offset
- */
- old_offset=prs_offset(ps);
- prs_set_offset(ps, prs_data_size(ps));
-
- if (!prs_grow(ps, extra_space))
- return False;
-
- prs_set_offset(ps, old_offset);
-
- buffer->string_at_end=prs_data_size(ps);
-
- return True;
-}
-
/***************************************************************************
check to see if the client motify handle is monitoring the notification
given by (notify_type, notify_field).
* might use the flags though instead of the NOTIFY_OPTION_INFO
* --jerry
*/
-
+
+ if (!option) {
+ return False;
+ }
+
if (p->notify.flags)
return is_monitoring_event_flags(
p->notify.flags, notify_type, notify_field);
}
}
- DEBUG(10, ("%s is not monitoring 0x%02x/0x%02x\n",
- (p->printer_type == PRINTER_HANDLE_IS_PRINTER) ?
- p->dev.handlename : p->dev.printerservername,
- notify_type, notify_field));
+ DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
+ p->servername, p->sharename, notify_type, notify_field));
return False;
}
init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE);
data->notify_data.data.length = msg->len * 2;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, msg->len * 2);
+ data->notify_data.data.string = TALLOC_ARRAY(mem_ctx, uint16, msg->len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
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;
}
return;
data->notify_data.data.length = prs_offset(&ps);
- data->notify_data.data.string = talloc(mem_ctx, prs_offset(&ps));
+ data->notify_data.data.string = TALLOC(mem_ctx, prs_offset(&ps));
prs_copy_all_data_out((char *)data->notify_data.data.string, &ps);
if ( i == ctr->num_groups ) {
ctr->num_groups++;
- if ( !(groups = talloc_realloc( ctr->ctx, ctr->msg_groups, sizeof(SPOOLSS_NOTIFY_MSG_GROUP)*ctr->num_groups)) ) {
+ if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
return 0;
}
msg_grp->num_msgs++;
- if ( !(msg_list = talloc_realloc( ctr->ctx, msg_grp->msgs, sizeof(SPOOLSS_NOTIFY_MSG)*msg_grp->num_msgs )) ) {
+ if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
return 0;
}
/* need to allocate own copy of data */
if ( msg->len != 0 )
- msg_grp->msgs[new_slot].notify.data = talloc_memdup( ctr->ctx, msg->notify.data, msg->len );
+ msg_grp->msgs[new_slot].notify.data = TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
return ctr->num_groups;
}
if ( !p->notify.client_connected )
continue;
- DEBUG(10,("Client connected! [%s]\n", p->dev.handlename));
+ DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
/* For this printer? Print servers always receive
notifications. */
if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER ) &&
- ( !strequal(msg_group->printername, p->dev.handlename) ) )
+ ( !strequal(msg_group->printername, p->sharename) ) )
continue;
DEBUG(10,("Our printer\n"));
/* allocate the max entries possible */
- data = talloc( mem_ctx, msg_group->num_msgs*sizeof(SPOOL_NOTIFY_INFO_DATA) );
+ data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs);
ZERO_STRUCTP(data);
/* build the array of change notifications */
sending_msg_count++;
- DEBUG(10,("process_notify2_message: Sending message type [%x] field [%x] for printer [%s]\n",
- msg->type, msg->field, p->dev.handlename));
+ DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
+ msg->type, msg->field, p->sharename));
/*
* if the is a printer notification handle and not a job notification
}
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;
ZERO_STRUCT( notify );
notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
msg_ptr += msg_len;
-
+
/* add to correct list in container */
notify_msg_ctr_addmsg( &messages, ¬ify );
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;
/* all we care about currently is the change_id */
- result = mod_a_printer(*printer, 2);
+ result = mod_a_printer(printer, 2);
if (!W_ERROR_IS_OK(result)) {
DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
dos_errstr(result)));
if ( (printer->printer_type == PRINTER_HANDLE_IS_PRINTER)
&& printer->notify.client_connected )
{
- snum = print_queue_snum(printer->dev.handlename);
+ snum = print_queue_snum(printer->sharename);
print_queue_status( snum, NULL, NULL );
}
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;
printer->info_2->printername, printer->info_2->drivername));
}
- result = mod_a_printer( *printer, 2 );
+ result = mod_a_printer( printer, 2 );
if ( !W_ERROR_IS_OK(result) ) {
DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
get_dos_error_msg(result)));
/* bulk copy first */
- d = talloc_memdup(ctx, devmode, sizeof(DEVICEMODE));
+ d = TALLOC_MEMDUP(ctx, devmode, sizeof(DEVICEMODE));
if (!d)
return NULL;
len = unistrlen(devmode->devicename.buffer);
if (len != -1) {
- d->devicename.buffer = talloc(ctx, len*2);
+ d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len);
if (unistrcpy(d->devicename.buffer, devmode->devicename.buffer) != len)
return NULL;
}
len = unistrlen(devmode->formname.buffer);
if (len != -1) {
- d->devicename.buffer = talloc(ctx, len*2);
+ d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len);
if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len)
return NULL;
}
- d->private = talloc_memdup(ctx, devmode->private, devmode->driverextra);
+ d->dev_private = TALLOC_MEMDUP(ctx, devmode->dev_private, devmode->driverextra);
return d;
}
* 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"));
- q_u_ex->printername_ptr = q_u->printername_ptr;
-
- if (q_u->printername_ptr)
- copy_unistr2(&q_u_ex->printername, &q_u->printername);
+ if ( q_u->printername ) {
+ 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);
WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
{
- UNISTR2 *printername = NULL;
PRINTER_DEFAULT *printer_default = &q_u->printer_default;
POLICY_HND *handle = &r_u->handle;
struct current_user user;
Printer_entry *Printer=NULL;
- if (q_u->printername_ptr != 0)
- printername = &q_u->printername;
-
- if (printername == NULL)
+ if ( !q_u->printername )
return WERR_INVALID_PRINTER_NAME;
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
- unistr2_to_ascii(name, printername, sizeof(name)-1);
+
+ unistr2_to_ascii(name, q_u->printername, sizeof(name)-1);
DEBUGADD(3,("checking name: %s\n",name));
return WERR_INVALID_PRINTER_NAME;
Printer=find_printer_index_by_hnd(p, handle);
- if (!Printer) {
- DEBUG(0,(" _spoolss_open_printer_ex: logic error. \
-Can't find printer handle we created for printer %s\n", name ));
+ if ( !Printer ) {
+ DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer "
+ "handle we created for printer %s\n", name ));
close_printer_handle(p,handle);
return WERR_INVALID_PRINTER_NAME;
}
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;
}
if ( printer_default->access_required & SERVER_ACCESS_ADMINISTER )
{
+ SE_PRIV se_printop = SE_PRINT_OPERATOR;
+
if (!lp_ms_add_printer_wizard()) {
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
}
- /* if the user is not root and not a printer admin, then fail */
+ /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
+ and not a printer admin, then fail */
if ( user.uid != 0
- && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum), user.groups, user.ngroups) )
+ && !user_has_privileges( user.nt_user_token, &se_printop )
+ && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum), user.groups, user.ngroups) )
{
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
/* check smb.conf parameters and the the sec_desc */
+ if ( !check_access(smbd_server_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
+ DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
+ return WERR_ACCESS_DENIED;
+ }
+
if (!user_ok(uidtoname(user.uid), snum, user.groups, user.ngroups) || !print_access_check(&user, snum, printer_default->access_required)) {
DEBUG(3, ("access DENIED for printer open\n"));
close_printer_handle(p, handle);
if ( (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
&& q_u->printer_default.devmode_cont.devmode_ptr )
{
- convert_devicemode( Printer->dev.handlename, q_u->printer_default.devmode_cont.devmode,
+ convert_devicemode( Printer->sharename, q_u->printer_default.devmode_cont.devmode,
&Printer->nt_devmode );
}
+#if 0 /* JERRY -- I'm doubtful this is really effective */
/* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
optimization in Windows 2000 clients --jerry */
DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
sys_usleep( 500000 );
}
+#endif
return WERR_OK;
}
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,
* has a new one. JRA.
*/
- if ((devmode->driverextra != 0) && (devmode->private != NULL)) {
- SAFE_FREE(nt_devmode->private);
+ if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
+ SAFE_FREE(nt_devmode->nt_dev_private);
nt_devmode->driverextra=devmode->driverextra;
- if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
+ if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
return False;
- memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
+ memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
}
*pp_nt_devmode = nt_devmode;
{"Windows NT R4000", "W32MIPS", 2 },
{"Windows NT Alpha_AXP", "W32ALPHA", 2 },
{"Windows NT PowerPC", "W32PPC", 2 },
+ {"Windows IA64", "IA64", 3 },
+ {"Windows x64", "x64", 3 },
{NULL, "", -1 }
};
/* this should not have failed---if it did, report to client */
if ( !W_ERROR_IS_OK(status_win2k) )
+ {
+ status = status_win2k;
goto done;
+ }
}
}
uint32 *needed, uint32 in_size )
{
REGISTRY_VALUE *val;
- int size, data_len;
+ uint32 size;
+ int data_len;
if ( !(val = get_printer_data( printer->info_2, key, value)) )
return WERR_BADFILE;
/* special case for 0 length values */
if ( data_len ) {
- if ( (*data = (uint8 *)talloc_memdup(ctx, regval_data_p(val), data_len)) == NULL )
+ if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
return WERR_NOMEM;
}
else {
- if ( (*data = (uint8 *)talloc_zero(ctx, in_size)) == NULL )
+ if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
return WERR_NOMEM;
}
}
Internal routine for storing printerdata
***************************************************************************/
-static WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
+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 );
}
DEBUG(8,("getprinterdata_printer_server:%s\n", value));
if (!StrCaseCmp(value, "W3SvcInstalled")) {
- *type = 0x4;
- if((*data = (uint8 *)talloc_zero(ctx, 4*sizeof(uint8) )) == NULL)
+ *type = REG_DWORD;
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
*needed = 0x4;
return WERR_OK;
}
if (!StrCaseCmp(value, "BeepEnabled")) {
- *type = 0x4;
- if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+ *type = REG_DWORD;
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
SIVAL(*data, 0, 0x00);
*needed = 0x4;
}
if (!StrCaseCmp(value, "EventLog")) {
- *type = 0x4;
- if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+ *type = REG_DWORD;
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
/* formally was 0x1b */
SIVAL(*data, 0, 0x0);
}
if (!StrCaseCmp(value, "NetPopup")) {
- *type = 0x4;
- if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+ *type = REG_DWORD;
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
SIVAL(*data, 0, 0x00);
*needed = 0x4;
}
if (!StrCaseCmp(value, "MajorVersion")) {
- *type = 0x4;
- if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+ *type = REG_DWORD;
+ 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 = 0x4;
- if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+ *type = REG_DWORD;
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
SIVAL(*data, 0, 0);
*needed = 0x4;
* extra unicode string = e.g. "Service Pack 3"
*/
if (!StrCaseCmp(value, "OSVersion")) {
- *type = 0x3;
+ *type = REG_BINARY;
*needed = 0x114;
- if((*data = (uint8 *)talloc(ctx, (*needed)*sizeof(uint8) )) == NULL)
+ if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
return WERR_NOMEM;
- ZERO_STRUCTP( *data );
-
+
SIVAL(*data, 0, *needed); /* size */
SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
SIVAL(*data, 8, 0);
if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
const char *string="C:\\PRINTERS";
- *type = 0x1;
+ *type = REG_SZ;
*needed = 2*(strlen(string)+1);
- if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
+ if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
return WERR_NOMEM;
memset(*data, 0, (*needed > in_size) ? *needed:in_size);
if (!StrCaseCmp(value, "Architecture")) {
const char *string="Windows NT x86";
- *type = 0x1;
+ *type = REG_SZ;
*needed = 2*(strlen(string)+1);
- if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
+ if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
return WERR_NOMEM;
memset(*data, 0, (*needed > in_size) ? *needed:in_size);
for (i=0; i<strlen(string); i++) {
}
if (!StrCaseCmp(value, "DsPresent")) {
- *type = 0x4;
- if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+ *type = REG_DWORD;
+ if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
- SIVAL(*data, 0, 0x01);
+
+ /* only show the publish check box if we are a
+ memeber of a AD domain */
+
+ if ( lp_security() == SEC_ADS )
+ SIVAL(*data, 0, 0x01);
+ else
+ SIVAL(*data, 0, 0x00);
+
*needed = 0x4;
return WERR_OK;
}
if (!get_mydnsfullname(hostname))
return WERR_BADFILE;
- *type = 0x1;
+ *type = REG_SZ;
*needed = 2*(strlen(hostname)+1);
- if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
+ if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
return WERR_NOMEM;
memset(*data, 0, (*needed > in_size) ? *needed:in_size);
for (i=0; i<strlen(hostname); i++) {
if ( strequal(value, "ChangeId") ) {
*type = REG_DWORD;
*needed = sizeof(uint32);
- if ( (*data = (uint8*)talloc(p->mem_ctx, sizeof(uint32))) == NULL) {
+ if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
status = WERR_NOMEM;
goto done;
}
/* reply this param doesn't exist */
if ( *out_size ) {
- if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL) {
+ if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
if ( printer )
free_a_printer( &printer, 2 );
return WERR_NOMEM;
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);
/* Tell the connections db we're now interested in printer
* notify messages. */
- register_message_flags( True, FLAG_MSG_PRINTING );
+ register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
}
/*
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))
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- pstring temp_name, temp;
+ pstring temp;
uint32 len;
- slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
-
- len = rpcstr_push(temp, temp_name, sizeof(temp)-2, STR_TERMINATE);
+ len = rpcstr_push(temp, printer->info_2->servername, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
len = sizeof(SYSTEMTIME);
data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+ data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
if (!data->notify_data.data.string) {
data->notify_data.data.length = 0;
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
+{ PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
};
/*******************************************************************
{
int i;
- for (i = 0; i < sizeof(notify_info_data_table); i++) {
+ for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
if (notify_info_data_table[i].type == type &&
notify_info_data_table[i].field == field &&
notify_info_data_table[i].fn != NULL) {
if (!search_notify(type, field, &j) )
continue;
- if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
+ if((tid=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
return False;
} else
if (!search_notify(type, field, &j) )
continue;
- if((tid=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
+ if((tid=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
return False;
}
info->data=NULL;
info->count=0;
+ /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
+ sending a ffpcn() request first */
+
+ if ( !option )
+ return WERR_BADFID;
+
for (i=0; i<option->count; i++) {
option_type=&(option->ctr.type[i]);
info->data=NULL;
info->count=0;
+ /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
+ sending a ffpcn() request first */
+
+ if ( !option )
+ return WERR_BADFID;
+
get_printer_snum(p, hnd, &snum);
for (i=0; i<option->count; i++) {
count = print_queue_length(snum, &status);
/* check if we already have a counter for this printer */
- session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
-
- for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
+ for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
if (session_counter->snum == snum)
break;
}
/* it's the first time, add it to the list */
if (session_counter==NULL) {
- if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
+ if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
free_a_printer(&ntprinter, 2);
return False;
}
ZERO_STRUCTP(session_counter);
session_counter->snum=snum;
session_counter->counter=0;
- ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
+ DLIST_ADD(counter_list, session_counter);
}
/* increment it */
init_unistr(&printer->printername, chaine);
- slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_called_name());
+ slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_server_name(print_hnd));
init_unistr(&printer->servername, chaine);
printer->cjobs = count;
if (dev == NULL)
return;
- SAFE_FREE(dev->private);
+ SAFE_FREE(dev->dev_private);
SAFE_FREE(dev);
}
devmode->mediatype = ntdevmode->mediatype;
devmode->dithertype = ntdevmode->dithertype;
- if (ntdevmode->private != NULL) {
- if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
+ if (ntdevmode->nt_dev_private != NULL) {
+ if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
return False;
}
goto done;
}
- if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
+ if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
DEBUG(2,("construct_dev_mode: malloc fail.\n"));
goto done;
}
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;
}
return False;
*pp_printer = NULL;
- if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
+ if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
return False;
}
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;
-
-#if 0
- /*
- * Set the flags for the components we are returning.
- */
+ /* These are the components of the SD we are returning. */
- if (printer->secdesc->owner_sid)
- printer->flags |= OWNER_SECURITY_INFORMATION;
+ printer->flags = 0x4;
- 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);
static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
{
char *guid_str = NULL;
- GUID guid;
+ struct uuid guid;
if (is_printer_published(print_hnd, snum, &guid)) {
asprintf(&guid_str, "{%s}", smb_uuid_string_static(guid));
Spoolss_enumprinters.
********************************************************************/
-static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int snum;
int i;
int n_services=lp_numservices();
PRINTER_INFO_1 *tp, *printers=NULL;
PRINTER_INFO_1 current_prt;
+ WERROR result = WERR_OK;
DEBUG(4,("enum_all_printers_info_1\n"));
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
- if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
+ if((tp=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
SAFE_FREE(printers);
*returned=0;
for (i=0; i<*returned; i++)
(*needed) += spoolss_size_printer_info_1(&printers[i]);
- if (!alloc_buffer_size(buffer, *needed))
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
/* fill the buffer with the structures */
for (i=0; i<*returned; i++)
smb_io_printer_info_1("", buffer, &printers[i], 0);
+out:
/* clear memory */
+
SAFE_FREE(printers);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
- else
- return WERR_OK;
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
+
+ return result;
}
/********************************************************************
enum_all_printers_info_1_local.
*********************************************************************/
-static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
DEBUG(4,("enum_all_printers_info_1_local\n"));
enum_all_printers_info_1_name.
*********************************************************************/
-static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
char *s = name;
return WERR_INVALID_NAME;
}
+#if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
/********************************************************************
enum_all_printers_info_1_remote.
*********************************************************************/
-static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTER_INFO_1 *printer;
fstring printername;
fstring desc;
fstring comment;
DEBUG(4,("enum_all_printers_info_1_remote\n"));
+ WERROR result = WERR_OK;
/* JFM: currently it's more a place holder than anything else.
* In the spooler world there is a notion of server registration.
- * the print servers are registring (sp ?) on the PDC (in the same domain)
+ * the print servers are registered on the PDC (in the same domain)
*
- * We should have a TDB here. The registration is done thru an undocumented RPC call.
+ * We should have a TDB here. The registration is done thru an
+ * undocumented RPC call.
*/
- if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
+ if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
return WERR_NOMEM;
*returned=1;
- slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", get_called_name());
- slprintf(desc, sizeof(desc)-1,"%s", get_called_name());
+ slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
+ slprintf(desc, sizeof(desc)-1,"%s", name);
slprintf(comment, sizeof(comment)-1, "Logged on Domain");
init_unistr(&printer->description, desc);
/* check the required size. */
*needed += spoolss_size_printer_info_1(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_1("", buffer, printer, 0);
+out:
/* clear memory */
SAFE_FREE(printer);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
- else
- return WERR_OK;
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
+
+ return result;
}
+#endif
+
/********************************************************************
enum_all_printers_info_1_network.
*********************************************************************/
-static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
char *s = name;
* called from api_spoolss_enumprinters (see this to understand)
********************************************************************/
-static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int snum;
int i;
int n_services=lp_numservices();
PRINTER_INFO_2 *tp, *printers=NULL;
PRINTER_INFO_2 current_prt;
+ WERROR result = WERR_OK;
for (snum=0; snum<n_services; snum++) {
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=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == 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)++;
}
}
for (i=0; i<*returned; i++)
(*needed) += spoolss_size_printer_info_2(&printers[i]);
- if (!alloc_buffer_size(buffer, *needed)) {
- for (i=0; i<*returned; i++) {
- free_devmode(printers[i].devmode);
- }
- SAFE_FREE(printers);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
for (i=0; i<*returned; i++)
smb_io_printer_info_2("", buffer, &(printers[i]), 0);
+out:
/* clear memory */
- for (i=0; i<*returned; i++) {
+
+ for (i=0; i<*returned; i++)
free_devmode(printers[i].devmode);
- }
+
SAFE_FREE(printers);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
- else
- return WERR_OK;
-}
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
+
+ return result;
+}
/********************************************************************
* handle enumeration of printers at level 1
********************************************************************/
static WERROR enumprinters_level1( uint32 flags, fstring name,
- NEW_BUFFER *buffer, uint32 offered,
+ RPC_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
/* Not all the flags are equals */
if (flags & PRINTER_ENUM_NAME)
return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
+#if 0 /* JERRY - disabled for now */
if (flags & PRINTER_ENUM_REMOTE)
return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
+#endif
if (flags & PRINTER_ENUM_NETWORK)
return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
********************************************************************/
static WERROR enumprinters_level2( uint32 flags, fstring servername,
- NEW_BUFFER *buffer, uint32 offered,
+ RPC_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
char *s = servername;
********************************************************************/
static WERROR enumprinters_level5( uint32 flags, fstring servername,
- NEW_BUFFER *buffer, uint32 offered,
+ RPC_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
uint32 flags = q_u->flags;
UNISTR2 *servername = &q_u->servername;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
fstring name;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_enumprinters\n"));
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_0 *printer=NULL;
+ WERROR result = WERR_OK;
- if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
+ if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
return WERR_NOMEM;
construct_printer_info_0(print_hnd, printer, snum);
/* check the required size. */
*needed += spoolss_size_printer_info_0(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_0("", buffer, printer, 0);
+out:
/* clear memory */
- SAFE_FREE(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
+ SAFE_FREE(printer);
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_1 *printer=NULL;
+ WERROR result = WERR_OK;
- if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
+ if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
return WERR_NOMEM;
construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
/* check the required size. */
*needed += spoolss_size_printer_info_1(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_1("", buffer, printer, 0);
+out:
/* clear memory */
SAFE_FREE(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_2 *printer=NULL;
+ WERROR result = WERR_OK;
- if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
+ if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
return WERR_NOMEM;
construct_printer_info_2(print_hnd, printer, snum);
/* check the required size. */
*needed += spoolss_size_printer_info_2(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_info_2(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
}
- /* fill the buffer with the structures */
- if (!smb_io_printer_info_2("", buffer, printer, 0)) {
- free_printer_info_2(printer);
- return WERR_NOMEM;
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
+
+ /* fill the buffer with the structures */
+ if (!smb_io_printer_info_2("", buffer, printer, 0))
+ result = WERR_NOMEM;
+out:
/* clear memory */
free_printer_info_2(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_3 *printer=NULL;
+ WERROR result = WERR_OK;
if (!construct_printer_info_3(print_hnd, &printer, snum))
return WERR_NOMEM;
/* check the required size. */
*needed += spoolss_size_printer_info_3(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_info_3(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_3("", buffer, printer, 0);
+out:
/* clear memory */
free_printer_info_3(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_4 *printer=NULL;
+ WERROR result = WERR_OK;
- if((printer=(PRINTER_INFO_4*)malloc(sizeof(PRINTER_INFO_4)))==NULL)
+ if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
return WERR_NOMEM;
if (!construct_printer_info_4(print_hnd, printer, snum))
/* check the required size. */
*needed += spoolss_size_printer_info_4(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_info_4(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_4("", buffer, printer, 0);
+out:
/* clear memory */
free_printer_info_4(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_5 *printer=NULL;
+ WERROR result = WERR_OK;
- if((printer=(PRINTER_INFO_5*)malloc(sizeof(PRINTER_INFO_5)))==NULL)
+ if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
return WERR_NOMEM;
if (!construct_printer_info_5(print_hnd, printer, snum))
/* check the required size. */
*needed += spoolss_size_printer_info_5(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_info_5(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_5("", buffer, printer, 0);
+out:
/* clear memory */
free_printer_info_5(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
-static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_7 *printer=NULL;
+ WERROR result = WERR_OK;
- if((printer=(PRINTER_INFO_7*)malloc(sizeof(PRINTER_INFO_7)))==NULL)
+ if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
return WERR_NOMEM;
if (!construct_printer_info_7(print_hnd, printer, snum))
/* check the required size. */
*needed += spoolss_size_printer_info_7(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_info_7(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+
}
/* fill the buffer with the structures */
smb_io_printer_info_7("", buffer, printer, 0);
+out:
/* clear memory */
free_printer_info_7(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
{
POLICY_HND *handle = &q_u->handle;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
int snum;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
*needed=0;
/* add one extra unit16 for the second terminating NULL */
- if ( (tuary=Realloc(*uni_array, (j+1+strlen(line)+2)*sizeof(uint16))) == NULL ) {
+ if ( (tuary=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
DEBUG(2,("init_unistr_array: Realloc error\n" ));
return 0;
} else
static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
{
SAFE_FREE(info->dependentfiles);
-
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_1 *info=NULL;
- WERROR status;
+ WERROR result;
- if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
+ if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
return WERR_NOMEM;
- status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- SAFE_FREE(info);
- return status;
- }
+ result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
+ if (!W_ERROR_IS_OK(result))
+ goto out;
/* check the required size. */
*needed += spoolss_size_printer_driver_info_1(info);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_driver_info_1("", buffer, info, 0);
+out:
/* clear memory */
SAFE_FREE(info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_2 *info=NULL;
- WERROR status;
+ WERROR result;
- if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
+ if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
return WERR_NOMEM;
- status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- SAFE_FREE(info);
- return status;
- }
+ result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
+ if (!W_ERROR_IS_OK(result))
+ goto out;
/* check the required size. */
*needed += spoolss_size_printer_driver_info_2(info);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_driver_info_2("", buffer, info, 0);
+out:
/* clear memory */
SAFE_FREE(info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_3 info;
- WERROR status;
+ WERROR result;
ZERO_STRUCT(info);
- status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- return status;
- }
+ result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
+ if (!W_ERROR_IS_OK(result))
+ goto out;
/* check the required size. */
*needed += spoolss_size_printer_driver_info_3(&info);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_driver_info_3(&info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_driver_info_3("", buffer, &info, 0);
+out:
free_printer_driver_info_3(&info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_6 info;
- WERROR status;
+ WERROR result;
ZERO_STRUCT(info);
- status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- return status;
- }
+ result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
+ if (!W_ERROR_IS_OK(result))
+ goto out;
/* check the required size. */
*needed += spoolss_size_printer_driver_info_6(&info);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_driver_info_6(&info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_driver_info_6("", buffer, &info, 0);
+out:
free_printer_driver_info_6(&info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
UNISTR2 *uni_arch = &q_u->architecture;
uint32 level = q_u->level;
uint32 clientmajorversion = q_u->clientmajorversion;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *servermajorversion = &r_u->servermajorversion;
uint32 *serverminorversion = &r_u->serverminorversion;
+ Printer_entry *printer;
fstring servername;
fstring architecture;
int snum;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_getprinterdriver2\n"));
+ if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
+ DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
+ return WERR_INVALID_PRINTER_NAME;
+ }
+
*needed = 0;
*servermajorversion = 0;
*serverminorversion = 0;
- fstrcpy(servername, get_called_name());
+ fstrcpy(servername, get_server_name( printer ));
unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
if (!get_printer_snum(p, handle, &snum))
return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
case 6:
return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+#if 0 /* JERRY */
+ case 101:
+ /* apparently this call is the equivalent of
+ EnumPrinterDataEx() for the DsDriver key */
+ break;
+#endif
}
return WERR_UNKNOWN_LEVEL;
if (!get_printer_snum(p, handle, &snum))
return WERR_BADFID;
- (*buffer_written) = print_job_write(snum, Printer->jobid, (char *)buffer, buffer_size);
- if (*buffer_written == -1) {
+ (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
+ (SMB_OFF_T)-1, (size_t)buffer_size);
+ if (*buffer_written == (uint32)-1) {
r_u->buffer_written = 0;
if (errno == ENOSPC)
return WERR_NO_SPOOL_SPACE;
pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
{
SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
- struct current_user user;
WERROR result;
int snum;
result = WERR_BADFID;
goto done;
}
+
+ /* Check the user has permissions to change the security
+ descriptor. By experimentation with two NT machines, the user
+ requires Full Access to the printer to change security
+ information. */
+
+ if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
+ DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
+ result = WERR_ACCESS_DENIED;
+ goto done;
+ }
/* NT seems to like setting the security descriptor even though
- nothing may have actually changed. This causes annoying
- dialog boxes when the user doesn't have permission to change
- the security descriptor. */
+ nothing may have actually changed. */
- nt_printing_getsec(p->mem_ctx, Printer->dev.handlename, &old_secdesc_ctr);
+ nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr);
if (DEBUGLEVEL >= 10) {
SEC_ACL *the_acl;
goto done;
}
- /* Work out which user is performing the operation */
-
- get_current_user(&user, p);
-
- /* Check the user has permissions to change the security
- descriptor. By experimentation with two NT machines, the user
- requires Full Access to the printer to change security
- information. */
-
- if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
- result = WERR_ACCESS_DENIED;
- goto done;
- }
-
- result = nt_printing_setsec(Printer->dev.handlename, new_secdesc_ctr);
+ result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
done:
}
/********************************************************************
- Do Samba sanity checks on a printer info struct.
- this has changed purpose: it now "canonicalises" printer
- info from a client rather than just checking it is correct
+ Canonicalize printer info from a client
+
+ ATTN: It does not matter what we set the servername to hear
+ since we do the necessary work in get_a_printer() to set it to
+ the correct value based on what the client sent in the
+ _spoolss_open_printer_ex().
********************************************************************/
static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
{
- DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
- info->servername, info->printername, info->sharename, info->portname, info->drivername, info->comment, info->location));
+ fstring printername;
+ const char *p;
+
+ DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
+ "portname=%s drivername=%s comment=%s location=%s\n",
+ info->servername, info->printername, info->sharename,
+ info->portname, info->drivername, info->comment, info->location));
/* we force some elements to "correct" values */
- slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", get_called_name());
+ slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
fstrcpy(info->sharename, lp_servicename(snum));
- slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
- get_called_name(), info->sharename);
- info->attributes = PRINTER_ATTRIBUTE_SAMBA;
+
+ /* check to see if we allow printername != sharename */
+
+ if ( lp_force_printername(snum) ) {
+ slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
+ global_myname(), info->sharename );
+ } else {
+
+ /* make sure printername is in \\server\printername format */
+
+ fstrcpy( printername, info->printername );
+ p = printername;
+ if ( printername[0] == '\\' && printername[1] == '\\' ) {
+ if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
+ p++;
+ }
+
+ slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
+ global_myname(), p );
+ }
+
+ info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
+ info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
+
return True;
/****************************************************************************
****************************************************************************/
-static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
+BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
{
- extern userdom_struct current_user_info;
char *cmd = lp_addprinter_cmd();
char **qlines;
pstring command;
int ret;
int fd;
fstring remote_machine = "%m";
+ SE_PRIV se_printop = SE_PRINT_OPERATOR;
+ BOOL is_print_op = False;
standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine));
printer->info_2->portname, printer->info_2->drivername,
printer->info_2->location, printer->info_2->comment, remote_machine);
+ if ( token )
+ is_print_op = user_has_privileges( token, &se_printop );
+
DEBUG(10,("Running [%s]\n", command));
- ret = smbrun(command, &fd);
+
+ /********* BEGIN SePrintOperatorPrivilege **********/
+
+ if ( is_print_op )
+ become_root();
+
+ if ( (ret = smbrun(command, &fd)) == 0 ) {
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
+ }
+
+ if ( is_print_op )
+ unbecome_root();
+
+ /********* END SePrintOperatorPrivilege **********/
+
DEBUGADD(10,("returned [%d]\n", ret));
if ( ret != 0 ) {
return False;
}
+ /* reload our services immediately */
+ reload_services( False );
+
numlines = 0;
/* Get lines and convert them back to dos-codepage */
qlines = fd_lines_load(fd, &numlines);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
close(fd);
- if(numlines) {
+ /* Set the portname to what the script says the portname should be. */
+ /* but don't require anything to be return from the script exit a good error code */
+
+ if (numlines) {
/* Set the portname to what the script says the portname should be. */
strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
-
- /* Send SIGHUP to process group... is there a better way? */
- kill(0, SIGHUP);
-
- /* reload our services immediately */
- reload_services( False );
}
file_lines_free(qlines);
|| !strequal(printer->info_2->portname, old_printer->info_2->portname)
|| !strequal(printer->info_2->location, old_printer->info_2->location)) )
{
- if ( !add_printer_hook(printer) ) {
+ /* 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);
}
/*
if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
- set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
- REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
notify_printer_sharename(snum, printer->info_2->sharename);
}
+ if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
+ char *pname;
+
+ if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
+ pname++;
+ else
+ pname = printer->info_2->printername;
+
+
+ init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
+ set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
+ REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+
+ notify_printer_printername( snum, pname );
+ }
+
if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
/* Update printer info */
- result = mod_a_printer(*printer, 2);
+ result = mod_a_printer(printer, 2);
done:
free_a_printer(&printer, 2);
DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
uint32 command = q_u->command;
+ WERROR result;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
case 0:
return control_printer(handle, command, p);
case 2:
- return update_printer(p, handle, level, info, devmode_ctr.devmode);
+ result = update_printer(p, handle, level, info, devmode_ctr.devmode);
+ if (!W_ERROR_IS_OK(result))
+ return result;
+ if (secdesc_ctr)
+ result = update_printer_sec(handle, level, info, p, secdesc_ctr);
+ return result;
case 3:
return update_printer_sec(handle, level, info, p,
secdesc_ctr);
WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
{
- /* that's an [in out] buffer (despite appearences to the contrary) */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
+ /* that's an [in out] buffer */
+
+ if ( q_u->buffer )
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
r_u->needed = 0;
return WERR_INVALID_PARAM; /* this is what a NT server
****************************************************************************/
static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
- int position, int snum)
+ int position, int snum,
+ NT_PRINTER_INFO_LEVEL *ntprinter)
{
- pstring temp_name;
-
struct tm *t;
t=gmtime(&queue->time);
- slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
job_info->jobid=queue->job;
init_unistr(&job_info->printername, lp_servicename(snum));
- init_unistr(&job_info->machinename, temp_name);
+ init_unistr(&job_info->machinename, ntprinter->info_2->servername);
init_unistr(&job_info->username, queue->fs_user);
init_unistr(&job_info->document, queue->fs_file);
init_unistr(&job_info->datatype, "RAW");
NT_PRINTER_INFO_LEVEL *ntprinter,
DEVICEMODE *devmode)
{
- pstring temp_name;
struct tm *t;
t=gmtime(&queue->time);
- slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
job_info->jobid=queue->job;
init_unistr(&job_info->printername, ntprinter->info_2->printername);
- init_unistr(&job_info->machinename, temp_name);
+ init_unistr(&job_info->machinename, ntprinter->info_2->servername);
init_unistr(&job_info->username, queue->fs_user);
init_unistr(&job_info->document, queue->fs_file);
init_unistr(&job_info->notifyname, queue->fs_user);
****************************************************************************/
static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
- NEW_BUFFER *buffer, uint32 offered,
+ NT_PRINTER_INFO_LEVEL *ntprinter,
+ RPC_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
JOB_INFO_1 *info;
int i;
+ WERROR result = WERR_OK;
- info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
+ info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
if (info==NULL) {
SAFE_FREE(queue);
*returned=0;
}
for (i=0; i<*returned; i++)
- fill_job_info_1(&info[i], &queue[i], i, snum);
+ fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
SAFE_FREE(queue);
for (i=0; i<*returned; i++)
(*needed) += spoolss_size_job_info_1(&info[i]);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
for (i=0; i<*returned; i++)
smb_io_job_info_1("", buffer, &info[i], 0);
+out:
/* clear memory */
SAFE_FREE(info);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
- NEW_BUFFER *buffer, uint32 offered,
+ NT_PRINTER_INFO_LEVEL *ntprinter,
+ RPC_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
JOB_INFO_2 *info = NULL;
int i;
- WERROR result;
+ WERROR result = WERR_OK;
DEVICEMODE *devmode = NULL;
- info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
- if (info==NULL) {
+ if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
*returned=0;
- result = WERR_NOMEM;
- goto done;
- }
-
- result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(result)) {
- *returned = 0;
- goto done;
+ return WERR_NOMEM;
}
/* this should not be a failure condition if the devmode is NULL */
devmode = construct_dev_mode(snum);
for (i=0; i<*returned; i++)
- fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter,
- devmode);
+ fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
free_a_printer(&ntprinter, 2);
SAFE_FREE(queue);
(*needed) += spoolss_size_job_info_2(&info[i]);
if (*needed > offered) {
- *returned=0;
result = WERR_INSUFFICIENT_BUFFER;
- goto done;
+ goto out;
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info);
- result = WERR_INSUFFICIENT_BUFFER;
- goto done;
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
for (i=0; i<*returned; i++)
smb_io_job_info_2("", buffer, &info[i], 0);
- result = WERR_OK;
-
- done:
- free_a_printer(&ntprinter, 2);
+out:
free_devmode(devmode);
- SAFE_FREE(queue);
SAFE_FREE(info);
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
+
return result;
}
{
POLICY_HND *handle = &q_u->handle;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
WERROR wret;
-
+ NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
int snum;
print_status_struct prt_status;
print_queue_struct *queue=NULL;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_enumjobs\n"));
*needed=0;
*returned=0;
+ /* lookup the printer snum and tdb entry */
+
if (!get_printer_snum(p, handle, &snum))
return WERR_BADFID;
+ wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
+ if ( !W_ERROR_IS_OK(wret) )
+ return wret;
+
*returned = print_queue_status(snum, &queue, &prt_status);
DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
switch (level) {
case 1:
- wret = enumjobs_level1(queue, snum, buffer, offered, needed, returned);
+ wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
return wret;
case 2:
- wret = enumjobs_level2(queue, snum, buffer, offered, needed, returned);
+ wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
return wret;
default:
SAFE_FREE(queue);
*returned=0;
- return WERR_UNKNOWN_LEVEL;
+ wret = WERR_UNKNOWN_LEVEL;
}
+
+ free_a_printer( &ntprinter, 2 );
+ return wret;
}
/****************************************************************************
return WERR_BADFID;
}
- if (!print_job_exists(snum, jobid)) {
+ if (!print_job_exists(lp_const_servicename(snum), jobid)) {
return WERR_INVALID_PRINTER_NAME;
}
Enumerates all printer drivers at level 1.
****************************************************************************/
-static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int i;
int ndrivers;
uint32 version;
fstring *list = NULL;
-
NT_PRINTER_DRIVER_INFO_LEVEL driver;
DRIVER_INFO_1 *tdi1, *driver_info_1=NULL;
+ WERROR result = WERR_OK;
*returned=0;
return WERR_NOMEM;
if(ndrivers != 0) {
- if((tdi1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
+ if((tdi1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
SAFE_FREE(driver_info_1);
SAFE_FREE(list);
*needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(driver_info_1);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the driver structures */
smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
}
+out:
SAFE_FREE(driver_info_1);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
Enumerates all printer drivers at level 2.
****************************************************************************/
-static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int i;
int ndrivers;
uint32 version;
fstring *list = NULL;
-
NT_PRINTER_DRIVER_INFO_LEVEL driver;
DRIVER_INFO_2 *tdi2, *driver_info_2=NULL;
+ WERROR result = WERR_OK;
*returned=0;
return WERR_NOMEM;
if(ndrivers != 0) {
- if((tdi2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
+ if((tdi2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
SAFE_FREE(driver_info_2);
SAFE_FREE(list);
*needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(driver_info_2);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the form structures */
smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
}
+out:
SAFE_FREE(driver_info_2);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
Enumerates all printer drivers at level 3.
****************************************************************************/
-static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int i;
int ndrivers;
uint32 version;
fstring *list = NULL;
-
NT_PRINTER_DRIVER_INFO_LEVEL driver;
DRIVER_INFO_3 *tdi3, *driver_info_3=NULL;
+ WERROR result = WERR_OK;
*returned=0;
return WERR_NOMEM;
if(ndrivers != 0) {
- if((tdi3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
+ if((tdi3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
SAFE_FREE(driver_info_3);
SAFE_FREE(list);
*needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(driver_info_3);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
}
-
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
+
/* fill the buffer with the driver structures */
for (i=0; i<*returned; i++) {
DEBUGADD(6,("adding driver [%d] to buffer\n",i));
smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
}
+out:
for (i=0; i<*returned; i++)
SAFE_FREE(driver_info_3[i].dependentfiles);
-
+
SAFE_FREE(driver_info_3);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
{
- UNISTR2 *environment = &q_u->environment;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
- fstring *list = NULL;
fstring servername;
fstring architecture;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_enumprinterdrivers\n"));
- fstrcpy(servername, get_called_name());
- *needed=0;
- *returned=0;
+
+ *needed = 0;
+ *returned = 0;
- unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
+ unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture)-1);
+ unistr2_to_ascii(servername, &q_u->name, sizeof(servername)-1);
+
+ if ( !is_myname_or_ipaddr( servername ) )
+ return WERR_UNKNOWN_PRINTER_DRIVER;
switch (level) {
case 1:
case 3:
return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
default:
- *returned=0;
- SAFE_FREE(list);
return WERR_UNKNOWN_LEVEL;
}
}
WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *numofforms = &r_u->numofforms;
int i;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_enumforms\n"));
DEBUGADD(5,("Offered buffer size [%d]\n", offered));
DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
*numofforms += numbuiltinforms;
- if (*numofforms == 0) return WERR_NO_MORE_ITEMS;
+ if (*numofforms == 0)
+ return WERR_NO_MORE_ITEMS;
switch (level) {
case 1:
- if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
+ if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
*numofforms=0;
return WERR_NOMEM;
}
*needed=buffer_size;
- if (!alloc_buffer_size(buffer, buffer_size)){
+ if (*needed > offered) {
SAFE_FREE(forms_1);
+ *numofforms=0;
return WERR_INSUFFICIENT_BUFFER;
}
+
+ if (!rpcbuf_alloc_size(buffer, buffer_size)){
+ SAFE_FREE(forms_1);
+ *numofforms=0;
+ return WERR_NOMEM;
+ }
/* fill the buffer with the form structures */
for (i=0; i<numbuiltinforms; i++) {
SAFE_FREE(forms_1);
- if (*needed > offered) {
- *numofforms=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
- else
- return WERR_OK;
+ return WERR_OK;
default:
SAFE_FREE(list);
{
uint32 level = q_u->level;
UNISTR2 *uni_formname = &q_u->formname;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
int numofforms=0, i=0;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
*needed=spoolss_size_form_1(&form_1);
- if (!alloc_buffer_size(buffer, buffer_size)){
+ if (*needed > offered)
return WERR_INSUFFICIENT_BUFFER;
- }
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if (!rpcbuf_alloc_size(buffer, buffer_size))
+ return WERR_NOMEM;
/* fill the buffer with the form structures */
DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
port->reserved=0x0;
}
+
/****************************************************************************
- enumports level 1.
+ wrapper around the enumer ports command
****************************************************************************/
-static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+WERROR enumports_hook( int *count, char ***lines )
{
- PORT_INFO_1 *ports=NULL;
- int i=0;
+ char *cmd = lp_enumports_cmd();
+ char **qlines;
+ pstring command;
+ int numlines;
+ int ret;
+ int fd;
- if (*lp_enumports_cmd()) {
- char *cmd = lp_enumports_cmd();
- char **qlines;
- pstring command;
- int numlines;
- int ret;
- int fd;
+ /* if no hook then just fill in the default port */
+
+ if ( !*cmd ) {
+ qlines = SMB_MALLOC_ARRAY( char*, 2 );
+ qlines[0] = SMB_STRDUP( SAMBA_PRINTER_PORT_NAME );
+ qlines[1] = NULL;
+ numlines = 1;
+ }
+ else {
+ /* we have a valid enumport command */
+
slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1);
DEBUG(10,("Running [%s]\n", command));
if (ret != 0) {
if (fd != -1)
close(fd);
- /* Is this the best error to return here? */
+
return WERR_ACCESS_DENIED;
}
qlines = fd_lines_load(fd, &numlines);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
close(fd);
+ }
+
+ *count = numlines;
+ *lines = qlines;
- if(numlines) {
- if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
- DEBUG(10,("Returning WERR_NOMEM [%s]\n",
- dos_errstr(WERR_NOMEM)));
- file_lines_free(qlines);
- return WERR_NOMEM;
- }
+ return WERR_OK;
+}
- for (i=0; i<numlines; i++) {
- DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
- fill_port_1(&ports[i], qlines[i]);
- }
+/****************************************************************************
+ enumports level 1.
+****************************************************************************/
+static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+{
+ PORT_INFO_1 *ports=NULL;
+ int i=0;
+ WERROR result = WERR_OK;
+ char **qlines;
+ int numlines;
+
+ if ( !W_ERROR_IS_OK(result = enumports_hook( &numlines, &qlines )) )
+ return result;
+
+ if(numlines) {
+ if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
+ DEBUG(10,("Returning WERR_NOMEM [%s]\n",
+ dos_errstr(WERR_NOMEM)));
file_lines_free(qlines);
+ return WERR_NOMEM;
}
- *returned = numlines;
-
- } else {
- *returned = 1; /* Sole Samba port returned. */
-
- if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
- return WERR_NOMEM;
-
- DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
+ for (i=0; i<numlines; i++) {
+ DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
+ fill_port_1(&ports[i], qlines[i]);
+ }
- fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
+ file_lines_free(qlines);
}
+ *returned = numlines;
+
/* check the required size. */
for (i=0; i<*returned; i++) {
DEBUGADD(6,("adding port [%d]'s size\n", i));
*needed += spoolss_size_port_info_1(&ports[i]);
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(ports);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the ports structures */
smb_io_port_1("", buffer, &ports[i], 0);
}
+out:
SAFE_FREE(ports);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
enumports level 2.
****************************************************************************/
-static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PORT_INFO_2 *ports=NULL;
int i=0;
+ WERROR result = WERR_OK;
+ char **qlines;
+ int numlines;
- if (*lp_enumports_cmd()) {
- char *cmd = lp_enumports_cmd();
- char *path;
- char **qlines;
- pstring tmp_file;
- pstring command;
- int numlines;
- int ret;
- int fd;
-
- if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
- path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
- else
- path = lp_lockdir();
-
- slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%u.", path, (unsigned int)sys_getpid());
- slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 2);
-
- unlink(tmp_file);
- DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
- ret = smbrun(command, &fd);
- DEBUGADD(10,("returned [%d]\n", ret));
- if (ret != 0) {
- if (fd != -1)
- close(fd);
- /* Is this the best error to return here? */
- return WERR_ACCESS_DENIED;
- }
-
- numlines = 0;
- qlines = fd_lines_load(fd, &numlines);
- DEBUGADD(10,("Lines returned = [%d]\n", numlines));
- close(fd);
-
- if(numlines) {
- if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
- file_lines_free(qlines);
- return WERR_NOMEM;
- }
-
- for (i=0; i<numlines; i++) {
- DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
- fill_port_2(&(ports[i]), qlines[i]);
- }
-
+ if ( !W_ERROR_IS_OK(result = enumports_hook( &numlines, &qlines )) )
+ return result;
+
+
+ if(numlines) {
+ if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
file_lines_free(qlines);
+ return WERR_NOMEM;
}
- *returned = numlines;
-
- } else {
-
- *returned = 1;
-
- if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
- return WERR_NOMEM;
-
- DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
+ for (i=0; i<numlines; i++) {
+ DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
+ fill_port_2(&(ports[i]), qlines[i]);
+ }
- fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
+ file_lines_free(qlines);
}
+ *returned = numlines;
+
/* check the required size. */
for (i=0; i<*returned; i++) {
DEBUGADD(6,("adding port [%d]'s size\n", i));
*needed += spoolss_size_port_info_2(&ports[i]);
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(ports);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the ports structures */
smb_io_port_2("", buffer, &ports[i], 0);
}
+out:
SAFE_FREE(ports);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_enumports\n"));
int snum;
WERROR err = WERR_OK;
- if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
+ if ((printer = SMB_MALLOC_P(NT_PRINTER_INFO_LEVEL)) == NULL) {
DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
return WERR_NOMEM;
}
/* check to see if the printer already exists */
if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
- DEBUG(5, ("_spoolss_addprinterex: Attempted to add a printer named [%s] when one already existed!\n",
+ DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
printer->info_2->sharename));
free_a_printer(&printer, 2);
return WERR_PRINTER_ALREADY_EXISTS;
trying to add a printer like this --jerry */
if (*lp_addprinter_cmd() ) {
- if ( !add_printer_hook(printer) ) {
+ if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
free_a_printer(&printer,2);
return WERR_ACCESS_DENIED;
+ }
+ } else {
+ DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
+ "smb.conf parameter \"addprinter command\" is defined. This"
+ "parameter must exist for this call to succeed\n",
+ printer->info_2->sharename ));
}
- }
- slprintf(name, sizeof(name)-1, "\\\\%s\\%s", get_called_name(),
+ /* use our primary netbios name since get_a_printer() will convert
+ it to what the client expects on a case by case basis */
+
+ slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
printer->info_2->sharename);
}
/* write the ASCII on disk */
- err = mod_a_printer(*printer, 2);
+ err = mod_a_printer(printer, 2);
if (!W_ERROR_IS_OK(err)) {
free_a_printer(&printer,2);
return err;
WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
{
- UNISTR2 *uni_srv_name = &q_u->server_name;
+ UNISTR2 *uni_srv_name = q_u->server_name;
uint32 level = q_u->level;
SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
DEVICEMODE *devmode = q_u->devmode_ctr.devmode;
goto done;
DEBUG(5,("Moving driver to final destination\n"));
- if(!move_driver_to_download_area(driver, level, &user, &err)) {
- if (W_ERROR_IS_OK(err))
- err = WERR_ACCESS_DENIED;
+ if( !W_ERROR_IS_OK(err = move_driver_to_download_area(driver, level, &user, &err)) ) {
goto done;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
pstring path;
pstring long_archi;
+ fstring servername;
+ char *pservername;
const char *short_archi;
DRIVER_DIRECTORY_1 *info=NULL;
+ WERROR result = WERR_OK;
+ unistr2_to_ascii(servername, name, sizeof(servername)-1);
unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
+ /* check for beginning double '\'s and that the server
+ long enough */
+
+ pservername = servername;
+ if ( *pservername == '\\' && strlen(servername)>2 ) {
+ pservername += 2;
+ }
+
+ if ( !is_myname_or_ipaddr( pservername ) )
+ return WERR_INVALID_PARAM;
+
if (!(short_archi = get_short_archi(long_archi)))
return WERR_INVALID_ENVIRONMENT;
- if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
+ if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL)
return WERR_NOMEM;
- slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi);
+ slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", pservername, short_archi);
DEBUG(4,("printer driver directory: [%s]\n", path));
*needed += spoolss_size_driverdir_info_1(info);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
smb_io_driverdir_1("", buffer, info, 0);
+out:
SAFE_FREE(info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
UNISTR2 *name = &q_u->name;
UNISTR2 *uni_environment = &q_u->environment;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
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 )
{
*out_max_value_len=(in_value_len/sizeof(uint16));
- if((*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
+ if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
{
result = WERR_NOMEM;
goto done;
/* only allocate when given a non-zero data_len */
- if ( in_data_len && ((*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;
/* name */
*out_max_value_len=(in_value_len/sizeof(uint16));
- if ( (*out_value = (uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
+ if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
{
result = WERR_NOMEM;
goto done;
/* 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 = (size_t)regval_size(val);
- memcpy( *data_out, regval_data_p(val), data_len );
+ data_len = regval_size(val);
+ if ( *data_out )
+ memcpy( *data_out, regval_data_p(val), data_len );
*out_data_len = data_len;
}
status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
type, data, real_len );
if ( W_ERROR_IS_OK(status) )
- status = mod_a_printer(*printer, 2);
+ status = mod_a_printer(printer, 2);
}
done:
status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename );
if ( W_ERROR_IS_OK(status) )
- mod_a_printer( *printer, 2 );
+ mod_a_printer( printer, 2 );
free_a_printer(&printer, 2);
*/
if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER )
- status = mod_a_printer(*printer, 2);
+ status = mod_a_printer(printer, 2);
done:
if ( printer )
*/
if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER )
- status = mod_a_printer(*printer, 2);
+ status = mod_a_printer(printer, 2);
done:
if ( printer )
*/
if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER )
- status = mod_a_printer(*printer, 2);
+ status = mod_a_printer(printer, 2);
done:
enumprintprocessors level 1.
****************************************************************************/
-static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTPROCESSOR_1 *info_1=NULL;
+ WERROR result = WERR_OK;
- if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
+ if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
return WERR_NOMEM;
(*returned) = 0x1;
*needed += spoolss_size_printprocessor_info_1(info_1);
- if (!alloc_buffer_size(buffer, *needed))
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
smb_io_printprocessor_info_1("", buffer, info_1, 0);
+out:
SAFE_FREE(info_1);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(5,("spoolss_enumprintprocessors\n"));
enumprintprocdatatypes level 1.
****************************************************************************/
-static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTPROCDATATYPE_1 *info_1=NULL;
+ WERROR result = WERR_NOMEM;
- if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
+ if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
return WERR_NOMEM;
(*returned) = 0x1;
*needed += spoolss_size_printprocdatatype_info_1(info_1);
- if (!alloc_buffer_size(buffer, *needed))
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
+out:
SAFE_FREE(info_1);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
enumprintmonitors level 1.
****************************************************************************/
-static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTMONITOR_1 *info_1=NULL;
+ WERROR result = WERR_OK;
- if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
+ if((info_1 = SMB_MALLOC_P(PRINTMONITOR_1)) == NULL)
return WERR_NOMEM;
(*returned) = 0x1;
*needed += spoolss_size_printmonitor_info_1(info_1);
- if (!alloc_buffer_size(buffer, *needed))
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
smb_io_printmonitor_info_1("", buffer, info_1, 0);
+out:
SAFE_FREE(info_1);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
enumprintmonitors level 2.
****************************************************************************/
-static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTMONITOR_2 *info_2=NULL;
+ WERROR result = WERR_OK;
- if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
+ if((info_2 = SMB_MALLOC_P(PRINTMONITOR_2)) == NULL)
return WERR_NOMEM;
(*returned) = 0x1;
*needed += spoolss_size_printmonitor_info_2(info_2);
- if (!alloc_buffer_size(buffer, *needed))
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
smb_io_printmonitor_info_2("", buffer, info_2, 0);
+out:
SAFE_FREE(info_2);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
+
+ return result;
}
/****************************************************************************
WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(5,("spoolss_enumprintmonitors\n"));
/****************************************************************************
****************************************************************************/
-static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
+ NT_PRINTER_INFO_LEVEL *ntprinter,
+ uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
+ uint32 *needed)
{
int i=0;
BOOL found=False;
JOB_INFO_1 *info_1=NULL;
+ WERROR result = WERR_OK;
- info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
+ info_1=SMB_MALLOC_P(JOB_INFO_1);
if (info_1 == NULL) {
return WERR_NOMEM;
return WERR_INVALID_PARAM;
}
- fill_job_info_1(info_1, &((*queue)[i-1]), i, snum);
+ fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
*needed += spoolss_size_job_info_1(info_1);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info_1);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
smb_io_job_info_1("", buffer, info_1, 0);
+out:
SAFE_FREE(info_1);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
+ NT_PRINTER_INFO_LEVEL *ntprinter,
+ uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
+ uint32 *needed)
{
int i = 0;
BOOL found = False;
JOB_INFO_2 *info_2;
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- WERROR ret;
+ WERROR result;
DEVICEMODE *devmode = NULL;
NT_DEVICEMODE *nt_devmode = NULL;
- info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
+ if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
+ return WERR_NOMEM;
ZERO_STRUCTP(info_2);
- if (info_2 == NULL) {
- ret = WERR_NOMEM;
- goto done;
- }
-
for ( i=0; i<count && found==False; i++ )
{
if ((*queue)[i].job == (int)jobid)
found = True;
}
- if ( !found )
- {
+ if ( !found ) {
/* NT treats not found as bad param... yet another bad
choice */
- ret = WERR_INVALID_PARAM;
+ result = WERR_INVALID_PARAM;
goto done;
}
- ret = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(ret))
- goto done;
-
/*
* if the print job does not have a DEVMODE associated with it,
* just use the one for the printer. A NULL devicemode is not
* a failure condition
*/
- if ( !(nt_devmode=print_job_devmode( snum, jobid )) )
+ if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
devmode = construct_dev_mode(snum);
else {
- if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) != NULL) {
+ if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
ZERO_STRUCTP( devmode );
convert_nt_devicemode( devmode, nt_devmode );
}
*needed += spoolss_size_job_info_2(info_2);
- if (!alloc_buffer_size(buffer, *needed)) {
- ret = WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
goto done;
}
- smb_io_job_info_2("", buffer, info_2, 0);
-
- if (*needed > offered) {
- ret = WERR_INSUFFICIENT_BUFFER;
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
goto done;
}
- ret = WERR_OK;
+ smb_io_job_info_2("", buffer, info_2, 0);
+
+ result = WERR_OK;
done:
/* Cleanup allocated memory */
free_job_info_2(info_2); /* Also frees devmode */
SAFE_FREE(info_2);
- free_a_printer(&ntprinter, 2);
- return ret;
+ return result;
}
/****************************************************************************
POLICY_HND *handle = &q_u->handle;
uint32 jobid = q_u->jobid;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
WERROR wstatus = WERR_OK;
-
+ NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
int snum;
int count;
print_queue_struct *queue = NULL;
print_status_struct prt_status;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(5,("spoolss_getjob\n"));
if (!get_printer_snum(p, handle, &snum))
return WERR_BADFID;
+ wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
+ if ( !W_ERROR_IS_OK(wstatus) )
+ return wstatus;
+
count = print_queue_status(snum, &queue, &prt_status);
DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
switch ( level ) {
case 1:
- wstatus = getjob_level_1(&queue, count, snum, jobid,
+ wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
buffer, offered, needed);
break;
case 2:
- wstatus = getjob_level_2(&queue, count, snum, jobid,
+ wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
buffer, offered, needed);
break;
default:
}
SAFE_FREE(queue);
+ free_a_printer( &ntprinter, 2 );
+
return wstatus;
}
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;
if ( *out_size )
{
- if( (*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) {
+ if( (*data=(uint8 *)TALLOC_ZERO(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) {
status = WERR_NOMEM;
goto done;
}
{
/* save the OID if one was specified */
if ( oid_string ) {
- fstrcat( keyname, "\\" );
- fstrcat( keyname, SPOOL_OID_KEY );
+ fstrcat( keyname, "\\" );
+ fstrcat( keyname, SPOOL_OID_KEY );
- /*
- * I'm not checking the status here on purpose. Don't know
- * if this is right, but I'm returning the status from the
- * previous set_printer_dataex() call. I have no idea if
- * this is right. --jerry
- */
+ /*
+ * I'm not checking the status here on purpose. Don't know
+ * if this is right, but I'm returning the status from the
+ * previous set_printer_dataex() call. I have no idea if
+ * this is right. --jerry
+ */
- set_printer_dataex( printer, keyname, valuename,
- REG_SZ, (void*)oid_string, strlen(oid_string)+1 );
- }
+ set_printer_dataex( printer, keyname, valuename,
+ REG_SZ, (void*)oid_string, strlen(oid_string)+1 );
+ }
- status = mod_a_printer(*printer, 2);
+ status = mod_a_printer(printer, 2);
}
free_a_printer(&printer, 2);
status = delete_printer_dataex( printer, keyname, valuename );
if ( W_ERROR_IS_OK(status) )
- mod_a_printer( *printer, 2 );
+ mod_a_printer( printer, 2 );
free_a_printer(&printer, 2);
/* 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 );
status = delete_all_printer_data( printer->info_2, key );
if ( W_ERROR_IS_OK(status) )
- status = mod_a_printer(*printer, 2);
+ status = mod_a_printer(printer, 2);
free_a_printer( &printer, 2 );
int i;
REGISTRY_VALUE *val;
char *value_name;
- int data_len;
+ uint32 data_len;
DEBUG(4,("_spoolss_enumprinterdataex\n"));
/* 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(p->mem_ctx, num_entries*sizeof(PRINTER_ENUM_VALUES))) == NULL )
+ if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
{
DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
(unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
{
/* 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 */
data_len = regval_size( val );
if ( data_len ) {
- if ( !(enum_values[i].data = talloc_memdup(p->mem_ctx, regval_data_p(val), data_len)) )
+ if ( !(enum_values[i].data = TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
{
DEBUG(0,("talloc_memdup failed to allocate memory [data_len=%d] for data!\n",
data_len ));
static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
UNISTR2 *environment,
- NEW_BUFFER *buffer,
+ RPC_BUFFER *buffer,
uint32 offered,
uint32 *needed)
{
pstring path;
pstring long_archi;
PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
+ WERROR result = WERR_OK;
unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
if (!get_short_archi(long_archi))
return WERR_INVALID_ENVIRONMENT;
- if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
+ if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL)
return WERR_NOMEM;
pstrcpy(path, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
*needed += spoolss_size_printprocessordirectory_info_1(info);
- if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
}
smb_io_printprocessordirectory_1("", buffer, info, 0);
- safe_free(info);
+out:
+ SAFE_FREE(info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
- else
- return WERR_OK;
+ return result;
}
WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
WERROR result;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(5,("_spoolss_getprintprocessordirectory\n"));