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