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