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