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