Line data Source code
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 668 : bool init_systemtime(struct spoolss_Time *r,
31 : struct tm *unixtime)
32 : {
33 668 : if (!r || !unixtime) {
34 0 : return false;
35 : }
36 :
37 668 : r->year = unixtime->tm_year+1900;
38 668 : r->month = unixtime->tm_mon+1;
39 668 : r->day_of_week = unixtime->tm_wday;
40 668 : r->day = unixtime->tm_mday;
41 668 : r->hour = unixtime->tm_hour;
42 668 : r->minute = unixtime->tm_min;
43 668 : r->second = unixtime->tm_sec;
44 668 : r->millisecond = 0;
45 :
46 668 : return true;
47 : }
48 :
49 0 : time_t spoolss_Time_to_time_t(const struct spoolss_Time *r)
50 : {
51 0 : struct tm unixtime = {
52 0 : .tm_year = r->year - 1900,
53 0 : .tm_mon = r->month - 1,
54 0 : .tm_wday = r->day_of_week,
55 0 : .tm_mday = r->day,
56 0 : .tm_hour = r->hour,
57 0 : .tm_min = r->minute,
58 0 : .tm_sec = r->second,
59 : };
60 :
61 0 : return mktime(&unixtime);
62 : }
63 :
64 : /*******************************************************************
65 : ********************************************************************/
66 :
67 0 : bool spoolss_timestr_to_NTTIME(const char *str,
68 : NTTIME *data)
69 : {
70 0 : struct tm tm;
71 0 : time_t t;
72 :
73 0 : if (strequal(str, "01/01/1601")) {
74 0 : *data = 0;
75 0 : return true;
76 : }
77 :
78 0 : ZERO_STRUCT(tm);
79 :
80 0 : if (sscanf(str, "%d/%d/%d",
81 : &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) {
82 0 : return false;
83 : }
84 0 : tm.tm_mon -= 1;
85 0 : tm.tm_year -= 1900;
86 0 : tm.tm_isdst = -1;
87 :
88 0 : t = mktime(&tm);
89 0 : unix_to_nt_time(data, t);
90 :
91 0 : return true;
92 : }
93 :
94 : /*******************************************************************
95 : ********************************************************************/
96 :
97 0 : bool spoolss_driver_version_to_qword(const char *str,
98 : uint64_t *data)
99 : {
100 0 : unsigned int v1, v2, v3, v4 = 0;
101 :
102 0 : if ((sscanf(str, "%u.%u.%u.%u", &v1, &v2, &v3, &v4) != 4) &&
103 0 : (sscanf(str, "%u.%u.%u", &v1, &v2, &v3) != 3))
104 : {
105 0 : return false;
106 : }
107 :
108 0 : *data = ((uint64_t)(v1 & 0xFFFF) << 48) +
109 0 : ((uint64_t)(v2 & 0xFFFF) << 32) +
110 0 : ((uint64_t)(v3 & 0xFFFF) << 16) +
111 0 : (uint64_t)(v4 & 0xFFFF);
112 :
113 0 : return true;
114 : }
115 :
116 : /*******************************************************************
117 : ********************************************************************/
118 :
119 0 : WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx,
120 : const DATA_BLOB *blob,
121 : union spoolss_PrinterData *data,
122 : enum winreg_Type type)
123 : {
124 0 : enum ndr_err_code ndr_err;
125 0 : ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type,
126 : (ndr_pull_flags_fn_t)ndr_pull_spoolss_PrinterData);
127 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
128 0 : return WERR_GEN_FAILURE;
129 : }
130 0 : return WERR_OK;
131 : }
132 :
133 : /*******************************************************************
134 : ********************************************************************/
135 :
136 400 : WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
137 : enum winreg_Type type,
138 : union spoolss_PrinterData *data)
139 : {
140 0 : enum ndr_err_code ndr_err;
141 400 : ndr_err = ndr_push_union_blob(blob, mem_ctx, data, type,
142 : (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData);
143 400 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
144 0 : return WERR_GEN_FAILURE;
145 : }
146 400 : return WERR_OK;
147 : }
148 :
149 : /*******************************************************************
150 : ********************************************************************/
151 :
152 0 : void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 *i,
153 : struct spoolss_SetPrinterInfo2 *s)
154 : {
155 0 : s->servername = i->servername;
156 0 : s->printername = i->printername;
157 0 : s->sharename = i->sharename;
158 0 : s->portname = i->portname;
159 0 : s->drivername = i->drivername;
160 0 : s->comment = i->comment;
161 0 : s->location = i->location;
162 0 : s->devmode_ptr = 0;
163 0 : s->sepfile = i->sepfile;
164 0 : s->printprocessor = i->printprocessor;
165 0 : s->datatype = i->datatype;
166 0 : s->parameters = i->parameters;
167 0 : s->secdesc_ptr = 0;
168 0 : s->attributes = i->attributes;
169 0 : s->priority = i->priority;
170 0 : s->defaultpriority = i->defaultpriority;
171 0 : s->starttime = i->starttime;
172 0 : s->untiltime = i->untiltime;
173 0 : s->status = i->status;
174 0 : s->cjobs = i->cjobs;
175 0 : s->averageppm = i->averageppm;
176 0 : }
177 :
178 : /****************************************************************************
179 : ****************************************************************************/
180 :
181 0 : bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
182 : struct spoolss_DriverInfo8 *_info8)
183 : {
184 0 : struct spoolss_DriverInfo8 info8;
185 :
186 0 : ZERO_STRUCT(info8);
187 :
188 0 : switch (r->level) {
189 0 : case 3:
190 0 : info8.version = r->info.info3->version;
191 0 : info8.driver_name = r->info.info3->driver_name;
192 0 : info8.architecture = r->info.info3->architecture;
193 0 : info8.driver_path = r->info.info3->driver_path;
194 0 : info8.data_file = r->info.info3->data_file;
195 0 : info8.config_file = r->info.info3->config_file;
196 0 : info8.help_file = r->info.info3->help_file;
197 0 : info8.monitor_name = r->info.info3->monitor_name;
198 0 : info8.default_datatype = r->info.info3->default_datatype;
199 0 : if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
200 0 : info8.dependent_files = r->info.info3->dependent_files->string;
201 : }
202 0 : break;
203 0 : case 6:
204 0 : info8.version = r->info.info6->version;
205 0 : info8.driver_name = r->info.info6->driver_name;
206 0 : info8.architecture = r->info.info6->architecture;
207 0 : info8.driver_path = r->info.info6->driver_path;
208 0 : info8.data_file = r->info.info6->data_file;
209 0 : info8.config_file = r->info.info6->config_file;
210 0 : info8.help_file = r->info.info6->help_file;
211 0 : info8.monitor_name = r->info.info6->monitor_name;
212 0 : info8.default_datatype = r->info.info6->default_datatype;
213 0 : if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
214 0 : info8.dependent_files = r->info.info6->dependent_files->string;
215 : }
216 0 : info8.driver_date = r->info.info6->driver_date;
217 0 : info8.driver_version = r->info.info6->driver_version;
218 0 : info8.manufacturer_name = r->info.info6->manufacturer_name;
219 0 : info8.manufacturer_url = r->info.info6->manufacturer_url;
220 0 : info8.hardware_id = r->info.info6->hardware_id;
221 0 : info8.provider = r->info.info6->provider;
222 0 : break;
223 0 : case 8:
224 0 : info8.version = r->info.info8->version;
225 0 : info8.driver_name = r->info.info8->driver_name;
226 0 : info8.architecture = r->info.info8->architecture;
227 0 : info8.driver_path = r->info.info8->driver_path;
228 0 : info8.data_file = r->info.info8->data_file;
229 0 : info8.config_file = r->info.info8->config_file;
230 0 : info8.help_file = r->info.info8->help_file;
231 0 : info8.monitor_name = r->info.info8->monitor_name;
232 0 : info8.default_datatype = r->info.info8->default_datatype;
233 0 : if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
234 0 : info8.dependent_files = r->info.info8->dependent_files->string;
235 : }
236 0 : if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
237 0 : info8.previous_names = r->info.info8->previous_names->string;
238 : }
239 0 : info8.driver_date = r->info.info8->driver_date;
240 0 : info8.driver_version = r->info.info8->driver_version;
241 0 : info8.manufacturer_name = r->info.info8->manufacturer_name;
242 0 : info8.manufacturer_url = r->info.info8->manufacturer_url;
243 0 : info8.hardware_id = r->info.info8->hardware_id;
244 0 : info8.provider = r->info.info8->provider;
245 0 : info8.print_processor = r->info.info8->print_processor;
246 0 : info8.vendor_setup = r->info.info8->vendor_setup;
247 0 : if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
248 0 : info8.color_profiles = r->info.info8->color_profiles->string;
249 : }
250 0 : info8.inf_path = r->info.info8->inf_path;
251 0 : info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
252 0 : if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
253 0 : info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
254 : }
255 0 : info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
256 0 : info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
257 0 : break;
258 0 : default:
259 0 : return false;
260 : }
261 :
262 0 : *_info8 = info8;
263 :
264 0 : return true;
265 : }
266 :
267 : /****************************************************************************
268 : Create and allocate a default devicemode.
269 : ****************************************************************************/
270 :
271 7082 : WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
272 : const char *devicename,
273 : struct spoolss_DeviceMode **devmode)
274 : {
275 0 : struct spoolss_DeviceMode *dm;
276 0 : char *dname;
277 :
278 7082 : dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
279 7082 : if (dm == NULL) {
280 0 : return WERR_NOT_ENOUGH_MEMORY;
281 : }
282 :
283 7082 : dname = talloc_asprintf(dm, "%s", devicename);
284 7082 : if (dname == NULL) {
285 0 : return WERR_NOT_ENOUGH_MEMORY;
286 : }
287 7082 : if (strlen(dname) > MAXDEVICENAME) {
288 64 : dname[MAXDEVICENAME] = '\0';
289 : }
290 7082 : dm->devicename = dname;
291 :
292 7082 : dm->formname = talloc_strdup(dm, "Letter");
293 7082 : if (dm->formname == NULL) {
294 0 : return WERR_NOT_ENOUGH_MEMORY;
295 : }
296 :
297 7082 : dm->specversion = DMSPEC_NT4_AND_ABOVE;
298 7082 : dm->driverversion = 0x0400;
299 7082 : dm->size = 0x00DC;
300 7082 : dm->__driverextra_length = 0;
301 7082 : dm->fields = DEVMODE_FORMNAME |
302 : DEVMODE_TTOPTION |
303 : DEVMODE_PRINTQUALITY |
304 : DEVMODE_DEFAULTSOURCE |
305 : DEVMODE_COPIES |
306 : DEVMODE_SCALE |
307 : DEVMODE_PAPERSIZE |
308 : DEVMODE_ORIENTATION;
309 7082 : dm->orientation = DMORIENT_PORTRAIT;
310 7082 : dm->papersize = DMPAPER_LETTER;
311 7082 : dm->paperlength = 0;
312 7082 : dm->paperwidth = 0;
313 7082 : dm->scale = 0x64;
314 7082 : dm->copies = 1;
315 7082 : dm->defaultsource = DMBIN_FORMSOURCE;
316 7082 : dm->printquality = DMRES_HIGH; /* 0x0258 */
317 7082 : dm->color = DMRES_MONOCHROME;
318 7082 : dm->duplex = DMDUP_SIMPLEX;
319 7082 : dm->yresolution = 0;
320 7082 : dm->ttoption = DMTT_SUBDEV;
321 7082 : dm->collate = DMCOLLATE_FALSE;
322 7082 : dm->icmmethod = 0;
323 7082 : dm->icmintent = 0;
324 7082 : dm->mediatype = 0;
325 7082 : dm->dithertype = 0;
326 :
327 7082 : dm->logpixels = 0;
328 7082 : dm->bitsperpel = 0;
329 7082 : dm->pelswidth = 0;
330 7082 : dm->pelsheight = 0;
331 7082 : dm->displayflags = 0;
332 7082 : dm->displayfrequency = 0;
333 7082 : dm->reserved1 = 0;
334 7082 : dm->reserved2 = 0;
335 7082 : dm->panningwidth = 0;
336 7082 : dm->panningheight = 0;
337 :
338 7082 : dm->driverextra_data.data = NULL;
339 7082 : dm->driverextra_data.length = 0;
340 :
341 7082 : *devmode = dm;
342 7082 : return WERR_OK;
343 : }
344 :
345 76 : WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
346 : struct spoolss_security_descriptor **secdesc)
347 : {
348 0 : struct security_ace ace[7]; /* max number of ace entries */
349 76 : int i = 0;
350 0 : uint32_t sa;
351 76 : struct security_acl *psa = NULL;
352 76 : struct security_descriptor *psd = NULL;
353 0 : struct dom_sid adm_sid;
354 0 : size_t sd_size;
355 :
356 : /* Create an ACE where Everyone is allowed to print */
357 :
358 76 : sa = PRINTER_ACE_PRINT;
359 76 : init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
360 : sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
361 :
362 : /* Add the domain admins group if we are a DC */
363 :
364 152 : if ( IS_DC ) {
365 0 : struct dom_sid domadmins_sid;
366 :
367 76 : sid_compose(&domadmins_sid, get_global_sam_sid(),
368 : DOMAIN_RID_ADMINS);
369 :
370 76 : sa = PRINTER_ACE_FULL_CONTROL;
371 76 : init_sec_ace(&ace[i++], &domadmins_sid,
372 : SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
373 : SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
374 76 : init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
375 : sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
376 : }
377 0 : else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
378 0 : sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
379 :
380 0 : sa = PRINTER_ACE_FULL_CONTROL;
381 0 : init_sec_ace(&ace[i++], &adm_sid,
382 : SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
383 : SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
384 0 : init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
385 : sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
386 : }
387 :
388 : /* add BUILTIN\Administrators as FULL CONTROL */
389 :
390 76 : sa = PRINTER_ACE_FULL_CONTROL;
391 76 : init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
392 : SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
393 : SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
394 76 : init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
395 : SEC_ACE_TYPE_ACCESS_ALLOWED,
396 : sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
397 :
398 : /* add BUILTIN\Print Operators as FULL CONTROL */
399 :
400 76 : sa = PRINTER_ACE_FULL_CONTROL;
401 76 : init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
402 : SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
403 : SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
404 76 : init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
405 : SEC_ACE_TYPE_ACCESS_ALLOWED,
406 : sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
407 :
408 : /* Make the security descriptor owned by the BUILTIN\Administrators */
409 :
410 : /* The ACL revision number in rpc_secdesc.h differs from the one
411 : created by NT when setting ACE entries in printer
412 : descriptors. NT4 complains about the property being edited by a
413 : NT5 machine. */
414 :
415 76 : if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
416 76 : psd = make_sec_desc(mem_ctx,
417 : SD_REVISION,
418 : SEC_DESC_SELF_RELATIVE,
419 : &global_sid_Builtin_Administrators,
420 : &global_sid_Builtin_Administrators,
421 : NULL,
422 : psa,
423 : &sd_size);
424 : }
425 :
426 76 : if (psd == NULL) {
427 0 : DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
428 0 : return WERR_NOT_ENOUGH_MEMORY;
429 : }
430 :
431 76 : DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
432 : (unsigned int)sd_size));
433 :
434 76 : *secdesc = psd;
435 :
436 76 : return WERR_OK;
437 : }
438 :
439 0 : const char *spoolss_get_short_filesys_environment(const char *environment)
440 : {
441 0 : if (strequal(environment, SPOOLSS_ARCHITECTURE_x64)) {
442 0 : return "amd64";
443 0 : } else if (strequal(environment, SPOOLSS_ARCHITECTURE_NT_X86)) {
444 0 : return "x86";
445 : } else {
446 0 : return NULL;
447 : }
448 : }
449 :
450 : /* Windows 7 and Windows Server 2008 R2 */
451 : #define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 6
452 : #define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 1
453 : #define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 7007
454 :
455 6 : WERROR spoolss_init_spoolss_UserLevel1(TALLOC_CTX *mem_ctx,
456 : const char *username,
457 : struct spoolss_UserLevel1 *r)
458 : {
459 6 : ZERO_STRUCTP(r);
460 :
461 6 : r->size = 28;
462 6 : r->client = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
463 6 : W_ERROR_HAVE_NO_MEMORY(r->client);
464 6 : r->user = talloc_strdup(mem_ctx, username);
465 6 : W_ERROR_HAVE_NO_MEMORY(r->user);
466 6 : r->processor = 0;
467 :
468 6 : r->major = lp_parm_int(GLOBAL_SECTION_SNUM,
469 : "spoolss_client", "os_major",
470 : GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT);
471 6 : r->minor = lp_parm_int(GLOBAL_SECTION_SNUM,
472 : "spoolss_client", "os_minor",
473 : GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT);
474 6 : r->build = lp_parm_int(GLOBAL_SECTION_SNUM,
475 : "spoolss_client", "os_build",
476 : GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT);
477 :
478 6 : return WERR_OK;
479 : }
|