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