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