Print this page
1575 untangle libmlrpc ... (smbsrv)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c
+++ new/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * Printing and Spooling RPC service.
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
28 28 */
29 29 #include <sys/types.h>
30 30 #include <sys/stat.h>
31 31 #include <sys/utsname.h>
32 32 #include <sys/atomic.h>
33 33 #include <unistd.h>
34 34 #include <stdlib.h>
35 35 #include <strings.h>
36 36 #include <fcntl.h>
37 37 #include <errno.h>
38 +#include <libmlrpc/libmlrpc.h>
38 39 #include <smbsrv/libsmb.h>
39 -#include <smbsrv/libmlrpc.h>
40 40 #include <smbsrv/libmlsvc.h>
41 41 #include <smbsrv/smb.h>
42 42 #include <smbsrv/ndl/spoolss.ndl>
43 43 #include <smbsrv/ndl/winreg.ndl>
44 44 #include <smb/nterror.h>
45 45 #include <smbsrv/smbinfo.h>
46 46 #include <smbsrv/nmpipes.h>
47 47 #include <mlsvc.h>
48 48
49 49 #ifdef HAVE_CUPS
50 50
51 51 #define SPOOLSS_PRINTER "Postscript"
52 52
53 53 typedef struct smb_spool {
54 54 list_t sp_list;
55 55 int sp_cnt;
56 56 rwlock_t sp_rwl;
57 57 int sp_initialized;
58 58 } smb_spool_t;
59 59
60 60 typedef struct smb_spooldoc {
61 61 uint32_t sd_magic;
62 62 list_node_t sd_lnd;
63 63 smb_inaddr_t sd_ipaddr;
64 64 int sd_spool_num;
65 65 char sd_username[MAXNAMELEN];
66 66 char sd_path[MAXPATHLEN];
67 67 char sd_doc_name[MAXNAMELEN];
68 68 char sd_printer_name[MAXPATHLEN];
69 69 int32_t sd_fd;
70 70 ndr_hdid_t sd_handle;
71 71 } smb_spooldoc_t;
72 72
73 73 typedef struct {
74 74 char *name;
75 75 uint32_t value;
76 76 } spoolss_winreg_t;
77 77
78 78 typedef struct {
79 79 uint8_t *sd_buf;
80 80 uint32_t sd_size;
81 81 } spoolss_sd_t;
82 82
83 83 static uint32_t spoolss_cnt;
84 84 static smb_spool_t spoolss_splist;
85 85
86 86 void (*spoolss_copyfile_callback)(smb_inaddr_t *, char *, char *, char *);
87 87
88 88 DECL_FIXUP_STRUCT(spoolss_GetPrinter_result_u);
89 89 DECL_FIXUP_STRUCT(spoolss_GetPrinter_result);
90 90 DECL_FIXUP_STRUCT(spoolss_GetPrinter);
91 91
92 92 DECL_FIXUP_STRUCT(spoolss_RPC_V2_NOTIFY_INFO_DATA_DATA);
93 93 DECL_FIXUP_STRUCT(spoolss_RPC_V2_NOTIFY_INFO_DATA);
94 94 DECL_FIXUP_STRUCT(spoolss_RPC_V2_NOTIFY_INFO);
95 95 DECL_FIXUP_STRUCT(spoolss_RFNPCNEX);
96 96
97 97 uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
98 98 static int spoolss_getservername(char *, size_t);
99 99 static uint32_t spoolss_make_sd(ndr_xa_t *, spoolss_sd_t *);
100 100 static uint32_t spoolss_format_sd(smb_sd_t *);
101 101 static int spoolss_find_document(ndr_hdid_t *);
102 102
103 103 static int spoolss_s_OpenPrinter(void *, ndr_xa_t *);
104 104 static int spoolss_s_ClosePrinter(void *, ndr_xa_t *);
105 105 static int spoolss_s_AbortPrinter(void *, ndr_xa_t *);
106 106 static int spoolss_s_ResetPrinter(void *, ndr_xa_t *);
107 107 static int spoolss_s_GetPrinter(void *, ndr_xa_t *);
108 108 static int spoolss_s_GetPrinterData(void *, ndr_xa_t *);
109 109 static int spoolss_s_AddJob(void *, ndr_xa_t *);
110 110 static int spoolss_s_GetJob(void *, ndr_xa_t *);
111 111 static int spoolss_s_EnumJobs(void *, ndr_xa_t *);
112 112 static int spoolss_s_ScheduleJob(void *, ndr_xa_t *);
113 113 static int spoolss_s_StartDocPrinter(void *, ndr_xa_t *);
114 114 static int spoolss_s_EndDocPrinter(void *, ndr_xa_t *);
115 115 static int spoolss_s_StartPagePrinter(void *, ndr_xa_t *);
116 116 static int spoolss_s_EndPagePrinter(void *, ndr_xa_t *);
117 117 static int spoolss_s_rfnpcnex(void *, ndr_xa_t *);
118 118 static int spoolss_s_WritePrinter(void *, ndr_xa_t *);
119 119 static int spoolss_s_AddForm(void *, ndr_xa_t *);
120 120 static int spoolss_s_DeleteForm(void *, ndr_xa_t *);
121 121 static int spoolss_s_EnumForms(void *, ndr_xa_t *);
122 122 static int spoolss_s_AddMonitor(void *, ndr_xa_t *);
123 123 static int spoolss_s_DeleteMonitor(void *, ndr_xa_t *);
124 124 static int spoolss_s_DeletePort(void *, ndr_xa_t *);
125 125 static int spoolss_s_AddPortEx(void *, ndr_xa_t *);
126 126 static int spoolss_s_SetPort(void *, ndr_xa_t *);
127 127 static int spoolss_s_stub(void *, ndr_xa_t *);
128 128
129 129 static ndr_stub_table_t spoolss_stub_table[] = {
130 130 { spoolss_s_GetJob, SPOOLSS_OPNUM_GetJob },
131 131 { spoolss_s_EnumJobs, SPOOLSS_OPNUM_EnumJobs },
132 132 { spoolss_s_stub, SPOOLSS_OPNUM_DeletePrinter },
133 133 { spoolss_s_GetPrinter, SPOOLSS_OPNUM_GetPrinter },
134 134 { spoolss_s_stub, SPOOLSS_OPNUM_GetPrinterDriver },
135 135 { spoolss_s_stub, SPOOLSS_OPNUM_DeletePrinterDriver },
136 136 { spoolss_s_OpenPrinter, SPOOLSS_OPNUM_OpenPrinter },
137 137 { spoolss_s_StartDocPrinter, SPOOLSS_OPNUM_StartDocPrinter },
138 138 { spoolss_s_WritePrinter, SPOOLSS_OPNUM_WritePrinter },
139 139 { spoolss_s_EndDocPrinter, SPOOLSS_OPNUM_EndDocPrinter },
140 140 { spoolss_s_StartPagePrinter, SPOOLSS_OPNUM_StartPagePrinter },
141 141 { spoolss_s_EndPagePrinter, SPOOLSS_OPNUM_EndPagePrinter },
142 142 { spoolss_s_AbortPrinter, SPOOLSS_OPNUM_AbortPrinter },
143 143 { spoolss_s_ResetPrinter, SPOOLSS_OPNUM_ResetPrinter },
144 144 { spoolss_s_AddJob, SPOOLSS_OPNUM_AddJob },
145 145 { spoolss_s_ScheduleJob, SPOOLSS_OPNUM_ScheduleJob },
146 146 { spoolss_s_GetPrinterData, SPOOLSS_OPNUM_GetPrinterData },
147 147 { spoolss_s_ClosePrinter, SPOOLSS_OPNUM_ClosePrinter },
148 148 { spoolss_s_AddForm, SPOOLSS_OPNUM_AddForm },
149 149 { spoolss_s_DeleteForm, SPOOLSS_OPNUM_DeleteForm },
150 150 { spoolss_s_EnumForms, SPOOLSS_OPNUM_EnumForms },
151 151 { spoolss_s_AddMonitor, SPOOLSS_OPNUM_AddMonitor },
152 152 { spoolss_s_DeleteMonitor, SPOOLSS_OPNUM_DeleteMonitor },
153 153 { spoolss_s_DeletePort, SPOOLSS_OPNUM_DeletePort },
154 154 { spoolss_s_AddPortEx, SPOOLSS_OPNUM_AddPortEx },
155 155 { spoolss_s_SetPort, SPOOLSS_OPNUM_SetPort },
156 156 { spoolss_s_stub, SPOOLSS_OPNUM_GetPrinterDriver2 },
157 157 { spoolss_s_stub, SPOOLSS_OPNUM_FCPN },
158 158 { spoolss_s_stub, SPOOLSS_OPNUM_ReplyOpenPrinter },
159 159 { spoolss_s_stub, SPOOLSS_OPNUM_ReplyClosePrinter },
160 160 { spoolss_s_stub, SPOOLSS_OPNUM_RFFPCNEX },
161 161 { spoolss_s_rfnpcnex, SPOOLSS_OPNUM_RFNPCNEX },
162 162 { spoolss_s_stub, SPOOLSS_OPNUM_RRPCN },
163 163 { spoolss_s_OpenPrinter, SPOOLSS_OPNUM_OpenPrinterEx },
164 164 { spoolss_s_stub, SPOOLSS_OPNUM_EnumPrinterData },
165 165 { spoolss_s_stub, SPOOLSS_OPNUM_EnumPrinterDataEx },
166 166 { spoolss_s_stub, SPOOLSS_OPNUM_EnumPrinterKey },
167 167 {0}
168 168 };
169 169
170 170 static ndr_service_t spoolss_service = {
171 171 "SPOOLSS", /* name */
172 172 "Print Spool Service", /* desc */
173 173 "\\spoolss", /* endpoint */
174 174 PIPE_SPOOLSS, /* sec_addr_port */
175 175 "12345678-1234-abcd-ef00-0123456789ab", 1, /* abstract */
176 176 NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
177 177 0, /* no bind_instance_size */
178 178 0, /* no bind_req() */
179 179 0, /* no unbind_and_close() */
180 180 0, /* use generic_call_stub() */
181 181 &TYPEINFO(spoolss_interface), /* interface ti */
182 182 spoolss_stub_table /* stub_table */
183 183 };
184 184
185 185 void
186 186 spoolss_initialize(void)
187 187 {
188 188 if (!spoolss_splist.sp_initialized) {
189 189 list_create(&spoolss_splist.sp_list,
190 190 sizeof (smb_spooldoc_t),
191 191 offsetof(smb_spooldoc_t, sd_lnd));
192 192 spoolss_splist.sp_initialized = 1;
193 193 }
194 194
195 195 spoolss_copyfile_callback = NULL;
196 196
197 197 (void) ndr_svc_register(&spoolss_service);
198 198 }
199 199
200 200 void
201 201 spoolss_finalize(void)
202 202 {
203 203 spoolss_copyfile_callback = NULL;
204 204 }
205 205
206 206 /*
207 207 * Register a copyfile callback that the spoolss service can use to
208 208 * copy files to the spool directory.
209 209 *
210 210 * Set a null pointer to disable the copying of files to the spool
211 211 * directory.
212 212 */
213 213 void
214 214 spoolss_register_copyfile(spoolss_copyfile_t copyfile)
215 215 {
216 216 spoolss_copyfile_callback = copyfile;
217 217 }
218 218
219 219 static void
220 220 spoolss_copyfile(smb_inaddr_t *ipaddr, char *username, char *path,
221 221 char *docname)
222 222 {
223 223 if (spoolss_copyfile_callback != NULL)
224 224 (*spoolss_copyfile_callback)(ipaddr, username, path, docname);
225 225 }
226 226
227 227 static int
228 228 spoolss_s_OpenPrinter(void *arg, ndr_xa_t *mxa)
229 229 {
230 230 struct spoolss_OpenPrinter *param = arg;
231 231 char *name = (char *)param->printer_name;
232 232 ndr_hdid_t *id;
233 233
234 234 if (name != NULL && *name != '\0') {
235 235 if (strspn(name, "\\") > 2) {
236 236 bzero(¶m->handle, sizeof (spoolss_handle_t));
237 237 param->status = ERROR_INVALID_PRINTER_NAME;
238 238 return (NDR_DRC_OK);
239 239 }
240 240
241 241 smb_tracef("spoolss_s_OpenPrinter: %s", name);
242 242 }
243 243
244 244 if ((id = ndr_hdalloc(mxa, NULL)) == NULL) {
245 245 bzero(¶m->handle, sizeof (spoolss_handle_t));
246 246 param->status = ERROR_NOT_ENOUGH_MEMORY;
247 247 return (NDR_DRC_OK);
248 248 }
249 249
250 250 bcopy(id, ¶m->handle, sizeof (spoolss_handle_t));
251 251 param->status = 0;
252 252 return (NDR_DRC_OK);
253 253 }
254 254
255 255 /*ARGSUSED*/
256 256 static int
257 257 spoolss_s_StartPagePrinter(void *arg, ndr_xa_t *mxa)
258 258 {
259 259 struct spoolss_StartPagePrinter *param = arg;
260 260
261 261 param->status = ERROR_SUCCESS;
262 262
263 263 return (NDR_DRC_OK);
264 264 }
265 265
266 266 /*ARGSUSED*/
267 267 static int
268 268 spoolss_s_EndPagePrinter(void *arg, ndr_xa_t *mxa)
269 269 {
270 270 struct spoolss_EndPagePrinter *param = arg;
271 271
272 272 param->status = ERROR_SUCCESS;
273 273
274 274 return (NDR_DRC_OK);
275 275 }
276 276
277 277 /*
278 278 * Windows XP and 2000 use this mechanism to write spool files.
279 279 * Create a spool file fd to be used by spoolss_s_WritePrinter
280 280 * and add it to the tail of the spool list.
281 281 */
282 282 static int
283 283 spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
284 284 {
285 285 struct spoolss_StartDocPrinter *param = arg;
286 286 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
287 287 smb_spooldoc_t *spfile;
288 288 spoolss_DocInfo_t *docinfo;
289 289 char g_path[MAXPATHLEN];
290 290 smb_share_t si;
291 291 int rc;
292 292 int fd;
293 293
294 294 if (ndr_hdlookup(mxa, id) == NULL) {
295 295 smb_tracef("spoolss_s_StartDocPrinter: invalid handle");
296 296 param->status = ERROR_INVALID_HANDLE;
297 297 return (NDR_DRC_OK);
298 298 }
299 299
300 300 if ((docinfo = param->dinfo.DocInfoContainer) == NULL) {
301 301 param->status = ERROR_INVALID_PARAMETER;
302 302 return (NDR_DRC_OK);
303 303 }
304 304
305 305 if ((rc = smb_shr_get(SMB_SHARE_PRINT, &si)) != NERR_Success) {
306 306 smb_tracef("spoolss_s_StartDocPrinter: %s error=%d",
307 307 SMB_SHARE_PRINT, rc);
308 308 param->status = rc;
309 309 return (NDR_DRC_OK);
310 310 }
311 311
312 312 if ((spfile = calloc(1, sizeof (smb_spooldoc_t))) == NULL) {
313 313 param->status = ERROR_NOT_ENOUGH_MEMORY;
314 314 return (NDR_DRC_OK);
315 315 }
316 316
317 317 if (docinfo->doc_name != NULL)
318 318 (void) strlcpy(spfile->sd_doc_name,
319 319 (char *)docinfo->doc_name, MAXNAMELEN);
320 320 else
321 321 (void) strlcpy(spfile->sd_doc_name, "document", MAXNAMELEN);
322 322
323 323 if (docinfo->printer_name != NULL)
324 324 (void) strlcpy(spfile->sd_printer_name,
325 325 (char *)docinfo->printer_name, MAXPATHLEN);
326 326 else
327 327 (void) strlcpy(spfile->sd_printer_name, "printer", MAXPATHLEN);
328 328
329 329 spfile->sd_ipaddr = mxa->pipe->np_user->ui_ipaddr;
330 330 (void) strlcpy((char *)spfile->sd_username,
331 331 mxa->pipe->np_user->ui_account, MAXNAMELEN);
332 332 (void) memcpy(&spfile->sd_handle, ¶m->handle, sizeof (ndr_hdid_t));
333 333
334 334 /*
335 335 * write temporary spool file to print$
336 336 */
337 337 (void) snprintf(g_path, MAXPATHLEN, "%s/%s%d", si.shr_path,
338 338 spfile->sd_username, spoolss_cnt);
339 339 atomic_inc_32(&spoolss_cnt);
340 340
341 341 fd = open(g_path, O_CREAT | O_RDWR, 0600);
342 342 if (fd == -1) {
343 343 smb_tracef("spoolss_s_StartDocPrinter: %s: %s",
344 344 g_path, strerror(errno));
345 345 param->status = ERROR_OPEN_FAILED;
346 346 free(spfile);
347 347 } else {
348 348 (void) strlcpy((char *)spfile->sd_path, g_path, MAXPATHLEN);
349 349 spfile->sd_fd = (uint16_t)fd;
350 350
351 351 /*
352 352 * Add the document to the spool list.
353 353 */
354 354 (void) rw_wrlock(&spoolss_splist.sp_rwl);
355 355 list_insert_tail(&spoolss_splist.sp_list, spfile);
356 356 spoolss_splist.sp_cnt++;
357 357 (void) rw_unlock(&spoolss_splist.sp_rwl);
358 358
359 359 /*
360 360 * JobId isn't used now, but if printQ management is added
361 361 * this will have to be incremented per job submitted.
362 362 */
363 363 param->JobId = 46;
364 364 param->status = ERROR_SUCCESS;
365 365 }
366 366 return (NDR_DRC_OK);
367 367 }
368 368
369 369 /*
370 370 * Windows XP and 2000 use this mechanism to write spool files
371 371 * Search the spooldoc list for a matching RPC handle and pass
372 372 * the spool the file for printing.
373 373 */
374 374 static int
375 375 spoolss_s_EndDocPrinter(void *arg, ndr_xa_t *mxa)
376 376 {
377 377 struct spoolss_EndDocPrinter *param = arg;
378 378 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
379 379 smb_spooldoc_t *sp;
380 380
381 381 if (ndr_hdlookup(mxa, id) == NULL) {
382 382 smb_tracef("spoolss_s_EndDocPrinter: invalid handle");
383 383 param->status = ERROR_INVALID_HANDLE;
384 384 return (NDR_DRC_OK);
385 385 }
386 386
387 387 param->status = ERROR_INVALID_HANDLE;
388 388 (void) rw_wrlock(&spoolss_splist.sp_rwl);
389 389
390 390 sp = list_head(&spoolss_splist.sp_list);
391 391 while (sp != NULL) {
392 392 if (!memcmp(id, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
393 393 spoolss_copyfile(&sp->sd_ipaddr,
394 394 sp->sd_username, sp->sd_path, sp->sd_doc_name);
395 395 (void) close(sp->sd_fd);
396 396 list_remove(&spoolss_splist.sp_list, sp);
397 397 free(sp);
398 398 param->status = ERROR_SUCCESS;
399 399 break;
400 400 }
401 401
402 402 sp = list_next(&spoolss_splist.sp_list, sp);
403 403 }
404 404
405 405 (void) rw_unlock(&spoolss_splist.sp_rwl);
406 406
407 407 if (param->status != ERROR_SUCCESS)
408 408 smb_tracef("spoolss_s_EndDocPrinter: document not found");
409 409 return (NDR_DRC_OK);
410 410 }
411 411
412 412 /*ARGSUSED*/
413 413 static int
414 414 spoolss_s_AbortPrinter(void *arg, ndr_xa_t *mxa)
415 415 {
416 416 struct spoolss_AbortPrinter *param = arg;
417 417
418 418 param->status = ERROR_SUCCESS;
419 419 return (NDR_DRC_OK);
420 420 }
421 421
422 422 /*ARGSUSED*/
423 423 static int
424 424 spoolss_s_ResetPrinter(void *arg, ndr_xa_t *mxa)
425 425 {
426 426 struct spoolss_AbortPrinter *param = arg;
427 427
428 428 param->status = ERROR_SUCCESS;
429 429 return (NDR_DRC_OK);
430 430 }
431 431
432 432 static int
433 433 spoolss_s_ClosePrinter(void *arg, ndr_xa_t *mxa)
434 434 {
435 435 struct spoolss_ClosePrinter *param = arg;
436 436 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
437 437 ndr_handle_t *hd;
438 438
439 439 if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
440 440 free(hd->nh_data);
441 441 hd->nh_data = NULL;
442 442 }
443 443
444 444 ndr_hdfree(mxa, id);
445 445 bzero(¶m->result_handle, sizeof (spoolss_handle_t));
446 446 param->status = ERROR_SUCCESS;
447 447 return (NDR_DRC_OK);
448 448 }
449 449
450 450 static int
451 451 spoolss_s_AddForm(void *arg, ndr_xa_t *mxa)
452 452 {
453 453 struct spoolss_AddForm *param = arg;
454 454 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
455 455
456 456 if (ndr_hdlookup(mxa, id) == NULL) {
457 457 bzero(param, sizeof (struct spoolss_AddForm));
458 458 param->status = ERROR_INVALID_HANDLE;
459 459 return (NDR_DRC_OK);
460 460 }
461 461
462 462 bzero(param, sizeof (struct spoolss_AddForm));
463 463 param->status = ERROR_SUCCESS;
464 464 return (NDR_DRC_OK);
465 465 }
466 466
467 467 static int
468 468 spoolss_s_DeleteForm(void *arg, ndr_xa_t *mxa)
469 469 {
470 470 struct spoolss_DeleteForm *param = arg;
471 471 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
472 472
473 473 if (ndr_hdlookup(mxa, id) == NULL) {
474 474 bzero(param, sizeof (struct spoolss_DeleteForm));
475 475 param->status = ERROR_INVALID_HANDLE;
476 476 return (NDR_DRC_OK);
477 477 }
478 478
479 479 bzero(param, sizeof (struct spoolss_DeleteForm));
480 480 param->status = ERROR_SUCCESS;
481 481 return (NDR_DRC_OK);
482 482 }
483 483
484 484 static int
485 485 spoolss_s_EnumForms(void *arg, ndr_xa_t *mxa)
486 486 {
487 487 struct spoolss_EnumForms *param = arg;
488 488 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
489 489
490 490 if (ndr_hdlookup(mxa, id) == NULL) {
491 491 bzero(param, sizeof (struct spoolss_EnumForms));
492 492 param->status = ERROR_INVALID_HANDLE;
493 493 return (NDR_DRC_OK);
494 494 }
495 495
496 496 bzero(param, sizeof (struct spoolss_EnumForms));
497 497 param->status = ERROR_SUCCESS;
498 498 param->needed = 0;
499 499 return (NDR_DRC_OK);
500 500 }
501 501
502 502 /*ARGSUSED*/
503 503 static int
504 504 spoolss_s_AddMonitor(void *arg, ndr_xa_t *mxa)
505 505 {
506 506 struct spoolss_AddMonitor *param = arg;
507 507
508 508 param->status = ERROR_SUCCESS;
509 509 return (NDR_DRC_OK);
510 510 }
511 511
512 512 /*ARGSUSED*/
513 513 static int
514 514 spoolss_s_DeleteMonitor(void *arg, ndr_xa_t *mxa)
515 515 {
516 516 struct spoolss_DeleteMonitor *param = arg;
517 517
518 518 param->status = ERROR_SUCCESS;
519 519 return (NDR_DRC_OK);
520 520 }
521 521
522 522 /*ARGSUSED*/
523 523 static int
524 524 spoolss_s_DeletePort(void *arg, ndr_xa_t *mxa)
525 525 {
526 526 struct spoolss_DeletePort *param = arg;
527 527
528 528 param->status = ERROR_SUCCESS;
529 529 return (NDR_DRC_OK);
530 530 }
531 531
532 532 /*ARGSUSED*/
533 533 static int
534 534 spoolss_s_AddPortEx(void *arg, ndr_xa_t *mxa)
535 535 {
536 536 struct spoolss_AddPortEx *param = arg;
537 537
538 538 param->status = ERROR_SUCCESS;
539 539 return (NDR_DRC_OK);
540 540 }
541 541
542 542 /*ARGSUSED*/
543 543 static int
544 544 spoolss_s_SetPort(void *arg, ndr_xa_t *mxa)
545 545 {
546 546 struct spoolss_SetPort *param = arg;
547 547
548 548 param->status = ERROR_SUCCESS;
549 549 return (NDR_DRC_OK);
550 550 }
551 551
552 552 /*ARGSUSED*/
553 553 static int
554 554 spoolss_s_EnumJobs(void *arg, ndr_xa_t *mxa)
555 555 {
556 556 struct spoolss_EnumJobs *param = arg;
557 557 DWORD status = ERROR_SUCCESS;
558 558
559 559 switch (param->level) {
560 560 case 1:
561 561 case 2:
562 562 case 3:
563 563 case 4:
564 564 default:
565 565 break;
566 566 }
567 567
568 568 param->status = status;
569 569 param->needed = 0;
570 570 param->needed2 = 0;
571 571 return (NDR_DRC_OK);
572 572 }
573 573
574 574
575 575 /*ARGSUSED*/
576 576 static int
577 577 spoolss_s_GetJob(void *arg, ndr_xa_t *mxa)
578 578 {
579 579 struct spoolss_GetJob *param = arg;
580 580 DWORD status = ERROR_SUCCESS;
581 581
582 582 if (param->BufCount == 0)
583 583 param->status = ERROR_INSUFFICIENT_BUFFER;
584 584 else
585 585 param->status = status;
586 586 param->needed = 0;
587 587 return (NDR_DRC_OK);
588 588 }
589 589
590 590
591 591 /*ARGSUSED*/
592 592 static int
593 593 spoolss_s_ScheduleJob(void *arg, ndr_xa_t *mxa)
594 594 {
595 595 struct spoolss_ScheduleJob *param = arg;
596 596 DWORD status = ERROR_SPL_NO_ADDJOB;
597 597
598 598 param->status = status;
599 599 return (NDR_DRC_OK);
600 600 }
601 601
602 602 /*ARGSUSED*/
603 603 static int
604 604 spoolss_s_AddJob(void *arg, ndr_xa_t *mxa)
605 605 {
606 606 struct spoolss_AddJob *param = arg;
607 607
608 608 param->status = ERROR_SUCCESS;
609 609 param->needed = 0;
610 610 return (NDR_DRC_OK);
611 611 }
612 612
613 613 /*ARGSUSED*/
614 614 static int
615 615 spoolss_s_rfnpcnex(void *arg, ndr_xa_t *mxa)
616 616 {
617 617 struct spoolss_RFNPCNEX *param = arg;
618 618
619 619 param->ppinfo = 0;
620 620 param->status = ERROR_SUCCESS;
621 621 return (NDR_DRC_OK);
622 622 }
623 623
624 624 /*
625 625 * Use the RPC context handle to find the fd and write the document content.
626 626 */
627 627 static int
628 628 spoolss_s_WritePrinter(void *arg, ndr_xa_t *mxa)
629 629 {
630 630 struct spoolss_WritePrinter *param = arg;
631 631 int written = 0;
632 632 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
633 633 int spfd;
634 634
635 635 if (ndr_hdlookup(mxa, id) == NULL) {
636 636 param->written = 0;
637 637 param->status = ERROR_INVALID_HANDLE;
638 638 smb_tracef("spoolss_s_WritePrinter: invalid handle");
639 639 return (NDR_DRC_OK);
640 640 }
641 641
642 642 if ((spfd = spoolss_find_document(id)) < 0) {
643 643 param->written = 0;
644 644 param->status = ERROR_INVALID_HANDLE;
645 645 smb_tracef("spoolss_s_WritePrinter: document not found");
646 646 return (NDR_DRC_OK);
647 647 }
648 648
649 649 written = write(spfd, param->pBuf, param->BufCount);
650 650 if (written < param->BufCount) {
651 651 smb_tracef("spoolss_s_WritePrinter: write failed");
652 652 param->written = 0;
653 653 param->status = ERROR_CANTWRITE;
654 654 return (NDR_DRC_OK);
655 655 }
656 656
657 657 param->written = written;
658 658 param->status = ERROR_SUCCESS;
659 659 return (NDR_DRC_OK);
660 660 }
661 661
662 662 /*
663 663 * Find a document by RPC handle in the spool list and return the fd.
664 664 */
665 665 static int
666 666 spoolss_find_document(ndr_hdid_t *handle)
667 667 {
668 668 smb_spooldoc_t *sp;
669 669
670 670 (void) rw_rdlock(&spoolss_splist.sp_rwl);
671 671
672 672 sp = list_head(&spoolss_splist.sp_list);
673 673 while (sp != NULL) {
674 674 if (!memcmp(handle, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
675 675 (void) rw_unlock(&spoolss_splist.sp_rwl);
676 676 return (sp->sd_fd);
677 677 }
678 678 sp = list_next(&spoolss_splist.sp_list, sp);
679 679 }
680 680
681 681 (void) rw_unlock(&spoolss_splist.sp_rwl);
682 682 return (-1);
683 683 }
684 684
685 685 /*
686 686 * GetPrinterData is used t obtain values from the registry for a
687 687 * printer or a print server. See [MS-RPRN] for value descriptions.
688 688 * The registry returns ERROR_FILE_NOT_FOUND for unknown keys.
689 689 */
690 690 static int
691 691 spoolss_s_GetPrinterData(void *arg, ndr_xa_t *mxa)
692 692 {
693 693 static spoolss_winreg_t reg[] = {
694 694 { "ChangeId", 0x0050acf2 },
695 695 { "W3SvcInstalled", 0x00000000 },
696 696 { "BeepEnabled", 0x00000000 },
697 697 { "EventLog", 0x0000001f },
698 698 { "NetPopup", 0x00000000 },
699 699 { "NetPopupToComputer", 0x00000000 },
700 700 { "MajorVersion", 0x00000003 },
701 701 { "MinorVersion", 0x00000000 },
702 702 { "DsPresent", 0x00000000 }
703 703 };
704 704
705 705 struct spoolss_GetPrinterData *param = arg;
706 706 char *name = (char *)param->pValueName;
707 707 char buf[MAXPATHLEN];
708 708 static uint8_t reserved_buf[4];
709 709 spoolss_winreg_t *rp;
710 710 smb_share_t si;
711 711 smb_version_t *osversion;
712 712 struct utsname sysname;
713 713 smb_wchar_t *wcs;
714 714 uint32_t value;
715 715 uint32_t status;
716 716 int wcslen;
717 717 int i;
718 718
719 719 if (name == NULL || *name == '\0') {
720 720 status = ERROR_FILE_NOT_FOUND;
721 721 goto report_error;
722 722 }
723 723
724 724 for (i = 0; i < sizeof (reg) / sizeof (reg[0]); ++i) {
725 725 param->pType = WINREG_DWORD;
726 726 param->Needed = sizeof (uint32_t);
727 727 rp = ®[i];
728 728
729 729 if (strcasecmp(name, rp->name) != 0)
730 730 continue;
731 731
732 732 if (param->Size < sizeof (uint32_t)) {
733 733 param->Size = 0;
734 734 goto need_more_data;
735 735 }
736 736
737 737 if ((param->Buf = NDR_NEW(mxa, uint32_t)) == NULL) {
738 738 status = ERROR_NOT_ENOUGH_MEMORY;
739 739 goto report_error;
740 740 }
741 741
742 742 value = rp->value;
743 743
744 744 if ((strcasecmp(name, "DsPresent") == 0) &&
745 745 (smb_config_get_secmode() == SMB_SECMODE_DOMAIN))
746 746 value = 0x00000001;
747 747
748 748 bcopy(&value, param->Buf, sizeof (uint32_t));
749 749 param->Size = sizeof (uint32_t);
750 750 param->status = ERROR_SUCCESS;
751 751 return (NDR_DRC_OK);
752 752 }
753 753
754 754 if (strcasecmp(name, "OSVersion") == 0) {
755 755 param->pType = WINREG_BINARY;
756 756 param->Needed = sizeof (smb_version_t);
757 757
758 758 if (param->Size < sizeof (smb_version_t)) {
759 759 param->Size = sizeof (smb_version_t);
760 760 goto need_more_data;
761 761 }
762 762
763 763 if ((osversion = NDR_NEW(mxa, smb_version_t)) == NULL) {
764 764 status = ERROR_NOT_ENOUGH_MEMORY;
765 765 goto report_error;
766 766 }
767 767
768 768 smb_config_get_version(osversion);
769 769 param->Buf = (uint8_t *)osversion;
770 770 param->status = ERROR_SUCCESS;
771 771 return (NDR_DRC_OK);
772 772 }
773 773
774 774 if (strcasecmp(name, "DNSMachineName") == 0) {
775 775 param->pType = WINREG_SZ;
776 776 buf[0] = '\0';
777 777 (void) smb_getfqhostname(buf, MAXHOSTNAMELEN);
778 778 goto encode_string;
779 779 }
780 780
781 781 if (strcasecmp(name, "DefaultSpoolDirectory") == 0) {
782 782 param->pType = WINREG_SZ;
783 783 buf[0] = '\0';
784 784
785 785 if (smb_shr_get(SMB_SHARE_PRINT, &si) != NERR_Success) {
786 786 status = ERROR_FILE_NOT_FOUND;
787 787 goto report_error;
788 788 }
789 789
790 790 (void) snprintf(buf, MAXPATHLEN, "C:/%s", si.shr_path);
791 791 (void) strcanon(buf, "/\\");
792 792 (void) strsubst(buf, '/', '\\');
793 793 goto encode_string;
794 794 }
795 795
796 796 if (strcasecmp(name, "Architecture") == 0) {
797 797 param->pType = WINREG_SZ;
798 798
799 799 if (uname(&sysname) < 0)
800 800 (void) strlcpy(buf, "Solaris", MAXPATHLEN);
801 801 else
802 802 (void) snprintf(buf, MAXPATHLEN, "%s %s",
803 803 sysname.sysname, sysname.machine);
804 804
805 805 goto encode_string;
806 806 }
807 807
808 808 status = ERROR_FILE_NOT_FOUND;
809 809
810 810 report_error:
811 811 bzero(param, sizeof (struct spoolss_GetPrinterData));
812 812 param->Buf = reserved_buf;
813 813 param->status = status;
814 814 return (NDR_DRC_OK);
815 815
816 816 encode_string:
817 817 wcslen = smb_wcequiv_strlen(buf) + sizeof (smb_wchar_t);
818 818 if (param->Size < wcslen) {
819 819 param->Needed = wcslen;
820 820 goto need_more_data;
821 821 }
822 822
823 823 if ((wcs = NDR_MALLOC(mxa, wcslen)) == NULL) {
824 824 status = ERROR_NOT_ENOUGH_MEMORY;
825 825 goto report_error;
826 826 }
827 827
828 828 (void) ndr_mbstowcs(NULL, wcs, buf, wcslen);
829 829 param->Buf = (uint8_t *)wcs;
830 830 param->Needed = wcslen;
831 831 param->status = ERROR_SUCCESS;
832 832 return (NDR_DRC_OK);
833 833
834 834 need_more_data:
835 835 param->Size = 0;
836 836 param->Buf = reserved_buf;
837 837 param->status = ERROR_MORE_DATA;
838 838 return (NDR_DRC_OK);
839 839 }
840 840
841 841 void
842 842 smb_rpc_off(char *dst, char *src, uint32_t *offset, uint32_t *outoffset)
843 843 {
844 844 int nwchars;
845 845 int bytes;
846 846
847 847 bytes = smb_wcequiv_strlen(src) + 2;
848 848 nwchars = strlen(src) + 1;
849 849 *offset -= bytes;
850 850 *outoffset = *offset;
851 851 /*LINTED E_BAD_PTR_CAST_ALIGN*/
852 852 (void) smb_mbstowcs(((smb_wchar_t *)(dst + *offset)), src, nwchars);
853 853 }
854 854
855 855 int
856 856 spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
857 857 {
858 858 struct spoolss_GetPrinter *param = arg;
859 859 struct spoolss_GetPrinter0 *pinfo0;
860 860 struct spoolss_GetPrinter1 *pinfo1;
861 861 struct spoolss_GetPrinter2 *pinfo2;
862 862 struct spoolss_DeviceMode *devmode2;
863 863 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
864 864 spoolss_sd_t secdesc;
865 865 char server[MAXNAMELEN];
866 866 char printer[MAXNAMELEN];
867 867 DWORD status = ERROR_SUCCESS;
868 868 char *wname;
869 869 uint32_t offset;
870 870 uint8_t *tmpbuf;
871 871
872 872 if (ndr_hdlookup(mxa, id) == NULL) {
873 873 status = ERROR_INVALID_HANDLE;
874 874 goto error_out;
875 875 }
876 876
877 877 if (spoolss_getservername(server, MAXNAMELEN) != 0) {
878 878 status = ERROR_INTERNAL_ERROR;
879 879 goto error_out;
880 880 }
881 881
882 882 (void) snprintf(printer, MAXNAMELEN, "%s\\%s", server, SPOOLSS_PRINTER);
883 883
884 884 switch (param->switch_value) {
885 885 case 0:
886 886 case 1:
887 887 param->needed = 460;
888 888 break;
889 889 case 2:
890 890 param->needed = 712;
891 891 break;
892 892 default:
893 893 status = ERROR_INVALID_LEVEL;
894 894 goto error_out;
895 895 }
896 896
897 897 if (param->BufCount < param->needed) {
898 898 param->BufCount = 0;
899 899 param->Buf = NULL;
900 900 param->status = ERROR_INSUFFICIENT_BUFFER;
901 901 return (NDR_DRC_OK);
902 902 }
903 903
904 904 if ((param->Buf = NDR_MALLOC(mxa, param->BufCount)) == NULL) {
905 905 status = ERROR_NOT_ENOUGH_MEMORY;
906 906 goto error_out;
907 907 }
908 908
909 909 bzero(param->Buf, param->BufCount);
910 910 wname = (char *)param->Buf;
911 911 offset = param->needed;
912 912
913 913 switch (param->switch_value) {
914 914 case 0:
915 915 /*LINTED E_BAD_PTR_CAST_ALIGN*/
916 916 pinfo0 = (struct spoolss_GetPrinter0 *)param->Buf;
917 917
918 918 smb_rpc_off(wname, server, &offset, &pinfo0->servername);
919 919 smb_rpc_off(wname, printer, &offset, &pinfo0->printername);
920 920 pinfo0->cjobs = 0;
921 921 pinfo0->total_jobs = 6;
922 922 pinfo0->total_bytes = 1040771;
923 923 pinfo0->time0 = 0;
924 924 pinfo0->time1 = 0;
925 925 pinfo0->time2 = 3;
926 926 pinfo0->time3 = 0;
927 927 pinfo0->global_counter = 2162710;
928 928 pinfo0->total_pages = 21495865;
929 929 pinfo0->version = 10;
930 930 pinfo0->session_counter = 1;
931 931 pinfo0->job_error = 0x6;
932 932 pinfo0->change_id = 0x1;
933 933 pinfo0->status = 0;
934 934 pinfo0->c_setprinter = 0;
935 935 break;
936 936 case 1:
937 937 /*LINTED E_BAD_PTR_CAST_ALIGN*/
938 938 pinfo1 = (struct spoolss_GetPrinter1 *)param->Buf;
939 939
940 940 pinfo1->flags = PRINTER_ENUM_ICON8;
941 941 smb_rpc_off(wname, printer, &offset, &pinfo1->flags);
942 942 smb_rpc_off(wname, printer, &offset, &pinfo1->description);
943 943 smb_rpc_off(wname, printer, &offset, &pinfo1->comment);
944 944 break;
945 945 case 2:
946 946 /*LINTED E_BAD_PTR_CAST_ALIGN*/
947 947 pinfo2 = (struct spoolss_GetPrinter2 *)param->Buf;
948 948
949 949 smb_rpc_off(wname, server, &offset, &pinfo2->servername);
950 950 smb_rpc_off(wname, printer, &offset, &pinfo2->printername);
951 951 smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
952 952 &pinfo2->sharename);
953 953 smb_rpc_off(wname, "CIFS Printer Port", &offset,
954 954 &pinfo2->portname);
955 955 smb_rpc_off(wname, "", &offset, &pinfo2->drivername);
956 956 smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
957 957 &pinfo2->comment);
958 958 smb_rpc_off(wname, "farside", &offset, &pinfo2->location);
959 959
960 960 offset -= sizeof (struct spoolss_DeviceMode);
961 961 pinfo2->devmode = offset;
962 962 /*LINTED E_BAD_PTR_CAST_ALIGN*/
963 963 devmode2 = (struct spoolss_DeviceMode *)(param->Buf + offset);
964 964
965 965 smb_rpc_off(wname, "farside", &offset, &pinfo2->sepfile);
966 966 smb_rpc_off(wname, "winprint", &offset,
967 967 &pinfo2->printprocessor);
968 968 smb_rpc_off(wname, "RAW", &offset, &pinfo2->datatype);
969 969 smb_rpc_off(wname, "", &offset, &pinfo2->parameters);
970 970
971 971 status = spoolss_make_sd(mxa, &secdesc);
972 972 if (status == ERROR_SUCCESS) {
973 973 offset -= secdesc.sd_size;
974 974 pinfo2->secdesc = offset;
975 975 tmpbuf = (uint8_t *)(param->Buf + offset);
976 976 bcopy(secdesc.sd_buf, tmpbuf, secdesc.sd_size);
977 977 }
978 978
979 979 pinfo2->attributes = 0x00001048;
980 980 pinfo2->status = 0x00000000;
981 981 pinfo2->starttime = 0;
982 982 pinfo2->untiltime = 0;
983 983 pinfo2->cjobs = 0;
984 984 pinfo2->averageppm = 0;
985 985 pinfo2->defaultpriority = 0;
986 986
987 987 /*LINTED E_BAD_PTR_CAST_ALIGN*/
988 988 (void) smb_mbstowcs((smb_wchar_t *)devmode2->devicename,
989 989 printer, 32);
990 990 devmode2->specversion = 0x0401;
991 991 devmode2->driverversion = 1024;
992 992 devmode2->size = 220;
993 993 devmode2->driverextra_length = 0;
994 994 devmode2->fields = 0x00014713;
995 995 devmode2->orientation = 1;
996 996 devmode2->papersize = 1;
997 997 devmode2->paperlength = 0;
998 998 devmode2->paperwidth = 0;
999 999 devmode2->scale = 100;
1000 1000 devmode2->copies = 1;
1001 1001 devmode2->defaultsource = 15;
1002 1002 devmode2->printquality = 65532;
1003 1003 devmode2->color = 1;
1004 1004 devmode2->duplex = 1;
1005 1005 devmode2->yresolution = 1;
1006 1006 devmode2->ttoption = 1;
1007 1007 devmode2->collate = 0;
1008 1008 /*LINTED E_BAD_PTR_CAST_ALIGN*/
1009 1009 (void) smb_mbstowcs((smb_wchar_t *)devmode2->formname,
1010 1010 "Letter", 32);
1011 1011 devmode2->logpixels = 0;
1012 1012 devmode2->bitsperpel = 0;
1013 1013 devmode2->pelswidth = 0;
1014 1014 devmode2->pelsheight = 0;
1015 1015 devmode2->displayflags = 0;
1016 1016 devmode2->displayfrequency = 0;
1017 1017 devmode2->icmmethod = 0;
1018 1018 devmode2->icmintent = 0;
1019 1019 devmode2->mediatype = 0;
1020 1020 devmode2->dithertype = 0;
1021 1021 devmode2->reserved1 = 0;
1022 1022 devmode2->reserved2 = 0;
1023 1023 devmode2->panningwidth = 0;
1024 1024 devmode2->panningheight = 0;
1025 1025 break;
1026 1026
1027 1027 default:
1028 1028 break;
1029 1029 }
1030 1030
1031 1031 param->status = status;
1032 1032 return (NDR_DRC_OK);
1033 1033
1034 1034 error_out:
1035 1035 smb_tracef("spoolss_s_GetPrinter: error %u", status);
1036 1036 bzero(param, sizeof (struct spoolss_GetPrinter));
1037 1037 param->status = status;
1038 1038 return (NDR_DRC_OK);
1039 1039 }
1040 1040
1041 1041 static int
1042 1042 spoolss_getservername(char *name, size_t namelen)
1043 1043 {
1044 1044 char hostname[MAXHOSTNAMELEN];
1045 1045 char ipstr[INET6_ADDRSTRLEN];
1046 1046 smb_inaddr_t ipaddr;
1047 1047 struct hostent *h;
1048 1048 const char *p;
1049 1049 int error;
1050 1050
1051 1051 if (smb_gethostname(hostname, MAXHOSTNAMELEN, 0) != 0) {
1052 1052 smb_tracef("spoolss_s_GetPrinter: gethostname failed");
1053 1053 return (-1);
1054 1054 }
1055 1055
1056 1056 if ((h = smb_gethostbyname(hostname, &error)) == NULL) {
1057 1057 smb_tracef("spoolss_s_GetPrinter: gethostbyname failed: %d",
1058 1058 error);
1059 1059 return (-1);
1060 1060 }
1061 1061
1062 1062 bcopy(h->h_addr, &ipaddr, h->h_length);
1063 1063 ipaddr.a_family = h->h_addrtype;
1064 1064 freehostent(h);
1065 1065
1066 1066 p = smb_inet_ntop(&ipaddr, ipstr, SMB_IPSTRLEN(ipaddr.a_family));
1067 1067 if (p == NULL) {
1068 1068 smb_tracef("spoolss_s_GetPrinter: inet_ntop failed");
1069 1069 return (-1);
1070 1070 }
1071 1071
1072 1072 (void) snprintf(name, namelen, "\\\\%s", ipstr);
1073 1073 return (0);
1074 1074 }
1075 1075
1076 1076 static uint32_t
1077 1077 spoolss_make_sd(ndr_xa_t *mxa, spoolss_sd_t *secdesc)
1078 1078 {
1079 1079 smb_sd_t sd;
1080 1080 uint8_t *sd_buf;
1081 1081 uint32_t sd_len;
1082 1082 uint32_t status;
1083 1083
1084 1084 bzero(&sd, sizeof (smb_sd_t));
1085 1085
1086 1086 if ((status = spoolss_format_sd(&sd)) != ERROR_SUCCESS)
1087 1087 return (status);
1088 1088
1089 1089 sd_len = smb_sd_len(&sd, SMB_ALL_SECINFO);
1090 1090
1091 1091 if ((sd_buf = NDR_MALLOC(mxa, sd_len)) == NULL)
1092 1092 return (ERROR_NOT_ENOUGH_MEMORY);
1093 1093
1094 1094 secdesc->sd_buf = sd_buf;
1095 1095 secdesc->sd_size = sd_len;
1096 1096
1097 1097 status = srvsvc_sd_set_relative(&sd, sd_buf);
1098 1098 smb_sd_term(&sd);
1099 1099 return (status);
1100 1100 }
1101 1101
1102 1102 static uint32_t
1103 1103 spoolss_format_sd(smb_sd_t *sd)
1104 1104 {
1105 1105 smb_fssd_t fs_sd;
1106 1106 acl_t *acl;
1107 1107 uint32_t status = ERROR_SUCCESS;
1108 1108
1109 1109 if (acl_fromtext("everyone@:full_set::allow", &acl) != 0) {
1110 1110 smb_tracef("spoolss_format_sd: NOT_ENOUGH_MEMORY");
1111 1111 return (ERROR_NOT_ENOUGH_MEMORY);
1112 1112 }
1113 1113 smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR);
1114 1114 fs_sd.sd_uid = 0;
1115 1115 fs_sd.sd_gid = 0;
1116 1116 fs_sd.sd_zdacl = acl;
1117 1117 fs_sd.sd_zsacl = NULL;
1118 1118
1119 1119 status = smb_sd_fromfs(&fs_sd, sd);
1120 1120 if (status != NT_STATUS_SUCCESS) {
1121 1121 smb_tracef("spoolss_format_sd: %u", status);
1122 1122 status = ERROR_ACCESS_DENIED;
1123 1123 }
1124 1124 smb_fssd_term(&fs_sd);
1125 1125 return (status);
1126 1126 }
1127 1127
1128 1128 /*ARGSUSED*/
1129 1129 static int
1130 1130 spoolss_s_stub(void *arg, ndr_xa_t *mxa)
1131 1131 {
1132 1132 return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);
1133 1133 }
1134 1134
1135 1135 void
1136 1136 fixup_spoolss_RFNPCNEX(struct spoolss_RFNPCNEX *val)
1137 1137 {
1138 1138 unsigned short size1 = 0;
1139 1139 unsigned short size2 = 0;
1140 1140 unsigned short size3 = 0;
1141 1141 struct spoolss_RPC_V2_NOTIFY_INFO *pinfo;
1142 1142
1143 1143 pinfo = val->ppinfo->pinfo;
1144 1144 switch (pinfo->aData->Reserved) {
1145 1145 case TABLE_STRING:
1146 1146 size1 = sizeof (struct STRING_CONTAINER);
1147 1147 break;
1148 1148 case TABLE_DWORD:
1149 1149 size1 = sizeof (DWORD) * 2;
1150 1150 break;
1151 1151 case TABLE_TIME:
1152 1152 size1 = sizeof (struct SYSTEMTIME_CONTAINER);
1153 1153 break;
1154 1154 case TABLE_DEVMODE:
1155 1155 size1 = sizeof (struct spoolssDevmodeContainer);
1156 1156 break;
1157 1157 case TABLE_SECURITY_DESCRIPTOR:
1158 1158 size1 = sizeof (struct SECURITY_CONTAINER);
1159 1159 break;
1160 1160 default:
1161 1161 return;
1162 1162 }
1163 1163 size2 = size1 + (2 * sizeof (DWORD));
1164 1164 size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1165 1165
1166 1166 FIXUP_PDU_SIZE(spoolss_RPC_V2_NOTIFY_INFO_DATA_DATA, size1);
1167 1167 FIXUP_PDU_SIZE(spoolss_RPC_V2_NOTIFY_INFO_DATA, size2);
1168 1168 FIXUP_PDU_SIZE(spoolss_RPC_V2_NOTIFY_INFO, size3);
1169 1169 FIXUP_PDU_SIZE(spoolss_RFNPCNEX, size3);
1170 1170 }
1171 1171
1172 1172 void
1173 1173 fixup_spoolss_GetPrinter(struct spoolss_GetPrinter *val)
1174 1174 {
1175 1175 unsigned short size1 = 0;
1176 1176 unsigned short size2 = 0;
1177 1177 unsigned short size3 = 0;
1178 1178
1179 1179 switch (val->switch_value) {
1180 1180 CASE_INFO_ENT(spoolss_GetPrinter, 0);
1181 1181 CASE_INFO_ENT(spoolss_GetPrinter, 1);
1182 1182 CASE_INFO_ENT(spoolss_GetPrinter, 2);
1183 1183 CASE_INFO_ENT(spoolss_GetPrinter, 3);
1184 1184 CASE_INFO_ENT(spoolss_GetPrinter, 4);
1185 1185 CASE_INFO_ENT(spoolss_GetPrinter, 5);
1186 1186 CASE_INFO_ENT(spoolss_GetPrinter, 6);
1187 1187 CASE_INFO_ENT(spoolss_GetPrinter, 7);
1188 1188 CASE_INFO_ENT(spoolss_GetPrinter, 8);
1189 1189
1190 1190 default:
1191 1191 return;
1192 1192 };
1193 1193
1194 1194 size2 = size1 + (2 * sizeof (DWORD));
1195 1195 size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1196 1196
1197 1197 FIXUP_PDU_SIZE(spoolss_GetPrinter_result_u, size1);
1198 1198 FIXUP_PDU_SIZE(spoolss_GetPrinter_result, size2);
1199 1199 FIXUP_PDU_SIZE(spoolss_GetPrinter, size3);
1200 1200 }
1201 1201
1202 1202 #else /* HAVE_CUPS */
1203 1203
1204 1204 /*
1205 1205 * If not HAVE_CUPS, just provide a few "stubs".
1206 1206 */
1207 1207
1208 1208 void
1209 1209 spoolss_initialize(void)
1210 1210 {
1211 1211 }
1212 1212
1213 1213 void
1214 1214 spoolss_finalize(void)
1215 1215 {
1216 1216 }
1217 1217
1218 1218 /*ARGSUSED*/
1219 1219 void
1220 1220 spoolss_register_copyfile(spoolss_copyfile_t copyfile)
1221 1221 {
1222 1222 }
1223 1223
1224 1224 #endif /* HAVE_CUPS */
↓ open down ↓ |
1175 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX