struct xcv_api_table {
const char *name;
- WERROR(*fn) (NT_USER_TOKEN *token, RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed);
+ WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
};
/********************************************************************
return False;
}
-/* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
+#define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
+ _data->data.integer[0] = _integer; \
+ _data->data.integer[1] = 0;
+
+
+#define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
+ _data->data.string.string = talloc_strdup(mem_ctx, _p); \
+ if (!_data->data.string.string) {\
+ _data->data.string.size = 0; \
+ } \
+ _data->data.string.size = strlen_m_term(_p) * 2;
+
+#define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
+ _data->data.devmode.devmode = _devmode;
+
+#define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
+ _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
+ if (!_data->data.sd.sd) { \
+ _data->data.sd.sd_size = 0; \
+ } \
+ _data->data.sd.sd_size = _size;
+
+static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
+ struct tm *t,
+ const char **pp,
+ uint32_t *plen)
+{
+ struct spoolss_Time st;
+ uint32_t len = 16;
+ char *p;
+
+ if (!init_systemtime(&st, t)) {
+ return;
+ }
+
+ p = talloc_array(mem_ctx, char, len);
+ if (!p) {
+ return;
+ }
+
+ /*
+ * Systemtime must be linearized as a set of UINT16's.
+ * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
+ */
+
+ SSVAL(p, 0, st.year);
+ SSVAL(p, 2, st.month);
+ SSVAL(p, 4, st.day_of_week);
+ SSVAL(p, 6, st.day);
+ SSVAL(p, 8, st.hour);
+ SSVAL(p, 10, st.minute);
+ SSVAL(p, 12, st.second);
+ SSVAL(p, 14, st.millisecond);
+
+ *pp = p;
+ *plen = len;
+}
+
+/* Convert a notification message to a struct spoolss_Notify */
static void notify_one_value(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = msg->notify.value[0];
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
}
static void notify_string(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
TALLOC_CTX *mem_ctx)
{
- UNISTR2 unistr;
-
/* The length of the message includes the trailing \0 */
- init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE);
-
- data->notify_data.data.length = 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;
+ data->data.string.size = msg->len * 2;
+ data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
+ if (!data->data.string.string) {
+ data->data.string.size = 0;
return;
}
-
- memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2);
}
static void notify_system_time(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
TALLOC_CTX *mem_ctx)
{
- SYSTEMTIME systime;
- prs_struct ps;
+ data->data.string.string = NULL;
+ data->data.string.size = 0;
if (msg->len != sizeof(time_t)) {
DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
return;
}
- if (!prs_init(&ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
- DEBUG(5, ("notify_system_time: prs_init() failed\n"));
- return;
- }
-
- if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) {
- DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
- prs_mem_free(&ps);
- return;
- }
-
- if (!spoolss_io_system_time("", &ps, 0, &systime)) {
- prs_mem_free(&ps);
- return;
- }
-
- data->notify_data.data.length = prs_offset(&ps);
- if (prs_offset(&ps)) {
- data->notify_data.data.string = (uint16 *)
- TALLOC(mem_ctx, prs_offset(&ps));
- if (!data->notify_data.data.string) {
- prs_mem_free(&ps);
- return;
- }
- prs_copy_all_data_out((char *)data->notify_data.data.string, &ps);
- } else {
- data->notify_data.data.string = NULL;
- }
-
- prs_mem_free(&ps);
+ init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
+ &data->data.string.string,
+ &data->data.string.size);
}
struct notify2_message_table {
const char *name;
void (*fn)(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx);
+ struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
};
static struct notify2_message_table printer_notify_table[] = {
/* loop over all printers */
for (p = printers_list; p; p = p->next) {
- SPOOL_NOTIFY_INFO_DATA *data;
- uint32 data_len = 0;
- uint32 id;
+ struct spoolss_Notify *notifies;
+ uint32_t count = 0;
+ uint32_t id;
int i;
/* Is there notification on this handle? */
/* allocate the max entries possible */
- data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs);
- if (!data) {
+ notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
+ if (!notifies) {
return;
}
- ZERO_STRUCTP(data);
-
/* build the array of change notifications */
sending_msg_count = 0;
}
}
- construct_info_data( &data[data_len], msg->type, msg->field, id );
+ construct_info_data( ¬ifies[count], msg->type, msg->field, id );
switch(msg->type) {
case PRINTER_NOTIFY_TYPE:
if ( printer_notify_table[msg->field].fn )
- printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
+ printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
break;
case JOB_NOTIFY_TYPE:
if ( job_notify_table[msg->field].fn )
- job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
+ job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
break;
default:
goto done;
}
- data_len++;
+ count++;
}
if ( sending_msg_count ) {
return;
}
-/********************************************************************
- Copy routines used by convert_to_openprinterex()
- *******************************************************************/
+/****************************************************************
+ _spoolss_OpenPrinter
+****************************************************************/
-static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
+WERROR _spoolss_OpenPrinter(pipes_struct *p,
+ struct spoolss_OpenPrinter *r)
{
- DEVICEMODE *d;
- int len;
-
- if (!devmode)
- return NULL;
+ struct spoolss_OpenPrinterEx e;
+ WERROR werr;
- DEBUG (8,("dup_devmode\n"));
+ ZERO_STRUCT(e.in.userlevel);
- /* bulk copy first */
-
- d = (DEVICEMODE *)TALLOC_MEMDUP(ctx, devmode, sizeof(DEVICEMODE));
- if (!d)
- return NULL;
-
- /* dup the pointer members separately */
-
- len = unistrlen(devmode->devicename.buffer);
- if (len != -1) {
- d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len);
- if (!d->devicename.buffer) {
- return NULL;
- }
- if (unistrcpy(d->devicename.buffer, devmode->devicename.buffer) != len)
- return NULL;
- }
+ e.in.printername = r->in.printername;
+ e.in.datatype = r->in.datatype;
+ e.in.devmode_ctr = r->in.devmode_ctr;
+ e.in.access_mask = r->in.access_mask;
+ e.in.level = 0;
+ e.out.handle = r->out.handle;
- len = unistrlen(devmode->formname.buffer);
- if (len != -1) {
- d->formname.buffer = TALLOC_ARRAY(ctx, uint16, len);
- if (!d->formname.buffer) {
- return NULL;
- }
- if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len)
- return NULL;
- }
+ werr = _spoolss_OpenPrinterEx(p, &e);
- if (devmode->driverextra) {
- d->dev_private = (uint8 *)TALLOC_MEMDUP(ctx, devmode->dev_private,
- devmode->driverextra);
- if (!d->dev_private) {
- return NULL;
- }
- } else {
- d->dev_private = NULL;
+ if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
+ /* OpenPrinterEx returns this for a bad
+ * printer name. We must return WERR_INVALID_PRINTER_NAME
+ * instead.
+ */
+ werr = WERR_INVALID_PRINTER_NAME;
}
- return d;
-}
-
-static void copy_devmode_ctr(TALLOC_CTX *ctx, DEVMODE_CTR *new_ctr, DEVMODE_CTR *ctr)
-{
- if (!new_ctr || !ctr)
- return;
-
- DEBUG(8,("copy_devmode_ctr\n"));
- new_ctr->size = ctr->size;
- new_ctr->devmode_ptr = ctr->devmode_ptr;
-
- if(ctr->devmode_ptr)
- new_ctr->devmode = dup_devicemode(ctx, ctr->devmode);
-}
-
-static void copy_printer_default(TALLOC_CTX *ctx, PRINTER_DEFAULT *new_def, PRINTER_DEFAULT *def)
-{
- if (!new_def || !def)
- return;
-
- DEBUG(8,("copy_printer_defaults\n"));
-
- new_def->datatype_ptr = def->datatype_ptr;
-
- if (def->datatype_ptr)
- copy_unistr2(&new_def->datatype, &def->datatype);
-
- copy_devmode_ctr(ctx, &new_def->devmode_cont, &def->devmode_cont);
-
- new_def->access_required = def->access_required;
+ return werr;
}
/********************************************************************
- * Convert a SPOOL_Q_OPEN_PRINTER structure to a
- * SPOOL_Q_OPEN_PRINTER_EX structure
+ FIXME: temporary convert_devicemode_new function
********************************************************************/
-static WERROR convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q_u_ex, SPOOL_Q_OPEN_PRINTER *q_u)
+static bool convert_devicemode_new(const char *printername,
+ struct spoolss_DeviceMode *devmode,
+ NT_DEVICEMODE **pp_nt_devmode)
{
- if (!q_u_ex || !q_u)
- return WERR_OK;
+ NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
- DEBUG(8,("convert_to_openprinterex\n"));
+ /*
+ * Ensure nt_devmode is a valid pointer
+ * as we will be overwriting it.
+ */
- 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);
+ if (nt_devmode == NULL) {
+ DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n"));
+ if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
+ return false;
}
- copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default);
-
- return WERR_OK;
-}
-
-/********************************************************************
- * spoolss_open_printer
- *
- * called from the spoolss dispatcher
- ********************************************************************/
-
-WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R_OPEN_PRINTER *r_u)
-{
- SPOOL_Q_OPEN_PRINTER_EX q_u_ex;
- SPOOL_R_OPEN_PRINTER_EX r_u_ex;
-
- if (!q_u || !r_u)
- return WERR_NOMEM;
-
- ZERO_STRUCT(q_u_ex);
- ZERO_STRUCT(r_u_ex);
-
- /* convert the OpenPrinter() call to OpenPrinterEx() */
+ rpcstr_push(nt_devmode->devicename, devmode->devicename, 31, 0);
+ rpcstr_push(nt_devmode->formname, devmode->formname, 31, 0);
+
+ nt_devmode->specversion = devmode->specversion;
+ nt_devmode->driverversion = devmode->driverversion;
+ nt_devmode->size = devmode->size;
+ nt_devmode->fields = devmode->fields;
+ nt_devmode->orientation = devmode->orientation;
+ nt_devmode->papersize = devmode->papersize;
+ nt_devmode->paperlength = devmode->paperlength;
+ nt_devmode->paperwidth = devmode->paperwidth;
+ nt_devmode->scale = devmode->scale;
+ nt_devmode->copies = devmode->copies;
+ nt_devmode->defaultsource = devmode->defaultsource;
+ nt_devmode->printquality = devmode->printquality;
+ nt_devmode->color = devmode->color;
+ nt_devmode->duplex = devmode->duplex;
+ nt_devmode->yresolution = devmode->yresolution;
+ nt_devmode->ttoption = devmode->ttoption;
+ nt_devmode->collate = devmode->collate;
+
+ nt_devmode->logpixels = devmode->logpixels;
+ nt_devmode->bitsperpel = devmode->bitsperpel;
+ nt_devmode->pelswidth = devmode->pelswidth;
+ nt_devmode->pelsheight = devmode->pelsheight;
+ nt_devmode->displayflags = devmode->displayflags;
+ nt_devmode->displayfrequency = devmode->displayfrequency;
+ nt_devmode->icmmethod = devmode->icmmethod;
+ nt_devmode->icmintent = devmode->icmintent;
+ nt_devmode->mediatype = devmode->mediatype;
+ nt_devmode->dithertype = devmode->dithertype;
+ nt_devmode->reserved1 = devmode->reserved1;
+ nt_devmode->reserved2 = devmode->reserved2;
+ nt_devmode->panningwidth = devmode->panningwidth;
+ nt_devmode->panningheight = devmode->panningheight;
- 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);
+ /*
+ * Only change private and driverextra if the incoming devmode
+ * has a new one. JRA.
+ */
- /* convert back to OpenPrinter() */
+ if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
+ SAFE_FREE(nt_devmode->nt_dev_private);
+ nt_devmode->driverextra = devmode->__driverextra_length;
+ if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
+ return false;
+ memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
+ }
- memcpy(r_u, &r_u_ex, sizeof(*r_u));
+ *pp_nt_devmode = nt_devmode;
- if (W_ERROR_EQUAL(r_u->status, WERR_INVALID_PARAM)) {
- /* OpenPrinterEx returns this for a bad
- * printer name. We must return WERR_INVALID_PRINTER_NAME
- * instead.
- */
- r_u->status = WERR_INVALID_PRINTER_NAME;
- }
- return r_u->status;
+ return true;
}
-/********************************************************************
- ********************************************************************/
+/****************************************************************
+ _spoolss_OpenPrinterEx
+****************************************************************/
-WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
+WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
+ struct spoolss_OpenPrinterEx *r)
{
- PRINTER_DEFAULT *printer_default = &q_u->printer_default;
- POLICY_HND *handle = &r_u->handle;
-
- fstring name;
+ POLICY_HND *handle = r->out.handle;
+ char *name = CONST_DISCARD(char *, r->in.printername);
int snum;
Printer_entry *Printer=NULL;
- if (!q_u->printername) {
+ if (!name) {
return WERR_INVALID_PARAM;
}
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
- unistr2_to_ascii(name, q_u->printername, sizeof(name));
-
DEBUGADD(3,("checking name: %s\n",name));
if (!open_printer_hnd(p, handle, name, 0)) {
+ ZERO_STRUCTP(r->out.handle);
return WERR_INVALID_PARAM;
}
Printer=find_printer_index_by_hnd(p, handle);
if ( !Printer ) {
- DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer "
+ DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
"handle we created for printer %s\n", name ));
close_printer_handle(p,handle);
+ ZERO_STRUCTP(r->out.handle);
return WERR_INVALID_PARAM;
}
/* Map standard access rights to object specific access rights */
- se_map_standard(&printer_default->access_required,
+ se_map_standard(&r->in.access_mask,
&printserver_std_mapping);
/* Deny any object specific bits that don't apply to print
servers (i.e printer and job specific bits) */
- printer_default->access_required &= SPECIFIC_RIGHTS_MASK;
+ r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
- if (printer_default->access_required &
+ if (r->in.access_mask &
~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
DEBUG(3, ("access DENIED for non-printserver bits\n"));
close_printer_handle(p, handle);
+ ZERO_STRUCTP(r->out.handle);
return WERR_ACCESS_DENIED;
}
/* Allow admin access */
- if ( printer_default->access_required & SERVER_ACCESS_ADMINISTER )
+ if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
{
SE_PRIV se_printop = SE_PRINT_OPERATOR;
if (!lp_ms_add_printer_wizard()) {
close_printer_handle(p, handle);
+ ZERO_STRUCTP(r->out.handle);
return WERR_ACCESS_DENIED;
}
p->server_info->ptok,
lp_printer_admin(snum))) {
close_printer_handle(p, handle);
+ ZERO_STRUCTP(r->out.handle);
return WERR_ACCESS_DENIED;
}
- printer_default->access_required = SERVER_ACCESS_ADMINISTER;
+ r->in.access_mask = SERVER_ACCESS_ADMINISTER;
}
else
{
- printer_default->access_required = SERVER_ACCESS_ENUMERATE;
+ r->in.access_mask = SERVER_ACCESS_ENUMERATE;
}
- DEBUG(4,("Setting print server access = %s\n", (printer_default->access_required == SERVER_ACCESS_ADMINISTER)
+ DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
/* We fall through to return WERR_OK */
if (!get_printer_snum(p, handle, &snum, NULL)) {
close_printer_handle(p, handle);
+ ZERO_STRUCTP(r->out.handle);
return WERR_BADFID;
}
- se_map_standard(&printer_default->access_required, &printer_std_mapping);
+ se_map_standard(&r->in.access_mask, &printer_std_mapping);
/* map an empty access mask to the minimum access mask */
- if (printer_default->access_required == 0x0)
- printer_default->access_required = PRINTER_ACCESS_USE;
+ if (r->in.access_mask == 0x0)
+ r->in.access_mask = PRINTER_ACCESS_USE;
/*
* If we are not serving the printer driver for this printer,
*/
if (lp_use_client_driver(snum)
- && (printer_default->access_required & PRINTER_ACCESS_ADMINISTER))
+ && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
{
- printer_default->access_required = PRINTER_ACCESS_USE;
+ r->in.access_mask = PRINTER_ACCESS_USE;
}
/* check smb.conf parameters and the the sec_desc */
if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
+ ZERO_STRUCTP(r->out.handle);
return WERR_ACCESS_DENIED;
}
if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
p->server_info->ptok, snum) ||
!print_access_check(p->server_info, snum,
- printer_default->access_required)) {
+ r->in.access_mask)) {
DEBUG(3, ("access DENIED for printer open\n"));
close_printer_handle(p, handle);
+ ZERO_STRUCTP(r->out.handle);
return WERR_ACCESS_DENIED;
}
- if ((printer_default->access_required & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
+ if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
close_printer_handle(p, handle);
+ ZERO_STRUCTP(r->out.handle);
return WERR_ACCESS_DENIED;
}
- if (printer_default->access_required & PRINTER_ACCESS_ADMINISTER)
- printer_default->access_required = PRINTER_ACCESS_ADMINISTER;
+ if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
+ r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
else
- printer_default->access_required = PRINTER_ACCESS_USE;
+ r->in.access_mask = PRINTER_ACCESS_USE;
- DEBUG(4,("Setting printer access = %s\n", (printer_default->access_required == PRINTER_ACCESS_ADMINISTER)
+ DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
break;
default:
/* sanity check to prevent programmer error */
+ ZERO_STRUCTP(r->out.handle);
return WERR_BADFID;
}
- Printer->access_granted = printer_default->access_required;
+ Printer->access_granted = r->in.access_mask;
/*
* If the client sent a devmode in the OpenPrinter() call, then
*/
if ( (Printer->printer_type != SPLHND_SERVER)
- && q_u->printer_default.devmode_cont.devmode_ptr )
+ && r->in.devmode_ctr.devmode )
{
- convert_devicemode( Printer->sharename, q_u->printer_default.devmode_cont.devmode,
- &Printer->nt_devmode );
+ convert_devicemode_new(Printer->sharename,
+ r->in.devmode_ctr.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 */
- if ( (printer_default->access_required == PRINTER_ACCESS_ADMINISTER)
+ if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
&& (RA_WIN2K == get_remote_arch()) )
{
- DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
+ DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
sys_usleep( 500000 );
}
#endif
/****************************************************************************
****************************************************************************/
-static bool convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
- NT_PRINTER_INFO_LEVEL *printer, uint32 level)
+static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
+ NT_PRINTER_INFO_LEVEL_2 *d)
+{
+ DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
+
+ if (!r || !d) {
+ return false;
+ }
+
+ d->attributes = r->attributes;
+ d->priority = r->priority;
+ d->default_priority = r->defaultpriority;
+ d->starttime = r->starttime;
+ d->untiltime = r->untiltime;
+ d->status = r->status;
+ d->cjobs = r->cjobs;
+
+ fstrcpy(d->servername, r->servername);
+ fstrcpy(d->printername, r->printername);
+ fstrcpy(d->sharename, r->sharename);
+ fstrcpy(d->portname, r->portname);
+ fstrcpy(d->drivername, r->drivername);
+ slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
+ fstrcpy(d->location, r->location);
+ fstrcpy(d->sepfile, r->sepfile);
+ fstrcpy(d->printprocessor, r->printprocessor);
+ fstrcpy(d->datatype, r->datatype);
+ fstrcpy(d->parameters, r->parameters);
+
+ return true;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr,
+ NT_PRINTER_INFO_LEVEL *printer)
{
bool ret;
- switch (level) {
- case 2:
- /* 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;
- }
+ switch (info_ctr->level) {
+ case 2:
+ /* 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_new: "
+ "talloc() failed!\n"));
+ return false;
}
+ }
+
+ ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
+ printer->info_2);
+ printer->info_2->setuptime = time(NULL);
+ return ret;
+ }
+
+ return false;
+}
- ret = uni_2_asc_printer_info_2(uni->info_2, printer->info_2);
- printer->info_2->setuptime = time(NULL);
+/*******************************************************************
+********************************************************************/
+
+static bool string_array_to_fstring_array(const char **sarray, fstring **farray)
+{
+ int i;
- return ret;
+ if (!sarray) {
+ *farray = NULL;
+ return true;
}
- return False;
+ *farray = SMB_MALLOC_ARRAY(fstring, 1);
+ if (!*farray) {
+ return false;
+ }
+
+ for (i=0; sarray[i] != NULL; i++) {
+ *farray = SMB_REALLOC_ARRAY(*farray, fstring, i+2);
+ if (!*farray) {
+ return false;
+ }
+ fstrcpy((*farray)[i], sarray[i]);
+ }
+
+ fstrcpy((*farray)[i], "");
+
+ return true;
+}
+
+/*******************************************************************
+********************************************************************/
+
+static bool driver_info3_to_nt_driver_info3(struct spoolss_AddDriverInfo3 *r,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 **p)
+{
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
+
+ DEBUG(7,("driver_info3_to_nt_driver_info3: Converting from UNICODE to ASCII\n"));
+
+ if (*p == NULL) {
+ *p = SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
+ if (*p == NULL) {
+ return false;
+ }
+ ZERO_STRUCTP(*p);
+ }
+
+ d = *p;
+
+ d->cversion = r->version;
+
+ fstrcpy(d->name, r->driver_name);
+ fstrcpy(d->environment, r->architecture);
+ fstrcpy(d->driverpath, r->driver_path);
+ fstrcpy(d->datafile, r->data_file);
+ fstrcpy(d->configfile, r->config_file);
+ fstrcpy(d->helpfile, r->help_file);
+ fstrcpy(d->monitorname, r->monitor_name);
+ fstrcpy(d->defaultdatatype, r->default_datatype);
+
+ DEBUGADD(8,( "version: %d\n", d->cversion));
+ DEBUGADD(8,( "name: %s\n", d->name));
+ DEBUGADD(8,( "environment: %s\n", d->environment));
+ DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
+ DEBUGADD(8,( "datafile: %s\n", d->datafile));
+ DEBUGADD(8,( "configfile: %s\n", d->configfile));
+ DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
+ DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
+ DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
+
+ if (r->dependent_files) {
+ if (!string_array_to_fstring_array(r->dependent_files->string,
+ &d->dependentfiles)) {
+ SAFE_FREE(*p);
+ return false;
+ }
+ }
+
+ return true;
}
-static bool convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
- NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
+/*******************************************************************
+********************************************************************/
+
+static bool driver_info6_to_nt_driver_info6(struct spoolss_AddDriverInfo6 *r,
+ NT_PRINTER_DRIVER_INFO_LEVEL_6 **p)
{
- bool result = True;
+ NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
+
+ DEBUG(7,("driver_info6_to_nt_driver_info6: Converting from UNICODE to ASCII\n"));
+ if (*p == NULL) {
+ *p = SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
+ if (*p == NULL) {
+ return false;
+ }
+ ZERO_STRUCTP(*p);
+ }
+
+ d = *p;
+
+ d->version = r->version;
+
+ fstrcpy(d->name, r->driver_name);
+ fstrcpy(d->environment, r->architecture);
+ fstrcpy(d->driverpath, r->driver_path);
+ fstrcpy(d->datafile, r->data_file);
+ fstrcpy(d->configfile, r->config_file);
+ fstrcpy(d->helpfile, r->help_file);
+ fstrcpy(d->monitorname, r->monitor_name);
+ fstrcpy(d->defaultdatatype, r->default_datatype);
+
+ DEBUGADD(8,( "version: %d\n", d->version));
+ DEBUGADD(8,( "name: %s\n", d->name));
+ DEBUGADD(8,( "environment: %s\n", d->environment));
+ DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
+ DEBUGADD(8,( "datafile: %s\n", d->datafile));
+ DEBUGADD(8,( "configfile: %s\n", d->configfile));
+ DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
+ DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
+ DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
+
+ if (r->dependent_files) {
+ if (!string_array_to_fstring_array(r->dependent_files->string,
+ &d->dependentfiles)) {
+ goto error;
+ }
+ }
+
+ if (r->previous_names) {
+ if (!string_array_to_fstring_array(r->previous_names->string,
+ &d->previousnames)) {
+ goto error;
+ }
+ }
+
+ return true;
+
+ error:
+ SAFE_FREE(*p);
+ return false;
+}
+
+/********************************************************************
+ ********************************************************************/
+
+static bool convert_printer_driver_info(const struct spoolss_AddDriverInfoCtr *r,
+ NT_PRINTER_DRIVER_INFO_LEVEL *printer,
+ uint32_t level)
+{
switch (level) {
- case 3:
- printer->info_3=NULL;
- if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
- result = False;
- break;
- case 6:
- printer->info_6=NULL;
- if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
- result = False;
- break;
- default:
- break;
+ case 3:
+ printer->info_3 = NULL;
+ if (!driver_info3_to_nt_driver_info3(r->info.info3, &printer->info_3)) {
+ return false;
+ }
+ break;
+ case 6:
+ printer->info_6 = NULL;
+ if (!driver_info6_to_nt_driver_info6(r->info.info6, &printer->info_6)) {
+ return false;
+ }
+ break;
+ default:
+ return false;
}
- return result;
+ return true;
}
bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
POLICY_HND *handle, struct sockaddr_storage *client_ss)
{
WERROR result;
+ NTSTATUS status;
/*
* If it's the first connection, contact the client
smb_connections++;
- result = rpccli_spoolss_reply_open_printer(notify_cli_pipe,
- talloc_tos(),
- printer,
- localprinter,
- type,
- handle);
-
- if (!W_ERROR_IS_OK(result))
+ status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
+ printer,
+ localprinter,
+ type,
+ 0,
+ NULL,
+ handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
win_errstr(result)));
********************************************************************/
void spoolss_notify_server_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->servername);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_printer_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
/* the notify name should not contain the \\server\ part */
char *p = strrchr(printer->info_2->printername, '\\');
p++;
}
- len = rpcstr_push_talloc(mem_ctx, &temp, p);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_share_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, lp_servicename(snum));
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
-
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
}
/*******************************************************************
********************************************************************/
void spoolss_notify_port_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- /* even if it's strange, that's consistant in all the code */
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->portname);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_driver_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->drivername);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_comment(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
+ char *p;
- if (*printer->info_2->comment == '\0')
- len = rpcstr_push_talloc(mem_ctx, &temp, lp_comment(snum));
- else
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->comment);
-
- if (len == (uint32)-1) {
- len = 0;
- }
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
+ if (*printer->info_2->comment == '\0') {
+ p = lp_comment(snum);
} else {
- data->notify_data.data.string = NULL;
+ p = printer->info_2->comment;
}
+
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_location(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->location);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_devmode(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
/* for a dummy implementation we have to zero the fields */
- data->notify_data.data.length = 0;
- data->notify_data.data.string = NULL;
+ SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_sepfile(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->sepfile);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_print_processor(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->printprocessor);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_parameters(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->parameters);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_datatype(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->datatype);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_security_desc(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.sd.size = printer->info_2->secdesc_buf->sd_size;
- data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sd ) ;
+ SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
+ printer->info_2->secdesc_buf->sd_size,
+ printer->info_2->secdesc_buf->sd);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_attributes(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = printer->info_2->attributes;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_priority(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = printer->info_2->priority;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_default_priority(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = printer->info_2->default_priority;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_start_time(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = printer->info_2->starttime;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_until_time(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = printer->info_2->untiltime;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_status(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
print_status_struct status;
print_queue_length(snum, &status);
- data->notify_data.value[0]=(uint32) status.status;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
}
/*******************************************************************
********************************************************************/
void spoolss_notify_cjobs(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = print_queue_length(snum, NULL);
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_average_ppm(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
/* always respond 8 pages per minutes */
/* a little hard ! */
- data->notify_data.value[0] = printer->info_2->averageppm;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_username(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_user);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_job_status(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=nt_printj_status(queue->status);
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_job_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_file);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_job_status_string(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
*/
const char *p = "";
- smb_ucs2_t *temp = NULL;
- uint32 len;
#if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
p = "unknown";
}
#endif /* NO LONGER NEEDED. */
- len = rpcstr_push_talloc(mem_ctx, &temp, p);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_job_time(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=0x0;
- data->notify_data.value[1]=0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_job_size(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=queue->size;
- data->notify_data.value[1]=0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
}
/*******************************************************************
* fill a notify_info_data with page info
********************************************************************/
static void spoolss_notify_total_pages(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=queue->page_count;
- data->notify_data.value[1]=0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
}
/*******************************************************************
* fill a notify_info_data with pages printed info.
********************************************************************/
static void spoolss_notify_pages_printed(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=0; /* Add code when back-end tracks this */
- data->notify_data.value[1]=0;
+ /* Add code when back-end tracks this */
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_job_position(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=queue->job;
- data->notify_data.value[1]=0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
}
/*******************************************************************
********************************************************************/
static void spoolss_notify_submitted_time(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- struct tm *t;
- uint32 len;
- SYSTEMTIME st;
- char *p;
-
- t=gmtime(&queue->time);
-
- len = sizeof(SYSTEMTIME);
-
- data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
+ data->data.string.string = NULL;
+ data->data.string.size = 0;
- if (!data->notify_data.data.string) {
- data->notify_data.data.length = 0;
- return;
- }
-
- make_systemtime(&st, t);
-
- /*
- * Systemtime must be linearized as a set of UINT16's.
- * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
- */
+ init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
+ &data->data.string.string,
+ &data->data.string.size);
- p = (char *)data->notify_data.data.string;
- SSVAL(p, 0, st.year);
- SSVAL(p, 2, st.month);
- SSVAL(p, 4, st.dayofweek);
- SSVAL(p, 6, st.day);
- SSVAL(p, 8, st.hour);
- SSVAL(p, 10, st.minute);
- SSVAL(p, 12, st.second);
- SSVAL(p, 14, st.milliseconds);
}
struct s_notify_info_data_table
uint16 field;
const char *name;
uint32 size;
- void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
+ void (*fn) (int snum, struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
};
/****************************************************************************
****************************************************************************/
-void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
+void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 field, int id)
{
- info_data->type = type;
- info_data->field = field;
- info_data->reserved = 0;
-
- info_data->size = size_of_notify_info_data(type, field);
- info_data->enc_type = type_of_notify_info_data(type, field);
-
- info_data->id = id;
+ info_data->type = type;
+ info_data->field = field;
+ info_data->variable_type = size_of_notify_info_data(type, field);
+ info_data->job_id = id;
}
/*******************************************************************
uint16 type;
uint16 field;
- SPOOL_NOTIFY_INFO_DATA *current_data;
+ struct spoolss_Notify *current_data;
NT_PRINTER_INFO_LEVEL *printer = NULL;
print_queue_struct *queue=NULL;
if (!search_notify(type, field, &j) )
continue;
- if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
+ if((info->data=SMB_REALLOC_ARRAY(info->data, struct spoolss_Notify, info->count+1)) == NULL) {
DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
free_a_printer(&printer, 2);
return False;
uint16 type;
uint16 field;
- SPOOL_NOTIFY_INFO_DATA *current_data;
+ struct spoolss_Notify *current_data;
DEBUG(4,("construct_notify_jobs_info\n"));
if (!search_notify(type, field, &j) )
continue;
- if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
+ if((info->data=SMB_REALLOC_ARRAY(info->data, struct spoolss_Notify, info->count+1)) == NULL) {
DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
return False;
}
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
return WERR_OK;
}
-/********************************************************************
- * api_spoolss_getprinter
- * called from the spoolss dispatcher
- *
- ********************************************************************/
+/****************************************************************
+ _spoolss_StartDocPrinter
+****************************************************************/
-WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u)
+WERROR _spoolss_StartDocPrinter(pipes_struct *p,
+ struct spoolss_StartDocPrinter *r)
{
- POLICY_HND *handle = &q_u->handle;
- DOC_INFO *docinfo = &q_u->doc_info_container.docinfo;
- uint32 *jobid = &r_u->jobid;
- TALLOC_CTX *ctx = p->mem_ctx;
- DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
+ POLICY_HND *handle = r->in.handle;
+ uint32_t *jobid = r->out.job_id;
+ struct spoolss_DocumentInfo1 *info_1;
int snum;
- char *jobname = NULL;
- fstring datatype;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
if (!Printer) {
- DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_StartDocPrinter: "
+ "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
return WERR_BADFID;
}
+ if (r->in.level != 1) {
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ info_1 = r->in.info.info1;
+
/*
* a nice thing with NT is it doesn't listen to what you tell it.
* when asked to send _only_ RAW datas, it tries to send datas
* So I add checks like in NT Server ...
*/
- if (info_1->p_datatype != 0) {
- unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
- if (strcmp(datatype, "RAW") != 0) {
+ if (info_1->datatype) {
+ if (strcmp(info_1->datatype, "RAW") != 0) {
(*jobid)=0;
return WERR_INVALID_DATATYPE;
}
return WERR_BADFID;
}
- jobname = unistr2_to_ascii_talloc(ctx, &info_1->docname);
-
- Printer->jobid = print_job_start(p->server_info, snum, jobname,
+ Printer->jobid = print_job_start(p->server_info, snum,
+ CONST_DISCARD(char *,info_1->document_name),
Printer->nt_devmode);
/* An error occured in print_job_start() so return an appropriate
return WERR_BADFID;
switch (command) {
- case PRINTER_CONTROL_PAUSE:
+ case SPOOLSS_PRINTER_CONTROL_PAUSE:
if (print_queue_pause(p->server_info, snum, &errcode)) {
errcode = WERR_OK;
}
break;
- case PRINTER_CONTROL_RESUME:
- case PRINTER_CONTROL_UNPAUSE:
+ case SPOOLSS_PRINTER_CONTROL_RESUME:
+ case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
if (print_queue_resume(p->server_info, snum, &errcode)) {
errcode = WERR_OK;
}
break;
- case PRINTER_CONTROL_PURGE:
+ case SPOOLSS_PRINTER_CONTROL_PURGE:
if (print_queue_purge(p->server_info, snum, &errcode)) {
errcode = WERR_OK;
}
* when updating a printer description
********************************************************************/
-static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
- const SPOOL_PRINTER_INFO_LEVEL *info,
+static WERROR update_printer_sec(POLICY_HND *handle,
pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
{
SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
* when updating a printer description.
********************************************************************/
-static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
- const SPOOL_PRINTER_INFO_LEVEL *info,
- DEVICEMODE *devmode)
+static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
+ struct spoolss_SetPrinterInfoCtr *info_ctr,
+ struct spoolss_DeviceMode *devmode)
{
int snum;
NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
* just read from the tdb in the pointer 'printer'.
*/
- if (!convert_printer_info(info, printer, level)) {
+ if (!convert_printer_info_new(info_ctr, printer)) {
result = WERR_NOMEM;
goto done;
}
convert it and link it*/
DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
- if (!convert_devicemode(printer->info_2->printername, devmode,
- &printer->info_2->devmode)) {
+ if (!convert_devicemode_new(printer->info_2->printername,
+ devmode,
+ &printer->info_2->devmode)) {
result = WERR_NOMEM;
goto done;
}
/****************************************************************************
****************************************************************************/
static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
- const SPOOL_PRINTER_INFO_LEVEL *info)
+ struct spoolss_SetPrinterInfo7 *info7)
{
#ifdef HAVE_ADS
- SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7;
int snum;
Printer_entry *Printer;
return WERR_UNKNOWN_LEVEL;
#endif
}
-/****************************************************************************
-****************************************************************************/
-WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
+/****************************************************************
+ _spoolss_SetPrinter
+****************************************************************/
+
+WERROR _spoolss_SetPrinter(pipes_struct *p,
+ struct spoolss_SetPrinter *r)
{
- POLICY_HND *handle = &q_u->handle;
- uint32 level = q_u->level;
- SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
- DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
- SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
- uint32 command = q_u->command;
+ POLICY_HND *handle = r->in.handle;
WERROR result;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
if (!Printer) {
- DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
+ OUR_HANDLE(handle)));
return WERR_BADFID;
}
/* check the level */
- switch (level) {
+ switch (r->in.info_ctr->level) {
case 0:
- return control_printer(handle, command, p);
+ return control_printer(handle, r->in.command, p);
case 2:
- result = update_printer(p, handle, level, info, devmode_ctr.devmode);
+ result = update_printer(p, handle,
+ r->in.info_ctr,
+ r->in.devmode_ctr->devmode);
if (!W_ERROR_IS_OK(result))
return result;
- if (secdesc_ctr)
- result = update_printer_sec(handle, level, info, p, secdesc_ctr);
+ if (r->in.secdesc_ctr->sd)
+ result = update_printer_sec(handle, p,
+ r->in.secdesc_ctr);
return result;
case 3:
- return update_printer_sec(handle, level, info, p,
- secdesc_ctr);
+ return update_printer_sec(handle, p,
+ r->in.secdesc_ctr);
case 7:
- return publish_or_unpublish_printer(p, handle, info);
+ return publish_or_unpublish_printer(p, handle,
+ r->in.info_ctr->info.info7);
default:
return WERR_UNKNOWN_LEVEL;
}
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
return WERR_OK;
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_SetJob
+****************************************************************/
-WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u)
+WERROR _spoolss_SetJob(pipes_struct *p,
+ struct spoolss_SetJob *r)
{
- POLICY_HND *handle = &q_u->handle;
- uint32 jobid = q_u->jobid;
- uint32 command = q_u->command;
+ POLICY_HND *handle = r->in.handle;
+ uint32 jobid = r->in.job_id;
+ uint32 command = r->in.command;
int snum;
WERROR errcode = WERR_BADFUNC;
}
switch (command) {
- case JOB_CONTROL_CANCEL:
- case JOB_CONTROL_DELETE:
+ case SPOOLSS_JOB_CONTROL_CANCEL:
+ case SPOOLSS_JOB_CONTROL_DELETE:
if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
errcode = WERR_OK;
}
break;
- case JOB_CONTROL_PAUSE:
+ case SPOOLSS_JOB_CONTROL_PAUSE:
if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
errcode = WERR_OK;
}
break;
- case JOB_CONTROL_RESTART:
- case JOB_CONTROL_RESUME:
+ case SPOOLSS_JOB_CONTROL_RESTART:
+ case SPOOLSS_JOB_CONTROL_RESUME:
if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
errcode = WERR_OK;
}
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
return WERR_BADFID;
}
+ ZERO_STRUCT(form_1);
+
switch (level) {
case 1:
if (foundBuiltin) {
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
/****************************************************************************
****************************************************************************/
-static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name,
- const SPOOL_PRINTER_INFO_LEVEL *info,
- DEVICEMODE *devmode, SEC_DESC_BUF *sec_desc_buf,
- uint32 user_switch, const SPOOL_USER_CTR *user,
- POLICY_HND *handle)
+static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
+ const char *server,
+ struct spoolss_SetPrinterInfoCtr *info_ctr,
+ struct spoolss_DeviceMode *devmode,
+ struct security_descriptor *sec_desc,
+ struct spoolss_UserLevelCtr *user_ctr,
+ POLICY_HND *handle)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
fstring name;
}
/* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
- if (!convert_printer_info(info, printer, 2)) {
+ if (!convert_printer_info_new(info_ctr, printer)) {
free_a_printer(&printer, 2);
return WERR_NOMEM;
}
*/
DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
- if (!convert_devicemode(printer->info_2->printername, devmode,
- &printer->info_2->devmode))
+ if (!convert_devicemode_new(printer->info_2->printername,
+ devmode,
+ &printer->info_2->devmode))
return WERR_NOMEM;
}
/* Handle open failed - remove addition. */
del_a_printer(printer->info_2->sharename);
free_a_printer(&printer,2);
+ ZERO_STRUCTP(handle);
return WERR_ACCESS_DENIED;
}
return WERR_OK;
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_AddPrinterEx
+****************************************************************/
-WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
+WERROR _spoolss_AddPrinterEx(pipes_struct *p,
+ struct spoolss_AddPrinterEx *r)
{
- 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;
- SEC_DESC_BUF *sdb = q_u->secdesc_ctr;
- uint32 user_switch = q_u->user_switch;
- SPOOL_USER_CTR *user = &q_u->user_ctr;
- POLICY_HND *handle = &r_u->handle;
-
- switch (level) {
- case 1:
- /* we don't handle yet */
- /* but I know what to do ... */
- return WERR_UNKNOWN_LEVEL;
- case 2:
- return spoolss_addprinterex_level_2(p, uni_srv_name, info,
- devmode, sdb,
- user_switch, user, handle);
- default:
- return WERR_UNKNOWN_LEVEL;
+ switch (r->in.info_ctr->level) {
+ case 1:
+ /* we don't handle yet */
+ /* but I know what to do ... */
+ return WERR_UNKNOWN_LEVEL;
+ case 2:
+ return spoolss_addprinterex_level_2(p, r->in.server,
+ r->in.info_ctr,
+ r->in.devmode_ctr->devmode,
+ r->in.secdesc_ctr->sd,
+ r->in.userlevel_ctr,
+ r->out.handle);
+ default:
+ return WERR_UNKNOWN_LEVEL;
}
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_AddPrinterDriver
+****************************************************************/
-WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
+WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
+ struct spoolss_AddPrinterDriver *r)
{
- uint32 level = q_u->level;
- SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
+ uint32_t level = r->in.info_ctr->level;
+ struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr;
WERROR err = WERR_OK;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
fstring driver_name;
uint32 version;
+ const char *fn;
+
+ switch (p->hdr_req.opnum) {
+ case NDR_SPOOLSS_ADDPRINTERDRIVER:
+ fn = "_spoolss_AddPrinterDriver";
+ break;
+ case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
+ fn = "_spoolss_AddPrinterDriverEx";
+ break;
+ default:
+ return WERR_INVALID_PARAM;
+ }
+
+
+ /* FIXME */
+ if (level != 3 && level != 6) {
+ /* Clever hack from Martin Zielinski <mz@seh.de>
+ * to allow downgrade from level 8 (Vista).
+ */
+ DEBUG(0,("%s: level %d not yet implemented\n", fn, level));
+ return WERR_UNKNOWN_LEVEL;
+ }
ZERO_STRUCT(driver);
*/
if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
- DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
- driver_name));
+ DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
+ fn, driver_name));
}
/*
* 9x printer driver - never delete init data
*/
case 0:
- DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
- driver_name));
+ DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
+ fn, driver_name));
break;
/*
* No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
*/
if (!del_driver_init(driver_name))
- DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name));
+ DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
+ fn, driver_name));
} else {
/*
* a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
*/
free_a_printer_driver(driver1,3);
- DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
- driver_name));
+ DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
+ fn, driver_name));
}
}
break;
*/
case 3:
if (!del_driver_init(driver_name))
- DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name));
+ DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
+ fn, driver_name));
break;
default:
- DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level));
+ DEBUG(0,("%s: invalid level=%d\n", fn, level));
break;
}
return err;
}
-/********************************************************************
- * spoolss_addprinterdriverex
- ********************************************************************/
+/****************************************************************
+ _spoolss_AddPrinterDriverEx
+****************************************************************/
-WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u)
+WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
+ struct spoolss_AddPrinterDriverEx *r)
{
- SPOOL_Q_ADDPRINTERDRIVER q_u_local;
- SPOOL_R_ADDPRINTERDRIVER r_u_local;
+ struct spoolss_AddPrinterDriver a;
/*
* we only support the semantics of AddPrinterDriver()
* i.e. only copy files that are newer than existing ones
*/
- if ( q_u->copy_flags != APD_COPY_NEW_FILES )
+ if (r->in.flags != APD_COPY_NEW_FILES) {
return WERR_ACCESS_DENIED;
+ }
- ZERO_STRUCT(q_u_local);
- ZERO_STRUCT(r_u_local);
-
- /* just pass the information off to _spoolss_addprinterdriver() */
- q_u_local.server_name_ptr = q_u->server_name_ptr;
- copy_unistr2(&q_u_local.server_name, &q_u->server_name);
- q_u_local.level = q_u->level;
- memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) );
-
- return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local );
-}
-
-/****************************************************************************
-****************************************************************************/
+ a.in.servername = r->in.servername;
+ a.in.info_ctr = r->in.info_ctr;
-static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
-{
- init_unistr(&info->name, name);
+ return _spoolss_AddPrinterDriver(p, &a);
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
+ const char *servername,
+ const char *environment,
+ struct spoolss_DriverDirectoryInfo1 *info1,
+ uint32_t offered,
+ uint32_t *needed)
{
char *path = NULL;
- char *long_archi = NULL;
- char *servername = NULL;
const char *pservername = NULL;
+ const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
const char *short_archi;
- DRIVER_DIRECTORY_1 *info=NULL;
- WERROR result = WERR_OK;
- TALLOC_CTX *ctx = talloc_tos();
- servername = unistr2_to_ascii_talloc(ctx, name);
- if (!servername) {
- return WERR_NOMEM;
- }
- long_archi = unistr2_to_ascii_talloc(ctx, uni_environment);
- if (!long_archi) {
- return WERR_NOMEM;
+ if (environment) {
+ long_archi = environment;
}
pservername = canon_servername(servername);
if (!(short_archi = get_short_archi(long_archi)))
return WERR_INVALID_ENVIRONMENT;
- if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL)
- return WERR_NOMEM;
-
- path = talloc_asprintf(ctx,
+ path = talloc_asprintf(mem_ctx,
"\\\\%s\\print$\\%s", pservername, short_archi);
if (!path) {
- result = WERR_NOMEM;
- goto out;
+ return WERR_NOMEM;
}
DEBUG(4,("printer driver directory: [%s]\n", path));
- fill_driverdir_1(info, path);
+ info1->directory_name = path;
- *needed += spoolss_size_driverdir_info_1(info);
+ *needed += ndr_size_spoolss_DriverDirectoryInfo1(info1, NULL, 0);
if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_NOMEM;
- goto out;
+ talloc_free(path);
+ ZERO_STRUCTP(info1);
+ return WERR_INSUFFICIENT_BUFFER;
}
- smb_io_driverdir_1("", buffer, info, 0);
-
-out:
- SAFE_FREE(info);
-
- return result;
+ return WERR_OK;
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_GetPrinterDriverDirectory
+****************************************************************/
-WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
+WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
+ struct spoolss_GetPrinterDriverDirectory *r)
{
- UNISTR2 *name = &q_u->name;
- UNISTR2 *uni_environment = &q_u->environment;
- uint32 level = q_u->level;
- RPC_BUFFER *buffer = NULL;
- uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
+ WERROR werror;
/* that's an [in out] buffer */
- if (!q_u->buffer && (offered!=0)) {
+ if (!r->in.buffer && (r->in.offered != 0)) {
return WERR_INVALID_PARAM;
}
- rpcbuf_move(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+ if (r->in.offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
- DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
+ DEBUG(4,("_spoolss_GetPrinterDriverDirectory\n"));
- *needed=0;
+ *r->out.needed = 0;
- switch(level) {
+ switch (r->in.level) {
case 1:
- return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
+ werror = getprinterdriverdir_level_1(p->mem_ctx,
+ r->in.server,
+ r->in.environment,
+ &r->out.info->info1,
+ r->in.offered,
+ r->out.needed);
+ if (!W_ERROR_IS_OK(werror)) {
+ TALLOC_FREE(r->out.info);
+ }
+ break;
default:
return WERR_UNKNOWN_LEVEL;
}
+
+ return werror;
}
/****************************************************************************
return status;
}
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_ResetPrinter
+****************************************************************/
-WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u)
+WERROR _spoolss_ResetPrinter(pipes_struct *p,
+ struct spoolss_ResetPrinter *r)
{
- POLICY_HND *handle = &q_u->handle;
+ POLICY_HND *handle = r->in.handle;
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
int snum;
- DEBUG(5,("_spoolss_resetprinter\n"));
+ DEBUG(5,("_spoolss_ResetPrinter\n"));
/*
* All we do is to check to see if the handle and queue is valid.
*/
if (!Printer) {
- DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
+ OUR_HANDLE(handle)));
return WERR_BADFID;
}
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
return WERR_INVALID_PARAM;
}
+ if (offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
+
rpcbuf_move(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
return wstatus;
}
-/********************************************************************
- spoolss_getprinterdataex
+/****************************************************************
+ _spoolss_GetPrinterDataEx
From MSDN documentation of GetPrinterDataEx: pass request
to GetPrinterData if key is "PrinterDriverData".
- ********************************************************************/
+****************************************************************/
-WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u)
+WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
+ struct spoolss_GetPrinterDataEx *r)
{
- POLICY_HND *handle = &q_u->handle;
- uint32 in_size = q_u->size;
- uint32 *type = &r_u->type;
- uint32 *out_size = &r_u->size;
- uint8 **data = &r_u->data;
- uint32 *needed = &r_u->needed;
- fstring keyname, valuename;
+ POLICY_HND *handle = r->in.handle;
+ uint8 *data = NULL;
+ const char *keyname = r->in.key_name;
+ const char *valuename = r->in.value_name;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
int snum = 0;
WERROR status = WERR_OK;
- DEBUG(4,("_spoolss_getprinterdataex\n"));
-
- unistr2_to_ascii(keyname, &q_u->keyname, sizeof(keyname));
- unistr2_to_ascii(valuename, &q_u->valuename, sizeof(valuename));
+ DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
- DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
+ DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
keyname, valuename));
/* in case of problem, return some default values */
- *needed = 0;
- *type = 0;
- *out_size = in_size;
+ *r->out.needed = 0;
+ *r->out.type = 0;
if (!Printer) {
- DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_GetPrinterDataEx: "
+ "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
status = WERR_BADFID;
goto done;
}
/* Is the handle to a printer or to the server? */
if (Printer->printer_type == SPLHND_SERVER) {
- DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
+ DEBUG(10,("_spoolss_GetPrinterDataEx: "
+ "Not implemented for server handles yet\n"));
status = WERR_INVALID_PARAM;
goto done;
}
}
if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
- DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname ));
+ DEBUG(4,("_spoolss_GetPrinterDataEx: "
+ "Invalid keyname [%s]\n", keyname ));
free_a_printer( &printer, 2 );
status = WERR_BADFILE;
goto done;
/* When given a new keyname, we should just create it */
- status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename, type, data, needed, in_size );
+ status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
+ r->out.type, &data, r->out.needed,
+ r->in.offered );
- if (*needed > *out_size)
+ if (*r->out.needed > r->in.offered) {
status = WERR_MORE_DATA;
+ }
-done:
- if ( !W_ERROR_IS_OK(status) )
- {
- DEBUG(5, ("error: allocating %d\n", *out_size));
-
- /* reply this param doesn't exist */
-
- if ( *out_size )
- {
- if( (*data=(uint8 *)TALLOC_ZERO(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) {
- status = WERR_NOMEM;
- goto done;
- }
- } else {
- *data = NULL;
- }
+ if (W_ERROR_IS_OK(status)) {
+ memcpy(r->out.buffer, data, r->in.offered);
}
+done:
if ( printer )
free_a_printer( &printer, 2 );
return status;
}
-/********************************************************************
- * spoolss_setprinterdataex
- ********************************************************************/
+/****************************************************************
+ _spoolss_SetPrinterDataEx
+****************************************************************/
-WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u)
+WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
+ struct spoolss_SetPrinterDataEx *r)
{
- POLICY_HND *handle = &q_u->handle;
- uint32 type = q_u->type;
- uint8 *data = q_u->data;
- uint32 real_len = q_u->real_len;
-
+ POLICY_HND *handle = r->in.handle;
NT_PRINTER_INFO_LEVEL *printer = NULL;
int snum = 0;
WERROR status = WERR_OK;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- fstring valuename;
- fstring keyname;
char *oid_string;
- DEBUG(4,("_spoolss_setprinterdataex\n"));
+ DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
/* From MSDN documentation of SetPrinterDataEx: pass request to
SetPrinterData if key is "PrinterDriverData" */
if (!Printer) {
- DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_SetPrinterDataEx: "
+ "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
return WERR_BADFID;
}
if ( Printer->printer_type == SPLHND_SERVER ) {
- DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
+ DEBUG(10,("_spoolss_SetPrinterDataEx: "
+ "Not implemented for server handles yet\n"));
return WERR_INVALID_PARAM;
}
if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
{
- DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
+ DEBUG(3, ("_spoolss_SetPrinterDataEx: "
+ "change denied by handle access permissions\n"));
return WERR_ACCESS_DENIED;
}
if (!W_ERROR_IS_OK(status))
return status;
- unistr2_to_ascii( valuename, &q_u->value, sizeof(valuename));
- unistr2_to_ascii( keyname, &q_u->key, sizeof(keyname));
-
/* check for OID in valuename */
- if ( (oid_string = strchr( valuename, ',' )) != NULL )
+ if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
{
*oid_string = '\0';
oid_string++;
/* save the registry data */
- status = set_printer_dataex( printer, keyname, valuename, type, data, real_len );
+ status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
+ r->in.type, r->in.buffer, r->in.offered );
if ( W_ERROR_IS_OK(status) )
{
/* save the OID if one was specified */
if ( oid_string ) {
- fstrcat( keyname, "\\" );
- fstrcat( keyname, SPOOL_OID_KEY );
+ char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
+ r->in.key_name, SPOOL_OID_KEY);
+ if (!str) {
+ return WERR_NOMEM;
+ }
/*
* I'm not checking the status here on purpose. Don't know
* this is right. --jerry
*/
- set_printer_dataex( printer, keyname, valuename,
+ set_printer_dataex( printer, str, r->in.value_name,
REG_SZ, (uint8 *)oid_string,
strlen(oid_string)+1 );
}
/****************************************************************************
****************************************************************************/
-static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, const char *name)
-{
- init_unistr(&info->name, name);
-}
-
-static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
- UNISTR2 *environment,
- RPC_BUFFER *buffer,
- uint32 offered,
- uint32 *needed)
+static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
+ const char *servername,
+ const char *environment,
+ struct spoolss_PrintProcessorDirectoryInfo1 *info1,
+ uint32_t offered,
+ uint32_t *needed)
{
- char *long_archi = NULL;
- PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
- WERROR result = WERR_OK;
- TALLOC_CTX *ctx = talloc_tos();
+ const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
+ const char *short_archi;
- long_archi = unistr2_to_ascii_talloc(ctx, environment);
- if (!long_archi) {
- return WERR_NOMEM;
+ if (environment) {
+ long_archi = environment;
}
- if (!get_short_archi(long_archi))
+ short_archi = get_short_archi(long_archi);
+ if (!short_archi) {
return WERR_INVALID_ENVIRONMENT;
+ }
- if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL)
- return WERR_NOMEM;
+ /* I think this should look like this - gd
+ info1->directory_name = talloc_asprintf(mem_ctx,
+ "C:\\WINNT\\System32\\spool\\PRTPROCS\\%s", short_archi);
+ */
+ info1->directory_name = talloc_strdup(mem_ctx,
+ "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
- fill_printprocessordirectory_1(info, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
+ if (!info1->directory_name) {
+ return WERR_NOMEM;
+ }
- *needed += spoolss_size_printprocessordirectory_info_1(info);
+ *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(info1, NULL, 0);
if (*needed > offered) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
- }
-
- if (!rpcbuf_alloc_size(buffer, *needed)) {
- result = WERR_INSUFFICIENT_BUFFER;
- goto out;
+ return WERR_INSUFFICIENT_BUFFER;
}
- smb_io_printprocessordirectory_1("", buffer, info, 0);
-
-out:
- SAFE_FREE(info);
-
- return result;
+ return WERR_OK;
}
-WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
+/****************************************************************
+ _spoolss_GetPrintProcessorDirectory
+****************************************************************/
+
+WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
+ struct spoolss_GetPrintProcessorDirectory *r)
{
- uint32 level = q_u->level;
- RPC_BUFFER *buffer = NULL;
- uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
WERROR result;
/* that's an [in out] buffer */
- if (!q_u->buffer && (offered!=0)) {
+ if (!r->in.buffer && (r->in.offered != 0)) {
return WERR_INVALID_PARAM;
}
- rpcbuf_move(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+ if (r->in.offered > MAX_RPC_DATA_SIZE) {
+ return WERR_INVALID_PARAM;
+ }
- DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
+ DEBUG(5,("_spoolss_GetPrintProcessorDirectory\n"));
- *needed=0;
+ *r->out.needed = 0;
- switch(level) {
+ switch (r->in.level) {
case 1:
- result = getprintprocessordirectory_level_1
- (&q_u->name, &q_u->environment, buffer, offered, needed);
+ result = getprintprocessordirectory_level_1(p->mem_ctx,
+ r->in.server,
+ r->in.environment,
+ &r->out.info->info1,
+ r->in.offered,
+ r->out.needed);
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(r->out.info);
+ }
break;
default:
result = WERR_UNKNOWN_LEVEL;
return result;
}
+/*******************************************************************
+ ********************************************************************/
+
+static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
+ const char *dllname)
+{
+ enum ndr_err_code ndr_err;
+ struct spoolss_MonitorUi ui;
+
+ ui.dll_name = dllname;
+
+ ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
+ (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
+ if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
+ NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
+ }
+ return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
+}
+
/*******************************************************************
Streams the monitor UI DLL name in UNICODE
*******************************************************************/
-static WERROR xcvtcp_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in,
- RPC_BUFFER *out, uint32 *needed )
+static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
+ NT_USER_TOKEN *token, DATA_BLOB *in,
+ DATA_BLOB *out, uint32_t *needed)
{
const char *dllname = "tcpmonui.dll";
*needed = (strlen(dllname)+1) * 2;
- if ( rpcbuf_get_size(out) < *needed ) {
+ if (out->length < *needed) {
return WERR_INSUFFICIENT_BUFFER;
}
- if ( !make_monitorui_buf( out, dllname ) ) {
+ if (!push_monitorui_buf(mem_ctx, out, dllname)) {
return WERR_NOMEM;
}
return WERR_OK;
}
+/*******************************************************************
+ ********************************************************************/
+
+static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
+ struct spoolss_PortData1 *port1,
+ const DATA_BLOB *buf)
+{
+ enum ndr_err_code ndr_err;
+ ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
+ (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
+ if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
+ NDR_PRINT_DEBUG(spoolss_PortData1, port1);
+ }
+ return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
+ struct spoolss_PortData2 *port2,
+ const DATA_BLOB *buf)
+{
+ enum ndr_err_code ndr_err;
+ ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
+ (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
+ if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
+ NDR_PRINT_DEBUG(spoolss_PortData2, port2);
+ }
+ return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
+}
+
/*******************************************************************
Create a new TCP/IP port
*******************************************************************/
-static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in,
- RPC_BUFFER *out, uint32 *needed )
+static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
+ NT_USER_TOKEN *token, DATA_BLOB *in,
+ DATA_BLOB *out, uint32_t *needed)
{
- NT_PORT_DATA_1 port1;
- TALLOC_CTX *ctx = talloc_tos();
+ struct spoolss_PortData1 port1;
+ struct spoolss_PortData2 port2;
char *device_uri = NULL;
+ uint32_t version;
- ZERO_STRUCT( port1 );
+ const char *portname;
+ const char *hostaddress;
+ const char *queue;
+ uint32_t port_number;
+ uint32_t protocol;
- /* convert to our internal port data structure */
+ /* peek for spoolss_PortData version */
- if ( !convert_port_data_1( &port1, in ) ) {
- return WERR_NOMEM;
+ if (!in || (in->length < (128 + 4))) {
+ return WERR_GENERAL_FAILURE;
+ }
+
+ version = IVAL(in->data, 128);
+
+ switch (version) {
+ case 1:
+ ZERO_STRUCT(port1);
+
+ if (!pull_port_data_1(mem_ctx, &port1, in)) {
+ return WERR_NOMEM;
+ }
+
+ portname = port1.portname;
+ hostaddress = port1.hostaddress;
+ queue = port1.queue;
+ protocol = port1.protocol;
+ port_number = port1.port_number;
+
+ break;
+ case 2:
+ ZERO_STRUCT(port2);
+
+ if (!pull_port_data_2(mem_ctx, &port2, in)) {
+ return WERR_NOMEM;
+ }
+
+ portname = port2.portname;
+ hostaddress = port2.hostaddress;
+ queue = port2.queue;
+ protocol = port2.protocol;
+ port_number = port2.port_number;
+
+ break;
+ default:
+ DEBUG(1,("xcvtcp_addport: "
+ "unknown version of port_data: %d\n", version));
+ return WERR_UNKNOWN_PORT;
}
/* create the device URI and call the add_port_hook() */
- switch ( port1.protocol ) {
- case PORT_PROTOCOL_DIRECT:
- device_uri = talloc_asprintf(ctx,
- "socket://%s:%d/", port1.hostaddr, port1.port );
+ switch (protocol) {
+ case PROTOCOL_RAWTCP_TYPE:
+ device_uri = talloc_asprintf(mem_ctx,
+ "socket://%s:%d/", hostaddress,
+ port_number);
break;
- case PORT_PROTOCOL_LPR:
- device_uri = talloc_asprintf(ctx,
- "lpr://%s/%s", port1.hostaddr, port1.queue );
+ case PROTOCOL_LPR_TYPE:
+ device_uri = talloc_asprintf(mem_ctx,
+ "lpr://%s/%s", hostaddress, queue );
break;
default:
return WERR_NOMEM;
}
- return add_port_hook(ctx, token, port1.name, device_uri );
+ return add_port_hook(mem_ctx, token, portname, device_uri);
}
/*******************************************************************
{ NULL, NULL }
};
-static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command,
- RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
- uint32 *needed )
+static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
+ NT_USER_TOKEN *token, const char *command,
+ DATA_BLOB *inbuf,
+ DATA_BLOB *outbuf,
+ uint32_t *needed )
{
int i;
for ( i=0; xcvtcp_cmds[i].name; i++ ) {
if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
- return xcvtcp_cmds[i].fn( token, inbuf, outbuf, needed );
+ return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
}
return WERR_BADFUNC;
*******************************************************************/
#if 0 /* don't support management using the "Local Port" monitor */
-static WERROR xcvlocal_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in,
- RPC_BUFFER *out, uint32 *needed )
+static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
+ NT_USER_TOKEN *token, DATA_BLOB *in,
+ DATA_BLOB *out, uint32_t *needed)
{
const char *dllname = "localui.dll";
*needed = (strlen(dllname)+1) * 2;
- if ( rpcbuf_get_size(out) < *needed ) {
+ if (out->length < *needed) {
return WERR_INSUFFICIENT_BUFFER;
}
- if ( !make_monitorui_buf( out, dllname )) {
+ if (!push_monitorui_buf(mem_ctx, out, dllname)) {
return WERR_NOMEM;
}
/*******************************************************************
*******************************************************************/
-static WERROR process_xcvlocal_command( NT_USER_TOKEN *token, const char *command,
- RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
- uint32 *needed )
+static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
+ NT_USER_TOKEN *token, const char *command,
+ DATA_BLOB *inbuf, DATA_BLOB *outbuf,
+ uint32_t *needed)
{
int i;
for ( i=0; xcvlocal_cmds[i].name; i++ ) {
if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
- return xcvlocal_cmds[i].fn( token, inbuf, outbuf , needed );
+ return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
}
return WERR_BADFUNC;
}
-/*******************************************************************
-*******************************************************************/
+/****************************************************************
+ _spoolss_XcvData
+****************************************************************/
-WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_XCVDATAPORT *r_u)
+WERROR _spoolss_XcvData(pipes_struct *p,
+ struct spoolss_XcvData *r)
{
- Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle);
- fstring command;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+ DATA_BLOB out_data;
+ WERROR werror;
if (!Printer) {
- DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u->handle)));
+ DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
+ OUR_HANDLE(r->in.handle)));
return WERR_BADFID;
}
/* Has to be a handle to the TCP/IP port monitor */
if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
- DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n"));
+ DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
return WERR_BADFID;
}
/* requires administrative access to the server */
if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
- DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n"));
+ DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
return WERR_ACCESS_DENIED;
}
- /* Get the command name. There's numerous commands supported by the
- TCPMON interface. */
-
- rpcstr_pull(command, q_u->dataname.buffer, sizeof(command),
- q_u->dataname.uni_str_len*2, 0);
-
/* Allocate the outgoing buffer */
- if (!rpcbuf_init( &r_u->outdata, q_u->offered, p->mem_ctx ))
- return WERR_NOMEM;
+ if (r->in.out_data_size) {
+ out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
+ if (out_data.data == NULL) {
+ return WERR_NOMEM;
+ }
+ }
switch ( Printer->printer_type ) {
case SPLHND_PORTMON_TCP:
- return process_xcvtcp_command( p->server_info->ptok, command,
- &q_u->indata, &r_u->outdata, &r_u->needed );
+ werror = process_xcvtcp_command(p->mem_ctx,
+ p->server_info->ptok,
+ r->in.function_name,
+ &r->in.in_data, &out_data,
+ r->out.needed);
+ break;
case SPLHND_PORTMON_LOCAL:
- return process_xcvlocal_command( p->server_info->ptok, command,
- &q_u->indata, &r_u->outdata, &r_u->needed );
+ werror = process_xcvlocal_command(p->mem_ctx,
+ p->server_info->ptok,
+ r->in.function_name,
+ &r->in.in_data, &out_data,
+ r->out.needed);
+ break;
+ default:
+ werror = WERR_INVALID_PRINT_MONITOR;
}
- return WERR_INVALID_PRINT_MONITOR;
+ if (!W_ERROR_IS_OK(werror)) {
+ return werror;
+ }
+
+ *r->out.status_code = 0;
+
+ memcpy(r->out.out_data, out_data.data, out_data.length);
+
+ return WERR_OK;
}
/****************************************************************
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_OpenPrinter
-****************************************************************/
-
-WERROR _spoolss_OpenPrinter(pipes_struct *p,
- struct spoolss_OpenPrinter *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_SetJob
-****************************************************************/
-
-WERROR _spoolss_SetJob(pipes_struct *p,
- struct spoolss_SetJob *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_GetJob
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_SetPrinter
-****************************************************************/
-
-WERROR _spoolss_SetPrinter(pipes_struct *p,
- struct spoolss_SetPrinter *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_GetPrinter
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_AddPrinterDriver
-****************************************************************/
-
-WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
- struct spoolss_AddPrinterDriver *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_EnumPrinterDrivers
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_GetPrinterDriverDirectory
-****************************************************************/
-
-WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
- struct spoolss_GetPrinterDriverDirectory *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_EnumPrintProcessors
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_GetPrintProcessorDirectory
-****************************************************************/
-
-WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
- struct spoolss_GetPrintProcessorDirectory *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_StartDocPrinter
-****************************************************************/
-
-WERROR _spoolss_StartDocPrinter(pipes_struct *p,
- struct spoolss_StartDocPrinter *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_ReadPrinter
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_ResetPrinter
-****************************************************************/
-
-WERROR _spoolss_ResetPrinter(pipes_struct *p,
- struct spoolss_ResetPrinter *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_GetPrinterDriver2
****************************************************************/
}
/****************************************************************
- _spoolss_RouterRefreshPrinterChangeNotification
+ _spoolss_RouterReplyPrinterEx
****************************************************************/
-WERROR _spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p,
- struct spoolss_RouterRefreshPrinterChangeNotification *r)
+WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
+ struct spoolss_RouterReplyPrinterEx *r)
{
p->rng_fault_state = true;
return WERR_NOT_SUPPORTED;
}
/****************************************************************
- _spoolss_RemoteFindNextPrinterChangeNotifyEx
+ _dcesrv_spoolss_RouterRefreshPrinterChangeNotify
****************************************************************/
-WERROR _spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p,
- struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r)
+WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
+ struct spoolss_RouterRefreshPrinterChangeNotify *r)
{
p->rng_fault_state = true;
return WERR_NOT_SUPPORTED;
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_OpenPrinterEx
-****************************************************************/
-
-WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
- struct spoolss_OpenPrinterEx *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_AddPrinterEx
-****************************************************************/
-
-WERROR _spoolss_AddPrinterEx(pipes_struct *p,
- struct spoolss_AddPrinterEx *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_47
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_SetPrinterDataEx
-****************************************************************/
-
-WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
- struct spoolss_SetPrinterDataEx *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_GetPrinterDataEx
-****************************************************************/
-
-WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
- struct spoolss_GetPrinterDataEx *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_EnumPrinterDataEx
****************************************************************/
return WERR_NOT_SUPPORTED;
}
-/****************************************************************
- _spoolss_XcvData
-****************************************************************/
-
-WERROR _spoolss_XcvData(pipes_struct *p,
- struct spoolss_XcvData *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_AddPrinterDriverEx
-****************************************************************/
-
-WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
- struct spoolss_AddPrinterDriverEx *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
/****************************************************************
_spoolss_5a
****************************************************************/