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