r7465: - return empty lists for now
[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 2 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, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25 #include "rpc_server/dcerpc_server.h"
26 #include "librpc/gen_ndr/ndr_spoolss.h"
27 #include "rpc_server/common/common.h"
28 #include "rpc_server/spoolss/dcesrv_spoolss.h"
29 #include "lib/socket/socket.h"
30 #include "smbd/service_stream.h"
31
32 #define SPOOLSS_BUFFER_SIZE(fn,level,count,info) \
33         ndr_size_##fn##_info(dce_call, level, count, info)
34
35 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((*r->in.buf_size >= *r->out.buf_size)?val_true:val_false)
36
37 /* 
38   spoolss_EnumPrinters 
39 */
40 static WERROR spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
41                        struct spoolss_EnumPrinters *r)
42 {
43         void *spoolss_ctx;
44         struct ldb_message **msgs;
45         int count;
46         int i;
47         union spoolss_PrinterInfo *info;
48
49         *r->out.buf_size = 0;
50
51         spoolss_ctx = spoolssdb_connect();
52         W_ERROR_HAVE_NO_MEMORY(spoolss_ctx);
53
54         count = spoolssdb_search(spoolss_ctx, mem_ctx, NULL, &msgs, NULL,
55                                "(&(objectclass=printer))");
56         spoolssdb_close(spoolss_ctx);
57
58         if (count == 0) return WERR_OK;
59         if (count < 0) return WERR_GENERAL_FAILURE;
60
61         info = talloc_array(mem_ctx, union spoolss_PrinterInfo, count);
62         W_ERROR_HAVE_NO_MEMORY(info);
63
64         switch(r->in.level) {
65         case 1:
66                 for (i = 0; i < count; i++) {
67                         info[i].info1.flags             = samdb_result_uint(msgs[i], "flags", 0);
68
69                         info[i].info1.name              = samdb_result_string(msgs[i], "name", "");
70                         W_ERROR_HAVE_NO_MEMORY(info[i].info1.name);
71
72                         info[i].info1.description       = samdb_result_string(msgs[i], "description", "");
73                         W_ERROR_HAVE_NO_MEMORY(info[i].info1.description);
74
75                         info[i].info1.comment           = samdb_result_string(msgs[i], "comment", NULL);
76                 }
77                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
78                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
79                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
80                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
81         case 2:
82                 for (i = 0; i < count; i++) {
83                         info[i].info2.servername        = samdb_result_string(msgs[i], "servername", "");
84                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
85
86                         info[i].info2.printername       = samdb_result_string(msgs[i], "printername", "");
87                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
88
89                         info[i].info2.sharename         = samdb_result_string(msgs[i], "sharename", "");
90                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.sharename);
91
92                         info[i].info2.portname          = samdb_result_string(msgs[i], "portname", "");
93                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.portname);
94
95                         info[i].info2.drivername        = samdb_result_string(msgs[i], "drivername", "");
96                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.drivername);
97
98                         info[i].info2.comment           = samdb_result_string(msgs[i], "comment", NULL);
99
100                         info[i].info2.location          = samdb_result_string(msgs[i], "location", NULL);
101
102                         info[i].info2.devmode           = NULL;
103
104                         info[i].info2.sepfile           = samdb_result_string(msgs[i], "sepfile", NULL);
105
106                         info[i].info2.printprocessor    = samdb_result_string(msgs[i], "printprocessor", "");
107                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.printprocessor);
108
109                         info[i].info2.datatype          = samdb_result_string(msgs[i], "datatype", "");
110                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.datatype);
111
112                         info[i].info2.parameters        = samdb_result_string(msgs[i], "parameters", NULL);
113
114                         info[i].info2.secdesc           = NULL;
115
116                         info[i].info2.attributes        = samdb_result_uint(msgs[i], "attributes", 0);
117                         info[i].info2.priority          = samdb_result_uint(msgs[i], "priority", 0);
118                         info[i].info2.defaultpriority   = samdb_result_uint(msgs[i], "defaultpriority", 0);
119                         info[i].info2.starttime         = samdb_result_uint(msgs[i], "starttime", 0);
120                         info[i].info2.untiltime         = samdb_result_uint(msgs[i], "untiltime", 0);
121                         info[i].info2.status            = samdb_result_uint(msgs[i], "status", 0);
122                         info[i].info2.cjobs             = samdb_result_uint(msgs[i], "cjobs", 0);
123                         info[i].info2.averageppm        = samdb_result_uint(msgs[i], "averageppm", 0);
124                 }
125                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
126                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
127                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
128                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
129         case 4:
130                 for (i = 0; i < count; i++) {
131                         info[i].info4.printername       = samdb_result_string(msgs[i], "printername", "");
132                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
133
134                         info[i].info4.servername        = samdb_result_string(msgs[i], "servername", "");
135                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
136
137                         info[i].info4.attributes        = samdb_result_uint(msgs[i], "attributes", 0);
138                 }
139                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
140                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
141                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
142                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
143         case 5:
144                 for (i = 0; i < count; i++) {
145                         info[i].info5.printername       = samdb_result_string(msgs[i], "name", "");
146                         W_ERROR_HAVE_NO_MEMORY(info[i].info5.printername);
147
148                         info[i].info5.portname          = samdb_result_string(msgs[i], "port", "");
149                         W_ERROR_HAVE_NO_MEMORY(info[i].info5.portname);
150
151                         info[i].info5.attributes        = samdb_result_uint(msgs[i], "attributes", 0);
152                         info[i].info5.device_not_selected_timeout = samdb_result_uint(msgs[i], "device_not_selected_timeout", 0);
153                         info[i].info5.transmission_retry_timeout  = samdb_result_uint(msgs[i], "transmission_retry_timeout", 0);
154                 }
155                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
156                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
157                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
158                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
159         }
160
161         return WERR_UNKNOWN_LEVEL;
162 }
163
164 static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
165                        struct spoolss_OpenPrinterEx *r);
166 /* 
167   spoolss_OpenPrinter 
168 */
169 static WERROR spoolss_OpenPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
170                        struct spoolss_OpenPrinter *r)
171 {
172         WERROR status;
173         struct spoolss_OpenPrinterEx *r2;
174
175         r2 = talloc(mem_ctx, struct spoolss_OpenPrinterEx);
176         W_ERROR_HAVE_NO_MEMORY(r2);
177
178         r2->in.printername      = r->in.printername;
179         r2->in.datatype         = r->in.datatype;
180         r2->in.devmode_ctr      = r->in.devmode_ctr;
181         r2->in.access_mask      = r->in.access_mask;
182         r2->in.level            = 1;
183         r2->in.userlevel.level1 = NULL;
184
185         r2->out.handle          = r->out.handle;
186
187         /* TODO: we should take care about async replies here,
188                  if spoolss_OpenPrinterEx() would be async!
189          */
190         status = spoolss_OpenPrinterEx(dce_call, mem_ctx, r2);
191
192         r->out.handle           = r2->out.handle;
193
194         return status;
195 }
196
197
198 /* 
199   spoolss_SetJob 
200 */
201 static WERROR spoolss_SetJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
202                        struct spoolss_SetJob *r)
203 {
204         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
205 }
206
207
208 /* 
209   spoolss_GetJob 
210 */
211 static WERROR spoolss_GetJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
212                        struct spoolss_GetJob *r)
213 {
214         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
215 }
216
217
218 /* 
219   spoolss_EnumJobs 
220 */
221 static WERROR spoolss_EnumJobs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
222                        struct spoolss_EnumJobs *r)
223 {
224         *r->out.buf_size        = 0;
225
226         return WERR_OK;
227 }
228
229
230 /* 
231   spoolss_AddPrinter 
232 */
233 static WERROR spoolss_AddPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
234                        struct spoolss_AddPrinter *r)
235 {
236         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
237 }
238
239
240 /* 
241   spoolss_DeletePrinter 
242 */
243 static WERROR spoolss_DeletePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
244                        struct spoolss_DeletePrinter *r)
245 {
246         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
247 }
248
249
250 /* 
251   spoolss_SetPrinter 
252 */
253 static WERROR spoolss_SetPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
254                        struct spoolss_SetPrinter *r)
255 {
256         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
257 }
258
259
260 /* 
261   spoolss_GetPrinter 
262 */
263 static WERROR spoolss_GetPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
264                        struct spoolss_GetPrinter *r)
265 {
266         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
267 }
268
269
270 /* 
271   spoolss_AddPrinterDriver 
272 */
273 static WERROR spoolss_AddPrinterDriver(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
274                        struct spoolss_AddPrinterDriver *r)
275 {
276         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
277 }
278
279
280 /* 
281   spoolss_EnumPrinterDrivers 
282 */
283 static WERROR spoolss_EnumPrinterDrivers(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
284                        struct spoolss_EnumPrinterDrivers *r)
285 {
286         union spoolss_DriverInfo *info;
287         int count;
288         int i;
289
290         *r->out.buf_size        = 0;
291
292         count = 0;
293
294         if (count == 0) return WERR_OK;
295         if (count < 0) return WERR_GENERAL_FAILURE;
296
297         info = talloc_array(mem_ctx, union spoolss_DriverInfo, count);
298         W_ERROR_HAVE_NO_MEMORY(info);
299
300         switch (r->in.level) {
301         case 1:
302                 for (i=0; i < count; i++) {
303                 }
304                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
305                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
306                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
307                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
308         case 2:
309                 for (i=0; i < count; i++) {
310                 }
311                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
312                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
313                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
314                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
315         case 3:
316                 for (i=0; i < count; i++) {
317                 }
318                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
319                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
320                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
321                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
322         case 4:
323                 for (i=0; i < count; i++) {
324                 }
325                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
326                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
327                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
328                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
329         case 5:
330                 for (i=0; i < count; i++) {
331                 }
332                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
333                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
334                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
335                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
336         case 6:
337                 for (i=0; i < count; i++) {
338                 }
339                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
340                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
341                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
342                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
343         }
344
345         return WERR_UNKNOWN_LEVEL;
346 }
347
348
349 /* 
350   spoolss_GetPrinterDriver 
351 */
352 static WERROR spoolss_GetPrinterDriver(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
353                        struct spoolss_GetPrinterDriver *r)
354 {
355         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
356 }
357
358
359 /* 
360   spoolss_GetPrinterDriverDirectory 
361 */
362 static WERROR spoolss_GetPrinterDriverDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
363                        struct spoolss_GetPrinterDriverDirectory *r)
364 {
365         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
366 }
367
368
369 /* 
370   spoolss_DeletePrinterDriver 
371 */
372 static WERROR spoolss_DeletePrinterDriver(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
373                        struct spoolss_DeletePrinterDriver *r)
374 {
375         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
376 }
377
378
379 /* 
380   spoolss_AddPrintProcessor 
381 */
382 static WERROR spoolss_AddPrintProcessor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
383                        struct spoolss_AddPrintProcessor *r)
384 {
385         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
386 }
387
388
389 /* 
390   spoolss_EnumPrintProcessors 
391 */
392 static WERROR spoolss_EnumPrintProcessors(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
393                        struct spoolss_EnumPrintProcessors *r)
394 {
395         *r->out.buf_size        = 0;
396
397         return WERR_OK;
398 }
399
400
401 /* 
402   spoolss_GetPrintProcessorDirectory 
403 */
404 static WERROR spoolss_GetPrintProcessorDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
405                        struct spoolss_GetPrintProcessorDirectory *r)
406 {
407         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
408 }
409
410
411 /* 
412   spoolss_StartDocPrinter 
413 */
414 static WERROR spoolss_StartDocPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
415                        struct spoolss_StartDocPrinter *r)
416 {
417         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
418 }
419
420
421 /* 
422   spoolss_StartPagePrinter 
423 */
424 static WERROR spoolss_StartPagePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
425                        struct spoolss_StartPagePrinter *r)
426 {
427         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
428 }
429
430
431 /* 
432   spoolss_WritePrinter 
433 */
434 static WERROR spoolss_WritePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
435                        struct spoolss_WritePrinter *r)
436 {
437         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
438 }
439
440
441 /* 
442   spoolss_EndPagePrinter 
443 */
444 static WERROR spoolss_EndPagePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
445                        struct spoolss_EndPagePrinter *r)
446 {
447         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
448 }
449
450
451 /* 
452   spoolss_AbortPrinter 
453 */
454 static WERROR spoolss_AbortPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
455                        struct spoolss_AbortPrinter *r)
456 {
457         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
458 }
459
460
461 /* 
462   spoolss_ReadPrinter 
463 */
464 static WERROR spoolss_ReadPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
465                        struct spoolss_ReadPrinter *r)
466 {
467         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
468 }
469
470
471 /* 
472   spoolss_EndDocPrinter 
473 */
474 static WERROR spoolss_EndDocPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
475                        struct spoolss_EndDocPrinter *r)
476 {
477         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
478 }
479
480
481 /* 
482   spoolss_AddJob 
483 */
484 static WERROR spoolss_AddJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
485                        struct spoolss_AddJob *r)
486 {
487         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
488 }
489
490
491 /* 
492   spoolss_ScheduleJob 
493 */
494 static WERROR spoolss_ScheduleJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
495                        struct spoolss_ScheduleJob *r)
496 {
497         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
498 }
499
500
501 /* 
502   spoolss_GetPrinterData 
503 */
504 static WERROR spoolss_GetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
505                        struct spoolss_GetPrinterData *r)
506 {
507         struct dcesrv_handle *h;
508         WERROR status = WERR_INVALID_PARAM;
509         enum spoolss_PrinterDataType type = SPOOLSS_PRINTER_DATA_TYPE_NULL;
510         union spoolss_PrinterData data;
511
512         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
513
514         if (h->wire_handle.handle_type == SPOOLSS_HANDLE_SERVER) {
515                 /* TODO: do access check here */
516
517                 if (strcmp("W3SvcInstalled", r->in.value_name) == 0) {
518                         type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
519                         data.value      = 0;
520                         status          = WERR_OK;
521                 } else if (strcmp("BeepEnabled", r->in.value_name) == 0) {
522                         type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
523                         data.value      = 0;
524                         status          = WERR_OK;
525                 } else if (strcmp("EventLog", r->in.value_name) == 0) {
526                         type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
527                         data.value      = 0;
528                         status          = WERR_OK;
529                 } else if (strcmp("NetPopup", r->in.value_name) == 0) {
530                         type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
531                         data.value      = 0;
532                         status          = WERR_OK;
533                 } else if (strcmp("NetPopupToComputer", r->in.value_name) == 0) {
534                         type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
535                         data.value      = 0;
536                         status          = WERR_OK;
537                 } else if (strcmp("MajorVersion", r->in.value_name) == 0) {
538                         type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
539                         data.value      = 3;
540                         status          = WERR_OK;
541                 } else if (strcmp("MinorVersion", r->in.value_name) == 0) {
542                         type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
543                         data.value      = 0;
544                         status          = WERR_OK;
545                 } else if (strcmp("DefaultSpoolDirectory", r->in.value_name) == 0) {
546                         type            = SPOOLSS_PRINTER_DATA_TYPE_STRING;
547                         data.string     = "C:\\PRINTERS";
548                         status          = WERR_OK;
549                 } else if (strcmp("Architecture", r->in.value_name) == 0) {
550                         type            = SPOOLSS_PRINTER_DATA_TYPE_STRING;
551                         data.string     = SPOOLSS_ARCHITECTURE_NT_X86;
552                         status          = WERR_OK;
553                 } else if (strcmp("DsPresent", r->in.value_name) == 0) {
554                         type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
555                         data.value      = 1;
556                         status          = WERR_OK;
557                 }
558         }
559
560         if (W_ERROR_IS_OK(status)) {
561                 *r->out.buf_size = ndr_size_spoolss_PrinterData(&data, type, 0);
562                 r->out.type     = SPOOLSS_BUFFER_OK(type, SPOOLSS_PRINTER_DATA_TYPE_NULL);
563                 r->out.data     = SPOOLSS_BUFFER_OK(data, data);
564                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
565         }
566
567         return status;
568 }
569
570
571 /* 
572   spoolss_SetPrinterData 
573 */
574 static WERROR spoolss_SetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
575                        struct spoolss_SetPrinterData *r)
576 {
577         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
578 }
579
580
581 /* 
582   spoolss_WaitForPrinterChange 
583 */
584 static WERROR spoolss_WaitForPrinterChange(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
585                        struct spoolss_WaitForPrinterChange *r)
586 {
587         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
588 }
589
590
591 /* 
592   spoolss_ClosePrinter 
593 */
594 static WERROR spoolss_ClosePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
595                        struct spoolss_ClosePrinter *r)
596 {
597         struct dcesrv_handle *h;
598
599         *r->out.handle = *r->in.handle;
600
601         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
602
603         talloc_free(h);
604
605         ZERO_STRUCTP(r->out.handle);
606
607         return WERR_OK;
608 }
609
610
611 /* 
612   spoolss_AddForm 
613 */
614 static WERROR spoolss_AddForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
615                        struct spoolss_AddForm *r)
616 {
617         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
618 }
619
620
621 /* 
622   spoolss_DeleteForm 
623 */
624 static WERROR spoolss_DeleteForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
625                        struct spoolss_DeleteForm *r)
626 {
627         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
628 }
629
630
631 /* 
632   spoolss_GetForm 
633 */
634 static WERROR spoolss_GetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
635                        struct spoolss_GetForm *r)
636 {
637         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
638 }
639
640
641 /* 
642   spoolss_SetForm 
643 */
644 static WERROR spoolss_SetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
645                        struct spoolss_SetForm *r)
646 {
647         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
648 }
649
650
651 /* 
652   spoolss_EnumForms 
653 */
654 static WERROR spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
655                        struct spoolss_EnumForms *r)
656 {
657         union spoolss_FormInfo *info;
658         int count;
659         int i;
660         struct dcesrv_handle *h;
661
662         *r->out.buf_size        = 0;
663
664         DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
665
666         count = 1;
667
668         if (count == 0) return WERR_OK;
669         if (count < 0) return WERR_GENERAL_FAILURE;
670
671         info = talloc_array(mem_ctx, union spoolss_FormInfo, count);
672         W_ERROR_HAVE_NO_MEMORY(info);
673
674         switch (r->in.level) {
675         case 1:
676                 for (i=0; i < count; i++) {
677                         info[i].info1.flags             = SPOOLSS_FORM_PRINTER;
678
679                         info[i].info1.form_name         = talloc_strdup(mem_ctx, "Samba Printer Form");
680                         W_ERROR_HAVE_NO_MEMORY(info[i].info1.form_name);
681
682                         info[i].info1.size.width        = 30;
683                         info[i].info1.size.height       = 40;
684
685                         info[i].info1.area.left         = 0;
686                         info[i].info1.area.top          = 0;
687                         info[i].info1.area.right        = 30;
688                         info[i].info1.area.bottom       = 40;
689                 }
690                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumForms, r->in.level, count, info);
691                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
692                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
693                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
694         }
695
696         return WERR_UNKNOWN_LEVEL;
697 }
698
699
700 /* 
701   spoolss_EnumPorts 
702 */
703 static WERROR spoolss_EnumPorts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
704                        struct spoolss_EnumPorts *r)
705 {
706         union spoolss_PortInfo *info;
707         int count;
708         int i;
709
710         *r->out.buf_size        = 0;
711
712         count = 1;
713
714         if (count == 0) return WERR_OK;
715         if (count < 0) return WERR_GENERAL_FAILURE;
716
717         info = talloc_array(mem_ctx, union spoolss_PortInfo, count);
718         W_ERROR_HAVE_NO_MEMORY(info);
719
720         switch (r->in.level) {
721         case 1:
722                 for (i=0; i < count; i++) {
723                         info[i].info1.port_name = talloc_strdup(mem_ctx, "Samba Printer Port");
724                         W_ERROR_HAVE_NO_MEMORY(info[i].info1.port_name);
725                 }
726                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPorts, r->in.level, count, info);
727                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
728                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
729                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
730         case 2:
731                 for (i=0; i < count; i++) {
732                         info[i].info2.port_name         = talloc_strdup(mem_ctx, "Samba Printer Port");
733                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.port_name);
734
735                         info[i].info2.monitor_name      = talloc_strdup(mem_ctx, "Local Monitor");
736                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
737
738                         info[i].info2.description       = talloc_strdup(mem_ctx, "Local Port");
739                         W_ERROR_HAVE_NO_MEMORY(info[i].info2.description);
740
741                         info[i].info2.port_type         = SPOOLSS_PORT_TYPE_WRITE;
742                         info[i].info2.reserved          = 0;
743                 }
744                 *r->out.buf_size= SPOOLSS_BUFFER_SIZE(spoolss_EnumPorts, r->in.level, count, info);
745                 r->out.info     = SPOOLSS_BUFFER_OK(info, NULL);
746                 r->out.count    = SPOOLSS_BUFFER_OK(count, 0);
747                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
748         }
749
750         return WERR_UNKNOWN_LEVEL;
751 }
752
753
754 /* 
755   spoolss_EnumMonitors 
756 */
757 static WERROR spoolss_EnumMonitors(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
758                        struct spoolss_EnumMonitors *r)
759 {
760         *r->out.buf_size        = 0;
761
762         return WERR_OK;
763 }
764
765
766 /* 
767   spoolss_AddPort 
768 */
769 static WERROR spoolss_AddPort(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
770                        struct spoolss_AddPort *r)
771 {
772         return WERR_NOT_SUPPORTED;
773 }
774
775
776 /* 
777   spoolss_ConfigurePort 
778 */
779 static WERROR spoolss_ConfigurePort(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
780                        struct spoolss_ConfigurePort *r)
781 {
782         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
783 }
784
785
786 /* 
787   spoolss_DeletePort 
788 */
789 static WERROR spoolss_DeletePort(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
790                        struct spoolss_DeletePort *r)
791 {
792         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
793 }
794
795
796 /* 
797   spoolss_CreatePrinterIC 
798 */
799 static WERROR spoolss_CreatePrinterIC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
800                        struct spoolss_CreatePrinterIC *r)
801 {
802         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
803 }
804
805
806 /* 
807   spoolss_PlayGDIScriptOnPrinterIC 
808 */
809 static WERROR spoolss_PlayGDIScriptOnPrinterIC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
810                        struct spoolss_PlayGDIScriptOnPrinterIC *r)
811 {
812         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
813 }
814
815
816 /* 
817   spoolss_DeletePrinterIC 
818 */
819 static WERROR spoolss_DeletePrinterIC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
820                        struct spoolss_DeletePrinterIC *r)
821 {
822         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
823 }
824
825
826 /* 
827   spoolss_AddPrinterConnection 
828 */
829 static WERROR spoolss_AddPrinterConnection(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
830                        struct spoolss_AddPrinterConnection *r)
831 {
832         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
833 }
834
835
836 /* 
837   spoolss_DeletePrinterConnection 
838 */
839 static WERROR spoolss_DeletePrinterConnection(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
840                        struct spoolss_DeletePrinterConnection *r)
841 {
842         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
843 }
844
845
846 /* 
847   spoolss_PrinterMessageBox 
848 */
849 static WERROR spoolss_PrinterMessageBox(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
850                        struct spoolss_PrinterMessageBox *r)
851 {
852         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
853 }
854
855
856 /* 
857   spoolss_AddMonitor 
858 */
859 static WERROR spoolss_AddMonitor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
860                        struct spoolss_AddMonitor *r)
861 {
862         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
863 }
864
865
866 /* 
867   spoolss_DeleteMonitor 
868 */
869 static WERROR spoolss_DeleteMonitor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
870                        struct spoolss_DeleteMonitor *r)
871 {
872         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
873 }
874
875
876 /* 
877   spoolss_DeletePrintProcessor 
878 */
879 static WERROR spoolss_DeletePrintProcessor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
880                        struct spoolss_DeletePrintProcessor *r)
881 {
882         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
883 }
884
885
886 /* 
887   spoolss_AddPrintProvidor 
888 */
889 static WERROR spoolss_AddPrintProvidor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
890                        struct spoolss_AddPrintProvidor *r)
891 {
892         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
893 }
894
895
896 /* 
897   spoolss_DeletePrintProvidor 
898 */
899 static WERROR spoolss_DeletePrintProvidor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
900                        struct spoolss_DeletePrintProvidor *r)
901 {
902         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
903 }
904
905
906 /* 
907   spoolss_EnumPrintProcDataTypes 
908 */
909 static WERROR spoolss_EnumPrintProcDataTypes(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
910                        struct spoolss_EnumPrintProcDataTypes *r)
911 {
912         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
913 }
914
915
916 /* 
917   spoolss_ResetPrinter 
918 */
919 static WERROR spoolss_ResetPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
920                        struct spoolss_ResetPrinter *r)
921 {
922         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
923 }
924
925
926 /* 
927   spoolss_GetPrinterDriver2 
928 */
929 static WERROR spoolss_GetPrinterDriver2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
930                        struct spoolss_GetPrinterDriver2 *r)
931 {
932         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
933 }
934
935
936 /* 
937   spoolss_FindFirstPrinterChangeNotification 
938 */
939 static WERROR spoolss_FindFirstPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
940                        struct spoolss_FindFirstPrinterChangeNotification *r)
941 {
942         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
943 }
944
945
946 /* 
947   spoolss_FindNextPrinterChangeNotification 
948 */
949 static WERROR spoolss_FindNextPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
950                        struct spoolss_FindNextPrinterChangeNotification *r)
951 {
952         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
953 }
954
955
956 /* 
957   spoolss_FindClosePrinterNotify 
958 */
959 static WERROR spoolss_FindClosePrinterNotify(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
960                        struct spoolss_FindClosePrinterNotify *r)
961 {
962         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
963 }
964
965
966 /* 
967   spoolss_RouterFindFirstPrinterChangeNotificationOld 
968 */
969 static WERROR spoolss_RouterFindFirstPrinterChangeNotificationOld(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
970                        struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
971 {
972         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
973 }
974
975
976 /* 
977   spoolss_ReplyOpenPrinter 
978 */
979 static WERROR spoolss_ReplyOpenPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
980                        struct spoolss_ReplyOpenPrinter *r)
981 {
982         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
983 }
984
985
986 /* 
987   spoolss_RouterReplyPrinter 
988 */
989 static WERROR spoolss_RouterReplyPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
990                        struct spoolss_RouterReplyPrinter *r)
991 {
992         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
993 }
994
995
996 /* 
997   spoolss_ReplyClosePrinter 
998 */
999 static WERROR spoolss_ReplyClosePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1000                        struct spoolss_ReplyClosePrinter *r)
1001 {
1002         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1003 }
1004
1005
1006 /* 
1007   spoolss_AddPortEx 
1008 */
1009 static WERROR spoolss_AddPortEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1010                        struct spoolss_AddPortEx *r)
1011 {
1012         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1013 }
1014
1015
1016 /* 
1017   spoolss_RouterFindFirstPrinterChangeNotification 
1018 */
1019 static WERROR spoolss_RouterFindFirstPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1020                        struct spoolss_RouterFindFirstPrinterChangeNotification *r)
1021 {
1022         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1023 }
1024
1025
1026 /* 
1027   spoolss_SpoolerInit 
1028 */
1029 static WERROR spoolss_SpoolerInit(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1030                        struct spoolss_SpoolerInit *r)
1031 {
1032         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1033 }
1034
1035
1036 /* 
1037   spoolss_ResetPrinterEx 
1038 */
1039 static WERROR spoolss_ResetPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1040                        struct spoolss_ResetPrinterEx *r)
1041 {
1042         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1043 }
1044
1045
1046 /* 
1047   spoolss_RemoteFindFirstPrinterChangeNotifyEx 
1048 */
1049 static WERROR spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1050                        struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
1051 {
1052         return WERR_NOT_SUPPORTED;
1053 }
1054
1055
1056 /* 
1057   spoolss_RouterRefreshPrinterChangeNotification 
1058 */
1059 static WERROR spoolss_RouterRefreshPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1060                        struct spoolss_RouterRefreshPrinterChangeNotification *r)
1061 {
1062         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1063 }
1064
1065
1066 /* 
1067   spoolss_RemoteFindNextPrinterChangeNotifyEx 
1068 */
1069 static WERROR spoolss_RemoteFindNextPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1070                        struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r)
1071 {
1072         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1073 }
1074
1075
1076 /* 
1077   spoolss_44 
1078 */
1079 static WERROR spoolss_44(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1080                        struct spoolss_44 *r)
1081 {
1082         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1083 }
1084
1085
1086 static WERROR spoolss_OpenPrinterEx_server(struct dcesrv_call_state *dce_call, 
1087                                            TALLOC_CTX *mem_ctx,
1088                                            struct spoolss_OpenPrinterEx *r,
1089                                            const char *server_name)
1090 {
1091         struct spoolss_handle_server *state;
1092         struct dcesrv_handle *handle;
1093         BOOL ret;
1094
1095         /* Check printername is our name or our ip address
1096          */
1097         ret = strequal(server_name, lp_netbios_name());
1098         if (!ret) {
1099                 const char *ip = socket_get_my_addr(dce_call->conn->srv_conn->socket, mem_ctx);
1100                 W_ERROR_HAVE_NO_MEMORY(ip);
1101
1102                 ret = strequal(server_name, ip);
1103                 if (!ret) {
1104                         return WERR_INVALID_PRINTER_NAME;
1105                 }
1106         }
1107
1108         /* TODO: do access check here */
1109
1110         handle = dcesrv_handle_new(dce_call->context, SPOOLSS_HANDLE_SERVER);
1111         W_ERROR_HAVE_NO_MEMORY(handle);
1112
1113         state = talloc(handle, struct spoolss_handle_server);
1114         W_ERROR_HAVE_NO_MEMORY(state);
1115
1116         handle->data = state;
1117
1118         state->access_mask = r->in.access_mask;
1119
1120         *r->out.handle  = handle->wire_handle;
1121
1122         return WERR_OK; 
1123 }
1124
1125 static WERROR spoolss_OpenPrinterEx_printer(struct dcesrv_call_state *dce_call, 
1126                                             TALLOC_CTX *mem_ctx,
1127                                             struct spoolss_OpenPrinterEx *r,
1128                                             const char *server_name,
1129                                             const char *printer_name)
1130 {
1131         DEBUG(1, ("looking for printer [%s] (server[%s])\n", printer_name, server_name));
1132
1133         return WERR_INVALID_PRINTER_NAME;
1134 }
1135
1136 /* 
1137   spoolss_OpenPrinterEx 
1138 */
1139 static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1140                        struct spoolss_OpenPrinterEx *r)
1141 {
1142         char *p;
1143         char *server = NULL;
1144         const char *printer = r->in.printername;
1145         ZERO_STRUCTP(r->out.handle);
1146
1147         /* no printername is there it's like open server */
1148         if (!r->in.printername) {
1149                 return spoolss_OpenPrinterEx_server(dce_call, mem_ctx, r, NULL);
1150         }
1151
1152         /* just "\\" is invalid */
1153         if (strequal(r->in.printername, "\\\\")) {
1154                 return WERR_INVALID_PRINTER_NAME;
1155         }
1156
1157         if (strncmp(r->in.printername, "\\\\", 2) == 0) {
1158                 server = talloc_strdup(mem_ctx, r->in.printername + 2);
1159                 W_ERROR_HAVE_NO_MEMORY(server);
1160
1161                 /* here we know we have "\\" in front not followed
1162                  * by '\0', now see if we have another "\" in the string
1163                  */
1164                 p = strchr_m(server, '\\');
1165                 if (!p) {
1166                         /* there's no other "\", so it's ("\\%s",server)
1167                          */
1168                         return spoolss_OpenPrinterEx_server(dce_call, mem_ctx, r, server);
1169                 }
1170                 /* here we know that we have ("\\%s\",server),
1171                  * if we have '\0' as next then it's an invalid name
1172                  * otherwise the printer_name
1173                  */
1174                 p[0] = '\0';
1175                 /* everything that follows is the printer name */
1176                 p++;
1177                 printer = p;
1178
1179                 /* just "" as server is invalid */
1180                 if (strequal(server, "")) {
1181                         DEBUG(2,("ivalid server: [%s][%s][%s]\n", r->in.printername, server, printer));
1182                         return WERR_INVALID_PRINTER_NAME;
1183                 }
1184         }
1185
1186         /* just "" is invalid */
1187         if (strequal(printer, "")) {
1188                 DEBUG(2,("invalid printer: [%s][%s][%s]\n", r->in.printername, server, printer));
1189                 return WERR_INVALID_PRINTER_NAME;
1190         }
1191
1192         DEBUG(3,("printer: [%s][%s][%s]\n", r->in.printername, server, printer));
1193         return spoolss_OpenPrinterEx_printer(dce_call, mem_ctx, r, server, printer);
1194 }
1195
1196
1197 /* 
1198   spoolss_AddPrinterEx 
1199 */
1200 static WERROR spoolss_AddPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1201                        struct spoolss_AddPrinterEx *r)
1202 {
1203         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1204 }
1205
1206
1207 /* 
1208   spoolss_47 
1209 */
1210 static WERROR spoolss_47(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1211                        struct spoolss_47 *r)
1212 {
1213         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1214 }
1215
1216
1217 /* 
1218   spoolss_EnumPrinterData 
1219 */
1220 static WERROR spoolss_EnumPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1221                        struct spoolss_EnumPrinterData *r)
1222 {
1223         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1224 }
1225
1226
1227 /* 
1228   spoolss_DeletePrinterData 
1229 */
1230 static WERROR spoolss_DeletePrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1231                        struct spoolss_DeletePrinterData *r)
1232 {
1233         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1234 }
1235
1236
1237 /* 
1238   spoolss_4a 
1239 */
1240 static WERROR spoolss_4a(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1241                        struct spoolss_4a *r)
1242 {
1243         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1244 }
1245
1246
1247 /* 
1248   spoolss_4b 
1249 */
1250 static WERROR spoolss_4b(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1251                        struct spoolss_4b *r)
1252 {
1253         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1254 }
1255
1256
1257 /* 
1258   spoolss_4c 
1259 */
1260 static WERROR spoolss_4c(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1261                        struct spoolss_4c *r)
1262 {
1263         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1264 }
1265
1266
1267 /* 
1268   spoolss_SetPrinterDataEx 
1269 */
1270 static WERROR spoolss_SetPrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1271                        struct spoolss_SetPrinterDataEx *r)
1272 {
1273         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1274 }
1275
1276
1277 /* 
1278   spoolss_GetPrinterDataEx 
1279 */
1280 static WERROR spoolss_GetPrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1281                        struct spoolss_GetPrinterDataEx *r)
1282 {
1283         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1284 }
1285
1286
1287 /* 
1288   spoolss_EnumPrinterDataEx 
1289 */
1290 static WERROR spoolss_EnumPrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1291                        struct spoolss_EnumPrinterDataEx *r)
1292 {
1293         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1294 }
1295
1296
1297 /* 
1298   spoolss_EnumPrinterKey 
1299 */
1300 static WERROR spoolss_EnumPrinterKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1301                        struct spoolss_EnumPrinterKey *r)
1302 {
1303         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1304 }
1305
1306
1307 /* 
1308   spoolss_DeletePrinterDataEx 
1309 */
1310 static WERROR spoolss_DeletePrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1311                        struct spoolss_DeletePrinterDataEx *r)
1312 {
1313         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1314 }
1315
1316
1317 /* 
1318   spoolss_DeletePrinterKey 
1319 */
1320 static WERROR spoolss_DeletePrinterKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1321                        struct spoolss_DeletePrinterKey *r)
1322 {
1323         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1324 }
1325
1326
1327 /* 
1328   spoolss_53 
1329 */
1330 static WERROR spoolss_53(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1331                        struct spoolss_53 *r)
1332 {
1333         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1334 }
1335
1336
1337 /* 
1338   spoolss_DeletePrinterDriverEx 
1339 */
1340 static WERROR spoolss_DeletePrinterDriverEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1341                        struct spoolss_DeletePrinterDriverEx *r)
1342 {
1343         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1344 }
1345
1346
1347 /* 
1348   spoolss_55 
1349 */
1350 static WERROR spoolss_55(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1351                        struct spoolss_55 *r)
1352 {
1353         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1354 }
1355
1356
1357 /* 
1358   spoolss_56 
1359 */
1360 static WERROR spoolss_56(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1361                        struct spoolss_56 *r)
1362 {
1363         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1364 }
1365
1366
1367 /* 
1368   spoolss_57 
1369 */
1370 static WERROR spoolss_57(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1371                        struct spoolss_57 *r)
1372 {
1373         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1374 }
1375
1376
1377 /* 
1378   spoolss_58 
1379 */
1380 static WERROR spoolss_58(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1381                        struct spoolss_58 *r)
1382 {
1383         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1384 }
1385
1386
1387 /* 
1388   spoolss_AddPrinterDriverEx 
1389 */
1390 static WERROR spoolss_AddPrinterDriverEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1391                        struct spoolss_AddPrinterDriverEx *r)
1392 {
1393         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1394 }
1395
1396
1397 /* 
1398   spoolss_5a 
1399 */
1400 static WERROR spoolss_5a(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1401                        struct spoolss_5a *r)
1402 {
1403         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1404 }
1405
1406
1407 /* 
1408   spoolss_5b 
1409 */
1410 static WERROR spoolss_5b(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1411                        struct spoolss_5b *r)
1412 {
1413         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1414 }
1415
1416
1417 /* 
1418   spoolss_5c 
1419 */
1420 static WERROR spoolss_5c(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1421                        struct spoolss_5c *r)
1422 {
1423         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1424 }
1425
1426
1427 /* 
1428   spoolss_5d 
1429 */
1430 static WERROR spoolss_5d(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1431                        struct spoolss_5d *r)
1432 {
1433         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1434 }
1435
1436
1437 /* 
1438   spoolss_5e 
1439 */
1440 static WERROR spoolss_5e(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1441                        struct spoolss_5e *r)
1442 {
1443         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1444 }
1445
1446
1447 /* 
1448   spoolss_5f 
1449 */
1450 static WERROR spoolss_5f(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1451                        struct spoolss_5f *r)
1452 {
1453         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1454 }
1455
1456
1457 /* include the generated boilerplate */
1458 #include "librpc/gen_ndr/ndr_spoolss_s.c"