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