python:tests: Store keys as bytes rather than as lists of ints
[samba.git] / source4 / torture / rpc / iremotewinspool_common.c
1 #include "includes.h"
2 #include "torture/torture.h"
3 #include "librpc/gen_ndr/ndr_winspool.h"
4 #include "librpc/gen_ndr/ndr_winspool_c.h"
5 #include "librpc/gen_ndr/ndr_spoolss_c.h"
6 #include "torture/rpc/torture_rpc.h"
7 #include "libcli/registry/util_reg.h"
8 #include "torture/rpc/iremotewinspool_common.h"
9 #include "lib/printer_driver/printer_driver.h"
10
11 void init_winreg_String(struct winreg_String *name, const char *s)
12 {
13         name->name = s;
14         if (s != NULL) {
15                 name->name_len = 2 * (strlen_m(s) + 1);
16                 name->name_size = name->name_len;
17         } else {
18                 name->name_len = 0;
19                 name->name_size = 0;
20         }
21 }
22
23 struct spoolss_UserLevel1 test_get_client_info(struct torture_context *tctx,
24                                                       enum client_os_version os,
25                                                       enum spoolss_MajorVersion major_number,
26                                                       enum spoolss_MinorVersion minor_number,
27                                                       const char *machine,
28                                                       const char *user)
29 {
30         struct spoolss_UserLevel1 level1;
31
32         level1.size     = 28;
33         level1.client   = talloc_asprintf(tctx, "\\\\%s", machine);
34         level1.user     = user;
35         level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
36         level1.major    = major_number;
37         level1.minor    = minor_number;
38
39         if (os == WIN_SERVER_2016 || os == WIN_10) {
40                 level1.build = 10586;
41         } else if (os == WIN_SERVER_2012 || os == WIN_8) {
42                 level1.build = 9200;
43         } else if (os == WIN_SERVER_2008R2 || os == WIN_7) {
44                 level1.build = 7007;
45         } else if (os == WIN_SERVER_2008 || os == WIN_VISTA) {
46                 level1.build = 6000;
47         } else if (os == WIN_2000) {
48                 level1.build = 1382;
49         }
50
51         return level1;
52 }
53
54 bool test_AsyncOpenPrinter_byprinter(struct torture_context *tctx,
55                                             struct test_iremotewinspool_context *ctx,
56                                             struct dcerpc_pipe *p,
57                                             const char *printer_name,
58                                             struct spoolss_UserLevel1 cinfo,
59                                             struct policy_handle *handle)
60 {
61         struct dcerpc_binding_handle *b = p->binding_handle;
62         struct spoolss_DevmodeContainer devmode_ctr;
63         struct spoolss_UserLevelCtr client_info_ctr;
64         uint32_t access_mask = SERVER_ALL_ACCESS;
65         struct winspool_AsyncOpenPrinter r;
66         NTSTATUS status;
67         bool ok = true;
68
69         ZERO_STRUCT(devmode_ctr);
70
71         client_info_ctr.level = 1;
72         client_info_ctr.user_info.level1 = &cinfo;
73
74         r.in.pPrinterName       = printer_name;
75         r.in.pDatatype          = NULL;
76         r.in.pDevModeContainer  = &devmode_ctr;
77         r.in.AccessRequired     = access_mask;
78         r.in.pClientInfo        = &client_info_ctr;
79         r.out.pHandle           = handle;
80
81         status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
82         torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncOpenPrinter failed");
83
84         torture_assert_werr_ok(tctx, r.out.result,
85                 "AsyncOpenPrinter failed");
86
87 done:
88
89         return ok;
90 }
91
92 bool test_get_environment(struct torture_context *tctx,
93                                  struct dcerpc_binding_handle *b,
94                                  struct policy_handle *handle,
95                                  const char **architecture)
96 {
97         DATA_BLOB blob;
98         enum winreg_Type type;
99         uint8_t *data;
100         uint32_t needed;
101         bool ok;
102
103         ok = test_AsyncGetPrinterData_args(tctx, b, handle, "Architecture", &type, &data, &needed);
104         torture_assert(tctx, ok, "failed to get Architecture");
105
106         torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");
107
108         blob = data_blob_const(data, needed);
109
110         torture_assert(tctx,
111                 pull_reg_sz(tctx, &blob, architecture),
112                 "failed to pull environment");
113
114         return true;
115 }
116
117 bool test_AsyncClosePrinter_byhandle(struct torture_context *tctx,
118                                             struct test_iremotewinspool_context *ctx,
119                                             struct dcerpc_pipe *p,
120                                             struct policy_handle *handle)
121 {
122         struct dcerpc_binding_handle *b = p->binding_handle;
123
124         struct winspool_AsyncClosePrinter r;
125         NTSTATUS status;
126         bool ok = true;
127
128         r.in.phPrinter = handle;
129         r.out.phPrinter = handle;
130
131         status = dcerpc_winspool_AsyncClosePrinter_r(b, tctx, &r);
132         torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncClosePrinter failed");
133
134         torture_assert_werr_ok(tctx, r.out.result,
135                 "AsyncClosePrinter failed");
136
137 done:
138
139         return ok;
140 }
141
142 static bool test_AsyncGetPrinterData_checktype(struct torture_context *tctx,
143                                                struct dcerpc_binding_handle *b,
144                                                struct policy_handle *handle,
145                                                const char *value_name,
146                                                enum winreg_Type *expected_type,
147                                                enum winreg_Type *type_p,
148                                                uint8_t **data_p,
149                                                uint32_t *needed_p)
150 {
151         struct winspool_AsyncGetPrinterData r;
152         enum winreg_Type type;
153         uint32_t needed;
154         NTSTATUS status;
155         bool ok = true;
156
157         r.in.hPrinter = *handle;
158         r.in.pValueName = value_name;
159         r.in.nSize = 0;
160         r.out.pType = &type;
161         r.out.pData = talloc_zero_array(tctx, uint8_t, r.in.nSize);
162         r.out.pcbNeeded = &needed;
163
164         torture_comment(tctx, "Testing AsyncGetPrinterData(%s)\n",
165                 r.in.pValueName);
166
167         status = dcerpc_winspool_AsyncGetPrinterData_r(b, tctx, &r);
168         torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncGetPrinterData failed");
169
170         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
171                 if (expected_type) {
172                         torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
173                 }
174                 r.in.nSize = needed;
175                 r.out.pData = talloc_zero_array(tctx, uint8_t, r.in.nSize);
176
177                 status = dcerpc_winspool_AsyncGetPrinterData_r(b, tctx, &r);
178                 torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncGetPrinterData failed");
179         }
180
181         torture_assert_werr_ok(tctx, r.out.result,
182                 "AsyncGetPrinterData failed");
183
184         if (type_p) {
185                 *type_p = type;
186         }
187
188         if (data_p) {
189                 *data_p = r.out.pData;
190         }
191
192         if (needed_p) {
193                 *needed_p = needed;
194         }
195
196 done:
197
198         return ok;
199 }
200
201 bool test_AsyncGetPrinterData_args(struct torture_context *tctx,
202                                           struct dcerpc_binding_handle *b,
203                                           struct policy_handle *handle,
204                                           const char *value_name,
205                                           enum winreg_Type *type_p,
206                                           uint8_t **data_p,
207                                           uint32_t *needed_p)
208 {
209         return test_AsyncGetPrinterData_checktype(tctx, b, handle,
210                                                   value_name,
211                                                   NULL,
212                                                   type_p, data_p, needed_p);
213 }
214
215 /* Parse a driver inf file */
216 bool parse_inf_driver(struct torture_context *tctx,
217                       const char *driver_name,
218                       const char *abs_inf_path,
219                       const char *driver_arch,
220                       const char *core_driver_inf,
221                       struct spoolss_AddDriverInfo8 **_parsed_dinfo)
222 {
223         struct spoolss_AddDriverInfo8 *drv_info;
224         const char *source_disk_name = NULL;
225         NTSTATUS status;
226         bool ok = true;
227
228         drv_info = talloc_zero(tctx, struct spoolss_AddDriverInfo8);
229         torture_assert_not_null_goto(tctx, drv_info, ok, done, "Cannot allocate memory");
230
231         status = driver_inf_parse(tctx,
232                                   core_driver_inf,
233                                   abs_inf_path,
234                                   driver_arch,
235                                   driver_name,
236                                   drv_info,
237                                   &source_disk_name);
238
239         if (NT_STATUS_EQUAL(status, NT_STATUS_DRIVER_INTERNAL_ERROR)) {
240                 torture_comment(tctx, "--- Verify the correct torture option:driver_name is provided\n");
241         }
242         torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "Failed to parse driver inf\n");
243
244         *_parsed_dinfo = drv_info;
245 done:
246         return ok;
247 }