s3:smbd: fix NULL dereference in case of readlink failure
[Samba.git] / source4 / torture / rpc / iremotewinspool_common.c
blobd4dd19ac3edb51cfc05979241abac30bd00f47c3
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"
11 void init_winreg_String(struct winreg_String *name, const char *s)
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;
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)
30 struct spoolss_UserLevel1 level1;
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;
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;
51 return level1;
54 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)
65 struct dcerpc_binding_handle *b = p->binding_handle;
66 struct spoolss_DevmodeContainer devmode_ctr;
67 struct spoolss_UserLevelCtr client_info_ctr;
68 struct winspool_AsyncOpenPrinter r;
69 NTSTATUS status;
70 bool ok = true;
72 ZERO_STRUCT(r);
73 ZERO_STRUCT(devmode_ctr);
75 client_info_ctr.level = 1;
76 client_info_ctr.user_info.level1 = &cinfo;
78 r.in.pPrinterName = printer_name;
79 r.in.pDatatype = NULL;
80 r.in.pDevModeContainer = &devmode_ctr;
81 r.in.AccessRequired = access_mask;
82 r.in.pClientInfo = &client_info_ctr;
83 r.out.pHandle = handle;
85 status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
86 torture_assert_ntstatus_equal(tctx, status, expected_status, "AsyncOpenPrinter failed");
87 torture_assert_werr_equal(tctx, r.out.result, expected_result,
88 "AsyncOpenPrinter failed");
89 torture_assert_u32_equal(tctx, p->last_fault_code, expected_fault_code,
90 "unexpected DCERPC fault code");
92 return ok;
95 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)
102 return test_AsyncOpenPrinter_byprinter_expect(tctx,
103 ctx,
105 printer_name,
106 SERVER_ALL_ACCESS,
107 cinfo,
108 NT_STATUS_OK,
109 WERR_OK,
111 handle);
114 bool test_get_environment(struct torture_context *tctx,
115 struct dcerpc_binding_handle *b,
116 struct policy_handle *handle,
117 const char **architecture)
119 DATA_BLOB blob;
120 enum winreg_Type type;
121 uint8_t *data;
122 uint32_t needed;
123 bool ok;
125 ok = test_AsyncGetPrinterData_args(tctx, b, handle, "Architecture", &type, &data, &needed);
126 torture_assert(tctx, ok, "failed to get Architecture");
128 torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");
130 blob = data_blob_const(data, needed);
132 torture_assert(tctx,
133 pull_reg_sz(tctx, &blob, architecture),
134 "failed to pull environment");
136 return true;
139 bool test_AsyncClosePrinter_byhandle(struct torture_context *tctx,
140 struct test_iremotewinspool_context *ctx,
141 struct dcerpc_pipe *p,
142 struct policy_handle *handle)
144 struct dcerpc_binding_handle *b = p->binding_handle;
146 struct winspool_AsyncClosePrinter r;
147 NTSTATUS status;
148 bool ok = true;
150 r.in.phPrinter = handle;
151 r.out.phPrinter = handle;
153 status = dcerpc_winspool_AsyncClosePrinter_r(b, tctx, &r);
154 torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncClosePrinter failed");
156 torture_assert_werr_ok(tctx, r.out.result,
157 "AsyncClosePrinter failed");
159 done:
161 return ok;
164 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)
173 struct winspool_AsyncGetPrinterData r;
174 enum winreg_Type type;
175 uint32_t needed;
176 NTSTATUS status;
177 bool ok = true;
179 r.in.hPrinter = *handle;
180 r.in.pValueName = value_name;
181 r.in.nSize = 0;
182 r.out.pType = &type;
183 r.out.pData = talloc_zero_array(tctx, uint8_t, r.in.nSize);
184 r.out.pcbNeeded = &needed;
186 torture_comment(tctx, "Testing AsyncGetPrinterData(%s)\n",
187 r.in.pValueName);
189 status = dcerpc_winspool_AsyncGetPrinterData_r(b, tctx, &r);
190 torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncGetPrinterData failed");
192 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
193 if (expected_type) {
194 torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
196 r.in.nSize = needed;
197 r.out.pData = talloc_zero_array(tctx, uint8_t, r.in.nSize);
199 status = dcerpc_winspool_AsyncGetPrinterData_r(b, tctx, &r);
200 torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "AsyncGetPrinterData failed");
203 torture_assert_werr_ok(tctx, r.out.result,
204 "AsyncGetPrinterData failed");
206 if (type_p) {
207 *type_p = type;
210 if (data_p) {
211 *data_p = r.out.pData;
214 if (needed_p) {
215 *needed_p = needed;
218 done:
220 return ok;
223 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)
231 return test_AsyncGetPrinterData_checktype(tctx, b, handle,
232 value_name,
233 NULL,
234 type_p, data_p, needed_p);
237 /* Parse a driver inf file */
238 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)
245 struct spoolss_AddDriverInfo8 *drv_info;
246 const char *source_disk_name = NULL;
247 NTSTATUS status;
248 bool ok = true;
250 drv_info = talloc_zero(tctx, struct spoolss_AddDriverInfo8);
251 torture_assert_not_null_goto(tctx, drv_info, ok, done, "Cannot allocate memory");
253 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);
261 if (NT_STATUS_EQUAL(status, NT_STATUS_DRIVER_INTERNAL_ERROR)) {
262 torture_comment(tctx, "--- Verify the correct torture option:driver_name is provided\n");
264 torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "Failed to parse driver inf\n");
266 *_parsed_dinfo = drv_info;
267 done:
268 return ok;