s3-printing: move spoolss_create_default_devmode/secdesc to init_spoolss.h
[vlendec/samba-autobuild/.git] / source3 / rpc_client / init_spoolss.c
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 }