This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "librpc/gen_ndr/ndr_spoolss.h"
+#include "torture/torture.h"
+#include "torture/rpc/rpc.h"
+#include "librpc/gen_ndr/ndr_spoolss_c.h"
struct test_spoolss_context {
struct dcerpc_pipe *p;
}\
} while(0)
+/* not every compiler supports __typeof__() */
+#if (__GNUC__ >= 3)
+#define _CHECK_FIELD_SIZE(c,r,e,type) do {\
+ if (sizeof(__typeof__(c.e)) != sizeof(type)) { \
+ printf(__location__ ":" #c "." #e "field is not " #type "\n"); \
+ smb_panic(__location__ ":" #c "." #e "field is not " #type ); \
+ ret = False; \
+ }\
+ if (sizeof(__typeof__(r.e)) != sizeof(type)) { \
+ printf(__location__ ":" #r "." #e "field is not " #type "\n"); \
+ smb_panic(__location__ ":" #r "." #e "field is not " #type ); \
+ ret = False; \
+ }\
+} while(0)
+#else
+#define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0)
+#endif
+
+#if 0 /* unused */
#define COMPARE_UINT16(c,r,e) do {\
+ _CHECK_FIELD_SIZE(c,r,e,uint16_t); \
if (c.e != r.e){\
- printf("%s: " #c "." #e " 0x%08X (%u) doesn't match " #r "." #e " 0x%08X (%u)\n",\
+ printf("%s: " #c "." #e " 0x%04X (%u) doesn't match " #r "." #e " 0x%04X (%u)\n",\
__location__, c.e, c.e, r.e, r.e);\
ret = False;\
}\
} while(0)
+#endif
#define COMPARE_UINT32(c,r,e) do {\
+ _CHECK_FIELD_SIZE(c,r,e,uint32_t); \
if (c.e != r.e){\
- printf("%s: " #c "." #e " 0x%04X (%u) doesn't match " #r "." #e " 0x%04X (%u)\n",\
+ printf("%s: " #c "." #e " 0x%08X (%u) doesn't match " #r "." #e " 0x%08X (%u)\n",\
__location__, c.e, c.e, r.e, r.e);\
ret = False;\
}\
} while(0)
+#if 0 /* unused */
#define COMPARE_UINT64(c,r,e) do {\
+ _CHECK_FIELD_SIZE(c,r,e,uint64_t); \
if (c.e != r.e){\
- printf("%s: " #c "." #e " 0x%08X%08X (%llu) doesn't match " #r "." #e " 0x%08X%08X (%llu)\n",\
- __location__, (uint32_t)(c.e >> 32), (uint32_t)(c.e & 0xFFFFFFFF), c.e,\
- (uint32_t)(r.e >> 32), (uint32_t)(r.e & 0xFFFFFFFF), r.e);\
+ printf("%s: " #c "." #e " 0x%016llX (%llu) doesn't match " #r "." #e " 0x%016llX (%llu)\n",\
+ __location__, c.e, c.e, r.e, r.e);\
ret = False;\
}\
} while(0)
+#endif
/* TODO: ! */
+#if 0 /* unused */
#define COMPARE_SEC_DESC(c,r,e)
#define COMPARE_SPOOLSS_TIME(c,r,e)
+#endif
#define COMPARE_STRING_ARRAY(c,r,e)
static BOOL test_OpenPrinter_server(struct test_spoolss_context *ctx)
op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p));
op.in.datatype = NULL;
- op.in.devmode_ctr.size = 0;
op.in.devmode_ctr.devmode= NULL;
op.in.access_mask = 0;
op.out.handle = &ctx->server_handle;
for (i=0;i<ARRAY_SIZE(levels);i++) {
int level = levels[i];
DATA_BLOB blob;
- uint32_t buf_size = 0;
r.in.servername = "";
r.in.level = level;
r.in.buffer = NULL;
- buf_size = 0;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing EnumPorts level %u\n", r.in.level);
ret = False;
continue;
}
-
+ if (W_ERROR_IS_OK(r.out.result)) {
+ /* TODO: do some more checks here */
+ continue;
+ }
if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
printf("EnumPorts unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
win_errstr(r.out.result));
continue;
}
- blob = data_blob_talloc(ctx, NULL, buf_size);
+ blob = data_blob_talloc(ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
return True;
}
+static BOOL test_GetPrinterDriverDirectory(struct test_spoolss_context *ctx)
+{
+ NTSTATUS status;
+ struct spoolss_GetPrinterDriverDirectory r;
+ struct {
+ uint16_t level;
+ const char *server;
+ } levels[] = {{
+ .level = 1,
+ .server = NULL
+ },{
+ .level = 1,
+ .server = ""
+ },{
+ .level = 78,
+ .server = ""
+ },{
+ .level = 1,
+ .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p))
+ },{
+ .level = 1024,
+ .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p))
+ }
+ };
+ int i;
+ BOOL ret = True;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i].level;
+ DATA_BLOB blob;
+
+ r.in.server = levels[i].server;
+ r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
+ r.in.level = level;
+ r.in.buffer = NULL;
+ r.in.offered = 0;
+
+ printf("Testing GetPrinterDriverDirectory level %u\n", r.in.level);
+
+ status = dcerpc_spoolss_GetPrinterDriverDirectory(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_GetPrinterDriverDirectory failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+ if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ printf("GetPrinterDriverDirectory unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+
+ blob = data_blob_talloc(ctx, NULL, r.out.needed);
+ data_blob_clear(&blob);
+ r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
+
+ status = dcerpc_spoolss_GetPrinterDriverDirectory(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_GetPrinterDriverDirectory failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("GetPrinterDriverDirectory failed - %s\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+ }
+
+ return True;
+}
+
static BOOL test_EnumPrinterDrivers(struct test_spoolss_context *ctx)
{
NTSTATUS status;
for (i=0;i<ARRAY_SIZE(levels);i++) {
int level = levels[i];
DATA_BLOB blob;
- uint32_t buf_size = 0;
- r.in.server = "";
- r.in.environment = "Windows NT x86";
- r.in.level = level;
- r.in.buffer = NULL;
- buf_size = 0;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.server = "";
+ r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
+ r.in.level = level;
+ r.in.buffer = NULL;
+ r.in.offered = 0;
printf("Testing EnumPrinterDrivers level %u\n", r.in.level);
ret = False;
continue;
}
-
+ if (W_ERROR_IS_OK(r.out.result)) {
+ /* TODO: do some more checks here */
+ continue;
+ }
if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
printf("EnumPrinterDrivers unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
win_errstr(r.out.result));
continue;
}
- blob = data_blob_talloc(ctx, NULL, buf_size);
+ blob = data_blob_talloc(ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
for (i=0;i<ARRAY_SIZE(levels);i++) {
int level = levels[i];
DATA_BLOB blob;
- uint32_t buf_size = 0;
r.in.servername = "";
r.in.level = level;
r.in.buffer = NULL;
- buf_size = 0;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing EnumMonitors level %u\n", r.in.level);
ret = False;
continue;
}
-
+ if (W_ERROR_IS_OK(r.out.result)) {
+ /* TODO: do some more checks here */
+ continue;
+ }
if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
printf("EnumMonitors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
win_errstr(r.out.result));
continue;
}
- blob = data_blob_talloc(ctx, NULL, buf_size);
+ blob = data_blob_talloc(ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
for (i=0;i<ARRAY_SIZE(levels);i++) {
int level = levels[i];
DATA_BLOB blob;
- uint32_t buf_size = 0;
r.in.servername = "";
r.in.environment = "Windows NT x86";
r.in.level = level;
r.in.buffer = NULL;
- buf_size = 0;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing EnumPrintProcessors level %u\n", r.in.level);
ret = False;
continue;
}
-
+ if (W_ERROR_IS_OK(r.out.result)) {
+ /* TODO: do some more checks here */
+ continue;
+ }
if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
printf("EnumPrintProcessors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
win_errstr(r.out.result));
continue;
}
- blob = data_blob_talloc(ctx, NULL, buf_size);
+ blob = data_blob_talloc(ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
for (i=0;i<ARRAY_SIZE(levels);i++) {
int level = levels[i];
DATA_BLOB blob;
- uint32_t buf_size = 0;
r.in.flags = PRINTER_ENUM_LOCAL;
r.in.server = "";
r.in.level = level;
r.in.buffer = NULL;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("\nTesting EnumPrinters level %u\n", r.in.level);
ret = False;
continue;
}
-
+ if (W_ERROR_IS_OK(r.out.result)) {
+ /* TODO: do some more checks here */
+ continue;
+ }
if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
printf("EnumPrinters unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
win_errstr(r.out.result));
continue;
}
- blob = data_blob_talloc(ctx, NULL, buf_size);
+ blob = data_blob_talloc(ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
+
status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
BOOL ret = True;
for (i=0;i<ARRAY_SIZE(levels);i++) {
- uint32_t buf_size = 0;
r.in.handle = handle;
r.in.level = levels[i];
r.in.buffer = NULL;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing GetPrinter level %u\n", r.in.level);
}
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
- DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
+ DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
}
ret = False;
continue;
}
-
+
if (!W_ERROR_IS_OK(r.out.result)) {
printf("GetPrinter failed - %s\n",
win_errstr(r.out.result));
{
NTSTATUS status;
struct spoolss_GetForm r;
- uint32_t buf_size;
r.in.handle = handle;
r.in.form_name = form_name;
r.in.level = 1;
r.in.buffer = NULL;
- buf_size = 0;
- r.in.buf_size = r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing GetForm\n");
status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
-
if (!NT_STATUS_IS_OK(status)) {
printf("GetForm failed - %s\n", nt_errstr(status));
return False;
}
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
- DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
-
+ DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
-
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("GetForm failed - %s\n",
+ nt_errstr(status));
+ return False;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("GetForm failed - %s\n",
+ win_errstr(r.out.result));
+ return False;
+ }
if (!r.out.info) {
- printf("No form info returned");
+ printf("No form info returned\n");
return False;
}
}
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("GetForm failed - %s\n",
+ win_errstr(r.out.result));
+ return False;
+ }
+
return True;
}
static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct policy_handle *handle)
+ struct policy_handle *handle, BOOL print_server)
{
NTSTATUS status;
struct spoolss_EnumForms r;
- uint32_t buf_size;
+ BOOL ret = True;
r.in.handle = handle;
r.in.level = 1;
r.in.buffer = NULL;
- buf_size = 0;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing EnumForms\n");
status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
-
if (!NT_STATUS_IS_OK(status)) {
printf("EnumForms failed - %s\n", nt_errstr(status));
return False;
}
+ if (print_server && W_ERROR_EQUAL(r.out.result,WERR_BADFID)) {
+ printf("EnumForms on the PrintServer isn't supported by test server (NT4)\n");
+ return True;
+ }
+
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
- DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
union spoolss_FormInfo *info;
int j;
-
+ DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
if (!r.out.info) {
- printf("No forms returned");
+ printf("No forms returned\n");
return False;
}
info = r.out.info;
for (j = 0; j < r.out.count; j++) {
- test_GetForm(p, mem_ctx, handle, info[j].info1.form_name);
+ if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, info[j].info1.form_name);
}
}
}
static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct policy_handle *handle)
+ struct policy_handle *handle, BOOL print_server)
{
struct spoolss_AddForm r;
struct spoolss_AddFormInfo1 addform;
}
if (!W_ERROR_IS_OK(r.out.result)) {
- printf("AddForm failed - %s\n", nt_errstr(status));
+ printf("AddForm failed - %s\n", win_errstr(r.out.result));
goto done;
}
+ if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, form_name);
+
{
struct spoolss_SetForm sf;
- struct spoolss_SetFormInfo1 setform;
+ struct spoolss_AddFormInfo1 setform;
sf.in.handle = handle;
sf.in.form_name = form_name;
}
}
+ if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, form_name);
+
done:
if (!test_DeleteForm(p, mem_ctx, handle, form_name)) {
printf("DeleteForm failed\n");
{
NTSTATUS status;
struct spoolss_EnumPorts r;
- uint32_t buf_size;
r.in.servername = talloc_asprintf(mem_ctx, "\\\\%s",
dcerpc_server_name(p));
r.in.level = 2;
r.in.buffer = NULL;
- buf_size = 0;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing EnumPorts\n");
}
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
- DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
-
+ DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
-
if (!NT_STATUS_IS_OK(status)) {
printf("EnumPorts failed - %s\n", nt_errstr(status));
return False;
}
if (!r.out.info) {
- printf("No ports returned");
+ printf("No ports returned\n");
return False;
}
}
{
NTSTATUS status;
struct spoolss_GetJob r;
- uint32_t buf_size;
r.in.handle = handle;
r.in.job_id = job_id;
r.in.level = 1;
r.in.buffer = NULL;
- buf_size = 0;
- r.in.buf_size = r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing GetJob\n");
status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
-
if (!NT_STATUS_IS_OK(status)) {
printf("GetJob failed - %s\n", nt_errstr(status));
return False;
}
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
- DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
-
+ DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
if (!r.out.info) {
- printf("No job info returned");
+ printf("No job info returned\n");
return False;
}
}
}
static BOOL test_SetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct policy_handle *handle, uint32_t job_id, uint32_t command)
+ struct policy_handle *handle, uint32_t job_id, enum spoolss_JobControl command)
{
NTSTATUS status;
struct spoolss_SetJob r;
- r.in.handle = handle;
- r.in.job_id = job_id;
- r.in.level = 0;
- r.in.command = command;
+ r.in.handle = handle;
+ r.in.job_id = job_id;
+ r.in.ctr = NULL;
+ r.in.command = command;
printf("Testing SetJob\n");
status = dcerpc_spoolss_SetJob(p, mem_ctx, &r);
-
if (!NT_STATUS_IS_OK(status)) {
printf("SetJob failed - %s\n", nt_errstr(status));
return False;
}
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("SetJob failed - %s\n", win_errstr(r.out.result));
+ return False;
+ }
return True;
}
{
NTSTATUS status;
struct spoolss_EnumJobs r;
- uint32_t buf_size;
r.in.handle = handle;
r.in.firstjob = 0;
r.in.numjobs = 0xffffffff;
r.in.level = 1;
r.in.buffer = NULL;
- buf_size = 0;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing EnumJobs\n");
}
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
- DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
union spoolss_JobInfo *info;
int j;
-
+ DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
if (!r.out.info) {
- printf("No jobs returned");
+ printf("No jobs returned\n");
return True;
}
for (j = 0; j < r.out.count; j++) {
test_GetJob(p, mem_ctx, handle, info[j].info1.job_id);
- test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, 1);
+ test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE);
+ test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME);
}
} else if (!W_ERROR_IS_OK(r.out.result)) {
return True;
}
+static BOOL test_DoPrintTest(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle)
+{
+ BOOL ret = True;
+ NTSTATUS status;
+ struct spoolss_StartDocPrinter s;
+ struct spoolss_DocumentInfo1 info1;
+ struct spoolss_StartPagePrinter sp;
+ struct spoolss_WritePrinter w;
+ struct spoolss_EndPagePrinter ep;
+ struct spoolss_EndDocPrinter e;
+ int i;
+ uint32_t job_id;
+
+ printf("Testing StartDocPrinter\n");
+
+ s.in.handle = handle;
+ s.in.level = 1;
+ s.in.info.info1 = &info1;
+ info1.document_name = "TorturePrintJob";
+ info1.output_file = NULL;
+ info1.datatype = "RAW";
+
+ status = dcerpc_spoolss_StartDocPrinter(p, mem_ctx, &s);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_StartDocPrinter failed - %s\n", nt_errstr(status));
+ return False;
+ }
+ if (!W_ERROR_IS_OK(s.out.result)) {
+ printf("StartDocPrinter failed - %s\n", win_errstr(s.out.result));
+ return False;
+ }
+
+ job_id = s.out.job_id;
+
+ for (i=1; i < 4; i++) {
+ printf("Testing StartPagePrinter: Page[%d]\n", i);
+
+ sp.in.handle = handle;
+
+ status = dcerpc_spoolss_StartPagePrinter(p, mem_ctx, &sp);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_StartPagePrinter failed - %s\n", nt_errstr(status));
+ return False;
+ }
+ if (!W_ERROR_IS_OK(sp.out.result)) {
+ printf("StartPagePrinter failed - %s\n", win_errstr(sp.out.result));
+ return False;
+ }
+
+ printf("Testing WritePrinter: Page[%d]\n", i);
+
+ w.in.handle = handle;
+ w.in.data = data_blob_string_const(talloc_asprintf(mem_ctx,"TortureTestPage: %d\nData\n",i));
+
+ status = dcerpc_spoolss_WritePrinter(p, mem_ctx, &w);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_WritePrinter failed - %s\n", nt_errstr(status));
+ return False;
+ }
+ if (!W_ERROR_IS_OK(w.out.result)) {
+ printf("WritePrinter failed - %s\n", win_errstr(w.out.result));
+ return False;
+ }
+
+ printf("Testing EndPagePrinter: Page[%d]\n", i);
+
+ ep.in.handle = handle;
+
+ status = dcerpc_spoolss_EndPagePrinter(p, mem_ctx, &ep);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EndPagePrinter failed - %s\n", nt_errstr(status));
+ return False;
+ }
+ if (!W_ERROR_IS_OK(ep.out.result)) {
+ printf("EndPagePrinter failed - %s\n", win_errstr(ep.out.result));
+ return False;
+ }
+ }
+
+ printf("Testing EndDocPrinter\n");
+
+ e.in.handle = handle;
+
+ status = dcerpc_spoolss_EndDocPrinter(p, mem_ctx, &e);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EndDocPrinter failed - %s\n", nt_errstr(status));
+ return False;
+ }
+ if (!W_ERROR_IS_OK(e.out.result)) {
+ printf("EndDocPrinter failed - %s\n", win_errstr(e.out.result));
+ return False;
+ }
+
+ ret &= test_EnumJobs(p, mem_ctx, handle);
+
+ ret &= test_SetJob(p, mem_ctx, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE);
+
+ return ret;
+}
+
+static BOOL test_PausePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle)
+{
+ NTSTATUS status;
+ struct spoolss_SetPrinter r;
+
+ r.in.handle = handle;
+ r.in.level = 0;
+ r.in.info.info1 = NULL;
+ r.in.devmode_ctr.devmode= NULL;
+ r.in.secdesc_ctr.sd = NULL;
+ r.in.command = SPOOLSS_PRINTER_CONTROL_PAUSE;
+
+ printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
+
+ status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("SetPrinter failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL test_ResumePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle)
+{
+ NTSTATUS status;
+ struct spoolss_SetPrinter r;
+
+ r.in.handle = handle;
+ r.in.level = 0;
+ r.in.info.info1 = NULL;
+ r.in.devmode_ctr.devmode= NULL;
+ r.in.secdesc_ctr.sd = NULL;
+ r.in.command = SPOOLSS_PRINTER_CONTROL_RESUME;
+
+ printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
+
+ status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("SetPrinter failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
+ return False;
+ }
+
+ return True;
+}
+
static BOOL test_GetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle,
const char *value_name)
{
NTSTATUS status;
struct spoolss_GetPrinterData r;
- uint32_t buf_size;
r.in.handle = handle;
r.in.value_name = value_name;
- buf_size = 0;
- r.in.buf_size = r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing GetPrinterData\n");
status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
-
if (!NT_STATUS_IS_OK(status)) {
printf("GetPrinterData failed - %s\n", nt_errstr(status));
return False;
}
if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
-
if (!NT_STATUS_IS_OK(status)) {
printf("GetPrinterData failed - %s\n",
nt_errstr(status));
{
NTSTATUS status;
struct spoolss_GetPrinterDataEx r;
- uint32_t buf_size;
r.in.handle = handle;
r.in.key_name = key_name;
r.in.value_name = value_name;
- buf_size = 0;
- r.in.buf_size = r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("Testing GetPrinterDataEx\n");
}
if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
-
if (!NT_STATUS_IS_OK(status)) {
printf("GetPrinterDataEx failed - %s\n",
nt_errstr(status));
r.in.handle = handle;
r.in.key_name = "PrinterDriverData";
- r.in.buf_size = 0;
+ r.in.offered = 0;
printf("Testing EnumPrinterDataEx\n");
status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
-
if (!NT_STATUS_IS_OK(status)) {
printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
return False;
}
- r.in.buf_size = r.out.buf_size;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
return False;
}
- status = dcerpc_bind_auth_none(p2, DCERPC_SPOOLSS_UUID,
- DCERPC_SPOOLSS_VERSION);
+ status = dcerpc_bind_auth_none(p2, &dcerpc_table_spoolss);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to create bind on secondary connection\n");
talloc_free(p2);
op.in.printername = name;
op.in.datatype = NULL;
- op.in.devmode_ctr.size = 0;
op.in.devmode_ctr.devmode= NULL;
op.in.access_mask = 0;
op.out.handle = &handle;
opEx.in.printername = name;
opEx.in.datatype = NULL;
- opEx.in.devmode_ctr.size = 0;
opEx.in.devmode_ctr.devmode = NULL;
opEx.in.access_mask = 0;
opEx.in.level = 1;
r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
r.in.datatype = NULL;
- r.in.devmode_ctr.size = 0;
r.in.devmode_ctr.devmode= NULL;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
r.out.handle = &handle;
}
r.in.datatype = NULL;
- r.in.devmode_ctr.size = 0;
r.in.devmode_ctr.devmode= NULL;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
r.in.level = 1;
ret = False;
}
- if (!test_EnumForms(p, mem_ctx, &handle)) {
+ if (!test_EnumForms(p, mem_ctx, &handle, False)) {
ret = False;
}
- if (!test_AddForm(p, mem_ctx, &handle)) {
+ if (!test_AddForm(p, mem_ctx, &handle, False)) {
ret = False;
}
ret = False;
}
- if (!test_EnumJobs(p, mem_ctx, &handle)) {
+ if (!test_PausePrinter(p, mem_ctx, &handle)) {
+ ret = False;
+ }
+
+ if (!test_DoPrintTest(p, mem_ctx, &handle)) {
+ ret = False;
+ }
+
+ if (!test_ResumePrinter(p, mem_ctx, &handle)) {
ret = False;
}
BOOL ret = True;
for (i=0;i<ARRAY_SIZE(levels);i++) {
- uint32_t buf_size = 0;
union spoolss_PrinterInfo *info;
int j;
r.in.server = "";
r.in.level = levels[i];
r.in.buffer = NULL;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("\nTesting EnumPrinters level %u\n", r.in.level);
}
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
- DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
+ DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
}
}
if (!r.out.info) {
- printf("No printers returned");
+ printf("No printers returned\n");
continue;
}
{
NTSTATUS status;
struct spoolss_GetPrinterDriver2 r;
- uint32_t buf_size;
r.in.handle = handle;
r.in.architecture = "W32X86";
r.in.level = 1;
- buf_size = 0;
r.in.buffer = NULL;
- r.in.buf_size = r.out.buf_size = &buf_size;
+ r.in.offered = 0;
r.in.client_major_version = 0;
r.in.client_minor_version = 0;
printf("Testing GetPrinterDriver2\n");
status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
-
if (!NT_STATUS_IS_OK(status)) {
printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
return False;
}
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
}
BOOL ret = True;
for (i=0;i<ARRAY_SIZE(levels);i++) {
- uint32_t buf_size;
r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
r.in.environment = "Windows NT x86";
r.in.level = levels[i];
r.in.buffer = NULL;
- buf_size = 0;
- r.in.buf_size = &buf_size;
- r.out.buf_size = &buf_size;
+ r.in.offered = 0;
printf("\nTesting EnumPrinterDrivers level %u\n", r.in.level);
}
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
- DATA_BLOB blob = data_blob_talloc(
- mem_ctx, NULL, buf_size);
-
+ DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
data_blob_clear(&blob);
r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
}
-
+
if (!NT_STATUS_IS_OK(status)) {
printf("EnumPrinterDrivers failed - %s\n",
nt_errstr(status));
}
if (!r.out.info) {
- printf("No printer drivers returned");
+ printf("No printer drivers returned\n");
break;
}
}
return ret;
}
-BOOL torture_rpc_spoolss(void)
+BOOL torture_rpc_spoolss(struct torture_context *torture)
{
NTSTATUS status;
struct dcerpc_pipe *p;
mem_ctx = talloc_init("torture_rpc_spoolss");
- status = torture_rpc_connection(mem_ctx,
- &p,
- DCERPC_SPOOLSS_NAME,
- DCERPC_SPOOLSS_UUID,
- DCERPC_SPOOLSS_VERSION);
+ status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_spoolss);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(mem_ctx);
return False;
ret &= test_OpenPrinter_server(ctx);
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "W3SvcInstalled");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "BeepEnabled");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "EventLog");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopup");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopupToComputer");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MajorVersion");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MinorVersion");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DefaultSpoolDirectory");
ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "Architecture");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DsPresent");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "OSVersion");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "OSVersionEx");
+ ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DNSMachineName");
- ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DefaultSpoolDirectory");
+ ret &= test_EnumForms(ctx->p, ctx, &ctx->server_handle, True);
+
+ ret &= test_AddForm(ctx->p, ctx, &ctx->server_handle, True);
ret &= test_EnumPorts(ctx);
+ ret &= test_GetPrinterDriverDirectory(ctx);
+
ret &= test_EnumPrinterDrivers(ctx);
ret &= test_EnumMonitors(ctx);