/src/samba/source3/rpc_client/init_spoolss.c
Line | Count | Source |
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 | 0 | { |
33 | 0 | if (!r || !unixtime) { |
34 | 0 | return false; |
35 | 0 | } |
36 | | |
37 | 0 | r->year = unixtime->tm_year+1900; |
38 | 0 | r->month = unixtime->tm_mon+1; |
39 | 0 | r->day_of_week = unixtime->tm_wday; |
40 | 0 | r->day = unixtime->tm_mday; |
41 | 0 | r->hour = unixtime->tm_hour; |
42 | 0 | r->minute = unixtime->tm_min; |
43 | 0 | r->second = unixtime->tm_sec; |
44 | 0 | r->millisecond = 0; |
45 | |
|
46 | 0 | return true; |
47 | 0 | } |
48 | | |
49 | | time_t spoolss_Time_to_time_t(const struct spoolss_Time *r) |
50 | 0 | { |
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 | 0 | }; |
60 | |
|
61 | 0 | return mktime(&unixtime); |
62 | 0 | } |
63 | | |
64 | | /******************************************************************* |
65 | | ********************************************************************/ |
66 | | |
67 | | bool spoolss_timestr_to_NTTIME(const char *str, |
68 | | NTTIME *data) |
69 | 0 | { |
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 | 0 | } |
77 | | |
78 | 0 | ZERO_STRUCT(tm); |
79 | |
|
80 | 0 | if (sscanf(str, "%d/%d/%d", |
81 | 0 | &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) { |
82 | 0 | return false; |
83 | 0 | } |
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 | 0 | } |
93 | | |
94 | | /******************************************************************* |
95 | | ********************************************************************/ |
96 | | |
97 | | bool spoolss_driver_version_to_qword(const char *str, |
98 | | uint64_t *data) |
99 | 0 | { |
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 | 0 | { |
105 | 0 | return false; |
106 | 0 | } |
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 | 0 | } |
115 | | |
116 | | /******************************************************************* |
117 | | ********************************************************************/ |
118 | | |
119 | | WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx, |
120 | | const DATA_BLOB *blob, |
121 | | union spoolss_PrinterData *data, |
122 | | enum winreg_Type type) |
123 | 0 | { |
124 | 0 | enum ndr_err_code ndr_err; |
125 | 0 | ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type, |
126 | 0 | (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 | 0 | } |
130 | 0 | return WERR_OK; |
131 | 0 | } |
132 | | |
133 | | /******************************************************************* |
134 | | ********************************************************************/ |
135 | | |
136 | | WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, |
137 | | enum winreg_Type type, |
138 | | union spoolss_PrinterData *data) |
139 | 0 | { |
140 | 0 | enum ndr_err_code ndr_err; |
141 | 0 | ndr_err = ndr_push_union_blob(blob, mem_ctx, data, type, |
142 | 0 | (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData); |
143 | 0 | if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { |
144 | 0 | return WERR_GEN_FAILURE; |
145 | 0 | } |
146 | 0 | return WERR_OK; |
147 | 0 | } |
148 | | |
149 | | /******************************************************************* |
150 | | ********************************************************************/ |
151 | | |
152 | | void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 *i, |
153 | | struct spoolss_SetPrinterInfo2 *s) |
154 | 0 | { |
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 | | bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r, |
182 | | struct spoolss_DriverInfo8 *_info8) |
183 | 0 | { |
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 | 0 | } |
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 | 0 | } |
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 | 0 | } |
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 | 0 | } |
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 | 0 | } |
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 | 0 | } |
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 | 0 | } |
261 | | |
262 | 0 | *_info8 = info8; |
263 | |
|
264 | 0 | return true; |
265 | 0 | } |
266 | | |
267 | | /**************************************************************************** |
268 | | Create and allocate a default devicemode. |
269 | | ****************************************************************************/ |
270 | | |
271 | | WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx, |
272 | | const char *devicename, |
273 | | struct spoolss_DeviceMode **devmode) |
274 | 0 | { |
275 | 0 | struct spoolss_DeviceMode *dm; |
276 | 0 | char *dname; |
277 | |
|
278 | 0 | dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode); |
279 | 0 | if (dm == NULL) { |
280 | 0 | return WERR_NOT_ENOUGH_MEMORY; |
281 | 0 | } |
282 | | |
283 | 0 | dname = talloc_asprintf(dm, "%s", devicename); |
284 | 0 | if (dname == NULL) { |
285 | 0 | return WERR_NOT_ENOUGH_MEMORY; |
286 | 0 | } |
287 | 0 | if (strlen(dname) > MAXDEVICENAME) { |
288 | 0 | dname[MAXDEVICENAME] = '\0'; |
289 | 0 | } |
290 | 0 | dm->devicename = dname; |
291 | |
|
292 | 0 | dm->formname = talloc_strdup(dm, "Letter"); |
293 | 0 | if (dm->formname == NULL) { |
294 | 0 | return WERR_NOT_ENOUGH_MEMORY; |
295 | 0 | } |
296 | | |
297 | 0 | dm->specversion = DMSPEC_NT4_AND_ABOVE; |
298 | 0 | dm->driverversion = 0x0400; |
299 | 0 | dm->size = 0x00DC; |
300 | 0 | dm->__driverextra_length = 0; |
301 | 0 | dm->fields = DEVMODE_FORMNAME | |
302 | 0 | DEVMODE_TTOPTION | |
303 | 0 | DEVMODE_PRINTQUALITY | |
304 | 0 | DEVMODE_DEFAULTSOURCE | |
305 | 0 | DEVMODE_COPIES | |
306 | 0 | DEVMODE_SCALE | |
307 | 0 | DEVMODE_PAPERSIZE | |
308 | 0 | DEVMODE_ORIENTATION; |
309 | 0 | dm->orientation = DMORIENT_PORTRAIT; |
310 | 0 | dm->papersize = DMPAPER_LETTER; |
311 | 0 | dm->paperlength = 0; |
312 | 0 | dm->paperwidth = 0; |
313 | 0 | dm->scale = 0x64; |
314 | 0 | dm->copies = 1; |
315 | 0 | dm->defaultsource = DMBIN_FORMSOURCE; |
316 | 0 | dm->printquality = DMRES_HIGH; /* 0x0258 */ |
317 | 0 | dm->color = DMRES_MONOCHROME; |
318 | 0 | dm->duplex = DMDUP_SIMPLEX; |
319 | 0 | dm->yresolution = 0; |
320 | 0 | dm->ttoption = DMTT_SUBDEV; |
321 | 0 | dm->collate = DMCOLLATE_FALSE; |
322 | 0 | dm->icmmethod = 0; |
323 | 0 | dm->icmintent = 0; |
324 | 0 | dm->mediatype = 0; |
325 | 0 | dm->dithertype = 0; |
326 | |
|
327 | 0 | dm->logpixels = 0; |
328 | 0 | dm->bitsperpel = 0; |
329 | 0 | dm->pelswidth = 0; |
330 | 0 | dm->pelsheight = 0; |
331 | 0 | dm->displayflags = 0; |
332 | 0 | dm->displayfrequency = 0; |
333 | 0 | dm->reserved1 = 0; |
334 | 0 | dm->reserved2 = 0; |
335 | 0 | dm->panningwidth = 0; |
336 | 0 | dm->panningheight = 0; |
337 | |
|
338 | 0 | dm->driverextra_data.data = NULL; |
339 | 0 | dm->driverextra_data.length = 0; |
340 | |
|
341 | 0 | *devmode = dm; |
342 | 0 | return WERR_OK; |
343 | 0 | } |
344 | | |
345 | | WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, |
346 | | struct spoolss_security_descriptor **secdesc) |
347 | 0 | { |
348 | 0 | struct security_ace ace[7] = {0}; /* max number of ace entries */ |
349 | 0 | int i = 0; |
350 | 0 | uint32_t sa; |
351 | 0 | struct security_acl *psa = NULL; |
352 | 0 | 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 | 0 | sa = PRINTER_ACE_PRINT; |
359 | 0 | init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, |
360 | 0 | sa, SEC_ACE_FLAG_CONTAINER_INHERIT); |
361 | | |
362 | | /* Add the domain admins group if we are a DC */ |
363 | |
|
364 | 0 | if ( IS_DC ) { |
365 | 0 | struct dom_sid domadmins_sid; |
366 | |
|
367 | 0 | sid_compose(&domadmins_sid, get_global_sam_sid(), |
368 | 0 | DOMAIN_RID_ADMINS); |
369 | |
|
370 | 0 | sa = PRINTER_ACE_FULL_CONTROL; |
371 | 0 | init_sec_ace(&ace[i++], &domadmins_sid, |
372 | 0 | SEC_ACE_TYPE_ACCESS_ALLOWED, sa, |
373 | 0 | SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); |
374 | 0 | init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, |
375 | 0 | sa, SEC_ACE_FLAG_CONTAINER_INHERIT); |
376 | 0 | } |
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 | 0 | SEC_ACE_TYPE_ACCESS_ALLOWED, sa, |
383 | 0 | 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 | 0 | sa, SEC_ACE_FLAG_CONTAINER_INHERIT); |
386 | 0 | } |
387 | | |
388 | | /* add BUILTIN\Administrators as FULL CONTROL */ |
389 | |
|
390 | 0 | sa = PRINTER_ACE_FULL_CONTROL; |
391 | 0 | init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, |
392 | 0 | SEC_ACE_TYPE_ACCESS_ALLOWED, sa, |
393 | 0 | SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); |
394 | 0 | init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, |
395 | 0 | SEC_ACE_TYPE_ACCESS_ALLOWED, |
396 | 0 | sa, SEC_ACE_FLAG_CONTAINER_INHERIT); |
397 | | |
398 | | /* add BUILTIN\Print Operators as FULL CONTROL */ |
399 | |
|
400 | 0 | sa = PRINTER_ACE_FULL_CONTROL; |
401 | 0 | init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators, |
402 | 0 | SEC_ACE_TYPE_ACCESS_ALLOWED, sa, |
403 | 0 | SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); |
404 | 0 | init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators, |
405 | 0 | SEC_ACE_TYPE_ACCESS_ALLOWED, |
406 | 0 | 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 | 0 | if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) { |
416 | 0 | psd = make_sec_desc(mem_ctx, |
417 | 0 | SD_REVISION, |
418 | 0 | SEC_DESC_SELF_RELATIVE, |
419 | 0 | &global_sid_Builtin_Administrators, |
420 | 0 | &global_sid_Builtin_Administrators, |
421 | 0 | NULL, |
422 | 0 | psa, |
423 | 0 | &sd_size); |
424 | 0 | } |
425 | |
|
426 | 0 | 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 | 0 | } |
430 | | |
431 | 0 | DEBUG(4,("construct_default_printer_sdb: size = %u.\n", |
432 | 0 | (unsigned int)sd_size)); |
433 | |
|
434 | 0 | *secdesc = psd; |
435 | |
|
436 | 0 | return WERR_OK; |
437 | 0 | } |
438 | | |
439 | | const char *spoolss_get_short_filesys_environment(const char *environment) |
440 | 0 | { |
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 | 0 | } else { |
446 | 0 | return NULL; |
447 | 0 | } |
448 | 0 | } |
449 | | |
450 | | /* Windows 7 and Windows Server 2008 R2 */ |
451 | 0 | #define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 6 |
452 | 0 | #define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 1 |
453 | 0 | #define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 7007 |
454 | | |
455 | | WERROR spoolss_init_spoolss_UserLevel1(TALLOC_CTX *mem_ctx, |
456 | | const char *username, |
457 | | struct spoolss_UserLevel1 *r) |
458 | 0 | { |
459 | 0 | ZERO_STRUCTP(r); |
460 | |
|
461 | 0 | r->size = 28; |
462 | 0 | r->client = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name()); |
463 | 0 | W_ERROR_HAVE_NO_MEMORY(r->client); |
464 | 0 | r->user = talloc_strdup(mem_ctx, username); |
465 | 0 | W_ERROR_HAVE_NO_MEMORY(r->user); |
466 | 0 | r->processor = 0; |
467 | |
|
468 | 0 | r->major = lp_parm_int(GLOBAL_SECTION_SNUM, |
469 | 0 | "spoolss_client", "os_major", |
470 | 0 | GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT); |
471 | 0 | r->minor = lp_parm_int(GLOBAL_SECTION_SNUM, |
472 | 0 | "spoolss_client", "os_minor", |
473 | 0 | GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT); |
474 | 0 | r->build = lp_parm_int(GLOBAL_SECTION_SNUM, |
475 | 0 | "spoolss_client", "os_build", |
476 | 0 | GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT); |
477 | |
|
478 | 0 | return WERR_OK; |
479 | 0 | } |