updated the 3.0 branch from the head branch - ready for alpha18
[samba.git] / source3 / rpc_client / cli_spoolss.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6  *  Copyright (C) Paul Ashton                  1997-2000,
7  *  Copyright (C) Jean Francois Micouleau      1998-2000,
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_parse.h"
26 #include "nterr.h"
27
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_RPC_CLI
30
31 /****************************************************************************
32 do a SPOOLSS Enum Printer Drivers
33 ****************************************************************************/
34 uint32 spoolss_enum_printerdrivers(const char *srv_name, const char *environment,
35                                    uint32 level, NEW_BUFFER *buffer, uint32 offered,
36                                    uint32 *needed, uint32 *returned)
37 {
38         prs_struct rbuf;
39         prs_struct buf;
40         SPOOL_Q_ENUMPRINTERDRIVERS q_o;
41         SPOOL_R_ENUMPRINTERDRIVERS r_o;
42         TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
43
44         struct cli_connection *con = NULL;
45
46         if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
47                 return False;
48
49         prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
50         prs_init(&rbuf, 0, ctx, UNMARSHALL);
51
52         /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
53
54         DEBUG(5,("SPOOLSS Enum Printer Drivers (Server: %s Environment: %s level: %d)\n",
55                                 srv_name, environment, level));
56
57         make_spoolss_q_enumprinterdrivers(&q_o, srv_name, environment,
58                                 level, buffer, offered);
59
60         /* turn parameters into data stream */
61         if (spoolss_io_q_enumprinterdrivers("", &q_o, &buf, 0) &&
62              rpc_con_pipe_req(con, SPOOLSS_ENUMPRINTERDRIVERS, &buf, &rbuf)) 
63         {
64                 prs_mem_free(&buf);
65                 ZERO_STRUCT(r_o);
66
67                 prs_switch_type(&buffer->prs, UNMARSHALL);
68                 prs_set_offset(&buffer->prs, 0);
69                 r_o.buffer=buffer;
70
71                 if(spoolss_io_r_enumprinterdrivers("", &r_o, &rbuf, 0)) 
72                 {
73                         if (r_o.status != NT_STATUS_OK)
74                         {
75                                 DEBUG(3,("SPOOLSS_ENUMPRINTERDRIVERS:  %s\n", nt_errstr(r_o.status)));
76                         }
77                         *needed=r_o.needed;
78                         *returned=r_o.returned;
79                 }
80         }
81
82         prs_mem_free(&rbuf);
83         prs_mem_free(&buf );
84
85         cli_connection_unlink(con);
86
87         return r_o.status;
88 }
89
90 /****************************************************************************
91 do a SPOOLSS Enum Printers
92 ****************************************************************************/
93 uint32 spoolss_enum_printers(uint32 flags, fstring srv_name, uint32 level,
94                              NEW_BUFFER *buffer, uint32 offered,
95                              uint32 *needed, uint32 *returned)
96 {
97         prs_struct rbuf;
98         prs_struct buf;
99         SPOOL_Q_ENUMPRINTERS q_o;
100         SPOOL_R_ENUMPRINTERS r_o;
101         TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
102
103         struct cli_connection *con = NULL;
104
105         if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
106                 return False;
107
108         prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
109         prs_init(&rbuf, 0, ctx, UNMARSHALL);
110
111         /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
112
113         DEBUG(5,("SPOOLSS Enum Printers (Server: %s level: %d)\n", srv_name, level));
114
115         make_spoolss_q_enumprinters(&q_o, flags, "", level, buffer, offered);
116
117         /* turn parameters into data stream */
118         if (spoolss_io_q_enumprinters("", &q_o, &buf, 0) &&
119            rpc_con_pipe_req(con, SPOOLSS_ENUMPRINTERS, &buf, &rbuf)) 
120         {
121                 ZERO_STRUCT(r_o);
122
123                 prs_switch_type(&buffer->prs, UNMARSHALL);
124                 prs_set_offset(&buffer->prs, 0);
125                 r_o.buffer=buffer;
126
127                 if(new_spoolss_io_r_enumprinters("", &r_o, &rbuf, 0)) 
128                 {
129                         if (r_o.status != NT_STATUS_OK)
130                         {
131                                 /* report error code */
132                                 DEBUG(3,("SPOOLSS_ENUMPRINTERS: %s\n", nt_errstr(r_o.status)));
133                         }
134
135                         *needed=r_o.needed;
136                         *returned=r_o.returned;
137                 }
138
139         }
140
141         prs_mem_free(&rbuf);
142         prs_mem_free(&buf );
143
144         cli_connection_unlink(con);
145
146         return r_o.status;
147 }
148
149 /****************************************************************************
150 do a SPOOLSS Enum Ports
151 ****************************************************************************/
152 uint32 spoolss_enum_ports(fstring srv_name, uint32 level,
153                              NEW_BUFFER *buffer, uint32 offered,
154                              uint32 *needed, uint32 *returned)
155 {
156         prs_struct rbuf;
157         prs_struct buf;
158         SPOOL_Q_ENUMPORTS q_o;
159         SPOOL_R_ENUMPORTS r_o;
160         TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
161
162         struct cli_connection *con = NULL;
163
164         if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
165                 return False;
166
167         prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
168         prs_init(&rbuf, 0, ctx, UNMARSHALL);
169
170         /* create and send a MSRPC command with api SPOOLSS_ENUMPORTS */
171
172         DEBUG(5,("SPOOLSS Enum Ports (Server: %s level: %d)\n", srv_name, level));
173
174         make_spoolss_q_enumports(&q_o, "", level, buffer, offered);
175
176         /* turn parameters into data stream */
177         if (spoolss_io_q_enumports("", &q_o, &buf, 0) &&
178              rpc_con_pipe_req(con, SPOOLSS_ENUMPORTS, &buf, &rbuf))
179         {
180                 prs_mem_free(&buf );
181                 ZERO_STRUCT(r_o);
182
183                 prs_switch_type(&buffer->prs, UNMARSHALL);
184                 prs_set_offset(&buffer->prs, 0);
185                 r_o.buffer=buffer;
186
187                 if(new_spoolss_io_r_enumports("", &r_o, &rbuf, 0)) 
188                 {
189                         if (r_o.status != NT_STATUS_OK)
190                         {
191                                 DEBUG(3,("SPOOLSS_ENUMPORTS: %s\n", nt_errstr(r_o.status)));
192                         }
193                         
194                         *needed=r_o.needed;
195                         *returned=r_o.returned;
196                 }
197         }
198
199         prs_mem_free(&rbuf);
200         prs_mem_free(&buf );
201
202         cli_connection_unlink(con);
203
204         return r_o.status;
205 }
206
207 /****************************************************************************
208 do a SPOOLSS Enum Jobs
209 ****************************************************************************/
210 uint32 spoolss_enum_jobs(const POLICY_HND *hnd, uint32 firstjob, uint32 numofjobs,
211                          uint32 level, NEW_BUFFER *buffer, uint32 offered,
212                          uint32 *needed, uint32 *returned)
213 {
214         prs_struct rbuf;
215         prs_struct buf;
216         SPOOL_Q_ENUMJOBS q_o;
217         SPOOL_R_ENUMJOBS r_o;
218         TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
219
220         if (hnd == NULL)
221                 return NT_STATUS_INVALID_PARAMETER;
222
223         prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
224         prs_init(&rbuf, 0, ctx, UNMARSHALL);
225
226         /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
227
228         DEBUG(5,("SPOOLSS Enum Jobs level: %d)\n", level));
229
230         make_spoolss_q_enumjobs(&q_o, hnd, firstjob, numofjobs, level, buffer, offered);
231
232         /* turn parameters into data stream */
233         if (spoolss_io_q_enumjobs("", &q_o, &buf, 0) &&
234              rpc_hnd_pipe_req(hnd, SPOOLSS_ENUMJOBS, &buf, &rbuf))
235         {
236                 ZERO_STRUCT(r_o);
237                 prs_mem_free(&buf );
238
239                 r_o.buffer=buffer;
240
241                 if(spoolss_io_r_enumjobs("", &r_o, &rbuf, 0)) 
242                 {
243                         if (r_o.status != NT_STATUS_OK)
244                         {
245                                 DEBUG(3,("SPOOLSS_ENUMJOBS: %s\n", nt_errstr(r_o.status)));
246                         }
247                         *needed=r_o.needed;
248                         *returned=r_o.returned;
249                 }
250         }
251
252         prs_mem_free(&rbuf);
253         prs_mem_free(&buf );
254
255         return r_o.status;
256 }
257
258 /***************************************************************************
259 do a SPOOLSS Enum printer datas
260 ****************************************************************************/
261 uint32 spoolss_enum_printerdata(const POLICY_HND *hnd, uint32 idx,
262                                 uint32 *valuelen, uint16 *value, uint32 *rvaluelen,
263                                 uint32 *type, uint32 *datalen, uint8 *data, 
264                                 uint32 *rdatalen)
265 {
266         prs_struct rbuf;
267         prs_struct buf;
268         SPOOL_Q_ENUMPRINTERDATA q_o;
269         SPOOL_R_ENUMPRINTERDATA r_o;
270         TALLOC_CTX *mem_ctx = NULL;
271         
272         if (hnd == NULL)
273                 return NT_STATUS_INVALID_PARAMETER;
274
275         if ((mem_ctx=talloc_init()) == NULL)
276         {
277                 DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
278                 return False;
279         }
280         prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
281         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
282
283         /* create and send a MSRPC command with api  SPOOLSS_ENUMPRINTERDATA*/
284
285         DEBUG(4,("SPOOLSS Enum Printer data\n"));
286
287         make_spoolss_q_enumprinterdata(&q_o, hnd, idx, *valuelen, *datalen);
288
289         /* turn parameters into data stream */
290         if (spoolss_io_q_enumprinterdata("", &q_o, &buf, 0) &&
291              rpc_hnd_pipe_req(hnd, SPOOLSS_ENUMPRINTERDATA, &buf, &rbuf)) 
292         {
293                 ZERO_STRUCT(r_o);
294                 prs_mem_free(&buf );
295
296                 r_o.data=data;
297                 r_o.value=value;
298
299                 if(spoolss_io_r_enumprinterdata("", &r_o, &rbuf, 0))
300                 {
301                         if (r_o.status != NT_STATUS_OK)
302                         {
303                                 DEBUG(3,("SPOOLSS_ENUMPRINTERDATA: %s\n", nt_errstr(r_o.status)));
304                         }
305                         
306                         *valuelen=r_o.valuesize;
307                         *rvaluelen=r_o.realvaluesize;
308                         *type=r_o.type;
309                         *datalen=r_o.datasize;
310                         *rdatalen=r_o.realdatasize;
311
312                 }
313         }
314
315         prs_mem_free(&rbuf);
316         prs_mem_free(&buf );
317         if (mem_ctx)
318                 talloc_destroy(mem_ctx);
319
320         return r_o.status;
321 }
322
323 /****************************************************************************
324 do a SPOOLSS Enum printer datas
325 ****************************************************************************/
326 uint32 spoolss_getprinter(const POLICY_HND *hnd, uint32 level,
327                              NEW_BUFFER *buffer, uint32 offered,
328                              uint32 *needed)
329 {
330         prs_struct rbuf;
331         prs_struct buf;
332         SPOOL_Q_GETPRINTER q_o;
333         SPOOL_R_GETPRINTER r_o;
334         TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
335
336         if (hnd == NULL)
337                 return NT_STATUS_INVALID_PARAMETER;
338
339         prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
340         prs_init(&rbuf, 0, ctx, UNMARSHALL);
341
342         /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
343
344         DEBUG(5,("SPOOLSS Enum Printer data)\n"));
345
346         make_spoolss_q_getprinter(&q_o, hnd, level, buffer, offered);
347
348         /* turn parameters into data stream */
349         if (spoolss_io_q_getprinter("", &q_o, &buf, 0) &&
350              rpc_hnd_pipe_req(hnd, SPOOLSS_GETPRINTER, &buf, &rbuf)) 
351         {
352                 ZERO_STRUCT(r_o);
353                 prs_mem_free(&buf );
354
355                 prs_switch_type(&buffer->prs, UNMARSHALL);
356                 prs_set_offset(&buffer->prs, 0);
357                 r_o.buffer=buffer;
358
359                 if(!spoolss_io_r_getprinter("", &r_o, &rbuf, 0)) 
360                 {
361                         if (r_o.status != NT_STATUS_OK)
362                         {
363                                 DEBUG(3,("SPOOLSS_GETPRINTER: %s\n", nt_errstr(r_o.status)));
364                         }
365                         *needed=r_o.needed;
366                 }
367         }
368
369         prs_mem_free(&rbuf);
370         prs_mem_free(&buf );
371
372         return r_o.status;
373 }
374
375 /****************************************************************************
376 do a SPOOLSS Enum printer driver
377 ****************************************************************************/
378 uint32 spoolss_getprinterdriver(const POLICY_HND *hnd,
379                                 const char *environment, uint32 level,
380                                 NEW_BUFFER *buffer, uint32 offered,
381                                 uint32 *needed)
382 {
383         prs_struct rbuf;
384         prs_struct buf;
385         SPOOL_Q_GETPRINTERDRIVER2 q_o;
386         SPOOL_R_GETPRINTERDRIVER2 r_o;
387         TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
388
389         if (hnd == NULL)
390                 return NT_STATUS_INVALID_PARAMETER;
391
392         prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
393         prs_init(&rbuf, 0, ctx, UNMARSHALL);
394
395         /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
396
397         DEBUG(5,("SPOOLSS Enum Printer driver)\n"));
398
399         make_spoolss_q_getprinterdriver2(&q_o, hnd, environment, level, 2, 0, buffer, offered);
400
401         /* turn parameters into data stream */
402         if (spoolss_io_q_getprinterdriver2("", &q_o, &buf, 0) &&
403              rpc_hnd_pipe_req(hnd, SPOOLSS_GETPRINTERDRIVER2, &buf, &rbuf)) 
404         {
405                 ZERO_STRUCT(r_o);
406                 prs_mem_free(&buf );
407
408                 prs_switch_type(&buffer->prs, UNMARSHALL);
409                 prs_set_offset(&buffer->prs, 0);
410                 r_o.buffer=buffer;
411
412                 if(spoolss_io_r_getprinterdriver2("", &r_o, &rbuf, 0)) 
413                 {
414                         if (r_o.status != NT_STATUS_OK)
415                         {
416                                 DEBUG(3,("SPOOLSS_GETPRINTERDRIVER2: %s\n", nt_errstr(r_o.status)));
417                         }
418
419                         *needed=r_o.needed;
420                 }
421         }
422
423         prs_mem_free(&rbuf);
424         prs_mem_free(&buf );
425
426         return r_o.status;
427 }
428
429
430
431 /****************************************************************************
432 do a SPOOLSS Open Printer Ex
433 ****************************************************************************/
434 BOOL spoolss_open_printer_ex(  const char *printername,
435                          const char *datatype, uint32 access_required,
436                          const char *station,  const char *username,
437                         POLICY_HND *hnd)
438 {
439         prs_struct rbuf;
440         prs_struct buf;
441         SPOOL_Q_OPEN_PRINTER_EX q_o;
442         BOOL valid_pol = False;
443         fstring srv_name;
444         char *s = NULL;
445         struct cli_connection *con = NULL;
446         TALLOC_CTX *mem_ctx = NULL;
447         
448         memset(srv_name, 0, sizeof(srv_name));
449         fstrcpy(srv_name, printername);
450
451         s = strchr_m(&srv_name[2], '\\');
452         if (s != NULL)
453                 *s = '\0';
454
455         if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
456                 return False;
457
458         if (hnd == NULL) 
459                 return False;
460
461         if ((mem_ctx=talloc_init()) == NULL)
462         {
463                 DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
464                 return False;
465         }
466         prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
467         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
468
469         /* create and send a MSRPC command with api SPOOLSS_OPENPRINTEREX */
470
471         DEBUG(5,("SPOOLSS Open Printer Ex\n"));
472
473         make_spoolss_q_open_printer_ex(&q_o, printername, datatype,
474                                        access_required, station, username);
475
476         /* turn parameters into data stream */
477         if (spoolss_io_q_open_printer_ex("", &q_o, &buf, 0) &&
478             rpc_con_pipe_req(con, SPOOLSS_OPENPRINTEREX, &buf, &rbuf))
479         {
480                 SPOOL_R_OPEN_PRINTER_EX r_o;
481                 BOOL p = True;
482
483                 spoolss_io_r_open_printer_ex("", &r_o, &rbuf, 0);
484
485                 if (prs_offset(&rbuf)!= 0 && r_o.status != 0)
486                 {
487                         /* report error code */
488                         DEBUG(3,("SPOOLSS_OPENPRINTEREX: %s\n", nt_errstr(r_o.status)));
489                         p = False;
490                 }
491
492                 if (p)
493                 {
494                         /* ok, at last: we're happy. return the policy handle */
495                         *hnd = r_o.handle;
496
497                         /* associate the handle returned with the current 
498                            state of the clienjt connection */
499                         valid_pol = RpcHndList_set_connection(hnd, con);
500
501                 }
502         }
503
504         prs_mem_free(&rbuf);
505         prs_mem_free(&buf );
506         if (mem_ctx)
507                 talloc_destroy(mem_ctx);
508
509         return valid_pol;
510 }
511
512 /****************************************************************************
513  do a SPOOLSS AddPrinterEx()
514  **ALWAYS** uses as PRINTER_INFO level 2 struct
515 ****************************************************************************/
516 BOOL spoolss_addprinterex(POLICY_HND *hnd, const char* srv_name, PRINTER_INFO_2 *info2)
517 {
518         prs_struct rbuf;
519         prs_struct buf;
520         SPOOL_Q_ADDPRINTEREX q_o;
521         SPOOL_R_ADDPRINTEREX r_o;
522         struct cli_connection *con = NULL;
523         TALLOC_CTX *mem_ctx = NULL;
524         fstring the_client_name;
525         BOOL valid_pol = True;
526
527
528
529         if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
530                 return NT_STATUS_ACCESS_DENIED;
531
532         if (hnd == NULL)
533                 return NT_STATUS_INVALID_PARAMETER;
534
535         if ((mem_ctx=talloc_init()) == NULL)
536         {
537                 DEBUG(0,("spoolss_addprinterex: talloc_init() failed!\n"));
538                 return NT_STATUS_ACCESS_DENIED;
539         }
540         prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
541         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
542
543         /* create and send a MSRPC command with api SPOOLSS_ENUMPORTS */
544         DEBUG(5,("SPOOLSS Add Printer Ex (Server: %s)\n", srv_name));
545         
546         fstrcpy(the_client_name, "\\\\");
547         fstrcat(the_client_name, con->pCli_state->desthost);
548         strupper(the_client_name);
549         
550
551         make_spoolss_q_addprinterex(mem_ctx, &q_o, srv_name, the_client_name, 
552                                     /* "Administrator", */
553                                     con->pCli_state->user_name,
554                                     2, info2);
555
556         /* turn parameters into data stream and send the request */
557         if (spoolss_io_q_addprinterex("", &q_o, &buf, 0) &&
558             rpc_con_pipe_req(con, SPOOLSS_ADDPRINTEREX, &buf, &rbuf)) 
559         {
560                 ZERO_STRUCT(r_o);
561
562                 if(spoolss_io_r_addprinterex("", &r_o, &rbuf, 0)) 
563                 {
564                         if (r_o.status != NT_STATUS_OK)
565                         {
566                                 /* report error code */
567                                 DEBUG(3,("SPOOLSS_ADDPRINTEREX: %s\n", nt_errstr(r_o.status)));
568                                 valid_pol = False;
569                         }
570                 }
571                 
572                 if (valid_pol)
573                 {
574                         /* ok, at last: we're happy. return the policy handle */
575                         copy_policy_hnd( hnd, &r_o.handle);
576
577                         /* associate the handle returned with the current 
578                            state of the clienjt connection */
579                         RpcHndList_set_connection(hnd, con);
580                 }
581         }
582
583
584         prs_mem_free(&rbuf);
585         prs_mem_free(&buf );
586
587         if (mem_ctx)
588                 talloc_destroy(mem_ctx);
589
590         return valid_pol;
591 }
592
593 /****************************************************************************
594 do a SPOOL Close
595 ****************************************************************************/
596 BOOL spoolss_closeprinter(POLICY_HND *hnd)
597 {
598         prs_struct rbuf;
599         prs_struct buf;
600         SPOOL_Q_CLOSEPRINTER q_c;
601         BOOL valid_close = False;
602         TALLOC_CTX *mem_ctx = NULL;
603         
604         if (hnd == NULL) 
605                 return False;
606
607         /* create and send a MSRPC command with api SPOOLSS_CLOSEPRINTER */
608         if ((mem_ctx=talloc_init()) == NULL)
609         {
610                 DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
611                 return False;
612         }
613         prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
614         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
615
616         DEBUG(4,("SPOOL Close Printer\n"));
617
618         /* store the parameters */
619         make_spoolss_q_closeprinter(&q_c, hnd);
620
621         /* turn parameters into data stream */
622         if (spoolss_io_q_closeprinter("", &q_c, &buf, 0) &&
623             rpc_hnd_pipe_req(hnd, SPOOLSS_CLOSEPRINTER, &buf, &rbuf))
624         {
625                 SPOOL_R_CLOSEPRINTER r_c;
626
627                 spoolss_io_r_closeprinter("", &r_c, &rbuf, 0);
628
629                 if (prs_offset(&rbuf)!=0 && r_c.status != 0)
630                 {
631                         /* report error code */
632                         DEBUG(3,("SPOOL_CLOSEPRINTER: %s\n", nt_errstr(r_c.status)));
633                 }
634                 else
635                         valid_close = True;
636         }
637
638         prs_mem_free(&rbuf);
639         prs_mem_free(&buf );
640         if (mem_ctx)
641                 talloc_destroy(mem_ctx);
642
643         /* disassociate with the cli_connection */
644         RpcHndList_del_connection(hnd);
645
646         return valid_close;
647 }
648
649 /****************************************************************************
650 do a SPOOLSS Get printer datas
651 ****************************************************************************/
652 uint32 spoolss_getprinterdata(const POLICY_HND *hnd, const UNISTR2 *valuename,
653                         uint32 in_size,
654                         uint32 *type,
655                         uint32 *out_size,
656                         uint8 *data,
657                         uint32 *needed)
658 {
659         prs_struct rbuf;
660         prs_struct buf;
661         SPOOL_Q_GETPRINTERDATA q_o;
662         SPOOL_R_GETPRINTERDATA r_o;
663         TALLOC_CTX *mem_ctx = NULL;
664
665         if (hnd == NULL)
666                 return NT_STATUS_INVALID_PARAMETER;
667
668         if ((mem_ctx=talloc_init()) == NULL)
669         {
670                 DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
671                 return False;
672         }
673         prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
674         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
675
676         /* create and send a MSRPC command with api SPOOLSS_GETPRINTERDATA */
677
678         DEBUG(5,("SPOOLSS Get Printer data)\n"));
679
680         make_spoolss_q_getprinterdata(&q_o, hnd,(UNISTR2 *)valuename, in_size);
681
682         /* turn parameters into data stream */
683         if (spoolss_io_q_getprinterdata("", &q_o, &buf, 0) &&
684              rpc_hnd_pipe_req(hnd, SPOOLSS_GETPRINTERDATA, &buf, &rbuf)) 
685         {
686                 ZERO_STRUCT(r_o);
687                 prs_mem_free(&buf );
688
689                 r_o.data=data;
690
691                 if(spoolss_io_r_getprinterdata("", &r_o, &rbuf, 0)) 
692                 {
693                         if (r_o.status != NT_STATUS_OK)
694                         {
695                                 DEBUG(3,("SPOOLSS_GETPRINTERDATA: %s\n", nt_errstr(r_o.status)));
696                         }
697
698                         *type=r_o.type;
699                         *out_size=r_o.size;
700                         *needed=r_o.needed;
701                 }
702         }
703
704         prs_mem_free(&rbuf);
705         prs_mem_free(&buf );
706
707         return r_o.status;
708 }
709
710 /****************************************************************************
711 do a SPOOLSS Get Printer Driver Direcotry
712 ****************************************************************************/
713 uint32 spoolss_getprinterdriverdir(fstring srv_name, fstring env_name, uint32 level,
714                              NEW_BUFFER *buffer, uint32 offered,
715                              uint32 *needed)
716 {
717         prs_struct rbuf;
718         prs_struct buf;
719         SPOOL_Q_GETPRINTERDRIVERDIR q_o;
720         SPOOL_R_GETPRINTERDRIVERDIR r_o;
721         TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
722
723         struct cli_connection *con = NULL;
724
725         if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
726                 return False;
727
728         prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
729         prs_init(&rbuf, 0, ctx, UNMARSHALL);
730
731         /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
732
733         DEBUG(5,("SPOOLSS GetPrinterDriverDir (Server: %s Env: %s level: %d)\n", 
734                   srv_name, env_name, level));
735
736         make_spoolss_q_getprinterdriverdir(&q_o, srv_name, env_name, level, 
737                                            buffer, offered);
738
739         /* turn parameters into data stream */
740         if (spoolss_io_q_getprinterdriverdir("", &q_o, &buf, 0) &&
741              rpc_con_pipe_req(con, SPOOLSS_GETPRINTERDRIVERDIRECTORY, &buf, &rbuf)) 
742         {
743                 prs_mem_free(&buf );
744                 ZERO_STRUCT(r_o);
745
746                 prs_switch_type(&buffer->prs, UNMARSHALL);
747                 prs_set_offset(&buffer->prs, 0);
748                 r_o.buffer=buffer;
749
750                 if(spoolss_io_r_getprinterdriverdir("", &r_o, &rbuf, 0)) 
751                 {
752                         if (r_o.status != NT_STATUS_OK)
753                         {
754                                 DEBUG(3,("SPOOLSS_GETPRINTERDRIVERDIRECTORY: %s\n", nt_errstr(r_o.status)));
755                         }
756
757                         *needed=r_o.needed;
758                 }
759         }
760
761         prs_mem_free(&rbuf);
762         prs_mem_free(&buf );
763
764         cli_connection_unlink(con);
765
766         return r_o.status;
767 }
768
769 /******************************************************************************
770  AddPrinterDriver()
771  *****************************************************************************/
772 uint32 spoolss_addprinterdriver(const char *srv_name, uint32 level, PRINTER_DRIVER_CTR *info)
773 {
774         prs_struct                      rbuf;
775         prs_struct                      buf;
776         SPOOL_Q_ADDPRINTERDRIVER        q_o;
777         SPOOL_R_ADDPRINTERDRIVER        r_o;
778         TALLOC_CTX                      *mem_ctx = NULL;
779         struct cli_connection           *con = NULL;
780         
781         if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
782                 return False;
783
784         if ((mem_ctx=talloc_init()) == NULL)
785         {
786                 DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
787                 return False;
788         }
789         prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
790         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
791         
792         /* make the ADDPRINTERDRIVER PDU */
793         make_spoolss_q_addprinterdriver(mem_ctx, &q_o, srv_name, level, info);
794
795         /* turn the data into an io stream */
796         if (spoolss_io_q_addprinterdriver("", &q_o, &buf, 0) &&
797             rpc_con_pipe_req(con, SPOOLSS_ADDPRINTERDRIVER, &buf, &rbuf)) 
798         {
799                 ZERO_STRUCT(r_o);
800
801                 if(spoolss_io_r_addprinterdriver("", &r_o, &rbuf, 0)) 
802                 {
803                         if (r_o.status != NT_STATUS_OK)
804                         {
805                                 /* report error code */
806                                 DEBUG(3,("SPOOLSS_ADDPRINTERDRIVER: %s\n", nt_errstr(r_o.status)));
807                         }
808                 }
809         }
810
811
812         prs_mem_free(&rbuf);
813         prs_mem_free(&buf );
814
815         if (mem_ctx)
816                 talloc_destroy(mem_ctx);
817                 
818         return r_o.status;
819
820 }