1 | /*
|
---|
2 | * Unix SMB/CIFS implementation.
|
---|
3 | * RPC Pipe client / server routines
|
---|
4 | * Copyright (C) Guenther Deschner 2009.
|
---|
5 | *
|
---|
6 | * This program is free software; you can redistribute it and/or modify
|
---|
7 | * it under the terms of the GNU General Public License as published by
|
---|
8 | * the Free Software Foundation; either version 3 of the License, or
|
---|
9 | * (at your option) any later version.
|
---|
10 | *
|
---|
11 | * This program is distributed in the hope that it will be useful,
|
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | * GNU General Public License for more details.
|
---|
15 | *
|
---|
16 | * You should have received a copy of the GNU General Public License
|
---|
17 | * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
---|
18 | */
|
---|
19 |
|
---|
20 | #include "includes.h"
|
---|
21 | #include "../librpc/gen_ndr/ndr_spoolss.h"
|
---|
22 | #include "rpc_client/init_spoolss.h"
|
---|
23 | #include "../libcli/security/security.h"
|
---|
24 | #include "secrets.h"
|
---|
25 | #include "passdb/machine_sid.h"
|
---|
26 |
|
---|
27 | /*******************************************************************
|
---|
28 | ********************************************************************/
|
---|
29 |
|
---|
30 | bool init_systemtime(struct spoolss_Time *r,
|
---|
31 | struct tm *unixtime)
|
---|
32 | {
|
---|
33 | if (!r || !unixtime) {
|
---|
34 | return false;
|
---|
35 | }
|
---|
36 |
|
---|
37 | r->year = unixtime->tm_year+1900;
|
---|
38 | r->month = unixtime->tm_mon+1;
|
---|
39 | r->day_of_week = unixtime->tm_wday;
|
---|
40 | r->day = unixtime->tm_mday;
|
---|
41 | r->hour = unixtime->tm_hour;
|
---|
42 | r->minute = unixtime->tm_min;
|
---|
43 | r->second = unixtime->tm_sec;
|
---|
44 | r->millisecond = 0;
|
---|
45 |
|
---|
46 | return true;
|
---|
47 | }
|
---|
48 |
|
---|
49 | time_t spoolss_Time_to_time_t(const struct spoolss_Time *r)
|
---|
50 | {
|
---|
51 | struct tm unixtime;
|
---|
52 |
|
---|
53 | unixtime.tm_year = r->year - 1900;
|
---|
54 | unixtime.tm_mon = r->month - 1;
|
---|
55 | unixtime.tm_wday = r->day_of_week;
|
---|
56 | unixtime.tm_mday = r->day;
|
---|
57 | unixtime.tm_hour = r->hour;
|
---|
58 | unixtime.tm_min = r->minute;
|
---|
59 | unixtime.tm_sec = r->second;
|
---|
60 |
|
---|
61 | return mktime(&unixtime);
|
---|
62 | }
|
---|
63 |
|
---|
64 | /*******************************************************************
|
---|
65 | ********************************************************************/
|
---|
66 |
|
---|
67 | WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx,
|
---|
68 | const DATA_BLOB *blob,
|
---|
69 | union spoolss_PrinterData *data,
|
---|
70 | enum winreg_Type type)
|
---|
71 | {
|
---|
72 | enum ndr_err_code ndr_err;
|
---|
73 | ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type,
|
---|
74 | (ndr_pull_flags_fn_t)ndr_pull_spoolss_PrinterData);
|
---|
75 | if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
---|
76 | return WERR_GENERAL_FAILURE;
|
---|
77 | }
|
---|
78 | return WERR_OK;
|
---|
79 | }
|
---|
80 |
|
---|
81 | /*******************************************************************
|
---|
82 | ********************************************************************/
|
---|
83 |
|
---|
84 | WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
|
---|
85 | enum winreg_Type type,
|
---|
86 | union spoolss_PrinterData *data)
|
---|
87 | {
|
---|
88 | enum ndr_err_code ndr_err;
|
---|
89 | ndr_err = ndr_push_union_blob(blob, mem_ctx, data, type,
|
---|
90 | (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData);
|
---|
91 | if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
---|
92 | return WERR_GENERAL_FAILURE;
|
---|
93 | }
|
---|
94 | return WERR_OK;
|
---|
95 | }
|
---|
96 |
|
---|
97 | /*******************************************************************
|
---|
98 | ********************************************************************/
|
---|
99 |
|
---|
100 | void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 *i,
|
---|
101 | struct spoolss_SetPrinterInfo2 *s)
|
---|
102 | {
|
---|
103 | s->servername = i->servername;
|
---|
104 | s->printername = i->printername;
|
---|
105 | s->sharename = i->sharename;
|
---|
106 | s->portname = i->portname;
|
---|
107 | s->drivername = i->drivername;
|
---|
108 | s->comment = i->comment;
|
---|
109 | s->location = i->location;
|
---|
110 | s->devmode_ptr = 0;
|
---|
111 | s->sepfile = i->sepfile;
|
---|
112 | s->printprocessor = i->printprocessor;
|
---|
113 | s->datatype = i->datatype;
|
---|
114 | s->parameters = i->parameters;
|
---|
115 | s->secdesc_ptr = 0;
|
---|
116 | s->attributes = i->attributes;
|
---|
117 | s->priority = i->priority;
|
---|
118 | s->defaultpriority = i->defaultpriority;
|
---|
119 | s->starttime = i->starttime;
|
---|
120 | s->untiltime = i->untiltime;
|
---|
121 | s->status = i->status;
|
---|
122 | s->cjobs = i->cjobs;
|
---|
123 | s->averageppm = i->averageppm;
|
---|
124 | }
|
---|
125 |
|
---|
126 | /****************************************************************************
|
---|
127 | ****************************************************************************/
|
---|
128 |
|
---|
129 | bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
|
---|
130 | struct spoolss_DriverInfo8 *_info8)
|
---|
131 | {
|
---|
132 | struct spoolss_DriverInfo8 info8;
|
---|
133 |
|
---|
134 | ZERO_STRUCT(info8);
|
---|
135 |
|
---|
136 | switch (r->level) {
|
---|
137 | case 3:
|
---|
138 | info8.version = r->info.info3->version;
|
---|
139 | info8.driver_name = r->info.info3->driver_name;
|
---|
140 | info8.architecture = r->info.info3->architecture;
|
---|
141 | info8.driver_path = r->info.info3->driver_path;
|
---|
142 | info8.data_file = r->info.info3->data_file;
|
---|
143 | info8.config_file = r->info.info3->config_file;
|
---|
144 | info8.help_file = r->info.info3->help_file;
|
---|
145 | info8.monitor_name = r->info.info3->monitor_name;
|
---|
146 | info8.default_datatype = r->info.info3->default_datatype;
|
---|
147 | if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
|
---|
148 | info8.dependent_files = r->info.info3->dependent_files->string;
|
---|
149 | }
|
---|
150 | break;
|
---|
151 | case 6:
|
---|
152 | info8.version = r->info.info6->version;
|
---|
153 | info8.driver_name = r->info.info6->driver_name;
|
---|
154 | info8.architecture = r->info.info6->architecture;
|
---|
155 | info8.driver_path = r->info.info6->driver_path;
|
---|
156 | info8.data_file = r->info.info6->data_file;
|
---|
157 | info8.config_file = r->info.info6->config_file;
|
---|
158 | info8.help_file = r->info.info6->help_file;
|
---|
159 | info8.monitor_name = r->info.info6->monitor_name;
|
---|
160 | info8.default_datatype = r->info.info6->default_datatype;
|
---|
161 | if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
|
---|
162 | info8.dependent_files = r->info.info6->dependent_files->string;
|
---|
163 | }
|
---|
164 | info8.driver_date = r->info.info6->driver_date;
|
---|
165 | info8.driver_version = r->info.info6->driver_version;
|
---|
166 | info8.manufacturer_name = r->info.info6->manufacturer_name;
|
---|
167 | info8.manufacturer_url = r->info.info6->manufacturer_url;
|
---|
168 | info8.hardware_id = r->info.info6->hardware_id;
|
---|
169 | info8.provider = r->info.info6->provider;
|
---|
170 | break;
|
---|
171 | case 8:
|
---|
172 | info8.version = r->info.info8->version;
|
---|
173 | info8.driver_name = r->info.info8->driver_name;
|
---|
174 | info8.architecture = r->info.info8->architecture;
|
---|
175 | info8.driver_path = r->info.info8->driver_path;
|
---|
176 | info8.data_file = r->info.info8->data_file;
|
---|
177 | info8.config_file = r->info.info8->config_file;
|
---|
178 | info8.help_file = r->info.info8->help_file;
|
---|
179 | info8.monitor_name = r->info.info8->monitor_name;
|
---|
180 | info8.default_datatype = r->info.info8->default_datatype;
|
---|
181 | if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
|
---|
182 | info8.dependent_files = r->info.info8->dependent_files->string;
|
---|
183 | }
|
---|
184 | if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
|
---|
185 | info8.previous_names = r->info.info8->previous_names->string;
|
---|
186 | }
|
---|
187 | info8.driver_date = r->info.info8->driver_date;
|
---|
188 | info8.driver_version = r->info.info8->driver_version;
|
---|
189 | info8.manufacturer_name = r->info.info8->manufacturer_name;
|
---|
190 | info8.manufacturer_url = r->info.info8->manufacturer_url;
|
---|
191 | info8.hardware_id = r->info.info8->hardware_id;
|
---|
192 | info8.provider = r->info.info8->provider;
|
---|
193 | info8.print_processor = r->info.info8->print_processor;
|
---|
194 | info8.vendor_setup = r->info.info8->vendor_setup;
|
---|
195 | if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
|
---|
196 | info8.color_profiles = r->info.info8->color_profiles->string;
|
---|
197 | }
|
---|
198 | info8.inf_path = r->info.info8->inf_path;
|
---|
199 | info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
|
---|
200 | if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
|
---|
201 | info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
|
---|
202 | }
|
---|
203 | info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
|
---|
204 | info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
|
---|
205 | break;
|
---|
206 | default:
|
---|
207 | return false;
|
---|
208 | }
|
---|
209 |
|
---|
210 | *_info8 = info8;
|
---|
211 |
|
---|
212 | return true;
|
---|
213 | }
|
---|
214 |
|
---|
215 | /****************************************************************************
|
---|
216 | Create and allocate a default devicemode.
|
---|
217 | ****************************************************************************/
|
---|
218 |
|
---|
219 | WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
|
---|
220 | const char *devicename,
|
---|
221 | struct spoolss_DeviceMode **devmode)
|
---|
222 | {
|
---|
223 | struct spoolss_DeviceMode *dm;
|
---|
224 | char *dname;
|
---|
225 |
|
---|
226 | dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
|
---|
227 | if (dm == NULL) {
|
---|
228 | return WERR_NOMEM;
|
---|
229 | }
|
---|
230 |
|
---|
231 | dname = talloc_asprintf(dm, "%s", devicename);
|
---|
232 | if (dname == NULL) {
|
---|
233 | return WERR_NOMEM;
|
---|
234 | }
|
---|
235 | if (strlen(dname) > MAXDEVICENAME) {
|
---|
236 | dname[MAXDEVICENAME] = '\0';
|
---|
237 | }
|
---|
238 | dm->devicename = dname;
|
---|
239 |
|
---|
240 | dm->formname = talloc_strdup(dm, "Letter");
|
---|
241 | if (dm->formname == NULL) {
|
---|
242 | return WERR_NOMEM;
|
---|
243 | }
|
---|
244 |
|
---|
245 | dm->specversion = DMSPEC_NT4_AND_ABOVE;
|
---|
246 | dm->driverversion = 0x0400;
|
---|
247 | dm->size = 0x00DC;
|
---|
248 | dm->__driverextra_length = 0;
|
---|
249 | dm->fields = DEVMODE_FORMNAME |
|
---|
250 | DEVMODE_TTOPTION |
|
---|
251 | DEVMODE_PRINTQUALITY |
|
---|
252 | DEVMODE_DEFAULTSOURCE |
|
---|
253 | DEVMODE_COPIES |
|
---|
254 | DEVMODE_SCALE |
|
---|
255 | DEVMODE_PAPERSIZE |
|
---|
256 | DEVMODE_ORIENTATION;
|
---|
257 | dm->orientation = DMORIENT_PORTRAIT;
|
---|
258 | dm->papersize = DMPAPER_LETTER;
|
---|
259 | dm->paperlength = 0;
|
---|
260 | dm->paperwidth = 0;
|
---|
261 | dm->scale = 0x64;
|
---|
262 | dm->copies = 1;
|
---|
263 | dm->defaultsource = DMBIN_FORMSOURCE;
|
---|
264 | dm->printquality = DMRES_HIGH; /* 0x0258 */
|
---|
265 | dm->color = DMRES_MONOCHROME;
|
---|
266 | dm->duplex = DMDUP_SIMPLEX;
|
---|
267 | dm->yresolution = 0;
|
---|
268 | dm->ttoption = DMTT_SUBDEV;
|
---|
269 | dm->collate = DMCOLLATE_FALSE;
|
---|
270 | dm->icmmethod = 0;
|
---|
271 | dm->icmintent = 0;
|
---|
272 | dm->mediatype = 0;
|
---|
273 | dm->dithertype = 0;
|
---|
274 |
|
---|
275 | dm->logpixels = 0;
|
---|
276 | dm->bitsperpel = 0;
|
---|
277 | dm->pelswidth = 0;
|
---|
278 | dm->pelsheight = 0;
|
---|
279 | dm->displayflags = 0;
|
---|
280 | dm->displayfrequency = 0;
|
---|
281 | dm->reserved1 = 0;
|
---|
282 | dm->reserved2 = 0;
|
---|
283 | dm->panningwidth = 0;
|
---|
284 | dm->panningheight = 0;
|
---|
285 |
|
---|
286 | dm->driverextra_data.data = NULL;
|
---|
287 | dm->driverextra_data.length = 0;
|
---|
288 |
|
---|
289 | *devmode = dm;
|
---|
290 | return WERR_OK;
|
---|
291 | }
|
---|
292 |
|
---|
293 | WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
|
---|
294 | struct spoolss_security_descriptor **secdesc)
|
---|
295 | {
|
---|
296 | struct security_ace ace[7]; /* max number of ace entries */
|
---|
297 | int i = 0;
|
---|
298 | uint32_t sa;
|
---|
299 | struct security_acl *psa = NULL;
|
---|
300 | struct security_descriptor *psd = NULL;
|
---|
301 | struct dom_sid adm_sid;
|
---|
302 | size_t sd_size;
|
---|
303 |
|
---|
304 | /* Create an ACE where Everyone is allowed to print */
|
---|
305 |
|
---|
306 | sa = PRINTER_ACE_PRINT;
|
---|
307 | init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
|
---|
308 | sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
|
---|
309 |
|
---|
310 | /* Add the domain admins group if we are a DC */
|
---|
311 |
|
---|
312 | if ( IS_DC ) {
|
---|
313 | struct dom_sid domadmins_sid;
|
---|
314 |
|
---|
315 | sid_compose(&domadmins_sid, get_global_sam_sid(),
|
---|
316 | DOMAIN_RID_ADMINS);
|
---|
317 |
|
---|
318 | sa = PRINTER_ACE_FULL_CONTROL;
|
---|
319 | init_sec_ace(&ace[i++], &domadmins_sid,
|
---|
320 | SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
|
---|
321 | SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
|
---|
322 | init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
|
---|
323 | sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
|
---|
324 | }
|
---|
325 | else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
|
---|
326 | sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
|
---|
327 |
|
---|
328 | sa = PRINTER_ACE_FULL_CONTROL;
|
---|
329 | init_sec_ace(&ace[i++], &adm_sid,
|
---|
330 | SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
|
---|
331 | SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
|
---|
332 | init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
|
---|
333 | sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
|
---|
334 | }
|
---|
335 |
|
---|
336 | /* add BUILTIN\Administrators as FULL CONTROL */
|
---|
337 |
|
---|
338 | sa = PRINTER_ACE_FULL_CONTROL;
|
---|
339 | init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
|
---|
340 | SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
|
---|
341 | SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
|
---|
342 | init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
|
---|
343 | SEC_ACE_TYPE_ACCESS_ALLOWED,
|
---|
344 | sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
|
---|
345 |
|
---|
346 | /* add BUILTIN\Print Operators as FULL CONTROL */
|
---|
347 |
|
---|
348 | sa = PRINTER_ACE_FULL_CONTROL;
|
---|
349 | init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
|
---|
350 | SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
|
---|
351 | SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
|
---|
352 | init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
|
---|
353 | SEC_ACE_TYPE_ACCESS_ALLOWED,
|
---|
354 | sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
|
---|
355 |
|
---|
356 | /* Make the security descriptor owned by the BUILTIN\Administrators */
|
---|
357 |
|
---|
358 | /* The ACL revision number in rpc_secdesc.h differs from the one
|
---|
359 | created by NT when setting ACE entries in printer
|
---|
360 | descriptors. NT4 complains about the property being edited by a
|
---|
361 | NT5 machine. */
|
---|
362 |
|
---|
363 | if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
|
---|
364 | psd = make_sec_desc(mem_ctx,
|
---|
365 | SD_REVISION,
|
---|
366 | SEC_DESC_SELF_RELATIVE,
|
---|
367 | &global_sid_Builtin_Administrators,
|
---|
368 | &global_sid_Builtin_Administrators,
|
---|
369 | NULL,
|
---|
370 | psa,
|
---|
371 | &sd_size);
|
---|
372 | }
|
---|
373 |
|
---|
374 | if (psd == NULL) {
|
---|
375 | DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
|
---|
376 | return WERR_NOMEM;
|
---|
377 | }
|
---|
378 |
|
---|
379 | DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
|
---|
380 | (unsigned int)sd_size));
|
---|
381 |
|
---|
382 | *secdesc = psd;
|
---|
383 |
|
---|
384 | return WERR_OK;
|
---|
385 | }
|
---|