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