r24937: Merge tests spoolss RPC callbacks.
[ira/wip.git] / source4 / rpc_server / spoolss / dcesrv_spoolss.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the spoolss pipe
5
6    Copyright (C) Tim Potter 2004
7    Copyright (C) Stefan Metzmacher 2005
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "rpc_server/dcerpc_server.h"
25 #include "librpc/gen_ndr/ndr_spoolss.h"
26 #include "rpc_server/common/common.h"
27 #include "ntptr/ntptr.h"
28 #include "lib/socket/socket.h"
29 #include "smbd/service_stream.h"
30 #include "librpc/gen_ndr/ndr_spoolss_c.h"
31 #include "auth/credentials/credentials.h"
32
33 enum spoolss_handle {
34         SPOOLSS_NOTIFY
35 };
36
37 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
38         ((info)?ndr_size_##fn(info, level, 0):0)
39
40 #define SPOOLSS_BUFFER_UNION_ARRAY(fn,info,level,count) \
41         ((info)?ndr_size_##fn##_info(dce_call, level, count, info):0)
42
43 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= r->out.needed)?val_true:val_false)
44
45 static WERROR dcesrv_spoolss_parse_printer_name(TALLOC_CTX *mem_ctx, const char *name,
46                                          const char **_server_name,
47                                          const char **_object_name,
48                                          enum ntptr_HandleType *_object_type)
49 {
50         char *p;
51         char *server = NULL;
52         char *server_unc = NULL;
53         const char *object = name;
54
55         /* no printername is there it's like open server */
56         if (!name) {
57                 *_server_name = NULL;
58                 *_object_name = NULL;
59                 *_object_type = NTPTR_HANDLE_SERVER;
60                 return WERR_OK;
61         }
62
63         /* just "\\" is invalid */
64         if (strequal("\\\\", name)) {
65                 return WERR_INVALID_PRINTER_NAME;
66         }
67
68         if (strncmp("\\\\", name, 2) == 0) {
69                 server_unc = talloc_strdup(mem_ctx, name);
70                 W_ERROR_HAVE_NO_MEMORY(server_unc);
71                 server = server_unc + 2;
72
73                 /* here we know we have "\\" in front not followed
74                  * by '\0', now see if we have another "\" in the string
75                  */
76                 p = strchr_m(server, '\\');
77                 if (!p) {
78                         /* there's no other "\", so it's ("\\%s",server)
79                          */
80                         *_server_name = server_unc;
81                         *_object_name = NULL;
82                         *_object_type = NTPTR_HANDLE_SERVER;
83                         return WERR_OK;
84                 }
85                 /* here we know that we have ("\\%s\",server),
86                  * if we have '\0' as next then it's an invalid name
87                  * otherwise the printer_name
88                  */
89                 p[0] = '\0';
90                 /* everything that follows is the printer name */
91                 p++;
92                 object = p;
93
94                 /* just "" as server is invalid */
95                 if (strequal(server, "")) {
96                         return WERR_INVALID_PRINTER_NAME;
97                 }
98         }
99
100         /* just "" is invalid */
101         if (strequal(object, "")) {
102                 return WERR_INVALID_PRINTER_NAME;
103         }
104
105 #define XCV_PORT ",XcvPort "
106 #define XCV_MONITOR ",XcvMonitor "
107         if (strncmp(object, XCV_PORT, strlen(XCV_PORT)) == 0) {
108                 object += strlen(XCV_PORT);
109
110                 /* just "" is invalid */
111                 if (strequal(object, "")) {
112                         return WERR_INVALID_PRINTER_NAME;
113                 }
114
115                 *_server_name = server_unc;
116                 *_object_name = object;
117                 *_object_type = NTPTR_HANDLE_PORT;
118                 return WERR_OK;
119         } else if (strncmp(object, XCV_MONITOR, strlen(XCV_MONITOR)) == 0) {
120                 object += strlen(XCV_MONITOR);
121
122                 /* just "" is invalid */
123                 if (strequal(object, "")) {
124                         return WERR_INVALID_PRINTER_NAME;
125                 }
126
127                 *_server_name = server_unc;
128                 *_object_name = object;
129                 *_object_type = NTPTR_HANDLE_MONITOR;
130                 return WERR_OK;
131         }
132
133         *_server_name = server_unc;
134         *_object_name = object;
135         *_object_type = NTPTR_HANDLE_PRINTER;
136         return WERR_OK;
137 }
138
139 /*
140  * Check server_name is:
141  * -  "" , functions that don't allow "",
142  *         should check that on their own, before calling this function
143  * -  our name (only netbios yet, TODO: need to test dns name!)
144  * -  our ip address of the current use socket
145  * otherwise return WERR_INVALID_PRINTER_NAME
146  */
147 static WERROR dcesrv_spoolss_check_server_name(struct dcesrv_call_state *dce_call, 
148                                         TALLOC_CTX *mem_ctx,
149                                         const char *server_name)
150 {
151         BOOL ret;
152         struct socket_address *myaddr;
153         const char **aliases;
154         int i;
155
156         /* NULL is ok */
157         if (!server_name) return WERR_OK;
158
159         /* "" is ok */
160         ret = strequal("",server_name);
161         if (ret) return WERR_OK;
162
163         /* just "\\" is invalid */
164         if (strequal("\\\\", server_name)) {
165                 return WERR_INVALID_PRINTER_NAME;
166         }
167
168         /* then we need "\\" */
169         if (strncmp("\\\\", server_name, 2) != 0) {
170                 return WERR_INVALID_PRINTER_NAME;
171         }
172
173         server_name += 2;
174
175         /* NETBIOS NAME is ok */
176         ret = strequal(lp_netbios_name(), server_name);
177         if (ret) return WERR_OK;
178
179         aliases = lp_netbios_aliases();
180
181         for (i=0; aliases && aliases[i]; i++) {
182                 if (strequal(aliases[i], server_name)) {
183                         return WERR_OK;
184                 }
185         }
186
187         /* DNS NAME is ok
188          * TODO: we need to check if aliases are also ok
189          */
190         if (lp_realm()) {
191                 char *str;
192
193                 str = talloc_asprintf(mem_ctx, "%s.%s",
194                                                 lp_netbios_name(),
195                                                 lp_realm());
196                 W_ERROR_HAVE_NO_MEMORY(str);
197
198                 ret = strequal(str, server_name);
199                 talloc_free(str);
200                 if (ret) return WERR_OK;
201         }
202
203         myaddr = dcesrv_connection_get_my_addr(dce_call->conn, mem_ctx);
204         W_ERROR_HAVE_NO_MEMORY(myaddr);
205
206         ret = strequal(myaddr->addr, server_name);
207         talloc_free(myaddr);
208         if (ret) return WERR_OK;
209
210         return WERR_INVALID_PRINTER_NAME;
211 }
212
213 static NTSTATUS dcerpc_spoolss_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
214 {
215         NTSTATUS status;
216         struct ntptr_context *ntptr;
217
218         status = ntptr_init_context(dce_call->context, lp_ntptr_providor(), &ntptr);
219         NT_STATUS_NOT_OK_RETURN(status);
220
221         dce_call->context->private = ntptr;
222
223         return NT_STATUS_OK;
224 }
225
226 #define DCESRV_INTERFACE_SPOOLSS_BIND dcerpc_spoolss_bind
227
228 /* 
229   spoolss_EnumPrinters 
230 */
231 static WERROR dcesrv_spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
232                        struct spoolss_EnumPrinters *r)
233 {
234         struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
235         WERROR status;
236
237         status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server);
238         W_ERROR_NOT_OK_RETURN(status);
239
240         status = ntptr_EnumPrinters(ntptr, mem_ctx, r);
241         W_ERROR_NOT_OK_RETURN(status);
242
243         r->out.needed   = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinters, r->out.info, r->in.level, r->out.count);
244         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
245         r->out.count    = SPOOLSS_BUFFER_OK(r->out.count, 0);
246         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
247 }
248
249 static WERROR dcesrv_spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
250                        struct spoolss_OpenPrinterEx *r);
251 /* 
252   spoolss_OpenPrinter 
253 */
254 static WERROR dcesrv_spoolss_OpenPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
255                        struct spoolss_OpenPrinter *r)
256 {
257         WERROR status;
258         struct spoolss_OpenPrinterEx *r2;
259
260         r2 = talloc(mem_ctx, struct spoolss_OpenPrinterEx);
261         W_ERROR_HAVE_NO_MEMORY(r2);
262
263         r2->in.printername      = r->in.printername;
264         r2->in.datatype         = r->in.datatype;
265         r2->in.devmode_ctr      = r->in.devmode_ctr;
266         r2->in.access_mask      = r->in.access_mask;
267         r2->in.level            = 1;
268         r2->in.userlevel.level1 = NULL;
269
270         r2->out.handle          = r->out.handle;
271
272         /* TODO: we should take care about async replies here,
273                  if spoolss_OpenPrinterEx() would be async!
274          */
275         status = dcesrv_spoolss_OpenPrinterEx(dce_call, mem_ctx, r2);
276
277         r->out.handle           = r2->out.handle;
278
279         return status;
280 }
281
282
283 /* 
284   spoolss_SetJob 
285 */
286 static WERROR dcesrv_spoolss_SetJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
287                        struct spoolss_SetJob *r)
288 {
289         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
290 }
291
292
293 /* 
294   spoolss_GetJob 
295 */
296 static WERROR dcesrv_spoolss_GetJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
297                        struct spoolss_GetJob *r)
298 {
299         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
300 }
301
302
303 /* 
304   spoolss_EnumJobs 
305 */
306 static WERROR dcesrv_spoolss_EnumJobs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
307                        struct spoolss_EnumJobs *r)
308 {
309         return WERR_OK;
310 }
311
312
313 /* 
314   spoolss_AddPrinter 
315 */
316 static WERROR dcesrv_spoolss_AddPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
317                        struct spoolss_AddPrinter *r)
318 {
319         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
320 }
321
322
323 /* 
324   spoolss_DeletePrinter 
325 */
326 static WERROR dcesrv_spoolss_DeletePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
327                        struct spoolss_DeletePrinter *r)
328 {
329         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
330 }
331
332
333 /* 
334   spoolss_SetPrinter 
335 */
336 static WERROR dcesrv_spoolss_SetPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
337                        struct spoolss_SetPrinter *r)
338 {
339         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
340 }
341
342
343 /* 
344   spoolss_GetPrinter 
345 */
346 static WERROR dcesrv_spoolss_GetPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
347                        struct spoolss_GetPrinter *r)
348 {
349         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
350 }
351
352
353 /* 
354   spoolss_AddPrinterDriver 
355 */
356 static WERROR dcesrv_spoolss_AddPrinterDriver(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
357                        struct spoolss_AddPrinterDriver *r)
358 {
359         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
360 }
361
362
363 /* 
364   spoolss_EnumPrinterDrivers 
365 */
366 static WERROR dcesrv_spoolss_EnumPrinterDrivers(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
367                        struct spoolss_EnumPrinterDrivers *r)
368 {
369         struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
370         WERROR status;
371
372         status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server);
373         W_ERROR_NOT_OK_RETURN(status);
374
375         status = ntptr_EnumPrinterDrivers(ntptr, mem_ctx, r);
376         W_ERROR_NOT_OK_RETURN(status);
377
378         r->out.needed   = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinterDrivers, r->out.info, r->in.level, r->out.count);
379         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
380         r->out.count    = SPOOLSS_BUFFER_OK(r->out.count, 0);
381         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
382 }
383
384
385 /* 
386   spoolss_GetPrinterDriver 
387 */
388 static WERROR dcesrv_spoolss_GetPrinterDriver(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
389                        struct spoolss_GetPrinterDriver *r)
390 {
391         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
392 }
393
394
395 /* 
396   spoolss_GetPrinterDriverDirectory 
397 */
398 static WERROR dcesrv_spoolss_GetPrinterDriverDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
399                        struct spoolss_GetPrinterDriverDirectory *r)
400 {
401         struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
402         WERROR status;
403
404         status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server);
405         W_ERROR_NOT_OK_RETURN(status);
406
407         status = ntptr_GetPrinterDriverDirectory(ntptr, mem_ctx, r);
408         W_ERROR_NOT_OK_RETURN(status);
409
410         r->out.needed   = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, r->out.info, r->in.level);
411         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
412         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
413 }
414
415
416 /* 
417   spoolss_DeletePrinterDriver 
418 */
419 static WERROR dcesrv_spoolss_DeletePrinterDriver(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
420                        struct spoolss_DeletePrinterDriver *r)
421 {
422         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
423 }
424
425
426 /* 
427   spoolss_AddPrintProcessor 
428 */
429 static WERROR dcesrv_spoolss_AddPrintProcessor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
430                        struct spoolss_AddPrintProcessor *r)
431 {
432         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
433 }
434
435
436 /* 
437   spoolss_EnumPrintProcessors 
438 */
439 static WERROR dcesrv_spoolss_EnumPrintProcessors(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
440                        struct spoolss_EnumPrintProcessors *r)
441 {
442         return WERR_OK;
443 }
444
445
446 /* 
447   spoolss_GetPrintProcessorDirectory 
448 */
449 static WERROR dcesrv_spoolss_GetPrintProcessorDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
450                        struct spoolss_GetPrintProcessorDirectory *r)
451 {
452         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
453 }
454
455
456 /* 
457   spoolss_StartDocPrinter 
458 */
459 static WERROR dcesrv_spoolss_StartDocPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
460                        struct spoolss_StartDocPrinter *r)
461 {
462         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
463 }
464
465
466 /* 
467   spoolss_StartPagePrinter 
468 */
469 static WERROR dcesrv_spoolss_StartPagePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
470                        struct spoolss_StartPagePrinter *r)
471 {
472         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
473 }
474
475
476 /* 
477   spoolss_WritePrinter 
478 */
479 static WERROR dcesrv_spoolss_WritePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
480                        struct spoolss_WritePrinter *r)
481 {
482         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
483 }
484
485
486 /* 
487   spoolss_EndPagePrinter 
488 */
489 static WERROR dcesrv_spoolss_EndPagePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
490                        struct spoolss_EndPagePrinter *r)
491 {
492         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
493 }
494
495
496 /* 
497   spoolss_AbortPrinter 
498 */
499 static WERROR dcesrv_spoolss_AbortPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
500                        struct spoolss_AbortPrinter *r)
501 {
502         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
503 }
504
505
506 /* 
507   spoolss_ReadPrinter 
508 */
509 static WERROR dcesrv_spoolss_ReadPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
510                        struct spoolss_ReadPrinter *r)
511 {
512         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
513 }
514
515
516 /* 
517   spoolss_EndDocPrinter 
518 */
519 static WERROR dcesrv_spoolss_EndDocPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
520                        struct spoolss_EndDocPrinter *r)
521 {
522         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
523 }
524
525
526 /* 
527   spoolss_AddJob 
528 */
529 static WERROR dcesrv_spoolss_AddJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
530                        struct spoolss_AddJob *r)
531 {
532         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
533 }
534
535
536 /* 
537   spoolss_ScheduleJob 
538 */
539 static WERROR dcesrv_spoolss_ScheduleJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
540                        struct spoolss_ScheduleJob *r)
541 {
542         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
543 }
544
545
546 /* 
547   spoolss_GetPrinterData 
548 */
549 static WERROR dcesrv_spoolss_GetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
550                        struct spoolss_GetPrinterData *r)
551 {
552         struct ntptr_GenericHandle *handle;
553         struct dcesrv_handle *h;
554         WERROR status;
555
556         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
557         handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
558         if (!handle)
559                 return WERR_BADFID;
560
561         switch (handle->type) {
562                 case NTPTR_HANDLE_SERVER:
563                         status = ntptr_GetPrintServerData(handle, mem_ctx, r);
564                         break;
565                 default:
566                         status = WERR_FOOBAR;
567                         break;
568         }
569
570         W_ERROR_NOT_OK_RETURN(status);
571
572         r->out.needed   = ndr_size_spoolss_PrinterData(&r->out.data, r->out.type, 0);
573         r->out.type     = SPOOLSS_BUFFER_OK(r->out.type, SPOOLSS_PRINTER_DATA_TYPE_NULL);
574         r->out.data     = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
575         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
576 }
577
578
579 /* 
580   spoolss_SetPrinterData 
581 */
582 static WERROR dcesrv_spoolss_SetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
583                        struct spoolss_SetPrinterData *r)
584 {
585         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
586 }
587
588
589 /* 
590   spoolss_WaitForPrinterChange 
591 */
592 static WERROR dcesrv_spoolss_WaitForPrinterChange(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
593                        struct spoolss_WaitForPrinterChange *r)
594 {
595         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
596 }
597
598
599 /* 
600   spoolss_ClosePrinter 
601 */
602 static WERROR dcesrv_spoolss_ClosePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
603                        struct spoolss_ClosePrinter *r)
604 {
605         struct dcesrv_handle *h;
606
607         *r->out.handle = *r->in.handle;
608
609         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
610
611         talloc_free(h);
612
613         ZERO_STRUCTP(r->out.handle);
614
615         return WERR_OK;
616 }
617
618
619 /* 
620   spoolss_AddForm 
621 */
622 static WERROR dcesrv_spoolss_AddForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
623                        struct spoolss_AddForm *r)
624 {
625         struct ntptr_GenericHandle *handle;
626         struct dcesrv_handle *h;
627         WERROR status;
628
629         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
630         handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
631         if (!handle)
632                 return WERR_BADFID;
633
634         switch (handle->type) {
635                 case NTPTR_HANDLE_SERVER:
636                         status = ntptr_AddPrintServerForm(handle, mem_ctx, r);
637                         W_ERROR_NOT_OK_RETURN(status);
638                         break;
639                 case NTPTR_HANDLE_PRINTER:
640                         status = ntptr_AddPrinterForm(handle, mem_ctx, r);
641                         W_ERROR_NOT_OK_RETURN(status);
642                         break;
643                 default:
644                         return WERR_FOOBAR;
645         }
646
647         return WERR_OK;
648 }
649
650
651 /* 
652   spoolss_DeleteForm 
653 */
654 static WERROR dcesrv_spoolss_DeleteForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
655                        struct spoolss_DeleteForm *r)
656 {
657         struct ntptr_GenericHandle *handle;
658         struct dcesrv_handle *h;
659         WERROR status;
660
661         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
662         handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
663         if (!handle)
664                 return WERR_BADFID;
665
666         switch (handle->type) {
667                 case NTPTR_HANDLE_SERVER:
668                         status = ntptr_DeletePrintServerForm(handle, mem_ctx, r);
669                         W_ERROR_NOT_OK_RETURN(status);
670                         break;
671                 case NTPTR_HANDLE_PRINTER:
672                         status = ntptr_DeletePrinterForm(handle, mem_ctx, r);
673                         W_ERROR_NOT_OK_RETURN(status);
674                         break;
675                 default:
676                         return WERR_FOOBAR;
677         }
678
679         return WERR_OK;
680 }
681
682
683 /* 
684   spoolss_GetForm 
685 */
686 static WERROR dcesrv_spoolss_GetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
687                        struct spoolss_GetForm *r)
688 {
689         struct ntptr_GenericHandle *handle;
690         struct dcesrv_handle *h;
691         WERROR status;
692
693         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
694         handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
695         if (!handle)
696                 return WERR_BADFID;
697
698         switch (handle->type) {
699                 case NTPTR_HANDLE_SERVER:
700                         /*
701                          * stupid, but w2k3 returns WERR_BADFID here?
702                          */
703                         return WERR_BADFID;
704                 case NTPTR_HANDLE_PRINTER:
705                         status = ntptr_GetPrinterForm(handle, mem_ctx, r);
706                         W_ERROR_NOT_OK_RETURN(status);
707                         break;
708                 default:
709                         return WERR_FOOBAR;
710         }
711
712         r->out.needed   = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, r->out.info, r->in.level);
713         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
714         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
715 }
716
717
718 /* 
719   spoolss_SetForm 
720 */
721 static WERROR dcesrv_spoolss_SetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
722                        struct spoolss_SetForm *r)
723 {
724         struct ntptr_GenericHandle *handle;
725         struct dcesrv_handle *h;
726         WERROR status;
727
728         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
729         handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
730         if (!handle)
731                 return WERR_BADFID;
732
733         switch (handle->type) {
734                 case NTPTR_HANDLE_SERVER:
735                         status = ntptr_SetPrintServerForm(handle, mem_ctx, r);
736                         W_ERROR_NOT_OK_RETURN(status);
737                         break;
738                 case NTPTR_HANDLE_PRINTER:
739                         status = ntptr_SetPrinterForm(handle, mem_ctx, r);
740                         W_ERROR_NOT_OK_RETURN(status);
741                         break;
742                 default:
743                         return WERR_FOOBAR;
744         }
745
746         return WERR_OK;
747 }
748
749
750 /* 
751   spoolss_EnumForms 
752 */
753 static WERROR dcesrv_spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
754                        struct spoolss_EnumForms *r)
755 {
756         struct ntptr_GenericHandle *handle;
757         struct dcesrv_handle *h;
758         WERROR status;
759
760         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
761         handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
762         if (!handle)
763                 return WERR_BADFID;
764
765         switch (handle->type) {
766                 case NTPTR_HANDLE_SERVER:
767                         status = ntptr_EnumPrintServerForms(handle, mem_ctx, r);
768                         W_ERROR_NOT_OK_RETURN(status);
769                         break;
770                 case NTPTR_HANDLE_PRINTER:
771                         status = ntptr_EnumPrinterForms(handle, mem_ctx, r);
772                         W_ERROR_NOT_OK_RETURN(status);
773                         break;
774                 default:
775                         return WERR_FOOBAR;
776         }
777
778         r->out.needed   = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumForms, r->out.info, r->in.level, r->out.count);
779         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
780         r->out.count    = SPOOLSS_BUFFER_OK(r->out.count, 0);
781         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
782 }
783
784
785 /* 
786   spoolss_EnumPorts 
787 */
788 static WERROR dcesrv_spoolss_EnumPorts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
789                        struct spoolss_EnumPorts *r)
790 {
791         struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
792         WERROR status;
793
794         status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.servername);
795         W_ERROR_NOT_OK_RETURN(status);
796
797         status = ntptr_EnumPorts(ntptr, mem_ctx, r);
798         W_ERROR_NOT_OK_RETURN(status);
799
800         r->out.needed   = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPorts, r->out.info, r->in.level, r->out.count);
801         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
802         r->out.count    = SPOOLSS_BUFFER_OK(r->out.count, 0);
803         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
804 }
805
806
807 /* 
808   spoolss_EnumMonitors 
809 */
810 static WERROR dcesrv_spoolss_EnumMonitors(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
811                        struct spoolss_EnumMonitors *r)
812 {
813         struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
814         WERROR status;
815
816         status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.servername);
817         W_ERROR_NOT_OK_RETURN(status);
818
819         status = ntptr_EnumMonitors(ntptr, mem_ctx, r);
820         W_ERROR_NOT_OK_RETURN(status);
821
822         r->out.needed   = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumMonitors, r->out.info, r->in.level, r->out.count);
823         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
824         r->out.count    = SPOOLSS_BUFFER_OK(r->out.count, 0);
825         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
826 }
827
828
829 /* 
830   spoolss_AddPort 
831 */
832 static WERROR dcesrv_spoolss_AddPort(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
833                        struct spoolss_AddPort *r)
834 {
835         return WERR_NOT_SUPPORTED;
836 }
837
838
839 /* 
840   spoolss_ConfigurePort 
841 */
842 static WERROR dcesrv_spoolss_ConfigurePort(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
843                        struct spoolss_ConfigurePort *r)
844 {
845         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
846 }
847
848
849 /* 
850   spoolss_DeletePort 
851 */
852 static WERROR dcesrv_spoolss_DeletePort(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
853                        struct spoolss_DeletePort *r)
854 {
855         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
856 }
857
858
859 /* 
860   spoolss_CreatePrinterIC 
861 */
862 static WERROR dcesrv_spoolss_CreatePrinterIC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
863                        struct spoolss_CreatePrinterIC *r)
864 {
865         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
866 }
867
868
869 /* 
870   spoolss_PlayGDIScriptOnPrinterIC 
871 */
872 static WERROR dcesrv_spoolss_PlayGDIScriptOnPrinterIC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
873                        struct spoolss_PlayGDIScriptOnPrinterIC *r)
874 {
875         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
876 }
877
878
879 /* 
880   spoolss_DeletePrinterIC 
881 */
882 static WERROR dcesrv_spoolss_DeletePrinterIC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
883                        struct spoolss_DeletePrinterIC *r)
884 {
885         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
886 }
887
888
889 /* 
890   spoolss_AddPrinterConnection 
891 */
892 static WERROR dcesrv_spoolss_AddPrinterConnection(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
893                        struct spoolss_AddPrinterConnection *r)
894 {
895         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
896 }
897
898
899 /* 
900   spoolss_DeletePrinterConnection 
901 */
902 static WERROR dcesrv_spoolss_DeletePrinterConnection(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
903                        struct spoolss_DeletePrinterConnection *r)
904 {
905         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
906 }
907
908
909 /* 
910   spoolss_PrinterMessageBox 
911 */
912 static WERROR dcesrv_spoolss_PrinterMessageBox(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
913                        struct spoolss_PrinterMessageBox *r)
914 {
915         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
916 }
917
918
919 /* 
920   spoolss_AddMonitor 
921 */
922 static WERROR dcesrv_spoolss_AddMonitor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
923                        struct spoolss_AddMonitor *r)
924 {
925         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
926 }
927
928
929 /* 
930   spoolss_DeleteMonitor 
931 */
932 static WERROR dcesrv_spoolss_DeleteMonitor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
933                        struct spoolss_DeleteMonitor *r)
934 {
935         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
936 }
937
938
939 /* 
940   spoolss_DeletePrintProcessor 
941 */
942 static WERROR dcesrv_spoolss_DeletePrintProcessor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
943                        struct spoolss_DeletePrintProcessor *r)
944 {
945         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
946 }
947
948
949 /* 
950   spoolss_AddPrintProvidor 
951 */
952 static WERROR dcesrv_spoolss_AddPrintProvidor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
953                        struct spoolss_AddPrintProvidor *r)
954 {
955         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
956 }
957
958
959 /* 
960   spoolss_DeletePrintProvidor 
961 */
962 static WERROR dcesrv_spoolss_DeletePrintProvidor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
963                        struct spoolss_DeletePrintProvidor *r)
964 {
965         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
966 }
967
968
969 /* 
970   spoolss_EnumPrintProcDataTypes 
971 */
972 static WERROR dcesrv_spoolss_EnumPrintProcDataTypes(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
973                        struct spoolss_EnumPrintProcDataTypes *r)
974 {
975         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
976 }
977
978
979 /* 
980   spoolss_ResetPrinter 
981 */
982 static WERROR dcesrv_spoolss_ResetPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
983                        struct spoolss_ResetPrinter *r)
984 {
985         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
986 }
987
988
989 /* 
990   spoolss_GetPrinterDriver2 
991 */
992 static WERROR dcesrv_spoolss_GetPrinterDriver2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
993                        struct spoolss_GetPrinterDriver2 *r)
994 {
995         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
996 }
997
998
999 /* 
1000   spoolss_FindFirstPrinterChangeNotification 
1001 */
1002 static WERROR dcesrv_spoolss_FindFirstPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1003                        struct spoolss_FindFirstPrinterChangeNotification *r)
1004 {
1005         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1006 }
1007
1008
1009 /* 
1010   spoolss_FindNextPrinterChangeNotification 
1011 */
1012 static WERROR dcesrv_spoolss_FindNextPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1013                        struct spoolss_FindNextPrinterChangeNotification *r)
1014 {
1015         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1016 }
1017
1018
1019 /* 
1020   spoolss_FindClosePrinterNotify 
1021 */
1022 static WERROR dcesrv_spoolss_FindClosePrinterNotify(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1023                        struct spoolss_FindClosePrinterNotify *r)
1024 {
1025         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1026 }
1027
1028
1029 /* 
1030   spoolss_RouterFindFirstPrinterChangeNotificationOld 
1031 */
1032 static WERROR dcesrv_spoolss_RouterFindFirstPrinterChangeNotificationOld(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1033                        struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
1034 {
1035         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1036 }
1037
1038
1039 /* 
1040   spoolss_ReplyOpenPrinter 
1041 */
1042 static WERROR dcesrv_spoolss_ReplyOpenPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1043                        struct spoolss_ReplyOpenPrinter *r)
1044 {
1045         struct dcesrv_handle *handle;
1046
1047         handle = dcesrv_handle_new(dce_call->context, SPOOLSS_NOTIFY);
1048         W_ERROR_HAVE_NO_MEMORY(handle);
1049
1050         /* For now, just return a handle */
1051
1052         *r->out.handle = handle->wire_handle;
1053
1054         return WERR_OK;
1055 }
1056
1057
1058 /* 
1059   spoolss_RouterReplyPrinter 
1060 */
1061 static WERROR dcesrv_spoolss_RouterReplyPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1062                        struct spoolss_RouterReplyPrinter *r)
1063 {
1064         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1065 }
1066
1067
1068 /* 
1069   spoolss_ReplyClosePrinter 
1070 */
1071 static WERROR dcesrv_spoolss_ReplyClosePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1072                        struct spoolss_ReplyClosePrinter *r)
1073 {
1074         struct dcesrv_handle *handle;
1075         
1076         DCESRV_PULL_HANDLE_WERR(handle, r->in.handle, SPOOLSS_NOTIFY);
1077
1078         talloc_free(handle);
1079
1080         ZERO_STRUCTP(r->out.handle);
1081
1082         return WERR_OK;
1083 }
1084
1085 /* 
1086   spoolss_AddPortEx 
1087 */
1088 static WERROR dcesrv_spoolss_AddPortEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1089                        struct spoolss_AddPortEx *r)
1090 {
1091         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1092 }
1093
1094
1095 /* 
1096   spoolss_RouterFindFirstPrinterChangeNotification 
1097 */
1098 static WERROR dcesrv_spoolss_RouterFindFirstPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1099                        struct spoolss_RouterFindFirstPrinterChangeNotification *r)
1100 {
1101         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1102 }
1103
1104
1105 /* 
1106   spoolss_SpoolerInit 
1107 */
1108 static WERROR dcesrv_spoolss_SpoolerInit(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1109                        struct spoolss_SpoolerInit *r)
1110 {
1111         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1112 }
1113
1114
1115 /* 
1116   spoolss_ResetPrinterEx 
1117 */
1118 static WERROR dcesrv_spoolss_ResetPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1119                        struct spoolss_ResetPrinterEx *r)
1120 {
1121         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1122 }
1123
1124
1125 /* 
1126   spoolss_RemoteFindFirstPrinterChangeNotifyEx 
1127 */
1128 static WERROR dcesrv_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1129                        struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
1130 {
1131         struct dcerpc_pipe *p;
1132         struct dcerpc_binding *binding;
1133         NTSTATUS status;
1134         struct spoolss_ReplyOpenPrinter rop;
1135         struct cli_credentials *creds;
1136         struct policy_handle notify_handle;
1137
1138         DEBUG(2, ("Received RFFPCNex from %s\n", r->in.str));
1139
1140         /*
1141          * TODO: for now just open a connection to the client and drop it again
1142          *       to keep the w2k3 PrintServer 
1143          *       happy to allow to open the Add Printer GUI
1144          *       and the torture suite passing
1145          */
1146
1147         binding = talloc_zero(mem_ctx, struct dcerpc_binding);
1148
1149         binding->transport = NCACN_NP; 
1150         if (strncmp(r->in.str, "\\\\", 2))
1151                 return WERR_INVALID_COMPUTERNAME;
1152         binding->host = r->in.str+2;
1153
1154         creds = cli_credentials_init_anon(mem_ctx); /* FIXME: Use machine credentials instead ? */
1155
1156         status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_spoolss, 
1157                                   creds, NULL);
1158
1159         if (NT_STATUS_IS_ERR(status)) {
1160                 DEBUG(0, ("unable to call back to %s\n", r->in.str));
1161                 return WERR_SERVER_UNAVAILABLE;
1162         }
1163
1164         ZERO_STRUCT(rop);
1165         rop.in.server_name = lp_netbios_name();
1166         W_ERROR_HAVE_NO_MEMORY(rop.in.server_name);
1167         rop.in.printer_local = 0;
1168         rop.in.type = REG_NONE;
1169         rop.in.unknown1 = 0;
1170         rop.in.unknown2 = 0;
1171         rop.out.handle = &notify_handle;
1172
1173         status = dcerpc_spoolss_ReplyOpenPrinter(p, mem_ctx, &rop);
1174         if (NT_STATUS_IS_ERR(status)) {
1175                 DEBUG(0, ("unable to open remote printer %s\n", r->in.str));
1176                 return WERR_SERVER_UNAVAILABLE;
1177         }
1178
1179         talloc_free(p);
1180
1181         return WERR_OK;
1182 }
1183
1184
1185 /* 
1186   spoolss_RouterRefreshPrinterChangeNotification 
1187 */
1188 static WERROR dcesrv_spoolss_RouterRefreshPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1189                        struct spoolss_RouterRefreshPrinterChangeNotification *r)
1190 {
1191         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1192 }
1193
1194
1195 /* 
1196   spoolss_RemoteFindNextPrinterChangeNotifyEx 
1197 */
1198 static WERROR dcesrv_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1199                        struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r)
1200 {
1201         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1202 }
1203
1204
1205 /* 
1206   spoolss_44 
1207 */
1208 static WERROR dcesrv_spoolss_44(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1209                        struct spoolss_44 *r)
1210 {
1211         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1212 }
1213
1214 /* 
1215   spoolss_OpenPrinterEx 
1216 */
1217 static WERROR dcesrv_spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1218                        struct spoolss_OpenPrinterEx *r)
1219 {
1220         struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
1221         struct ntptr_GenericHandle *handle;
1222         struct dcesrv_handle *h;
1223         const char *server;
1224         const char *object;
1225         enum ntptr_HandleType type;
1226         WERROR status;
1227
1228         ZERO_STRUCTP(r->out.handle);
1229
1230         status = dcesrv_spoolss_parse_printer_name(mem_ctx, r->in.printername, &server, &object, &type);
1231         W_ERROR_NOT_OK_RETURN(status);
1232
1233         status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, server);
1234         W_ERROR_NOT_OK_RETURN(status);
1235
1236         switch (type) {
1237                 case NTPTR_HANDLE_SERVER:
1238                         status = ntptr_OpenPrintServer(ntptr, mem_ctx, r, server, &handle);
1239                         W_ERROR_NOT_OK_RETURN(status);
1240                         break;
1241                 case NTPTR_HANDLE_PORT:
1242                         status = ntptr_OpenPort(ntptr, mem_ctx, r, object, &handle);
1243                         W_ERROR_NOT_OK_RETURN(status);
1244                         break;
1245                 case NTPTR_HANDLE_MONITOR:
1246                         status = ntptr_OpenMonitor(ntptr, mem_ctx, r, object, &handle);
1247                         W_ERROR_NOT_OK_RETURN(status);
1248                         break;
1249                 case NTPTR_HANDLE_PRINTER:
1250                         status = ntptr_OpenPrinter(ntptr, mem_ctx, r, object, &handle);
1251                         W_ERROR_NOT_OK_RETURN(status);
1252                         break;
1253                 default:
1254                         return WERR_FOOBAR;
1255         }
1256
1257         h = dcesrv_handle_new(dce_call->context, handle->type);
1258         W_ERROR_HAVE_NO_MEMORY(h);
1259
1260         h->data = talloc_steal(h, handle);
1261
1262         *r->out.handle  = h->wire_handle;
1263
1264         return WERR_OK;
1265 }
1266
1267 /* 
1268   spoolss_AddPrinterEx 
1269 */
1270 static WERROR dcesrv_spoolss_AddPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1271                        struct spoolss_AddPrinterEx *r)
1272 {
1273         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1274 }
1275
1276
1277 /* 
1278   spoolss_47 
1279 */
1280 static WERROR dcesrv_spoolss_47(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1281                        struct spoolss_47 *r)
1282 {
1283         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1284 }
1285
1286
1287 /* 
1288   spoolss_EnumPrinterData 
1289 */
1290 static WERROR dcesrv_spoolss_EnumPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1291                        struct spoolss_EnumPrinterData *r)
1292 {
1293         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1294 }
1295
1296
1297 /* 
1298   spoolss_DeletePrinterData 
1299 */
1300 static WERROR dcesrv_spoolss_DeletePrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1301                        struct spoolss_DeletePrinterData *r)
1302 {
1303         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1304 }
1305
1306
1307 /* 
1308   spoolss_4a 
1309 */
1310 static WERROR dcesrv_spoolss_4a(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1311                        struct spoolss_4a *r)
1312 {
1313         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1314 }
1315
1316
1317 /* 
1318   spoolss_4b 
1319 */
1320 static WERROR dcesrv_spoolss_4b(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1321                        struct spoolss_4b *r)
1322 {
1323         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1324 }
1325
1326
1327 /* 
1328   spoolss_4c 
1329 */
1330 static WERROR dcesrv_spoolss_4c(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1331                        struct spoolss_4c *r)
1332 {
1333         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1334 }
1335
1336
1337 /* 
1338   spoolss_SetPrinterDataEx 
1339 */
1340 static WERROR dcesrv_spoolss_SetPrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1341                        struct spoolss_SetPrinterDataEx *r)
1342 {
1343         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1344 }
1345
1346
1347 /* 
1348   spoolss_GetPrinterDataEx 
1349 */
1350 static WERROR dcesrv_spoolss_GetPrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1351                        struct spoolss_GetPrinterDataEx *r)
1352 {
1353         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1354 }
1355
1356
1357 /* 
1358   spoolss_EnumPrinterDataEx 
1359 */
1360 static WERROR dcesrv_spoolss_EnumPrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1361                        struct spoolss_EnumPrinterDataEx *r)
1362 {
1363         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1364 }
1365
1366
1367 /* 
1368   spoolss_EnumPrinterKey 
1369 */
1370 static WERROR dcesrv_spoolss_EnumPrinterKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1371                        struct spoolss_EnumPrinterKey *r)
1372 {
1373         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1374 }
1375
1376
1377 /* 
1378   spoolss_DeletePrinterDataEx 
1379 */
1380 static WERROR dcesrv_spoolss_DeletePrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1381                        struct spoolss_DeletePrinterDataEx *r)
1382 {
1383         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1384 }
1385
1386
1387 /* 
1388   spoolss_DeletePrinterKey 
1389 */
1390 static WERROR dcesrv_spoolss_DeletePrinterKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1391                        struct spoolss_DeletePrinterKey *r)
1392 {
1393         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1394 }
1395
1396
1397 /* 
1398   spoolss_53 
1399 */
1400 static WERROR dcesrv_spoolss_53(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1401                        struct spoolss_53 *r)
1402 {
1403         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1404 }
1405
1406
1407 /* 
1408   spoolss_DeletePrinterDriverEx 
1409 */
1410 static WERROR dcesrv_spoolss_DeletePrinterDriverEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1411                        struct spoolss_DeletePrinterDriverEx *r)
1412 {
1413         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1414 }
1415
1416
1417 /* 
1418   spoolss_55 
1419 */
1420 static WERROR dcesrv_spoolss_55(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1421                        struct spoolss_55 *r)
1422 {
1423         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1424 }
1425
1426
1427 /* 
1428   spoolss_56 
1429 */
1430 static WERROR dcesrv_spoolss_56(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1431                        struct spoolss_56 *r)
1432 {
1433         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1434 }
1435
1436
1437 /* 
1438   spoolss_57 
1439 */
1440 static WERROR dcesrv_spoolss_57(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1441                        struct spoolss_57 *r)
1442 {
1443         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1444 }
1445
1446
1447 /* 
1448   spoolss_XcvData
1449 */
1450 static WERROR dcesrv_spoolss_XcvData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1451                        struct spoolss_XcvData *r)
1452 {
1453         struct ntptr_GenericHandle *handle;
1454         struct dcesrv_handle *h;
1455         WERROR status;
1456
1457         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
1458         handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
1459
1460         switch (handle->type) {
1461                 case NTPTR_HANDLE_SERVER:
1462                         status = ntptr_XcvDataPrintServer(handle, mem_ctx, r);
1463                         W_ERROR_NOT_OK_RETURN(status);
1464                         break;
1465                 case NTPTR_HANDLE_PRINTER:
1466                         status = ntptr_XcvDataPrinter(handle, mem_ctx, r);
1467                         W_ERROR_NOT_OK_RETURN(status);
1468                         break;
1469                 case NTPTR_HANDLE_PORT:
1470                         status = ntptr_XcvDataPort(handle, mem_ctx, r);
1471                         W_ERROR_NOT_OK_RETURN(status);
1472                         break;
1473                 case NTPTR_HANDLE_MONITOR:
1474                         status = ntptr_XcvDataMonitor(handle, mem_ctx, r);
1475                         W_ERROR_NOT_OK_RETURN(status);
1476                         break;
1477                 default:
1478                         return WERR_FOOBAR;
1479         }
1480
1481         /* TODO: handle the buffer sizes here! */
1482         return WERR_OK;
1483 }
1484
1485
1486 /* 
1487   spoolss_AddPrinterDriverEx 
1488 */
1489 static WERROR dcesrv_spoolss_AddPrinterDriverEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1490                        struct spoolss_AddPrinterDriverEx *r)
1491 {
1492         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1493 }
1494
1495
1496 /* 
1497   spoolss_5a 
1498 */
1499 static WERROR dcesrv_spoolss_5a(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1500                        struct spoolss_5a *r)
1501 {
1502         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1503 }
1504
1505
1506 /* 
1507   spoolss_5b 
1508 */
1509 static WERROR dcesrv_spoolss_5b(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1510                        struct spoolss_5b *r)
1511 {
1512         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1513 }
1514
1515
1516 /* 
1517   spoolss_5c 
1518 */
1519 static WERROR dcesrv_spoolss_5c(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1520                        struct spoolss_5c *r)
1521 {
1522         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1523 }
1524
1525
1526 /* 
1527   spoolss_5d 
1528 */
1529 static WERROR dcesrv_spoolss_5d(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1530                        struct spoolss_5d *r)
1531 {
1532         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1533 }
1534
1535
1536 /* 
1537   spoolss_5e 
1538 */
1539 static WERROR dcesrv_spoolss_5e(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1540                        struct spoolss_5e *r)
1541 {
1542         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1543 }
1544
1545
1546 /* 
1547   spoolss_5f 
1548 */
1549 static WERROR dcesrv_spoolss_5f(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1550                        struct spoolss_5f *r)
1551 {
1552         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1553 }
1554
1555
1556 /* include the generated boilerplate */
1557 #include "librpc/gen_ndr/ndr_spoolss_s.c"