bool ex;
};
+struct torture_printer_context {
+ struct spoolss_SetPrinterInfo2 info2;
+ struct torture_driver_context driver;
+ bool ex;
+ bool wellknown;
+ bool added_driver;
+ bool have_driver;
+};
+
+static bool upload_printer_driver(struct torture_context *tctx,
+ const char *server_name,
+ struct torture_driver_context *d);
+static bool remove_printer_driver(struct torture_context *tctx,
+ const char *server_name,
+ struct torture_driver_context *d);
+static bool fillup_printserver_info(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct torture_driver_context *d);
+static bool test_AddPrinterDriver_args_level_3(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ const char *server_name,
+ struct spoolss_AddDriverInfo8 *r,
+ uint32_t flags,
+ bool ex);
+
#define COMPARE_STRING(tctx, c,r,e) \
torture_assert_str_equal(tctx, c.e, r.e, "invalid value")
return true;
}
-static bool test_AddPrinterEx(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct policy_handle *handle_p,
- const char *printername,
- const char *drivername,
- const char *portname)
-{
- bool ret = true;
-
- if (!torture_setting_bool(tctx, "samba3", false)) {
- if (!test_AddPrinter_wellknown(tctx, p, TORTURE_WELLKNOWN_PRINTER_EX, true)) {
- torture_comment(tctx, "failed to add printer to well known list\n");
- ret = false;
- }
- }
-
- if (!test_AddPrinter_normal(tctx, p, handle_p,
- printername, drivername, portname,
- true)) {
- torture_comment(tctx, "failed to add printer to printer list\n");
- ret = false;
- }
-
- return ret;
-}
-
-static bool test_AddPrinter(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct policy_handle *handle_p,
- const char *printername,
- const char *drivername,
- const char *portname)
-{
- bool ret = true;
-
- if (!torture_setting_bool(tctx, "samba3", false)) {
- if (!test_AddPrinter_wellknown(tctx, p, TORTURE_WELLKNOWN_PRINTER, false)) {
- torture_comment(tctx, "failed to add printer to well known list\n");
- ret = false;
- }
- }
-
- if (!test_AddPrinter_normal(tctx, p, handle_p,
- printername, drivername, portname,
- false)) {
- torture_comment(tctx, "failed to add printer to printer list\n");
- ret = false;
- }
-
- return ret;
-}
-
static bool test_printer_info(struct torture_context *tctx,
struct dcerpc_binding_handle *b,
struct policy_handle *handle)
struct policy_handle *handle,
const char *name,
const char *drivername,
- const char *environment)
+ const char *environment,
+ bool have_driver)
{
bool ret = true;
struct dcerpc_binding_handle *b = p->binding_handle;
ret = false;
}
- if (!test_DriverInfo_winreg(tctx, p, handle, name, drivername, environment)) {
- ret = false;
+ if (have_driver) {
+ if (!test_DriverInfo_winreg(tctx, p, handle, name, drivername, environment)) {
+ ret = false;
+ }
}
if (!test_printer_rename(tctx, p, handle, name)) {
* been added */
torture_assert(tctx,
- test_AddPrinter(tctx, p, &new_handle, printername, drivername, portname),
+ test_AddPrinter_normal(tctx, p, &new_handle, printername, drivername, portname, false),
"failed to add new printer");
torture_assert(tctx,
test_GetPrinter_level(tctx, b, handle, 0, &info),
return true;
}
-static bool test_printer(struct torture_context *tctx,
- struct dcerpc_pipe *p)
+static bool test_add_printer_args_with_driver(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct torture_printer_context *t)
{
bool ret = true;
- struct policy_handle handle[2];
- struct policy_handle printserver_handle;
+ struct policy_handle handle;
bool found = false;
- const char *drivername = "Microsoft XPS Document Writer";
- const char *portname = "LPT1:";
struct dcerpc_binding_handle *b = p->binding_handle;
- const char *environment;
-
- torture_assert(tctx,
- test_OpenPrinter_server(tctx, p, &printserver_handle),
- "failed to open printserver");
- torture_assert(tctx,
- test_get_environment(tctx, b, &printserver_handle, &environment),
- "failed to get environment");
- torture_assert(tctx,
- test_ClosePrinter(tctx, b, &printserver_handle),
- "failed to close printserver");
-
- /* test printer created via AddPrinter */
+ const char *printer_name = t->info2.printername;
+ const char *driver_name = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
+ const char *port_name = t->info2.portname;
+ const char *printer_name2 = talloc_asprintf(tctx, "%s2", printer_name);
- if (!test_AddPrinter(tctx, p, &handle[0], TORTURE_PRINTER, drivername, portname)) {
- return false;
+ if (t->wellknown) {
+ torture_assert(tctx,
+ test_AddPrinter_wellknown(tctx, p, printer_name, t->ex),
+ "failed to add wellknown printer");
+ } else {
+ torture_assert(tctx,
+ test_AddPrinter_normal(tctx, p, &handle, printer_name, driver_name, port_name, t->ex),
+ "failed to add printer");
}
- if (!test_csetprinter(tctx, p, &handle[0], TORTURE_PRINTER "2", drivername, portname)) {
+ if (!test_csetprinter(tctx, p, &handle, printer_name2, driver_name, port_name)) {
ret = false;
}
- if (!test_one_printer(tctx, p, &handle[0], TORTURE_PRINTER, drivername, environment)) {
+ if (!test_one_printer(tctx, p, &handle, printer_name, driver_name, t->driver.remote.environment, t->have_driver)) {
ret = false;
}
- if (!test_DeletePrinter(tctx, b, &handle[0])) {
+ if (!test_DeletePrinter(tctx, b, &handle)) {
ret = false;
}
if (!test_EnumPrinters_findname(tctx, b, PRINTER_ENUM_LOCAL, 1,
- TORTURE_PRINTER, &found)) {
+ printer_name, &found)) {
ret = false;
}
torture_assert(tctx, !found, "deleted printer still there");
- /* test printer created via AddPrinterEx */
+ return ret;
+}
- if (!test_AddPrinterEx(tctx, p, &handle[1], TORTURE_PRINTER_EX, drivername, portname)) {
- return false;
+static bool compose_local_driver_directory(struct torture_context *tctx,
+ const char *environment,
+ const char *local_dir,
+ const char **path)
+{
+ char *p;
+
+ p = strrchr(local_dir, '/');
+ if (!p) {
+ return NULL;
}
+ p++;
- if (!test_csetprinter(tctx, p, &handle[1], TORTURE_PRINTER_EX "2", drivername, portname)) {
- ret = false;
+ if (strequal(environment, "Windows x64")) {
+ if (!strequal(p, "x64")) {
+ *path = talloc_asprintf(tctx, "%s/x64", local_dir);
+ }
+ } else if (strequal(environment, "Windows NT x86")) {
+ if (!strequal(p, "i386")) {
+ *path = talloc_asprintf(tctx, "%s/i386", local_dir);
+ }
+ } else {
+ torture_assert(tctx, "unknown environment: '%s'\n", environment);
}
- if (!test_one_printer(tctx, p, &handle[1], TORTURE_PRINTER_EX, drivername, environment)) {
- ret = false;
+ return true;
+}
+
+static bool test_add_printer_args(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct torture_printer_context *t)
+{
+ bool ret = true;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+ const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+
+ if (t->wellknown && torture_setting_bool(tctx, "samba3", false)) {
+ torture_skip(tctx, "skipping AddPrinter level 1 against samba");
}
- if (!test_DeletePrinter(tctx, b, &handle[1])) {
- ret = false;
+ torture_assert(tctx,
+ fillup_printserver_info(tctx, p, &t->driver),
+ "failed to fillup printserver info");
+
+ t->driver.info8.architecture = talloc_strdup(t, t->driver.remote.environment);
+
+ torture_assert(tctx,
+ compose_local_driver_directory(tctx, t->driver.remote.environment,
+ t->driver.local.driver_directory,
+ &t->driver.local.driver_directory),
+ "failed to compose local driver directory");
+
+ if (test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, t->driver.remote.environment, 3, t->info2.drivername)) {
+ t->have_driver = true;
+ goto try_run;
}
- if (!test_EnumPrinters_findname(tctx, b, PRINTER_ENUM_LOCAL, 1,
- TORTURE_PRINTER_EX, &found)) {
- ret = false;
+ torture_comment(tctx, "driver '%s' (architecture: %s, version: 3) does not exist on the server\n",
+ t->info2.drivername, t->driver.remote.environment);
+ torture_comment(tctx, "trying to upload own driver\n");
+
+ if (!directory_exist(t->driver.local.driver_directory)) {
+ torture_warning(tctx, "no local driver is available!");
+ t->have_driver = false;
+ goto try_run;
}
- torture_assert(tctx, !found, "deleted printer still there");
+ torture_assert(tctx,
+ upload_printer_driver(tctx, dcerpc_server_name(p), &t->driver),
+ "failed to upload printer driver");
+
+ torture_assert(tctx,
+ test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &t->driver.info8, 0, false),
+ "failed to add driver");
+
+ t->added_driver = true;
+ t->have_driver = true;
+
+ try_run:
+ ret = test_add_printer_args_with_driver(tctx, p, t);
+
+ if (t->added_driver) {
+ torture_assert(tctx,
+ remove_printer_driver(tctx, dcerpc_server_name(p), &t->driver),
+ "failed to remove printer driver");
+ }
return ret;
}
+static bool test_add_printer(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+
+ t->ex = false;
+ t->wellknown = false;
+ t->info2.printername = TORTURE_PRINTER;
+
+ return test_add_printer_args(tctx, p, t);
+}
+
+static bool test_add_printer_wellknown(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+
+ t->ex = false;
+ t->wellknown = true;
+ t->info2.printername = TORTURE_WELLKNOWN_PRINTER;
+
+ return test_add_printer_args(tctx, p, t);
+}
+
+static bool test_add_printer_ex(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+
+ t->ex = true;
+ t->wellknown = false;
+ t->info2.printername = TORTURE_PRINTER_EX;
+
+ return test_add_printer_args(tctx, p, t);
+}
+
+static bool test_add_printer_ex_wellknown(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+
+ t->ex = true;
+ t->wellknown = true;
+ t->info2.printername = TORTURE_WELLKNOWN_PRINTER_EX;
+
+ return test_add_printer_args(tctx, p, t);
+}
+
static bool test_architecture_buffer(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
"printer", &ndr_table_spoolss);
- torture_rpc_tcase_add_test(tcase, "printer", test_printer);
+ struct torture_printer_context *t;
+
+ t = talloc_zero(mem_ctx, struct torture_printer_context);
+
+ t->driver.info8.version = SPOOLSS_DRIVER_VERSION_200X;
+ t->driver.info8.driver_name = TORTURE_DRIVER;
+ t->driver.info8.architecture = "Windows NT x86";
+ t->driver.info8.driver_path = "pscript5.dll";
+ t->driver.info8.data_file = "cups6.ppd";
+ t->driver.info8.config_file = "cupsui6.dll";
+ t->driver.local.environment = "Windows NT x86";
+ t->driver.local.driver_directory= "/usr/share/cups/drivers/i386";
+
+ t->info2.drivername = "Microsoft XPS Document Writer";
+ t->info2.portname = "LPT1:";
+
+ torture_rpc_tcase_add_test_ex(tcase, "add_printer", test_add_printer, t);
+ torture_rpc_tcase_add_test_ex(tcase, "add_printer_wellknown", test_add_printer_wellknown, t);
+ torture_rpc_tcase_add_test_ex(tcase, "add_printer_ex", test_add_printer_ex, t);
+ torture_rpc_tcase_add_test_ex(tcase, "add_printer_ex_wellknown", test_add_printer_ex_wellknown, t);
return suite;
}
}
}
+static const char *get_environment_from_info(struct spoolss_AddDriverInfoCtr *info_ctr)
+{
+ if (info_ctr == NULL) {
+ return NULL;
+ }
+
+ switch (info_ctr->level) {
+ case 2:
+ return info_ctr->info.info2->architecture;
+ case 3:
+ return info_ctr->info.info3->architecture;
+ case 4:
+ return info_ctr->info.info4->architecture;
+ case 6:
+ return info_ctr->info.info6->architecture;
+ case 8:
+ return info_ctr->info.info8->architecture;
+ default:
+ return NULL;
+ }
+}
+
+
static bool test_AddPrinterDriver_exp(struct torture_context *tctx,
struct dcerpc_binding_handle *b,
const char *servername,
{
struct spoolss_AddPrinterDriver r;
const char *drivername = get_driver_from_info(info_ctr);
+ const char *environment = get_environment_from_info(info_ctr);
r.in.servername = servername;
r.in.info_ctr = info_ctr;
- torture_comment(tctx, "Testing AddPrinterDriver(%s) level %d\n",
- drivername, info_ctr->level);
+ torture_comment(tctx, "Testing AddPrinterDriver(%s) level: %d, environment: '%s'\n",
+ drivername, info_ctr->level, environment);
torture_assert_ntstatus_ok(tctx,
dcerpc_spoolss_AddPrinterDriver_r(b, tctx, &r),
{
struct spoolss_AddPrinterDriverEx r;
const char *drivername = get_driver_from_info(info_ctr);
+ const char *environment = get_environment_from_info(info_ctr);
r.in.servername = servername;
r.in.info_ctr = info_ctr;
r.in.flags = flags;
- torture_comment(tctx, "Testing AddPrinterDriverEx(%s) level %d\n",
- drivername, info_ctr->level);
+ torture_comment(tctx, "Testing AddPrinterDriverEx(%s) level: %d, environment: '%s'\n",
+ drivername, info_ctr->level, environment);
torture_assert_ntstatus_ok(tctx,
dcerpc_spoolss_AddPrinterDriverEx_r(b, tctx, &r),
struct spoolss_AddDriverInfoCtr info_ctr;
struct spoolss_AddDriverInfo3 info3;
- ZERO_STRUCT(info3);
-
info3.driver_name = r->driver_name;
info3.version = r->version;
info3.architecture = r->architecture;
info3.driver_path = r->driver_path;
info3.data_file = r->data_file;
info3.config_file = r->config_file;
+ info3.help_file = r->help_file;
+ info3.monitor_name = r->monitor_name;
+ info3.default_datatype = r->default_datatype;
+ info3._ndr_size_dependent_files = r->_ndr_size_dependent_files;
+ info3.dependent_files = r->dependent_files;
info_ctr.level = 3;
info_ctr.info.info3 = &info3;
struct spoolss_AddDriverInfoCtr info_ctr;
struct spoolss_AddDriverInfo4 info4;
- ZERO_STRUCT(info4);
-
- info4.driver_name = r->driver_name;
info4.version = r->version;
+ info4.driver_name = r->driver_name;
info4.architecture = r->architecture;
info4.driver_path = r->driver_path;
info4.data_file = r->data_file;
info4.config_file = r->config_file;
+ info4.help_file = r->help_file;
+ info4.monitor_name = r->monitor_name;
+ info4.default_datatype = r->default_datatype;
+ info4._ndr_size_dependent_files = r->_ndr_size_dependent_files;
+ info4.dependent_files = r->dependent_files;
+ info4._ndr_size_previous_names = r->_ndr_size_previous_names;
+ info4.previous_names = r->previous_names;
info_ctr.level = 4;
info_ctr.info.info4 = &info4;
struct spoolss_AddDriverInfoCtr info_ctr;
struct spoolss_AddDriverInfo6 info6;
- ZERO_STRUCT(info6);
-
- info6.driver_name = r->driver_name;
info6.version = r->version;
+ info6.driver_name = r->driver_name;
info6.architecture = r->architecture;
info6.driver_path = r->driver_path;
info6.data_file = r->data_file;
info6.config_file = r->config_file;
+ info6.help_file = r->help_file;
+ info6.monitor_name = r->monitor_name;
+ info6.default_datatype = r->default_datatype;
+ info6._ndr_size_dependent_files = r->_ndr_size_dependent_files;
+ info6.dependent_files = r->dependent_files;
+ info6._ndr_size_previous_names = r->_ndr_size_previous_names;
+ info6.previous_names = r->previous_names;
+ info6.driver_date = r->driver_date;
+ info6.driver_version = r->driver_version;
+ info6.manufacturer_name = r->manufacturer_name;
+ info6.manufacturer_url = r->manufacturer_url;
+ info6.hardware_id = r->hardware_id;
+ info6.provider = r->provider;
info_ctr.level = 6;
info_ctr.info.info6 = &info6;
bool ex)
{
struct spoolss_AddDriverInfoCtr info_ctr;
- struct spoolss_AddDriverInfo8 info8;
-
- ZERO_STRUCT(info8);
-
- info8.driver_name = r->driver_name;
- info8.version = r->version;
- info8.architecture = r->architecture;
- info8.driver_path = r->driver_path;
- info8.data_file = r->data_file;
- info8.config_file = r->config_file;
info_ctr.level = 8;
- info_ctr.info.info8 = &info8;
+ info_ctr.info.info8 = r;
if (ex) {
torture_assert(tctx,
struct smbcli_options smb_options;
struct smbcli_session_options smb_session_options;
- torture_comment(tctx, "Connecting printer driver share\n");
+ torture_comment(tctx, "Connecting printer driver share '%s' on '%s'\n",
+ share_name, server_name);
lp_smbcli_options(tctx->lp_ctx, &smb_options);
lp_smbcli_session_options(tctx->lp_ctx, &smb_session_options);
"failed to remove help_file");
if (d->info8.dependent_files) {
for (i=0; d->info8.dependent_files->string && d->info8.dependent_files->string[i] != NULL; i++) {
+ if (strequal(d->info8.dependent_files->string[i], d->info8.driver_path) ||
+ strequal(d->info8.dependent_files->string[i], d->info8.data_file) ||
+ strequal(d->info8.dependent_files->string[i], d->info8.config_file) ||
+ strequal(d->info8.dependent_files->string[i], d->info8.help_file)) {
+ continue;
+ }
torture_assert(tctx,
remove_printer_driver_file(tctx, cli, d, d->info8.dependent_files->string[i]),
"failed to remove dependent_files");