gitlab-ci: Update image to Fedora 40
[Samba.git] / source3 / rpc_client / init_spoolss.c
blobc341b82b6ee1f26b3130ec075dc56ff68345d697
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Guenther Deschner 2009.
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.
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.
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/>.
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"
27 /*******************************************************************
28 ********************************************************************/
30 bool init_systemtime(struct spoolss_Time *r,
31 struct tm *unixtime)
33 if (!r || !unixtime) {
34 return false;
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;
46 return true;
49 time_t spoolss_Time_to_time_t(const struct spoolss_Time *r)
51 struct tm unixtime = {
52 .tm_year = r->year - 1900,
53 .tm_mon = r->month - 1,
54 .tm_wday = r->day_of_week,
55 .tm_mday = r->day,
56 .tm_hour = r->hour,
57 .tm_min = r->minute,
58 .tm_sec = r->second,
61 return mktime(&unixtime);
64 /*******************************************************************
65 ********************************************************************/
67 bool spoolss_timestr_to_NTTIME(const char *str,
68 NTTIME *data)
70 struct tm tm;
71 time_t t;
73 if (strequal(str, "01/01/1601")) {
74 *data = 0;
75 return true;
78 ZERO_STRUCT(tm);
80 if (sscanf(str, "%d/%d/%d",
81 &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) {
82 return false;
84 tm.tm_mon -= 1;
85 tm.tm_year -= 1900;
86 tm.tm_isdst = -1;
88 t = mktime(&tm);
89 unix_to_nt_time(data, t);
91 return true;
94 /*******************************************************************
95 ********************************************************************/
97 bool spoolss_driver_version_to_qword(const char *str,
98 uint64_t *data)
100 unsigned int v1, v2, v3, v4 = 0;
102 if ((sscanf(str, "%u.%u.%u.%u", &v1, &v2, &v3, &v4) != 4) &&
103 (sscanf(str, "%u.%u.%u", &v1, &v2, &v3) != 3))
105 return false;
108 *data = ((uint64_t)(v1 & 0xFFFF) << 48) +
109 ((uint64_t)(v2 & 0xFFFF) << 32) +
110 ((uint64_t)(v3 & 0xFFFF) << 16) +
111 (uint64_t)(v4 & 0xFFFF);
113 return true;
116 /*******************************************************************
117 ********************************************************************/
119 WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx,
120 const DATA_BLOB *blob,
121 union spoolss_PrinterData *data,
122 enum winreg_Type type)
124 enum ndr_err_code ndr_err;
125 ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type,
126 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PrinterData);
127 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
128 return WERR_GEN_FAILURE;
130 return WERR_OK;
133 /*******************************************************************
134 ********************************************************************/
136 WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
137 enum winreg_Type type,
138 union spoolss_PrinterData *data)
140 enum ndr_err_code ndr_err;
141 ndr_err = ndr_push_union_blob(blob, mem_ctx, data, type,
142 (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData);
143 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
144 return WERR_GEN_FAILURE;
146 return WERR_OK;
149 /*******************************************************************
150 ********************************************************************/
152 void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 *i,
153 struct spoolss_SetPrinterInfo2 *s)
155 s->servername = i->servername;
156 s->printername = i->printername;
157 s->sharename = i->sharename;
158 s->portname = i->portname;
159 s->drivername = i->drivername;
160 s->comment = i->comment;
161 s->location = i->location;
162 s->devmode_ptr = 0;
163 s->sepfile = i->sepfile;
164 s->printprocessor = i->printprocessor;
165 s->datatype = i->datatype;
166 s->parameters = i->parameters;
167 s->secdesc_ptr = 0;
168 s->attributes = i->attributes;
169 s->priority = i->priority;
170 s->defaultpriority = i->defaultpriority;
171 s->starttime = i->starttime;
172 s->untiltime = i->untiltime;
173 s->status = i->status;
174 s->cjobs = i->cjobs;
175 s->averageppm = i->averageppm;
178 /****************************************************************************
179 ****************************************************************************/
181 bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
182 struct spoolss_DriverInfo8 *_info8)
184 struct spoolss_DriverInfo8 info8;
186 ZERO_STRUCT(info8);
188 switch (r->level) {
189 case 3:
190 info8.version = r->info.info3->version;
191 info8.driver_name = r->info.info3->driver_name;
192 info8.architecture = r->info.info3->architecture;
193 info8.driver_path = r->info.info3->driver_path;
194 info8.data_file = r->info.info3->data_file;
195 info8.config_file = r->info.info3->config_file;
196 info8.help_file = r->info.info3->help_file;
197 info8.monitor_name = r->info.info3->monitor_name;
198 info8.default_datatype = r->info.info3->default_datatype;
199 if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
200 info8.dependent_files = r->info.info3->dependent_files->string;
202 break;
203 case 6:
204 info8.version = r->info.info6->version;
205 info8.driver_name = r->info.info6->driver_name;
206 info8.architecture = r->info.info6->architecture;
207 info8.driver_path = r->info.info6->driver_path;
208 info8.data_file = r->info.info6->data_file;
209 info8.config_file = r->info.info6->config_file;
210 info8.help_file = r->info.info6->help_file;
211 info8.monitor_name = r->info.info6->monitor_name;
212 info8.default_datatype = r->info.info6->default_datatype;
213 if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
214 info8.dependent_files = r->info.info6->dependent_files->string;
216 info8.driver_date = r->info.info6->driver_date;
217 info8.driver_version = r->info.info6->driver_version;
218 info8.manufacturer_name = r->info.info6->manufacturer_name;
219 info8.manufacturer_url = r->info.info6->manufacturer_url;
220 info8.hardware_id = r->info.info6->hardware_id;
221 info8.provider = r->info.info6->provider;
222 break;
223 case 8:
224 info8.version = r->info.info8->version;
225 info8.driver_name = r->info.info8->driver_name;
226 info8.architecture = r->info.info8->architecture;
227 info8.driver_path = r->info.info8->driver_path;
228 info8.data_file = r->info.info8->data_file;
229 info8.config_file = r->info.info8->config_file;
230 info8.help_file = r->info.info8->help_file;
231 info8.monitor_name = r->info.info8->monitor_name;
232 info8.default_datatype = r->info.info8->default_datatype;
233 if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
234 info8.dependent_files = r->info.info8->dependent_files->string;
236 if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
237 info8.previous_names = r->info.info8->previous_names->string;
239 info8.driver_date = r->info.info8->driver_date;
240 info8.driver_version = r->info.info8->driver_version;
241 info8.manufacturer_name = r->info.info8->manufacturer_name;
242 info8.manufacturer_url = r->info.info8->manufacturer_url;
243 info8.hardware_id = r->info.info8->hardware_id;
244 info8.provider = r->info.info8->provider;
245 info8.print_processor = r->info.info8->print_processor;
246 info8.vendor_setup = r->info.info8->vendor_setup;
247 if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
248 info8.color_profiles = r->info.info8->color_profiles->string;
250 info8.inf_path = r->info.info8->inf_path;
251 info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
252 if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
253 info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
255 info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
256 info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
257 break;
258 default:
259 return false;
262 *_info8 = info8;
264 return true;
267 /****************************************************************************
268 Create and allocate a default devicemode.
269 ****************************************************************************/
271 WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
272 const char *devicename,
273 struct spoolss_DeviceMode **devmode)
275 struct spoolss_DeviceMode *dm;
276 char *dname;
278 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
279 if (dm == NULL) {
280 return WERR_NOT_ENOUGH_MEMORY;
283 dname = talloc_asprintf(dm, "%s", devicename);
284 if (dname == NULL) {
285 return WERR_NOT_ENOUGH_MEMORY;
287 if (strlen(dname) > MAXDEVICENAME) {
288 dname[MAXDEVICENAME] = '\0';
290 dm->devicename = dname;
292 dm->formname = talloc_strdup(dm, "Letter");
293 if (dm->formname == NULL) {
294 return WERR_NOT_ENOUGH_MEMORY;
297 dm->specversion = DMSPEC_NT4_AND_ABOVE;
298 dm->driverversion = 0x0400;
299 dm->size = 0x00DC;
300 dm->__driverextra_length = 0;
301 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 dm->orientation = DMORIENT_PORTRAIT;
310 dm->papersize = DMPAPER_LETTER;
311 dm->paperlength = 0;
312 dm->paperwidth = 0;
313 dm->scale = 0x64;
314 dm->copies = 1;
315 dm->defaultsource = DMBIN_FORMSOURCE;
316 dm->printquality = DMRES_HIGH; /* 0x0258 */
317 dm->color = DMRES_MONOCHROME;
318 dm->duplex = DMDUP_SIMPLEX;
319 dm->yresolution = 0;
320 dm->ttoption = DMTT_SUBDEV;
321 dm->collate = DMCOLLATE_FALSE;
322 dm->icmmethod = 0;
323 dm->icmintent = 0;
324 dm->mediatype = 0;
325 dm->dithertype = 0;
327 dm->logpixels = 0;
328 dm->bitsperpel = 0;
329 dm->pelswidth = 0;
330 dm->pelsheight = 0;
331 dm->displayflags = 0;
332 dm->displayfrequency = 0;
333 dm->reserved1 = 0;
334 dm->reserved2 = 0;
335 dm->panningwidth = 0;
336 dm->panningheight = 0;
338 dm->driverextra_data.data = NULL;
339 dm->driverextra_data.length = 0;
341 *devmode = dm;
342 return WERR_OK;
345 WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
346 struct spoolss_security_descriptor **secdesc)
348 struct security_ace ace[7]; /* max number of ace entries */
349 int i = 0;
350 uint32_t sa;
351 struct security_acl *psa = NULL;
352 struct security_descriptor *psd = NULL;
353 struct dom_sid adm_sid;
354 size_t sd_size;
356 /* Create an ACE where Everyone is allowed to print */
358 sa = PRINTER_ACE_PRINT;
359 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
360 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
362 /* Add the domain admins group if we are a DC */
364 if ( IS_DC ) {
365 struct dom_sid domadmins_sid;
367 sid_compose(&domadmins_sid, get_global_sam_sid(),
368 DOMAIN_RID_ADMINS);
370 sa = PRINTER_ACE_FULL_CONTROL;
371 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 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
375 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
377 else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
378 sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
380 sa = PRINTER_ACE_FULL_CONTROL;
381 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 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
385 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
388 /* add BUILTIN\Administrators as FULL CONTROL */
390 sa = PRINTER_ACE_FULL_CONTROL;
391 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 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
395 SEC_ACE_TYPE_ACCESS_ALLOWED,
396 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
398 /* add BUILTIN\Print Operators as FULL CONTROL */
400 sa = PRINTER_ACE_FULL_CONTROL;
401 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 init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
405 SEC_ACE_TYPE_ACCESS_ALLOWED,
406 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
408 /* Make the security descriptor owned by the BUILTIN\Administrators */
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. */
415 if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
416 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);
426 if (psd == NULL) {
427 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
428 return WERR_NOT_ENOUGH_MEMORY;
431 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
432 (unsigned int)sd_size));
434 *secdesc = psd;
436 return WERR_OK;
439 const char *spoolss_get_short_filesys_environment(const char *environment)
441 if (strequal(environment, SPOOLSS_ARCHITECTURE_x64)) {
442 return "amd64";
443 } else if (strequal(environment, SPOOLSS_ARCHITECTURE_NT_X86)) {
444 return "x86";
445 } else {
446 return NULL;
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
455 WERROR spoolss_init_spoolss_UserLevel1(TALLOC_CTX *mem_ctx,
456 const char *username,
457 struct spoolss_UserLevel1 *r)
459 ZERO_STRUCTP(r);
461 r->size = 28;
462 r->client = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
463 W_ERROR_HAVE_NO_MEMORY(r->client);
464 r->user = talloc_strdup(mem_ctx, username);
465 W_ERROR_HAVE_NO_MEMORY(r->user);
466 r->processor = 0;
468 r->major = lp_parm_int(GLOBAL_SECTION_SNUM,
469 "spoolss_client", "os_major",
470 GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT);
471 r->minor = lp_parm_int(GLOBAL_SECTION_SNUM,
472 "spoolss_client", "os_minor",
473 GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT);
474 r->build = lp_parm_int(GLOBAL_SECTION_SNUM,
475 "spoolss_client", "os_build",
476 GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT);
478 return WERR_OK;