diff options
author | Andrew Tridgell <tridge@samba.org> | 2003-11-16 13:49:14 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2003-11-16 13:49:14 +0000 |
commit | ae4cb40100a5c04a4604acfde989ce96ef1801bd (patch) | |
tree | 48baadf0d3f5076475025e1f4f52abb4fe62290e | |
parent | c4b7585288095cb9459feb237a9581ba30b850d0 (diff) | |
download | samba-ae4cb40100a5c04a4604acfde989ce96ef1801bd.tar.gz samba-ae4cb40100a5c04a4604acfde989ce96ef1801bd.tar.bz2 samba-ae4cb40100a5c04a4604acfde989ce96ef1801bd.zip |
use nstring and [relative] to support levels 1 and 2 of EnumPrinters
fully
(This used to be commit 69c6017c945bdd7d1945f22fcad49112ba6a2d2d)
-rw-r--r-- | source4/librpc/idl/spoolss.idl | 68 | ||||
-rw-r--r-- | source4/librpc/ndr/libndr.h | 7 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr.c | 76 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_basic.c | 65 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_spoolss.c | 279 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_spoolss.h | 61 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_spoolss_buf.c | 6 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_spoolss_buf.h | 1 | ||||
-rw-r--r-- | source4/torture/rpc/spoolss.c | 64 |
9 files changed, 533 insertions, 94 deletions
diff --git a/source4/librpc/idl/spoolss.idl b/source4/librpc/idl/spoolss.idl index e2965c3586..94c3bf127c 100644 --- a/source4/librpc/idl/spoolss.idl +++ b/source4/librpc/idl/spoolss.idl @@ -10,13 +10,75 @@ /******************/ /* Function: 0x00 */ + typedef struct { + nstring devicename; + uint16 specversion; + uint16 driverversion; + uint16 size; + uint16 driverextra; + uint32 fields; + uint16 orientation; + uint16 papersize; + uint16 paperlength; + uint16 paperwidth; + uint16 scale; + uint16 copies; + uint16 defaultsource; + uint16 printquality; + uint16 color; + uint16 duplex; + uint16 yresolution; + uint16 ttoption; + uint16 collate; + nstring formname; + uint16 logpixels; + uint32 bitsperpel; + uint32 pelswidth; + uint32 pelsheight; + uint32 displayflags; + uint32 displayfrequency; + uint32 icmmethod; + uint32 icmintent; + uint32 mediatype; + uint32 dithertype; + uint32 reserved1; + uint32 reserved2; + uint32 panningwidth; + uint32 panningheight; +// uint8 private[driverextra]; + } spoolss_DeviceMode; + typedef [public] struct { uint32 flags; - relstr name; - relstr description; - relstr comment; + [relative] nstring name; + [relative] nstring description; + [relative] nstring comment; } spoolss_PrinterEnum1; + typedef [public] struct { + [relative] nstring servername; + [relative] nstring printername; + [relative] nstring sharename; + [relative] nstring portname; + [relative] nstring drivername; + [relative] nstring comment; + [relative] nstring location; + [relative] spoolss_DeviceMode *devmode; + [relative] nstring sepfile; + [relative] nstring printprocessor; + [relative] nstring datatype; + [relative] nstring parameters; + [relative] security_descriptor *secdesc; + uint32 attributes; + uint32 priority; + uint32 defaultpriority; + uint32 starttime; + uint32 untiltime; + uint32 status; + uint32 cjobs; + uint32 averageppm; + } spoolss_PrinterEnum2; + NTSTATUS spoolss_EnumPrinters( [in] uint32 flags, [in] unistr *server, diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h index 5e53704255..f5e64ec872 100644 --- a/source4/librpc/ndr/libndr.h +++ b/source4/librpc/ndr/libndr.h @@ -53,8 +53,8 @@ struct ndr_push { uint32 offset; TALLOC_CTX *mem_ctx; - /* this list is used by the relstr code to find the offsets */ - struct ndr_push_save *relstr_list; + /* this list is used by the [relative] code to find the offsets */ + struct ndr_push_save *relative_list; }; struct ndr_push_save { @@ -85,7 +85,7 @@ enum ndr_err_code { NDR_ERR_ARRAY_SIZE, NDR_ERR_BAD_SWITCH, NDR_ERR_OFFSET, - NDR_ERR_RELSTR, + NDR_ERR_RELATIVE, NDR_ERR_CHARCNV, NDR_ERR_LENGTH }; @@ -150,6 +150,7 @@ typedef NTSTATUS (*ndr_push_fn_t)(struct ndr_push *, void *); typedef NTSTATUS (*ndr_pull_fn_t)(struct ndr_pull *, void *); typedef NTSTATUS (*ndr_push_flags_fn_t)(struct ndr_push *, int ndr_flags, void *); +typedef NTSTATUS (*ndr_push_const_fn_t)(struct ndr_push *, int ndr_flags, const void *); typedef NTSTATUS (*ndr_pull_flags_fn_t)(struct ndr_pull *, int ndr_flags, void *); typedef NTSTATUS (*ndr_push_union_fn_t)(struct ndr_push *, int ndr_flags, uint16, void *); typedef NTSTATUS (*ndr_pull_union_fn_t)(struct ndr_pull *, int ndr_flags, uint16 *, void *); diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c index 25bfd20006..fb7c602ce8 100644 --- a/source4/librpc/ndr/ndr.c +++ b/source4/librpc/ndr/ndr.c @@ -207,8 +207,8 @@ NTSTATUS ndr_push_set_offset(struct ndr_push *ndr, uint32 ofs) push a generic array */ NTSTATUS ndr_push_array(struct ndr_push *ndr, int ndr_flags, void *base, - size_t elsize, uint32 count, - NTSTATUS (*push_fn)(struct ndr_push *, int, void *)) + size_t elsize, uint32 count, + NTSTATUS (*push_fn)(struct ndr_push *, int, void *)) { int i; char *p = base; @@ -419,3 +419,75 @@ NTSTATUS ndr_pull_subcontext_union_fn(struct ndr_pull *ndr, NDR_CHECK(ndr_pull_advance(ndr, size)); return NT_STATUS_OK; } + + +/* + pull a relative structure +*/ +NTSTATUS ndr_pull_relative(struct ndr_pull *ndr, const void **buf, size_t size, + NTSTATUS (*fn)(struct ndr_pull *, int ndr_flags, void *)) +{ + struct ndr_pull ndr2; + uint32 ofs; + struct ndr_pull_save save; + void *p; + + NDR_CHECK(ndr_pull_uint32(ndr, &ofs)); + if (ofs == 0) { + (*buf) = NULL; + return NT_STATUS_OK; + } + ndr_pull_save(ndr, &save); + NDR_CHECK(ndr_pull_set_offset(ndr, ofs)); + NDR_CHECK(ndr_pull_subcontext(ndr, &ndr2, ndr->data_size - ndr->offset)); + if (size == 1) { + /* oh what a hack! */ + NDR_CHECK(fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, (void *)&p)); + } else { + NDR_ALLOC_SIZE(ndr, p, size); + NDR_CHECK(fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, p)); + } + (*buf) = p; + ndr_pull_restore(ndr, &save); + return NT_STATUS_OK; +} + +/* + push a relative structure +*/ +NTSTATUS ndr_push_relative(struct ndr_push *ndr, int ndr_flags, const void *p, + NTSTATUS (*fn)(struct ndr_push *, int , const void *)) +{ + struct ndr_push_save *save; + if (ndr_flags & NDR_SCALARS) { + if (!p) { + NDR_CHECK(ndr_push_uint32(ndr, 0)); + return NT_STATUS_OK; + } + save = talloc(ndr->mem_ctx, sizeof(*save)); + if (!save) return NT_STATUS_NO_MEMORY; + NDR_CHECK(ndr_push_align(ndr, 4)); + ndr_push_save(ndr, save); + NDR_CHECK(ndr_push_uint32(ndr, 0xFFFFFFFF)); + save->next = ndr->relative_list; + ndr->relative_list = save; + } + if (ndr_flags & NDR_BUFFERS) { + struct ndr_push_save save2; + if (!p) { + return NT_STATUS_OK; + } + save = ndr->relative_list; + if (!save) { + return ndr_push_error(ndr, NDR_ERR_RELATIVE, "Empty relative stack"); + } + ndr->relative_list = save->next; + NDR_CHECK(ndr_push_align(ndr, 8)); + ndr_push_save(ndr, &save2); + ndr_push_restore(ndr, save); + NDR_CHECK(ndr_push_uint32(ndr, save2.offset)); + ndr_push_restore(ndr, &save2); + NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p)); + } + return NT_STATUS_OK; +} diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c index ece496ebde..408d041e3c 100644 --- a/source4/librpc/ndr/ndr_basic.c +++ b/source4/librpc/ndr/ndr_basic.c @@ -466,7 +466,7 @@ void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16 level) } void ndr_print_array_uint32(struct ndr_print *ndr, const char *name, - uint32 *data, uint32 count) + const uint32 *data, uint32 count) { int i; @@ -484,7 +484,7 @@ void ndr_print_array_uint32(struct ndr_print *ndr, const char *name, } void ndr_print_array_uint8(struct ndr_print *ndr, const char *name, - uint8 *data, uint32 count) + const uint8 *data, uint32 count) { int i; @@ -501,7 +501,7 @@ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name, ndr->depth--; } -void ndr_print_GUID(struct ndr_print *ndr, const char *name, struct GUID *guid) +void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid) { ndr->print(ndr, "%-25s: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", name, @@ -513,73 +513,50 @@ void ndr_print_GUID(struct ndr_print *ndr, const char *name, struct GUID *guid) /* - pull a spoolss style "relative string" + pull a null terminated UCS2 string */ -NTSTATUS ndr_pull_relstr(struct ndr_pull *ndr, int ndr_flags, const char **s) +NTSTATUS ndr_pull_nstring(struct ndr_pull *ndr, int ndr_flags, const char **s) { - uint32 ofs; int ret; - struct ndr_pull_save save; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } - NDR_CHECK(ndr_pull_uint32(ndr, &ofs)); - ndr_pull_save(ndr, &save); - NDR_CHECK(ndr_pull_set_offset(ndr, ofs)); ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, ndr->data+ndr->offset, ndr->data_size - ndr->offset, (const void **)s); if (ret == -1) { - return ndr_pull_error(ndr, NDR_ERR_RELSTR, "Bad relative string"); + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, "Bad character conversion"); } - ndr_pull_restore(ndr, &save); + ndr->offset += ret; return NT_STATUS_OK; } /* push a spoolss style "relative string" */ -NTSTATUS ndr_push_relstr(struct ndr_push *ndr, int ndr_flags, const char **s) +NTSTATUS ndr_push_nstring(struct ndr_push *ndr, int ndr_flags, const char **s) { - struct ndr_push_save *save; - if (ndr_flags & NDR_SCALARS) { - save = talloc(ndr->mem_ctx, sizeof(*save)); - if (!save) return NT_STATUS_NO_MEMORY; - NDR_CHECK(ndr_push_align(ndr, 4)); - ndr_push_save(ndr, save); - NDR_CHECK(ndr_push_uint32(ndr, 0xFFFFFFFF)); - save->next = ndr->relstr_list; - ndr->relstr_list = save; + uint32 len; + int ret; + + if (!(ndr_flags & NDR_SCALARS)) { + return NT_STATUS_OK; } - if (ndr_flags & NDR_BUFFERS) { - struct ndr_push_save save2; - uint32 len; - int ret; - save = ndr->relstr_list; - if (!save) { - return ndr_push_error(ndr, NDR_ERR_RELSTR, "Empty relstr stack"); - } - ndr->relstr_list = save->next; - NDR_CHECK(ndr_push_align(ndr, 2)); - ndr_push_save(ndr, &save2); - ndr_push_restore(ndr, save); - NDR_CHECK(ndr_push_uint32(ndr, save2.offset)); - ndr_push_restore(ndr, &save2); - len = 2*(strlen_m(*s)+1); - NDR_PUSH_NEED_BYTES(ndr, len); - ret = push_ucs2(NULL, ndr->data + ndr->offset, *s, len, STR_TERMINATE); - if (ret == -1) { - return ndr_push_error(ndr, NDR_ERR_CHARCNV, "Bad string conversion"); - } - ndr->offset += len; + + len = 2*(strlen_m(*s)+1); + NDR_PUSH_NEED_BYTES(ndr, len); + ret = push_ucs2(NULL, ndr->data + ndr->offset, *s, len, STR_TERMINATE); + if (ret == -1) { + return ndr_push_error(ndr, NDR_ERR_CHARCNV, "Bad string conversion"); } + ndr->offset += len; return NT_STATUS_OK; } -void ndr_print_relstr(struct ndr_print *ndr, const char *name, const char **s) +void ndr_print_nstring(struct ndr_print *ndr, const char *name, const char **s) { ndr_print_unistr(ndr, name, *s); } diff --git a/source4/librpc/ndr/ndr_spoolss.c b/source4/librpc/ndr/ndr_spoolss.c index f5e8f2b2cf..0ddd9b2ac8 100644 --- a/source4/librpc/ndr/ndr_spoolss.c +++ b/source4/librpc/ndr/ndr_spoolss.c @@ -2,19 +2,113 @@ #include "includes.h" +NTSTATUS ndr_push_spoolss_DeviceMode(struct ndr_push *ndr, int ndr_flags, struct spoolss_DeviceMode *r) +{ + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_nstring(ndr, NDR_SCALARS, &r->devicename)); + NDR_CHECK(ndr_push_uint16(ndr, r->specversion)); + NDR_CHECK(ndr_push_uint16(ndr, r->driverversion)); + NDR_CHECK(ndr_push_uint16(ndr, r->size)); + NDR_CHECK(ndr_push_uint16(ndr, r->driverextra)); + NDR_CHECK(ndr_push_uint32(ndr, r->fields)); + NDR_CHECK(ndr_push_uint16(ndr, r->orientation)); + NDR_CHECK(ndr_push_uint16(ndr, r->papersize)); + NDR_CHECK(ndr_push_uint16(ndr, r->paperlength)); + NDR_CHECK(ndr_push_uint16(ndr, r->paperwidth)); + NDR_CHECK(ndr_push_uint16(ndr, r->scale)); + NDR_CHECK(ndr_push_uint16(ndr, r->copies)); + NDR_CHECK(ndr_push_uint16(ndr, r->defaultsource)); + NDR_CHECK(ndr_push_uint16(ndr, r->printquality)); + NDR_CHECK(ndr_push_uint16(ndr, r->color)); + NDR_CHECK(ndr_push_uint16(ndr, r->duplex)); + NDR_CHECK(ndr_push_uint16(ndr, r->yresolution)); + NDR_CHECK(ndr_push_uint16(ndr, r->ttoption)); + NDR_CHECK(ndr_push_uint16(ndr, r->collate)); + NDR_CHECK(ndr_push_nstring(ndr, NDR_SCALARS, &r->formname)); + NDR_CHECK(ndr_push_uint16(ndr, r->logpixels)); + NDR_CHECK(ndr_push_uint32(ndr, r->bitsperpel)); + NDR_CHECK(ndr_push_uint32(ndr, r->pelswidth)); + NDR_CHECK(ndr_push_uint32(ndr, r->pelsheight)); + NDR_CHECK(ndr_push_uint32(ndr, r->displayflags)); + NDR_CHECK(ndr_push_uint32(ndr, r->displayfrequency)); + NDR_CHECK(ndr_push_uint32(ndr, r->icmmethod)); + NDR_CHECK(ndr_push_uint32(ndr, r->icmintent)); + NDR_CHECK(ndr_push_uint32(ndr, r->mediatype)); + NDR_CHECK(ndr_push_uint32(ndr, r->dithertype)); + NDR_CHECK(ndr_push_uint32(ndr, r->reserved1)); + NDR_CHECK(ndr_push_uint32(ndr, r->reserved2)); + NDR_CHECK(ndr_push_uint32(ndr, r->panningwidth)); + NDR_CHECK(ndr_push_uint32(ndr, r->panningheight)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_CHECK(ndr_push_nstring(ndr, NDR_BUFFERS, &r->devicename)); + NDR_CHECK(ndr_push_nstring(ndr, NDR_BUFFERS, &r->formname)); +done: + return NT_STATUS_OK; +} + NTSTATUS ndr_push_spoolss_PrinterEnum1(struct ndr_push *ndr, int ndr_flags, struct spoolss_PrinterEnum1 *r) { if (!(ndr_flags & NDR_SCALARS)) goto buffers; NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint32(ndr, r->flags)); - NDR_CHECK(ndr_push_relstr(ndr, NDR_SCALARS, &r->name)); - NDR_CHECK(ndr_push_relstr(ndr, NDR_SCALARS, &r->description)); - NDR_CHECK(ndr_push_relstr(ndr, NDR_SCALARS, &r->comment)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->name, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->description, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->comment, (ndr_push_const_fn_t) ndr_push_nstring)); buffers: if (!(ndr_flags & NDR_BUFFERS)) goto done; - NDR_CHECK(ndr_push_relstr(ndr, NDR_BUFFERS, &r->name)); - NDR_CHECK(ndr_push_relstr(ndr, NDR_BUFFERS, &r->description)); - NDR_CHECK(ndr_push_relstr(ndr, NDR_BUFFERS, &r->comment)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->name, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->description, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->comment, (ndr_push_const_fn_t) ndr_push_nstring)); +done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_push_spoolss_PrinterEnum2(struct ndr_push *ndr, int ndr_flags, struct spoolss_PrinterEnum2 *r) +{ + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->servername, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->printername, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->sharename, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->portname, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->drivername, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->comment, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->location, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->devmode, (ndr_push_const_fn_t) ndr_push_spoolss_DeviceMode)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->sepfile, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->printprocessor, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->datatype, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->parameters, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, r->secdesc, (ndr_push_const_fn_t) ndr_push_security_descriptor)); + NDR_CHECK(ndr_push_uint32(ndr, r->attributes)); + NDR_CHECK(ndr_push_uint32(ndr, r->priority)); + NDR_CHECK(ndr_push_uint32(ndr, r->defaultpriority)); + NDR_CHECK(ndr_push_uint32(ndr, r->starttime)); + NDR_CHECK(ndr_push_uint32(ndr, r->untiltime)); + NDR_CHECK(ndr_push_uint32(ndr, r->status)); + NDR_CHECK(ndr_push_uint32(ndr, r->cjobs)); + NDR_CHECK(ndr_push_uint32(ndr, r->averageppm)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->servername, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->printername, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->sharename, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->portname, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->drivername, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->comment, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->location, (ndr_push_const_fn_t) ndr_push_nstring)); + if (r->devmode) { + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, r->devmode, (ndr_push_const_fn_t) ndr_push_spoolss_DeviceMode)); + } + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->sepfile, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->printprocessor, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->datatype, (ndr_push_const_fn_t) ndr_push_nstring)); + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, &r->parameters, (ndr_push_const_fn_t) ndr_push_nstring)); + if (r->secdesc) { + NDR_CHECK(ndr_push_relative(ndr, NDR_BUFFERS, r->secdesc, (ndr_push_const_fn_t) ndr_push_security_descriptor)); + } done: return NT_STATUS_OK; } @@ -719,19 +813,95 @@ NTSTATUS ndr_push_spoolss_5f(struct ndr_push *ndr, struct spoolss_5f *r) return NT_STATUS_OK; } +NTSTATUS ndr_pull_spoolss_DeviceMode(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DeviceMode *r) +{ + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_nstring(ndr, NDR_SCALARS, &r->devicename)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->specversion)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->driverversion)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->size)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->driverextra)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->fields)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->orientation)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->papersize)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->paperlength)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->paperwidth)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->scale)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->copies)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->defaultsource)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->printquality)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->color)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->duplex)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->yresolution)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->ttoption)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->collate)); + NDR_CHECK(ndr_pull_nstring(ndr, NDR_SCALARS, &r->formname)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->logpixels)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->bitsperpel)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->pelswidth)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->pelsheight)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->displayflags)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->displayfrequency)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->icmmethod)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->icmintent)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->mediatype)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->dithertype)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->reserved1)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->reserved2)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->panningwidth)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->panningheight)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_CHECK(ndr_pull_nstring(ndr, NDR_BUFFERS, &r->devicename)); + NDR_CHECK(ndr_pull_nstring(ndr, NDR_BUFFERS, &r->formname)); +done: + return NT_STATUS_OK; +} + NTSTATUS ndr_pull_spoolss_PrinterEnum1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterEnum1 *r) { if (!(ndr_flags & NDR_SCALARS)) goto buffers; NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, &r->flags)); - NDR_CHECK(ndr_pull_relstr(ndr, NDR_SCALARS, &r->name)); - NDR_CHECK(ndr_pull_relstr(ndr, NDR_SCALARS, &r->description)); - NDR_CHECK(ndr_pull_relstr(ndr, NDR_SCALARS, &r->comment)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->name, sizeof(*r->name), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->description, sizeof(*r->description), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->comment, sizeof(*r->comment), (ndr_pull_flags_fn_t)ndr_pull_nstring)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; +done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_spoolss_PrinterEnum2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterEnum2 *r) +{ + uint32 _ptr_devmode; + uint32 _ptr_secdesc; + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->servername, sizeof(*r->servername), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->printername, sizeof(*r->printername), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->sharename, sizeof(*r->sharename), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->portname, sizeof(*r->portname), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->drivername, sizeof(*r->drivername), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->comment, sizeof(*r->comment), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->location, sizeof(*r->location), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->devmode, sizeof(*r->devmode), (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->sepfile, sizeof(*r->sepfile), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->printprocessor, sizeof(*r->printprocessor), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->datatype, sizeof(*r->datatype), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->parameters, sizeof(*r->parameters), (ndr_pull_flags_fn_t)ndr_pull_nstring)); + NDR_CHECK(ndr_pull_relative(ndr, (const void **)&r->secdesc, sizeof(*r->secdesc), (ndr_pull_flags_fn_t)ndr_pull_security_descriptor)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->attributes)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->priority)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->defaultpriority)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->starttime)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->untiltime)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->status)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->cjobs)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->averageppm)); buffers: if (!(ndr_flags & NDR_BUFFERS)) goto done; - NDR_CHECK(ndr_pull_relstr(ndr, NDR_BUFFERS, &r->name)); - NDR_CHECK(ndr_pull_relstr(ndr, NDR_BUFFERS, &r->description)); - NDR_CHECK(ndr_pull_relstr(ndr, NDR_BUFFERS, &r->comment)); done: return NT_STATUS_OK; } @@ -1464,14 +1634,93 @@ NTSTATUS ndr_pull_spoolss_5f(struct ndr_pull *ndr, struct spoolss_5f *r) return NT_STATUS_OK; } +void ndr_print_spoolss_DeviceMode(struct ndr_print *ndr, const char *name, struct spoolss_DeviceMode *r) +{ + ndr_print_struct(ndr, name, "spoolss_DeviceMode"); + ndr->depth++; + ndr_print_nstring(ndr, "devicename", &r->devicename); + ndr_print_uint16(ndr, "specversion", r->specversion); + ndr_print_uint16(ndr, "driverversion", r->driverversion); + ndr_print_uint16(ndr, "size", r->size); + ndr_print_uint16(ndr, "driverextra", r->driverextra); + ndr_print_uint32(ndr, "fields", r->fields); + ndr_print_uint16(ndr, "orientation", r->orientation); + ndr_print_uint16(ndr, "papersize", r->papersize); + ndr_print_uint16(ndr, "paperlength", r->paperlength); + ndr_print_uint16(ndr, "paperwidth", r->paperwidth); + ndr_print_uint16(ndr, "scale", r->scale); + ndr_print_uint16(ndr, "copies", r->copies); + ndr_print_uint16(ndr, "defaultsource", r->defaultsource); + ndr_print_uint16(ndr, "printquality", r->printquality); + ndr_print_uint16(ndr, "color", r->color); + ndr_print_uint16(ndr, "duplex", r->duplex); + ndr_print_uint16(ndr, "yresolution", r->yresolution); + ndr_print_uint16(ndr, "ttoption", r->ttoption); + ndr_print_uint16(ndr, "collate", r->collate); + ndr_print_nstring(ndr, "formname", &r->formname); + ndr_print_uint16(ndr, "logpixels", r->logpixels); + ndr_print_uint32(ndr, "bitsperpel", r->bitsperpel); + ndr_print_uint32(ndr, "pelswidth", r->pelswidth); + ndr_print_uint32(ndr, "pelsheight", r->pelsheight); + ndr_print_uint32(ndr, "displayflags", r->displayflags); + ndr_print_uint32(ndr, "displayfrequency", r->displayfrequency); + ndr_print_uint32(ndr, "icmmethod", r->icmmethod); + ndr_print_uint32(ndr, "icmintent", r->icmintent); + ndr_print_uint32(ndr, "mediatype", r->mediatype); + ndr_print_uint32(ndr, "dithertype", r->dithertype); + ndr_print_uint32(ndr, "reserved1", r->reserved1); + ndr_print_uint32(ndr, "reserved2", r->reserved2); + ndr_print_uint32(ndr, "panningwidth", r->panningwidth); + ndr_print_uint32(ndr, "panningheight", r->panningheight); + ndr->depth--; +} + void ndr_print_spoolss_PrinterEnum1(struct ndr_print *ndr, const char *name, struct spoolss_PrinterEnum1 *r) { ndr_print_struct(ndr, name, "spoolss_PrinterEnum1"); ndr->depth++; ndr_print_uint32(ndr, "flags", r->flags); - ndr_print_relstr(ndr, "name", &r->name); - ndr_print_relstr(ndr, "description", &r->description); - ndr_print_relstr(ndr, "comment", &r->comment); + ndr_print_nstring(ndr, "name", &r->name); + ndr_print_nstring(ndr, "description", &r->description); + ndr_print_nstring(ndr, "comment", &r->comment); + ndr->depth--; +} + +void ndr_print_spoolss_PrinterEnum2(struct ndr_print *ndr, const char *name, struct spoolss_PrinterEnum2 *r) +{ + ndr_print_struct(ndr, name, "spoolss_PrinterEnum2"); + ndr->depth++; + ndr_print_nstring(ndr, "servername", &r->servername); + ndr_print_nstring(ndr, "printername", &r->printername); + ndr_print_nstring(ndr, "sharename", &r->sharename); + ndr_print_nstring(ndr, "portname", &r->portname); + ndr_print_nstring(ndr, "drivername", &r->drivername); + ndr_print_nstring(ndr, "comment", &r->comment); + ndr_print_nstring(ndr, "location", &r->location); + ndr_print_ptr(ndr, "devmode", r->devmode); + ndr->depth++; + if (r->devmode) { + ndr_print_spoolss_DeviceMode(ndr, "devmode", r->devmode); + } + ndr->depth--; + ndr_print_nstring(ndr, "sepfile", &r->sepfile); + ndr_print_nstring(ndr, "printprocessor", &r->printprocessor); + ndr_print_nstring(ndr, "datatype", &r->datatype); + ndr_print_nstring(ndr, "parameters", &r->parameters); + ndr_print_ptr(ndr, "secdesc", r->secdesc); + ndr->depth++; + if (r->secdesc) { + ndr_print_security_descriptor(ndr, "secdesc", r->secdesc); + } + ndr->depth--; + ndr_print_uint32(ndr, "attributes", r->attributes); + ndr_print_uint32(ndr, "priority", r->priority); + ndr_print_uint32(ndr, "defaultpriority", r->defaultpriority); + ndr_print_uint32(ndr, "starttime", r->starttime); + ndr_print_uint32(ndr, "untiltime", r->untiltime); + ndr_print_uint32(ndr, "status", r->status); + ndr_print_uint32(ndr, "cjobs", r->cjobs); + ndr_print_uint32(ndr, "averageppm", r->averageppm); ndr->depth--; } diff --git a/source4/librpc/ndr/ndr_spoolss.h b/source4/librpc/ndr/ndr_spoolss.h index c05f3d7494..53e504bf17 100644 --- a/source4/librpc/ndr/ndr_spoolss.h +++ b/source4/librpc/ndr/ndr_spoolss.h @@ -1,5 +1,42 @@ /* header auto-generated by pidl */ +struct spoolss_DeviceMode { + const char * devicename; + uint16 specversion; + uint16 driverversion; + uint16 size; + uint16 driverextra; + uint32 fields; + uint16 orientation; + uint16 papersize; + uint16 paperlength; + uint16 paperwidth; + uint16 scale; + uint16 copies; + uint16 defaultsource; + uint16 printquality; + uint16 color; + uint16 duplex; + uint16 yresolution; + uint16 ttoption; + uint16 collate; + const char * formname; + uint16 logpixels; + uint32 bitsperpel; + uint32 pelswidth; + uint32 pelsheight; + uint32 displayflags; + uint32 displayfrequency; + uint32 icmmethod; + uint32 icmintent; + uint32 mediatype; + uint32 dithertype; + uint32 reserved1; + uint32 reserved2; + uint32 panningwidth; + uint32 panningheight; +}; + struct spoolss_PrinterEnum1 { uint32 flags; const char * name; @@ -7,6 +44,30 @@ struct spoolss_PrinterEnum1 { const char * comment; }; +struct spoolss_PrinterEnum2 { + const char * servername; + const char * printername; + const char * sharename; + const char * portname; + const char * drivername; + const char * comment; + const char * location; + struct spoolss_DeviceMode *devmode; + const char * sepfile; + const char * printprocessor; + const char * datatype; + const char * parameters; + struct security_descriptor *secdesc; + uint32 attributes; + uint32 priority; + uint32 defaultpriority; + uint32 starttime; + uint32 untiltime; + uint32 status; + uint32 cjobs; + uint32 averageppm; +}; + struct spoolss_EnumPrinters { struct { uint32 flags; diff --git a/source4/librpc/ndr/ndr_spoolss_buf.c b/source4/librpc/ndr/ndr_spoolss_buf.c index 292de862cf..2290150b1d 100644 --- a/source4/librpc/ndr/ndr_spoolss_buf.c +++ b/source4/librpc/ndr/ndr_spoolss_buf.c @@ -31,6 +31,9 @@ NTSTATUS ndr_pull_spoolss_PrinterEnum(struct ndr_pull *ndr, int ndr_flags, case 1: NDR_CHECK(ndr_pull_spoolss_PrinterEnum1(ndr, NDR_SCALARS|NDR_BUFFERS, &info->info1)); break; + case 2: + NDR_CHECK(ndr_pull_spoolss_PrinterEnum2(ndr, NDR_SCALARS|NDR_BUFFERS, &info->info2)); + break; default: return NT_STATUS_INVALID_LEVEL; } @@ -47,5 +50,8 @@ void ndr_print_spoolss_PrinterEnum(struct ndr_print *ndr, const char *name, uint case 1: ndr_print_spoolss_PrinterEnum1(ndr, "info1", &info->info1); break; + case 2: + ndr_print_spoolss_PrinterEnum2(ndr, "info2", &info->info2); + break; } } diff --git a/source4/librpc/ndr/ndr_spoolss_buf.h b/source4/librpc/ndr/ndr_spoolss_buf.h index 7c57fb81e6..5670c750a6 100644 --- a/source4/librpc/ndr/ndr_spoolss_buf.h +++ b/source4/librpc/ndr/ndr_spoolss_buf.h @@ -23,4 +23,5 @@ union spoolss_PrinterEnum { /* [case(1)] */ struct spoolss_PrinterEnum1 info1; + /* [case(2)] */ struct spoolss_PrinterEnum2 info2; }; diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index e0aa429ae7..e7e35659d7 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -25,40 +25,50 @@ static BOOL test_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { struct spoolss_EnumPrinters r; NTSTATUS status; - uint32 needed = 0; + uint16 levels[] = {1, 2}; + int i; + BOOL ret = True; - r.in.flags = 0x02; - r.in.server = ""; - r.in.level = 1; - r.in.buf = NULL; - r.in.offered = needed; - r.out.needed = &needed; + for (i=0;i<ARRAY_SIZE(levels);i++) { + uint32 needed = 0; + + r.in.flags = 0x02; + r.in.server = ""; + r.in.level = levels[i]; + r.in.buf = NULL; + r.in.offered = needed; + r.out.needed = &needed; - status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - printf("EnumPrinters failed - %s\n", nt_errstr(status)); - return False; - } + printf("\nTesting EnumPrinters level %u\n", r.in.level); - if (NT_STATUS_V(status) == 0x0000007a) { - r.in.buf = talloc(mem_ctx, needed); - if (!r.in.buf) { - return False; - } - memset(r.in.buf, 0xfe, needed); - r.in.offered = needed; status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r); - } - - if (!NT_STATUS_IS_OK(status)) { - printf("EnumPrinters failed - %s\n", nt_errstr(status)); - } + if (NT_STATUS_IS_ERR(status)) { + printf("EnumPrinters failed - %s\n", nt_errstr(status)); + ret = False; + continue; + } + + if (NT_STATUS_V(status) == 0x0000007a) { + r.in.buf = talloc(mem_ctx, needed); + if (!r.in.buf) { + ret = False; + continue; + } + memset(r.in.buf, 0xfe, needed); + r.in.offered = needed; + status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r); + } + + if (!NT_STATUS_IS_OK(status)) { + printf("EnumPrinters failed - %s\n", nt_errstr(status)); + } - if (r.out.info) { - NDR_PRINT_UNION_DEBUG(spoolss_PrinterEnum, r.in.level, r.out.info); + if (r.out.info) { + NDR_PRINT_UNION_DEBUG(spoolss_PrinterEnum, r.in.level, r.out.info); + } } - return True; + return ret; } static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, |