LCOV - code coverage report
Current view: top level - source4/torture/rpc - iremotewinspool.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 22 477 4.6 %
Date: 2024-04-21 15:09:00 Functions: 1 26 3.8 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    test suite for iremotewinspool rpc operations
       4             : 
       5             :    Copyright (C) Guenther Deschner 2013,2023
       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           0 :         const char *printer_name;
      34           0 :         struct spoolss_UserLevel1 client_info;
      35           0 :         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           0 :         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           0 :         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           0 :         const char *printer_name;
     110           0 :         struct spoolss_UserLevel1 client_info;
     111           0 :         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           0 :         const char *printer_name;
     136           0 :         struct spoolss_UserLevel1 client_info;
     137           0 :         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           0 :         const char *printer_name;
     165           0 :         struct spoolss_UserLevel1 client_info;
     166           0 :         struct policy_handle handle;
     167           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     168           0 :         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           0 :         struct winspool_AsyncOpenPrinter r;
     174           0 :         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           0 :         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           0 :         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           0 :         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           0 :         struct winspool_SyncRegisterForRemoteNotifications r;
     313           0 :         struct winspool_PrintPropertiesCollection NotifyFilter;
     314           0 :         struct winspool_PrintNamedProperty *c;
     315           0 :         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           0 :         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           0 :         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           0 :         struct winspool_AsyncEnumPrinters r;
     445           0 :         uint32_t levels[] = { 1, 2, /*3,*/ 4, 5 };
     446           0 :         int i;
     447             : 
     448           0 :         uint32_t needed;
     449           0 :         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           0 :         DATA_BLOB blob;
     491           0 :         const char *s;
     492           0 :         bool ok;
     493             : 
     494           0 :         uint32_t pType;
     495           0 :         uint32_t pcbNeeded;
     496           0 :         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           0 :         struct winspool_AsyncCorePrinterDriverInstalled r;
     534           0 :         int32_t pbDriverInstalled;
     535           0 :         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           0 :         struct winspool_AsyncGetCorePrinterDrivers r;
     634           0 :         DATA_BLOB blob;
     635           0 :         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           0 :         struct winspool_AsyncDeletePrinterDriverPackage r;
     674             : 
     675           0 :         const char *architectures[] = {
     676             : /*              SPOOLSS_ARCHITECTURE_NT_X86, */
     677             :                 SPOOLSS_ARCHITECTURE_x64
     678             :         };
     679           0 :         int i;
     680             : 
     681           0 :         for (i=0; i < ARRAY_SIZE(architectures); i++) {
     682             : 
     683           0 :                 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           0 :         struct winspool_AsyncGetPrinterDriverDirectory r;
     736           0 :         uint32_t pcbNeeded;
     737           0 :         DATA_BLOB blob;
     738           0 :         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           0 :         const char *printer_name;
     781           0 :         struct policy_handle handle;
     782           0 :         struct dcerpc_pipe *s;
     783           0 :         struct dcerpc_binding *binding;
     784           0 :         struct spoolss_UserLevel1 client_info;
     785           0 :         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           0 : static bool test_object_one_uuid(struct torture_context *tctx,
     826             :                                  const struct GUID *object_uuid,
     827             :                                  NTSTATUS expected_status,
     828             :                                  uint32_t expected_fault_code)
     829             : {
     830           0 :         const char *printer_name;
     831           0 :         struct spoolss_UserLevel1 client_info;
     832           0 :         struct dcerpc_binding *binding;
     833           0 :         struct dcerpc_pipe *p;
     834           0 :         struct policy_handle server_handle;
     835             : 
     836           0 :         torture_comment(tctx, "Testing with object_uuid: %s\n",
     837             :                         GUID_string(tctx, object_uuid));
     838             : 
     839           0 :         torture_assert_ntstatus_ok(tctx,
     840             :                 torture_rpc_binding(tctx, &binding),
     841             :                 "failed to retrieve torture binding");
     842             : 
     843           0 :         if (object_uuid) {
     844           0 :                 torture_assert_ntstatus_ok(tctx,
     845             :                         dcerpc_binding_set_object(binding, *object_uuid),
     846             :                         "failed to set object_uuid");
     847             :         }
     848             : 
     849           0 :         torture_assert_ntstatus_ok(tctx,
     850             :                 torture_rpc_connection_with_binding(tctx, binding, &p,
     851             :                         &ndr_table_iremotewinspool),
     852             :                 "Error connecting to server");
     853             : 
     854           0 :         printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     855           0 :         torture_assert(tctx, printer_name, "out of memory");
     856             : 
     857           0 :         client_info = test_get_client_info(tctx,
     858             :                 WIN_7, 6, 1, "testclient_machine", "testclient_user");
     859             : 
     860           0 :         torture_assert(tctx,
     861             :                 test_AsyncOpenPrinter_byprinter_expect(tctx, NULL,
     862             :                                                        p,
     863             :                                                        printer_name,
     864             :                                                        SEC_FLAG_MAXIMUM_ALLOWED,
     865             :                                                        client_info,
     866             :                                                        expected_status,
     867             :                                                        WERR_OK,
     868             :                                                        expected_fault_code,
     869             :                                                        &server_handle),
     870             :                                                 "failed to open printserver");
     871           0 :         if (NT_STATUS_IS_OK(expected_status)) {
     872           0 :                 test_AsyncClosePrinter_byhandle(tctx, NULL, p, &server_handle);
     873             :         }
     874             : 
     875           0 :         talloc_free(p);
     876             : 
     877           0 :         return true;
     878             : }
     879             : 
     880           0 : static bool test_object_uuid(struct torture_context *tctx,
     881             :                              void *private_data)
     882             : {
     883           0 :         struct GUID object_uuid;
     884             : 
     885           0 :         torture_assert(tctx,
     886             :                 test_object_one_uuid(tctx, NULL,
     887             :                         NT_STATUS_RPC_NOT_RPC_ERROR,
     888             :                         DCERPC_NCA_S_UNSUPPORTED_TYPE),
     889             :                 "failed to test NULL object uuid");
     890             : 
     891           0 :         object_uuid = GUID_zero();
     892           0 :         torture_assert(tctx,
     893             :                 test_object_one_uuid(tctx, &object_uuid,
     894             :                         NT_STATUS_RPC_NOT_RPC_ERROR,
     895             :                         DCERPC_NCA_S_UNSUPPORTED_TYPE),
     896             :                 "failed to test zeroed object uuid");
     897             : 
     898           0 :         object_uuid = GUID_random();
     899           0 :         torture_assert(tctx,
     900             :                 test_object_one_uuid(tctx, &object_uuid,
     901             :                         NT_STATUS_RPC_NOT_RPC_ERROR,
     902             :                         DCERPC_NCA_S_UNSUPPORTED_TYPE),
     903             :                 "failed to test random object uuid");
     904             : 
     905           0 :         GUID_from_string(IREMOTEWINSPOOL_OBJECT_GUID, &object_uuid);
     906           0 :         torture_assert(tctx,
     907             :                 test_object_one_uuid(tctx, &object_uuid,
     908             :                         NT_STATUS_OK,
     909             :                         0),
     910             :                 "failed to test IREMOTEWINSPOOL_OBJECT_GUID");
     911             : 
     912           0 :         torture_assert(tctx,
     913             :                 test_object_one_uuid(tctx, &ndr_table_spoolss.syntax_id.uuid,
     914             :                         NT_STATUS_RPC_NOT_RPC_ERROR,
     915             :                         DCERPC_NCA_S_UNSUPPORTED_TYPE),
     916             :                 "failed to test spoolss interface uuid");
     917             : 
     918           0 :         torture_assert(tctx,
     919             :                 test_object_one_uuid(tctx, &ndr_table_iremotewinspool.syntax_id.uuid,
     920             :                         NT_STATUS_RPC_NOT_RPC_ERROR,
     921             :                         DCERPC_NCA_S_UNSUPPORTED_TYPE),
     922             :                 "failed to test iremotewinspool interface uuid");
     923             : 
     924           0 :         return true;
     925             : }
     926             : 
     927           0 : static bool test_setup_binding_handle(struct torture_context *tctx,
     928             :                                       struct GUID object_uuid,
     929             :                                       enum dcerpc_transport_t transport,
     930             :                                       const struct ndr_interface_table *table,
     931             :                                       struct dcerpc_pipe **p)
     932             : {
     933           0 :         struct dcerpc_binding *binding;
     934             : 
     935           0 :         torture_assert_ntstatus_ok(tctx,
     936             :                 torture_rpc_binding(tctx, &binding),
     937             :                 "failed to retrieve torture binding");
     938             : 
     939           0 :         torture_assert_ntstatus_ok(tctx,
     940             :                 dcerpc_binding_set_object(binding, object_uuid),
     941             :                 "failed to set object_uuid");
     942             : 
     943           0 :         torture_assert_ntstatus_ok(tctx,
     944             :                 dcerpc_binding_set_transport(binding, transport),
     945             :                 "failed to set transport");
     946             : 
     947           0 :         torture_assert_ntstatus_ok(tctx,
     948             :                 torture_rpc_connection_with_binding(tctx, binding, p, table),
     949             :                 "Error connecting to server");
     950             : 
     951           0 :         return true;
     952             : }
     953             : 
     954           0 : static enum ndr_err_code ndr_push_inout_blob(DATA_BLOB *blob,
     955             :                                              TALLOC_CTX *mem_ctx,
     956             :                                              ndr_flags_type flags,
     957             :                                              const void *p,
     958             :                                              ndr_push_flags_fn_t fn)
     959             : {
     960           0 :         struct ndr_push *ndr;
     961           0 :         ndr = ndr_push_init_ctx(mem_ctx);
     962           0 :         NDR_ERR_HAVE_NO_MEMORY(ndr);
     963             : 
     964           0 :         NDR_CHECK_FREE(fn(ndr, flags, p));
     965             : 
     966           0 :         *blob = ndr_push_blob(ndr);
     967           0 :         talloc_steal(mem_ctx, blob->data);
     968           0 :         talloc_free(ndr);
     969             : 
     970           0 :         return NDR_ERR_SUCCESS;
     971             : }
     972             : 
     973           0 : static bool test_compare_spoolss(struct torture_context *tctx,
     974             :                                  void *private_data)
     975             : {
     976           0 :         DATA_BLOB reply_iremotewinspool, reply_spoolss, request_spoolss;
     977           0 :         struct dcerpc_pipe *iremotewinspool_pipe, *spoolss_pipe;
     978           0 :         struct GUID object_uuid;
     979           0 :         uint32_t out_flags;
     980           0 :         NTSTATUS status;
     981           0 :         struct spoolss_EnumPrinters r;
     982           0 :         DATA_BLOB blob;
     983             : 
     984             :         /* setup two dcerpc pipes */
     985             : 
     986           0 :         torture_assert_ntstatus_ok(tctx,
     987             :                 GUID_from_string(IREMOTEWINSPOOL_OBJECT_GUID, &object_uuid),
     988             :                 "failed to parse GUID");
     989             : 
     990           0 :         torture_assert(tctx,
     991             :                 test_setup_binding_handle(tctx, object_uuid, NCACN_IP_TCP,
     992             :                         &ndr_table_iremotewinspool, &iremotewinspool_pipe),
     993             :                 "failed to setup binding handle");
     994             : 
     995           0 :         torture_assert(tctx,
     996             :                 test_setup_binding_handle(tctx, GUID_zero(), NCACN_NP,
     997             :                         &ndr_table_spoolss, &spoolss_pipe),
     998             :                 "failed to setup binding handle");
     999             : 
    1000             : 
    1001             :         /* create a spoolss enumprinters request */
    1002             : 
    1003           0 :         ZERO_STRUCT(r);
    1004             : 
    1005           0 :         blob = data_blob_talloc_zero(tctx, 0x1000);
    1006             : 
    1007           0 :         r.in.flags      = PRINTER_ENUM_LOCAL;
    1008           0 :         r.in.server     = talloc_asprintf(tctx, "\\\\%s",
    1009             :                                 dcerpc_server_name(spoolss_pipe));
    1010           0 :         r.in.level      = 1;
    1011           0 :         r.in.buffer     = &blob;
    1012           0 :         r.in.offered    = blob.length;
    1013             : 
    1014           0 :         torture_assert_ndr_success(tctx,
    1015             :                 ndr_push_inout_blob(&request_spoolss, tctx, NDR_IN | NDR_SET_VALUES, &r,
    1016             :                         (ndr_push_flags_fn_t)ndr_push_spoolss_EnumPrinters),
    1017             :                 "failed to push EnumPrinters request");
    1018             : 
    1019             :         /* send same request to both endpoints */
    1020             : 
    1021           0 :         status = dcerpc_binding_handle_raw_call(iremotewinspool_pipe->binding_handle,
    1022             :                                                 NULL,
    1023             :                                                 NDR_WINSPOOL_ASYNCENUMPRINTERS,
    1024             :                                                 0, /* in_flags */
    1025           0 :                                                 request_spoolss.data,
    1026             :                                                 request_spoolss.length,
    1027             :                                                 tctx,
    1028             :                                                 &reply_iremotewinspool.data,
    1029             :                                                 &reply_iremotewinspool.length,
    1030             :                                                 &out_flags);
    1031           0 :         torture_assert_ntstatus_ok(tctx, status, "dcerpc_binding_handle_raw_call failed");
    1032             : 
    1033           0 :         status = dcerpc_binding_handle_raw_call(spoolss_pipe->binding_handle,
    1034             :                                                 NULL,
    1035             :                                                 NDR_SPOOLSS_ENUMPRINTERS,
    1036             :                                                 0, /* in_flags */
    1037           0 :                                                 request_spoolss.data,
    1038             :                                                 request_spoolss.length,
    1039             :                                                 tctx,
    1040             :                                                 &reply_spoolss.data,
    1041             :                                                 &reply_spoolss.length,
    1042             :                                                 &out_flags);
    1043           0 :         torture_assert_ntstatus_ok(tctx, status, "dcerpc_binding_handle_raw_call failed");
    1044             : 
    1045           0 :         torture_assert_data_blob_equal(tctx,
    1046             :                 reply_iremotewinspool,
    1047             :                 reply_spoolss,
    1048             :                 "unexpected difference in replies from spoolss and iremotewinspool servers");
    1049             : 
    1050           0 :         talloc_free(iremotewinspool_pipe);
    1051           0 :         talloc_free(spoolss_pipe);
    1052             : 
    1053           0 :         return true;
    1054             : }
    1055             : 
    1056        2354 : struct torture_suite *torture_rpc_iremotewinspool(TALLOC_CTX *mem_ctx)
    1057             : {
    1058        2354 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "iremotewinspool");
    1059        2354 :         struct torture_tcase *tcase = torture_suite_add_tcase(suite, "printserver");
    1060             : 
    1061        2354 :         torture_tcase_set_fixture(tcase,
    1062             :                                   torture_rpc_iremotewinspool_setup,
    1063             :                                   torture_rpc_iremotewinspool_teardown);
    1064             : 
    1065        2354 :         torture_tcase_add_simple_test(tcase, "AsyncOpenPrinter", test_AsyncOpenPrinter);
    1066        2354 :         torture_tcase_add_simple_test(tcase, "SyncRegisterForRemoteNotifications", test_SyncRegisterForRemoteNotifications);
    1067        2354 :         torture_tcase_add_simple_test(tcase, "SyncUnRegisterForRemoteNotifications", test_SyncUnRegisterForRemoteNotifications);
    1068        2354 :         torture_tcase_add_simple_test(tcase, "AsyncClosePrinter", test_AsyncClosePrinter);
    1069        2354 :         torture_tcase_add_simple_test(tcase, "AsyncUploadPrinterDriverPackage", test_AsyncUploadPrinterDriverPackage);
    1070        2354 :         torture_tcase_add_simple_test(tcase, "AsyncEnumPrinters", test_AsyncEnumPrinters);
    1071        2354 :         torture_tcase_add_simple_test(tcase, "AsyncGetPrinterData", test_AsyncGetPrinterData);
    1072        2354 :         torture_tcase_add_simple_test(tcase, "AsyncCorePrinterDriverInstalled", test_AsyncCorePrinterDriverInstalled);
    1073        2354 :         torture_tcase_add_simple_test(tcase, "AsyncDeletePrintDriverPackage", test_AsyncDeletePrintDriverPackage);
    1074        2354 :         torture_tcase_add_simple_test(tcase, "AsyncGetPrinterDriverDirectory", test_AsyncGetPrinterDriverDirectory);
    1075        2354 :         torture_tcase_add_simple_test(tcase, "AsyncOpenPrinterValidateBuildNumber", test_AsyncOpenPrinterValidateBuildNumber);
    1076             : 
    1077        2354 :         tcase = torture_suite_add_tcase(suite, "handles");
    1078             : 
    1079        2354 :         torture_tcase_set_fixture(tcase,
    1080             :                                   torture_rpc_iremotewinspool_setup,
    1081             :                                   torture_rpc_iremotewinspool_teardown);
    1082             : 
    1083        2354 :         torture_tcase_add_simple_test(tcase, "OpenPrinter", test_OpenPrinter);
    1084             : 
    1085        2354 :         tcase = torture_suite_add_tcase(suite, "protocol");
    1086        2354 :         torture_tcase_add_simple_test(tcase, "object_uuid", test_object_uuid);
    1087        2354 :         torture_tcase_add_simple_test(tcase, "compare_spoolss", test_compare_spoolss);
    1088             : 
    1089        2354 :         return suite;
    1090             : }

Generated by: LCOV version 1.14