LCOV - code coverage report
Current view: top level - source4/torture/rpc - iremotewinspool.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 19 343 5.5 %
Date: 2021-09-23 10:06:22 Functions: 1 23 4.3 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    test suite for iremotewinspool rpc operations
       4             : 
       5             :    Copyright (C) Guenther Deschner 2013
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "torture/torture.h"
      23             : #include "librpc/gen_ndr/ndr_winspool.h"
      24             : #include "librpc/gen_ndr/ndr_winspool_c.h"
      25             : #include "librpc/gen_ndr/ndr_spoolss_c.h"
      26             : #include "torture/rpc/torture_rpc.h"
      27             : #include "libcli/registry/util_reg.h"
      28             : #include "torture/rpc/iremotewinspool_common.h"
      29             : 
      30           0 : static bool torture_rpc_iremotewinspool_setup_common(struct torture_context *tctx,
      31             :                                                      struct test_iremotewinspool_context *t)
      32             : {
      33             :         const char *printer_name;
      34             :         struct spoolss_UserLevel1 client_info;
      35             :         struct dcerpc_binding *binding;
      36             : 
      37           0 :         torture_assert_ntstatus_ok(tctx,
      38             :                 GUID_from_string(IREMOTEWINSPOOL_OBJECT_GUID, &t->object_uuid),
      39             :                 "failed to parse GUID");
      40             : 
      41           0 :         torture_assert_ntstatus_ok(tctx,
      42             :                 torture_rpc_binding(tctx, &binding),
      43             :                 "failed to retrieve torture binding");
      44             : 
      45           0 :         torture_assert_ntstatus_ok(tctx,
      46             :                 dcerpc_binding_set_object(binding, t->object_uuid),
      47             :                 "failed to set object_uuid");
      48             : 
      49           0 :         torture_assert_ntstatus_ok(tctx,
      50             :                 torture_rpc_connection_with_binding(tctx, binding, &t->iremotewinspool_pipe, &ndr_table_iremotewinspool),
      51             :                 "Error connecting to server");
      52             : 
      53           0 :         printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(t->iremotewinspool_pipe));
      54             : 
      55           0 :         client_info = test_get_client_info(tctx, WIN_7, 6, 1, "testclient_machine", "testclient_user");
      56             : 
      57           0 :         torture_assert(tctx,
      58             :                 test_AsyncOpenPrinter_byprinter(tctx, t,
      59             :                                                 t->iremotewinspool_pipe, printer_name,
      60             :                                                 client_info, &t->server_handle),
      61             :                                                 "failed to open printserver");
      62           0 :         torture_assert(tctx,
      63             :                 test_get_environment(tctx,
      64             :                                      t->iremotewinspool_pipe->binding_handle,
      65             :                                      &t->server_handle, &t->environment),
      66             :                                      "failed to get environment");
      67             : 
      68           0 :         return true;
      69             : }
      70             : 
      71           0 : static bool torture_rpc_iremotewinspool_setup(struct torture_context *tctx,
      72             :                                               void **data)
      73             : {
      74             :         struct test_iremotewinspool_context *t;
      75             : 
      76           0 :         *data = t = talloc_zero(tctx, struct test_iremotewinspool_context);
      77             : 
      78           0 :         return torture_rpc_iremotewinspool_setup_common(tctx, t);
      79             : }
      80             : 
      81           0 : static bool torture_rpc_iremotewinspool_teardown_common(struct torture_context *tctx,
      82             :                                                         struct test_iremotewinspool_context *t)
      83             : {
      84             : 
      85           0 :         test_AsyncClosePrinter_byhandle(tctx, t, t->iremotewinspool_pipe, &t->server_handle);
      86             : 
      87           0 :         return true;
      88             : }
      89             : 
      90           0 : static bool torture_rpc_iremotewinspool_teardown(struct torture_context *tctx,
      91             :                                                  void *data)
      92             : {
      93           0 :         struct test_iremotewinspool_context *t = talloc_get_type(data, struct test_iremotewinspool_context);
      94             :         bool ret;
      95             : 
      96           0 :         ret = torture_rpc_iremotewinspool_teardown_common(tctx, t);
      97           0 :         talloc_free(t);
      98             : 
      99           0 :         return ret;
     100             : }
     101             : 
     102           0 : static bool test_AsyncClosePrinter(struct torture_context *tctx,
     103             :                                    void *private_data)
     104             : {
     105           0 :         struct test_iremotewinspool_context *ctx =
     106           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     107             : 
     108           0 :         struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
     109             :         const char *printer_name;
     110             :         struct spoolss_UserLevel1 client_info;
     111             :         struct policy_handle handle;
     112             : 
     113           0 :         printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     114             : 
     115           0 :         client_info = test_get_client_info(tctx, WIN_7, 6, 1, "testclient_machine", "testclient_user");
     116             : 
     117           0 :         torture_assert(tctx,
     118             :                 test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
     119             :                 "failed to test AsyncOpenPrinter");
     120             : 
     121           0 :         torture_assert(tctx,
     122             :                 test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle),
     123             :                 "failed to test AsyncClosePrinter");
     124             : 
     125           0 :         return true;
     126             : }
     127             : 
     128           0 : static bool test_AsyncOpenPrinter(struct torture_context *tctx,
     129             :                                   void *private_data)
     130             : {
     131           0 :         struct test_iremotewinspool_context *ctx =
     132           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     133             : 
     134           0 :         struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
     135             :         const char *printer_name;
     136             :         struct spoolss_UserLevel1 client_info;
     137             :         struct policy_handle handle;
     138             : 
     139           0 :         printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     140             : 
     141           0 :         client_info = test_get_client_info(tctx, WIN_7, 6, 1, "testclient_machine", "testclient_user");
     142             : 
     143           0 :         torture_assert(tctx,
     144             :                 test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
     145             :                 "failed to test AsyncOpenPrinter");
     146             : 
     147           0 :         test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle);
     148             : 
     149           0 :         return true;
     150             : }
     151             : 
     152             : /*
     153             :  * Validate the result of AsyncOpenPrinter calls based on client info
     154             :  * build number. Windows Server 2016 rejects an advertised build
     155             :  * number less than 6000(Windows Vista and Windows Server 2008, or older)
     156             :  */
     157           0 : static bool test_AsyncOpenPrinterValidateBuildNumber(struct torture_context *tctx,
     158             :                                                      void *private_data)
     159             : {
     160           0 :         struct test_iremotewinspool_context *ctx =
     161           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     162             : 
     163           0 :         struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
     164             :         const char *printer_name;
     165             :         struct spoolss_UserLevel1 client_info;
     166             :         struct policy_handle handle;
     167           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     168             :         struct spoolss_DevmodeContainer devmode_ctr;
     169           0 :         struct spoolss_UserLevelCtr client_info_ctr = {
     170             :                 .level = 1,
     171             :         };
     172           0 :         uint32_t access_mask = SERVER_ALL_ACCESS;
     173             :         struct winspool_AsyncOpenPrinter r;
     174             :         NTSTATUS status;
     175           0 :         bool ok = false;
     176             : 
     177           0 :         printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     178           0 :         torture_assert_not_null(tctx, printer_name, "Cannot allocate memory");
     179             : 
     180             :         /* fail with Windows 2000 build number */
     181           0 :         client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0,
     182             :                                            "testclient_machine", "testclient_user");
     183             : 
     184           0 :         ZERO_STRUCT(devmode_ctr);
     185             : 
     186           0 :         client_info_ctr.user_info.level1 = &client_info;
     187             : 
     188           0 :         r.in.pPrinterName       = printer_name;
     189           0 :         r.in.pDatatype          = NULL;
     190           0 :         r.in.pDevModeContainer  = &devmode_ctr;
     191           0 :         r.in.AccessRequired     = access_mask;
     192           0 :         r.in.pClientInfo        = &client_info_ctr;
     193           0 :         r.out.pHandle           = &handle;
     194             : 
     195           0 :         status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
     196           0 :         torture_assert_ntstatus_ok(tctx, status, "AsyncOpenPrinter failed");
     197           0 :         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
     198             :                 "AsyncOpenPrinter should have failed");
     199             : 
     200             :         /* succeed with Windows 7 build number */
     201           0 :         client_info = test_get_client_info(tctx, WIN_7, 6, 1,
     202             :                                            "testclient_machine", "testclient_user");
     203           0 :         client_info_ctr.user_info.level1 = &client_info;
     204           0 :         r.in.pClientInfo        = &client_info_ctr;
     205             : 
     206           0 :         status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
     207           0 :         torture_assert_ntstatus_ok(tctx, status, "AsyncOpenPrinter failed");
     208           0 :         torture_assert_werr_ok(tctx, r.out.result,
     209             :                 "AsyncOpenPrinter failed");
     210             : 
     211           0 :         ok = test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle);
     212           0 :         torture_assert(tctx, ok, "failed to AsyncClosePrinter handle");
     213             : 
     214           0 :         return true;
     215             : 
     216             : }
     217             : 
     218           0 : static struct spoolss_NotifyOption *setup_printserver_NotifyOption(struct torture_context *tctx)
     219             : {
     220             :         struct spoolss_NotifyOption *o;
     221             : 
     222           0 :         o = talloc_zero(tctx, struct spoolss_NotifyOption);
     223           0 :         if (o == NULL) {
     224           0 :                 return NULL;
     225             :         }
     226             : 
     227           0 :         o->version = 2;
     228           0 :         o->flags = PRINTER_NOTIFY_OPTIONS_REFRESH;
     229             : 
     230           0 :         o->count = 2;
     231           0 :         o->types = talloc_zero_array(o, struct spoolss_NotifyOptionType, o->count);
     232           0 :         if (o->types == NULL) {
     233           0 :                 talloc_free(o);
     234           0 :                 return NULL;
     235             :         }
     236             : 
     237           0 :         o->types[0].type = PRINTER_NOTIFY_TYPE;
     238           0 :         o->types[0].count = 1;
     239           0 :         o->types[0].fields = talloc_array(o->types, union spoolss_Field, o->types[0].count);
     240           0 :         if (o->types[0].fields == NULL) {
     241           0 :                 talloc_free(o);
     242           0 :                 return NULL;
     243             :         }
     244           0 :         o->types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
     245             : 
     246           0 :         o->types[1].type = JOB_NOTIFY_TYPE;
     247           0 :         o->types[1].count = 1;
     248           0 :         o->types[1].fields = talloc_array(o->types, union spoolss_Field, o->types[1].count);
     249           0 :         if (o->types[1].fields == NULL) {
     250           0 :                 talloc_free(o);
     251           0 :                 return NULL;
     252             :         }
     253           0 :         o->types[1].fields[0].field = JOB_NOTIFY_FIELD_MACHINE_NAME;
     254             : 
     255           0 :         return o;
     256             : }
     257             : 
     258           0 : static bool test_SyncUnRegisterForRemoteNotifications_args(struct torture_context *tctx,
     259             :                                                            struct dcerpc_pipe *p,
     260             :                                                            struct policy_handle *notify_handle)
     261             : {
     262             :         struct winspool_SyncUnRegisterForRemoteNotifications r;
     263           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     264             : 
     265           0 :         r.in.phRpcHandle = notify_handle;
     266           0 :         r.out.phRpcHandle = notify_handle;
     267             : 
     268           0 :         torture_assert_ntstatus_ok(tctx,
     269             :                 dcerpc_winspool_SyncUnRegisterForRemoteNotifications_r(b, tctx, &r),
     270             :                 "SyncUnRegisterForRemoteNotifications failed");
     271           0 :         torture_assert_hresult_ok(tctx, r.out.result,
     272             :                 "SyncUnRegisterForRemoteNotifications failed");
     273             : 
     274           0 :         return true;
     275             : }
     276             : 
     277             : static bool test_SyncRegisterForRemoteNotifications_args(struct torture_context *tctx,
     278             :                                                          struct dcerpc_pipe *p,
     279             :                                                          struct policy_handle *server_handle,
     280             :                                                          struct policy_handle *notify_handle);
     281             : 
     282           0 : static bool test_SyncUnRegisterForRemoteNotifications(struct torture_context *tctx,
     283             :                                                       void *private_data)
     284             : {
     285           0 :         struct test_iremotewinspool_context *ctx =
     286           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     287             :         struct policy_handle notify_handle;
     288             : 
     289           0 :         torture_assert(tctx,
     290             :                 test_SyncRegisterForRemoteNotifications_args(tctx,
     291             :                                                              ctx->iremotewinspool_pipe,
     292             :                                                              &ctx->server_handle,
     293             :                                                              &notify_handle),
     294             :                 "failed to test SyncRegisterForRemoteNotifications");
     295             : 
     296           0 :         torture_assert(tctx,
     297             :                 test_SyncUnRegisterForRemoteNotifications_args(tctx,
     298             :                                                                ctx->iremotewinspool_pipe,
     299             :                                                                &notify_handle),
     300             :                 "failed to test UnSyncRegisterForRemoteNotifications");
     301             : 
     302           0 :         return true;
     303             : }
     304             : 
     305           0 : static bool test_SyncRegisterForRemoteNotifications_args(struct torture_context *tctx,
     306             :                                                          struct dcerpc_pipe *p,
     307             :                                                          struct policy_handle *server_handle,
     308             :                                                          struct policy_handle *notify_handle)
     309             : {
     310           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     311             : 
     312             :         struct winspool_SyncRegisterForRemoteNotifications r;
     313             :         struct winspool_PrintPropertiesCollection NotifyFilter;
     314             :         struct winspool_PrintNamedProperty *c;
     315             :         struct spoolss_NotifyOption *options;
     316             : 
     317           0 :         ZERO_STRUCT(NotifyFilter);
     318             : 
     319           0 :         options = setup_printserver_NotifyOption(tctx);
     320           0 :         torture_assert(tctx, options, "out of memory");
     321             : 
     322           0 :         c = talloc_zero_array(tctx, struct winspool_PrintNamedProperty, 4);
     323           0 :         torture_assert(tctx, c, "out of memory");
     324             : 
     325           0 :         c[0].propertyName = "RemoteNotifyFilter Flags";
     326           0 :         c[0].propertyValue.PropertyType = winspool_PropertyTypeInt32;
     327           0 :         c[0].propertyValue.value.propertyInt32 = 0xff;
     328             : 
     329           0 :         c[1].propertyName = "RemoteNotifyFilter Options";
     330           0 :         c[1].propertyValue.PropertyType = winspool_PropertyTypeInt32;
     331           0 :         c[1].propertyValue.value.propertyInt32 = 0;
     332             : 
     333           0 :         c[2].propertyName = "RemoteNotifyFilter Color";
     334           0 :         c[2].propertyValue.PropertyType = winspool_PropertyTypeInt32;
     335           0 :         c[2].propertyValue.value.propertyInt32 = 0;
     336             : 
     337           0 :         c[3].propertyName = "RemoteNotifyFilter NotifyOptions";
     338           0 :         c[3].propertyValue.PropertyType = winspool_PropertyTypeNotificationOptions;
     339           0 :         c[3].propertyValue.value.propertyOptionsContainer.pOptions = options;
     340             : 
     341           0 :         NotifyFilter.numberOfProperties = 4;
     342           0 :         NotifyFilter.propertiesCollection = c;
     343             : 
     344           0 :         r.in.hPrinter = *server_handle;
     345           0 :         r.in.pNotifyFilter = &NotifyFilter;
     346           0 :         r.out.phRpcHandle = notify_handle;
     347             : 
     348           0 :         torture_assert_ntstatus_ok(tctx,
     349             :                 dcerpc_winspool_SyncRegisterForRemoteNotifications_r(b, tctx, &r),
     350             :                 "SyncRegisterForRemoteNotifications failed");
     351           0 :         torture_assert_hresult_ok(tctx, r.out.result,
     352             :                 "SyncRegisterForRemoteNotifications failed");
     353             : 
     354           0 :         return true;
     355             : }
     356             : 
     357           0 : static bool test_SyncRegisterForRemoteNotifications(struct torture_context *tctx,
     358             :                                                     void *private_data)
     359             : {
     360           0 :         struct test_iremotewinspool_context *ctx =
     361           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     362             :         struct policy_handle notify_handle;
     363             : 
     364           0 :         torture_assert(tctx,
     365             :                 test_SyncRegisterForRemoteNotifications_args(tctx,
     366             :                                                              ctx->iremotewinspool_pipe,
     367             :                                                              &ctx->server_handle,
     368             :                                                              &notify_handle),
     369             :                 "failed to test SyncRegisterForRemoteNotifications");
     370             : 
     371           0 :         test_SyncUnRegisterForRemoteNotifications_args(tctx, ctx->iremotewinspool_pipe, &notify_handle);
     372             : 
     373           0 :         return true;
     374             : }
     375             : 
     376           0 : static bool test_AsyncUploadPrinterDriverPackage(struct torture_context *tctx,
     377             :                                                  void *private_data)
     378             : {
     379           0 :         struct test_iremotewinspool_context *ctx =
     380           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     381             : 
     382           0 :         struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
     383           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     384             : 
     385             :         struct winspool_AsyncUploadPrinterDriverPackage r;
     386           0 :         uint32_t pcchDestInfPath = 0;
     387             : 
     388           0 :         r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     389           0 :         r.in.pszInfPath = "";
     390           0 :         r.in.pszEnvironment = "";
     391           0 :         r.in.dwFlags = 0;
     392           0 :         r.in.pszDestInfPath = NULL;
     393           0 :         r.in.pcchDestInfPath = &pcchDestInfPath;
     394           0 :         r.out.pszDestInfPath = NULL;
     395           0 :         r.out.pcchDestInfPath = &pcchDestInfPath;
     396             : 
     397           0 :         torture_assert_ntstatus_ok(tctx,
     398             :                 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
     399             :                 "AsyncUploadPrinterDriverPackage failed");
     400           0 :         torture_assert_hresult_equal(tctx, r.out.result, HRES_E_INVALIDARG,
     401             :                 "AsyncUploadPrinterDriverPackage failed");
     402             : 
     403           0 :         pcchDestInfPath = 260;
     404           0 :         r.in.pszDestInfPath = talloc_zero(tctx, const char);
     405           0 :         r.out.pszDestInfPath = talloc_zero(tctx, const char);
     406             : 
     407           0 :         torture_assert_ntstatus_ok(tctx,
     408             :                 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
     409             :                 "AsyncUploadPrinterDriverPackage failed");
     410           0 :         torture_assert_werr_equal(tctx,
     411             :                 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
     412             :                 "AsyncUploadPrinterDriverPackage failed");
     413             : 
     414           0 :         r.in.pszEnvironment = SPOOLSS_ARCHITECTURE_x64;
     415             : 
     416           0 :         torture_assert_ntstatus_ok(tctx,
     417             :                 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
     418             :                 "AsyncUploadPrinterDriverPackage failed");
     419           0 :         torture_assert_werr_equal(tctx,
     420             :                 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_FILE_NOT_FOUND,
     421             :                 "AsyncUploadPrinterDriverPackage failed");
     422             : 
     423           0 :         r.in.pszInfPath = "\\\\mthelena\\print$\\x64\\{BD443844-ED00-4D96-8CAE-95E49492312A}\\prnbrcl1.inf";
     424             : 
     425           0 :         torture_assert_ntstatus_ok(tctx,
     426             :                 dcerpc_winspool_AsyncUploadPrinterDriverPackage_r(b, tctx, &r),
     427             :                 "AsyncUploadPrinterDriverPackage failed");
     428           0 :         torture_assert_werr_equal(tctx,
     429             :                 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_FILE_NOT_FOUND,
     430             :                 "AsyncUploadPrinterDriverPackage failed");
     431             : 
     432           0 :         return true;
     433             : }
     434             : 
     435           0 : static bool test_AsyncEnumPrinters(struct torture_context *tctx,
     436             :                                    void *private_data)
     437             : {
     438           0 :         struct test_iremotewinspool_context *ctx =
     439           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     440             : 
     441           0 :         struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
     442           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     443             : 
     444             :         struct winspool_AsyncEnumPrinters r;
     445           0 :         uint32_t levels[] = { 1, 2, /*3,*/ 4, 5 };
     446             :         int i;
     447             : 
     448             :         uint32_t needed;
     449             :         uint32_t returned;
     450             : 
     451           0 :         for (i = 0; i < ARRAY_SIZE(levels); i++) {
     452             : 
     453           0 :                 r.in.Flags = PRINTER_ENUM_LOCAL;
     454           0 :                 r.in.pName = NULL;
     455           0 :                 r.in.Level = levels[i];
     456           0 :                 r.in.cbBuf = 0;
     457           0 :                 r.in.pPrinterEnum = NULL;
     458           0 :                 r.out.pcbNeeded = &needed;
     459           0 :                 r.out.pcReturned = &returned;
     460           0 :                 r.out.pPrinterEnum = NULL;
     461             : 
     462           0 :                 torture_assert_ntstatus_ok(tctx,
     463             :                         dcerpc_winspool_AsyncEnumPrinters_r(b, tctx, &r),
     464             :                         "AsyncEnumPrinters failed");
     465           0 :                 torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
     466             :                         "AsyncEnumPrinters failed");
     467             : 
     468           0 :                 r.in.cbBuf = needed;
     469           0 :                 r.in.pPrinterEnum = talloc_zero_array(tctx, uint8_t, r.in.cbBuf);
     470           0 :                 r.out.pPrinterEnum = r.in.pPrinterEnum;
     471             : 
     472           0 :                 torture_assert_ntstatus_ok(tctx,
     473             :                         dcerpc_winspool_AsyncEnumPrinters_r(b, tctx, &r),
     474             :                         "AsyncEnumPrinters failed");
     475           0 :                 torture_assert_werr_ok(tctx, r.out.result,
     476             :                         "AsyncEnumPrinters failed");
     477             :         }
     478             : 
     479           0 :         return true;
     480             : }
     481             : 
     482           0 : static bool test_AsyncGetPrinterData(struct torture_context *tctx,
     483             :                                      void *private_data)
     484             : {
     485           0 :         struct test_iremotewinspool_context *ctx =
     486           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     487             : 
     488           0 :         struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
     489           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     490             :         DATA_BLOB blob;
     491             :         const char *s;
     492             :         bool ok;
     493             : 
     494             :         uint32_t pType;
     495             :         uint32_t pcbNeeded;
     496             :         uint8_t *pData;
     497             : 
     498           0 :         torture_assert(tctx,
     499             :                 test_AsyncGetPrinterData_args(tctx, b, &ctx->server_handle,
     500             :                                               "MajorVersion",
     501             :                                               &pType, &pData, &pcbNeeded),
     502             :                 "failed to check for MajorVersion");
     503             : 
     504           0 :         torture_assert_int_equal(tctx, pcbNeeded, 4, "pcbNeeded");
     505           0 :         torture_assert_int_equal(tctx, pType, REG_DWORD, "pType");
     506           0 :         torture_assert_int_equal(tctx, IVAL(pData, 0), 3, "pData");
     507             : 
     508           0 :         torture_assert(tctx,
     509             :                 test_AsyncGetPrinterData_args(tctx, b, &ctx->server_handle,
     510             :                                               "Architecture",
     511             :                                               &pType, &pData, &pcbNeeded),
     512             :                 "failed to check for Architecture");
     513             : 
     514           0 :         blob = data_blob_const(pData, pcbNeeded);
     515             : 
     516           0 :         torture_assert_int_equal(tctx, pType, REG_SZ, "pType");
     517           0 :         torture_assert(tctx, pull_reg_sz(tctx, &blob, &s), "");
     518           0 :         ok = strequal(s, SPOOLSS_ARCHITECTURE_x64) || strequal(s, SPOOLSS_ARCHITECTURE_NT_X86);
     519           0 :         torture_assert(tctx, ok, "unexpected architecture returned");
     520             : 
     521           0 :         return true;
     522             : }
     523             : 
     524           0 : static bool test_AsyncCorePrinterDriverInstalled(struct torture_context *tctx,
     525             :                                                  void *private_data)
     526             : {
     527           0 :         struct test_iremotewinspool_context *ctx =
     528           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     529             : 
     530           0 :         struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
     531           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     532             : 
     533             :         struct winspool_AsyncCorePrinterDriverInstalled r;
     534             :         int32_t pbDriverInstalled;
     535             :         struct GUID guid;
     536             : 
     537           0 :         r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     538           0 :         r.in.pszEnvironment = "";
     539           0 :         r.in.CoreDriverGUID = GUID_zero();
     540           0 :         r.in.ftDriverDate = 0;
     541           0 :         r.in.dwlDriverVersion = 0;
     542           0 :         r.out.pbDriverInstalled = &pbDriverInstalled;
     543             : 
     544           0 :         torture_assert_ntstatus_ok(tctx,
     545             :                 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
     546             :                 "AsyncCorePrinterDriverInstalled failed");
     547           0 :         torture_assert_werr_equal(tctx,
     548             :                 W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
     549             :                 "AsyncCorePrinterDriverInstalled failed");
     550             : 
     551           0 :         r.in.pszEnvironment = SPOOLSS_ARCHITECTURE_x64;
     552             : 
     553           0 :         torture_assert_ntstatus_ok(tctx,
     554             :                 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
     555             :                 "AsyncCorePrinterDriverInstalled failed");
     556           0 :         torture_assert_hresult_ok(tctx, r.out.result,
     557             :                 "AsyncCorePrinterDriverInstalled failed");
     558           0 :         torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
     559             :                                 "unexpected driver installed");
     560             : 
     561           0 :         r.in.CoreDriverGUID = GUID_random();
     562             : 
     563           0 :         torture_assert_ntstatus_ok(tctx,
     564             :                 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
     565             :                 "AsyncCorePrinterDriverInstalled failed");
     566           0 :         torture_assert_hresult_ok(tctx, r.out.result,
     567             :                 "AsyncCorePrinterDriverInstalled failed");
     568           0 :         torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
     569             :                                 "unexpected driver installed");
     570             : 
     571           0 :         torture_assert_ntstatus_ok(tctx,
     572             :                 GUID_from_string(SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV, &guid), "");
     573             : 
     574           0 :         r.in.CoreDriverGUID = guid;
     575             : 
     576           0 :         torture_assert_ntstatus_ok(tctx,
     577             :                 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
     578             :                 "AsyncCorePrinterDriverInstalled failed");
     579           0 :         torture_assert_hresult_ok(tctx, r.out.result,
     580             :                 "AsyncCorePrinterDriverInstalled failed");
     581           0 :         torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, true,
     582             :                                 "xps core driver not installed?");
     583             : 
     584           0 :         r.in.dwlDriverVersion = 0xffffffff;
     585             : 
     586           0 :         torture_assert_ntstatus_ok(tctx,
     587             :                 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
     588             :                 "AsyncCorePrinterDriverInstalled failed");
     589           0 :         torture_assert_hresult_ok(tctx, r.out.result,
     590             :                 "AsyncCorePrinterDriverInstalled failed");
     591           0 :         torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, true,
     592             :                                 "xps core driver not installed?");
     593             : 
     594           0 :         r.in.dwlDriverVersion = 1234;
     595             : 
     596           0 :         torture_assert_ntstatus_ok(tctx,
     597             :                 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
     598             :                 "AsyncCorePrinterDriverInstalled failed");
     599           0 :         torture_assert_hresult_ok(tctx, r.out.result,
     600             :                 "AsyncCorePrinterDriverInstalled failed");
     601           0 :         torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, true,
     602             :                                 "xps core driver not installed?");
     603             : 
     604           0 :         r.in.ftDriverDate = unix_timespec_to_nt_time(timespec_current());
     605             : 
     606           0 :         torture_assert_ntstatus_ok(tctx,
     607             :                 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
     608             :                 "AsyncCorePrinterDriverInstalled failed");
     609           0 :         torture_assert_hresult_ok(tctx, r.out.result,
     610             :                 "AsyncCorePrinterDriverInstalled failed");
     611           0 :         torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
     612             :                                 "driver too old ?");
     613             : 
     614           0 :         r.in.dwlDriverVersion = 0;
     615             : 
     616           0 :         torture_assert_ntstatus_ok(tctx,
     617             :                 dcerpc_winspool_AsyncCorePrinterDriverInstalled_r(b, tctx, &r),
     618             :                 "AsyncCorePrinterDriverInstalled failed");
     619           0 :         torture_assert_hresult_ok(tctx, r.out.result,
     620             :                 "AsyncCorePrinterDriverInstalled failed");
     621           0 :         torture_assert_int_equal(tctx, *r.out.pbDriverInstalled, false,
     622             :                                 "unexpected driver installed");
     623             : 
     624           0 :         return true;
     625             : }
     626             : 
     627           0 : static bool test_get_core_printer_drivers_arch_guid(struct torture_context *tctx,
     628             :                                                     struct dcerpc_pipe *p,
     629             :                                                     const char *architecture,
     630             :                                                     const char *guid_str,
     631             :                                                     const char **package_id)
     632             : {
     633             :         struct winspool_AsyncGetCorePrinterDrivers r;
     634             :         DATA_BLOB blob;
     635             :         const char **s;
     636           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     637             : 
     638           0 :         s = talloc_zero_array(tctx, const char *, 2);
     639           0 :         s[0] = guid_str;
     640             : 
     641           0 :         torture_assert(tctx,
     642             :                 push_reg_multi_sz(tctx, &blob, s),
     643             :                 "push_reg_multi_sz failed");
     644             : 
     645           0 :         r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     646           0 :         r.in.pszEnvironment = architecture;
     647           0 :         r.in.cchCoreDrivers = blob.length/2;
     648           0 :         r.in.pszzCoreDriverDependencies = (uint16_t *)blob.data;
     649           0 :         r.in.cCorePrinterDrivers = 1;
     650           0 :         r.out.pCorePrinterDrivers = talloc_zero_array(tctx, struct spoolss_CorePrinterDriver, r.in.cCorePrinterDrivers);
     651             : 
     652           0 :         torture_assert_ntstatus_ok(tctx,
     653             :                 dcerpc_winspool_AsyncGetCorePrinterDrivers_r(b, tctx, &r),
     654             :                 "winspool_AsyncCorePrinterDrivers failed");
     655           0 :         torture_assert_hresult_ok(tctx, r.out.result,
     656             :                 "winspool_AsyncCorePrinterDrivers failed");
     657             : 
     658           0 :         if (package_id) {
     659           0 :                 *package_id = r.out.pCorePrinterDrivers[0].szPackageID;
     660             :         }
     661             : 
     662           0 :         return true;
     663             : }
     664             : 
     665           0 : static bool test_AsyncDeletePrintDriverPackage(struct torture_context *tctx,
     666             :                                                void *private_data)
     667             : {
     668           0 :         struct test_iremotewinspool_context *ctx =
     669           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     670             : 
     671           0 :         struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
     672           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     673             :         struct winspool_AsyncDeletePrinterDriverPackage r;
     674             : 
     675           0 :         const char *architectures[] = {
     676             : /*              SPOOLSS_ARCHITECTURE_NT_X86, */
     677             :                 SPOOLSS_ARCHITECTURE_x64
     678             :         };
     679             :         int i;
     680             : 
     681           0 :         for (i=0; i < ARRAY_SIZE(architectures); i++) {
     682             : 
     683             :                 const char *package_id;
     684             : 
     685           0 :                 torture_assert(tctx,
     686             :                         test_get_core_printer_drivers_arch_guid(tctx, p,
     687             :                                                                 architectures[i],
     688             :                                                                 SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV,
     689             :                                                                 &package_id),
     690             :                         "failed to get core printer driver");
     691             : 
     692           0 :                 r.in.pszServer = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     693           0 :                 r.in.pszEnvironment = "";
     694           0 :                 r.in.pszInfPath = "";
     695             : 
     696           0 :                 torture_comment(tctx, "Testing AsyncDeletePrinterDriverPackage(%s, %s, %s)\n",
     697             :                         r.in.pszServer, architectures[i], package_id);
     698             : 
     699           0 :                 torture_assert_ntstatus_ok(tctx,
     700             :                         dcerpc_winspool_AsyncDeletePrinterDriverPackage_r(b, tctx, &r),
     701             :                         "AsyncDeletePrinterDriverPackage failed");
     702           0 :                 torture_assert_werr_equal(tctx,
     703             :                         W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_NOT_FOUND,
     704             :                         "AsyncDeletePrinterDriverPackage failed");
     705             : 
     706           0 :                 r.in.pszInfPath = package_id;
     707             : 
     708           0 :                 torture_assert_ntstatus_ok(tctx,
     709             :                         dcerpc_winspool_AsyncDeletePrinterDriverPackage_r(b, tctx, &r),
     710             :                         "AsyncDeletePrinterDriverPackage failed");
     711           0 :                 torture_assert_werr_equal(tctx,
     712             :                         W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
     713             :                         "AsyncDeletePrinterDriverPackage failed");
     714             : 
     715           0 :                 r.in.pszEnvironment = architectures[i];
     716             : 
     717           0 :                 torture_assert_ntstatus_ok(tctx,
     718             :                         dcerpc_winspool_AsyncDeletePrinterDriverPackage_r(b, tctx, &r),
     719             :                         "AsyncDeletePrinterDriverPackage failed");
     720           0 :                 torture_assert_hresult_equal(tctx, r.out.result, HRES_E_ACCESSDENIED,
     721             :                         "AsyncDeletePrinterDriverPackage failed");
     722             :         }
     723             : 
     724           0 :         return true;
     725             : }
     726             : 
     727           0 : static bool test_AsyncGetPrinterDriverDirectory(struct torture_context *tctx,
     728             :                                                 void *private_data)
     729             : {
     730           0 :         struct test_iremotewinspool_context *ctx =
     731           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     732             : 
     733           0 :         struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
     734           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     735             :         struct winspool_AsyncGetPrinterDriverDirectory r;
     736             :         uint32_t pcbNeeded;
     737             :         DATA_BLOB blob;
     738             :         const char *s;
     739             : 
     740           0 :         r.in.pName = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     741           0 :         r.in.pEnvironment = ctx->environment;
     742           0 :         r.in.Level = 1;
     743           0 :         r.in.cbBuf = 0x200;
     744           0 :         r.in.pDriverDirectory = talloc_zero_array(tctx, uint8_t, r.in.cbBuf);
     745           0 :         r.out.pcbNeeded = &pcbNeeded;
     746           0 :         r.out.pDriverDirectory = r.in.pDriverDirectory;
     747             : 
     748           0 :         torture_comment(tctx, "Testing AsyncGetPrinterDriverDirectory(%s, %s)\n",
     749             :                 r.in.pName, r.in.pEnvironment);
     750             : 
     751           0 :         torture_assert_ntstatus_ok(tctx,
     752             :                 dcerpc_winspool_AsyncGetPrinterDriverDirectory_r(b, tctx, &r),
     753             :                 "AsyncGetPrinterDriverDirectory failed");
     754           0 :         torture_assert_werr_ok(tctx, r.out.result,
     755             :                 "AsyncGetPrinterDriverDirectory failed");
     756             : 
     757           0 :         blob = data_blob_const(r.out.pDriverDirectory, pcbNeeded);
     758             : 
     759           0 :         torture_assert(tctx,
     760             :                 pull_reg_sz(tctx, &blob, &s),
     761             :                 "failed to pull reg_sz");
     762             : 
     763           0 :         torture_comment(tctx, "got: %s\n", s);
     764             : 
     765           0 :         return true;
     766             : }
     767             : 
     768             : /*
     769             :  * Test if one can close a printserver handle that has been acquired via
     770             :  * winspool_AsyncOpenPrinter with a spoolss_ClosePrinter operation.
     771             :  */
     772             : 
     773           0 : static bool test_OpenPrinter(struct torture_context *tctx,
     774             :                              void *private_data)
     775             : {
     776           0 :         struct test_iremotewinspool_context *ctx =
     777           0 :                 talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
     778             : 
     779           0 :         struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
     780             :         const char *printer_name;
     781             :         struct policy_handle handle;
     782             :         struct dcerpc_pipe *s;
     783             :         struct dcerpc_binding *binding;
     784             :         struct spoolss_UserLevel1 client_info;
     785             :         struct spoolss_ClosePrinter r;
     786             : 
     787           0 :         torture_assert_ntstatus_ok(tctx,
     788             :                 torture_rpc_binding(tctx, &binding),
     789             :                 "failed to get binding");
     790             : 
     791           0 :         torture_assert_ntstatus_ok(tctx,
     792             :                 dcerpc_binding_set_transport(binding, NCACN_NP),
     793             :                 "failed to set ncacn_np transport");
     794             : 
     795           0 :         torture_assert_ntstatus_ok(tctx,
     796             :                 dcerpc_binding_set_object(binding, GUID_zero()),
     797             :                 "failed to set object uuid to zero");
     798             : 
     799           0 :         torture_assert_ntstatus_ok(tctx,
     800             :                 torture_rpc_connection_with_binding(tctx, binding, &s, &ndr_table_spoolss),
     801             :                 "failed to connect to spoolss");
     802             : 
     803           0 :         printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     804             : 
     805           0 :         client_info = test_get_client_info(tctx, WIN_7, 6, 1, "testclient_machine", "testclient_user");
     806             : 
     807           0 :         torture_assert(tctx,
     808             :                 test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
     809             :                 "failed to open printserver via winspool");
     810             : 
     811             : 
     812           0 :         r.in.handle = &handle;
     813           0 :         r.out.handle = &handle;
     814             : 
     815           0 :         torture_assert_ntstatus_equal(tctx,
     816             :                 dcerpc_spoolss_ClosePrinter_r(s->binding_handle, tctx, &r),
     817             :                 NT_STATUS_RPC_SS_CONTEXT_MISMATCH,
     818             :                 "ClosePrinter failed");
     819             : 
     820           0 :         talloc_free(s);
     821             : 
     822           0 :         return true;
     823             : }
     824             : 
     825        2355 : struct torture_suite *torture_rpc_iremotewinspool(TALLOC_CTX *mem_ctx)
     826             : {
     827        2355 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "iremotewinspool");
     828        2355 :         struct torture_tcase *tcase = torture_suite_add_tcase(suite, "printserver");
     829             : 
     830        2355 :         torture_tcase_set_fixture(tcase,
     831             :                                   torture_rpc_iremotewinspool_setup,
     832             :                                   torture_rpc_iremotewinspool_teardown);
     833             : 
     834        2355 :         torture_tcase_add_simple_test(tcase, "AsyncOpenPrinter", test_AsyncOpenPrinter);
     835        2355 :         torture_tcase_add_simple_test(tcase, "SyncRegisterForRemoteNotifications", test_SyncRegisterForRemoteNotifications);
     836        2355 :         torture_tcase_add_simple_test(tcase, "SyncUnRegisterForRemoteNotifications", test_SyncUnRegisterForRemoteNotifications);
     837        2355 :         torture_tcase_add_simple_test(tcase, "AsyncClosePrinter", test_AsyncClosePrinter);
     838        2355 :         torture_tcase_add_simple_test(tcase, "AsyncUploadPrinterDriverPackage", test_AsyncUploadPrinterDriverPackage);
     839        2355 :         torture_tcase_add_simple_test(tcase, "AsyncEnumPrinters", test_AsyncEnumPrinters);
     840        2355 :         torture_tcase_add_simple_test(tcase, "AsyncGetPrinterData", test_AsyncGetPrinterData);
     841        2355 :         torture_tcase_add_simple_test(tcase, "AsyncCorePrinterDriverInstalled", test_AsyncCorePrinterDriverInstalled);
     842        2355 :         torture_tcase_add_simple_test(tcase, "AsyncDeletePrintDriverPackage", test_AsyncDeletePrintDriverPackage);
     843        2355 :         torture_tcase_add_simple_test(tcase, "AsyncGetPrinterDriverDirectory", test_AsyncGetPrinterDriverDirectory);
     844        2355 :         torture_tcase_add_simple_test(tcase, "AsyncOpenPrinterValidateBuildNumber", test_AsyncOpenPrinterValidateBuildNumber);
     845             : 
     846        2355 :         tcase = torture_suite_add_tcase(suite, "handles");
     847             : 
     848        2355 :         torture_tcase_set_fixture(tcase,
     849             :                                   torture_rpc_iremotewinspool_setup,
     850             :                                   torture_rpc_iremotewinspool_teardown);
     851             : 
     852        2355 :         torture_tcase_add_simple_test(tcase, "OpenPrinter", test_OpenPrinter);
     853             : 
     854        2355 :         return suite;
     855             : }

Generated by: LCOV version 1.13