Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : client print routines
4 : Copyright (C) Andrew Tridgell 1994-1998
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "libsmb/libsmb.h"
22 : #include "libsmb/clirap.h"
23 : #include "../libcli/smb/smbXcli_base.h"
24 : #include "lib/util/string_wrappers.h"
25 :
26 : /*****************************************************************************
27 : Convert a character pointer in a cli_call_api() response to a form we can use.
28 : This function contains code to prevent core dumps if the server returns
29 : invalid data.
30 : *****************************************************************************/
31 0 : static const char *fix_char_ptr(unsigned int datap, unsigned int converter,
32 : char *rdata, int rdrcnt)
33 : {
34 0 : unsigned int offset;
35 :
36 0 : if (datap == 0) {
37 : /* turn NULL pointers into zero length strings */
38 0 : return "";
39 : }
40 :
41 0 : offset = datap - converter;
42 :
43 0 : if (offset >= rdrcnt) {
44 0 : DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>\n",
45 : datap, converter, rdrcnt));
46 0 : return "<ERROR>";
47 : }
48 0 : return &rdata[offset];
49 : }
50 :
51 : /****************************************************************************
52 : call fn() on each entry in a print queue
53 : ****************************************************************************/
54 :
55 0 : NTSTATUS cli_print_queue(struct cli_state *cli,
56 : void (*fn)(struct print_job_info *))
57 : {
58 0 : uint8_t *rparam = NULL;
59 0 : uint8_t *rdata = NULL;
60 0 : char *p = NULL;
61 0 : uint32_t rdrcnt, rprcnt;
62 0 : char param[1024];
63 0 : int converter;
64 0 : int result_code=0;
65 0 : int i = -1;
66 0 : NTSTATUS status;
67 :
68 0 : memset(param,'\0',sizeof(param));
69 :
70 0 : p = param;
71 0 : SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */
72 0 : p += 2;
73 0 : strlcpy_base(p,"zWrLeh", param, sizeof(param)); /* parameter description? */
74 0 : p = skip_string(param,sizeof(param),p);
75 0 : strlcpy_base(p,"WWzWWDDzz", param, sizeof(param)); /* returned data format */
76 0 : p = skip_string(param,sizeof(param),p);
77 0 : strlcpy_base(p,cli->share, param, sizeof(param)); /* name of queue */
78 0 : p = skip_string(param,sizeof(param),p);
79 0 : SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */
80 0 : SSVAL(p,2,1000); /* size of bytes of returned data buffer */
81 0 : p += 4;
82 0 : strlcpy_base(p,"", param,sizeof(param)); /* subformat */
83 0 : p = skip_string(param,sizeof(param),p);
84 :
85 0 : DEBUG(4,("doing cli_print_queue for %s\n", cli->share));
86 :
87 0 : status = cli_trans(
88 : talloc_tos(),
89 : cli,
90 : SMBtrans, /* trans_cmd */
91 : "\\PIPE\\LANMAN", /* name */
92 : 0, /* fid */
93 : 0, /* function */
94 : 0, /* flags */
95 : NULL, /* setup */
96 : 0, /* num_setup */
97 : 0, /* max_setup */
98 : (uint8_t *)param, /* param */
99 0 : PTR_DIFF(p,param), /* num_param */
100 : 1024, /* max_param */
101 : NULL, /* data */
102 : 0, /* num_data */
103 : CLI_BUFFER_SIZE, /* max_data */
104 : NULL, /* recv_flags2 */
105 : NULL, /* rsetup */
106 : 0, /* min_rsetup */
107 : NULL, /* num_rsetup */
108 : &rparam, /* rparam */
109 : 8, /* min_rparam */
110 : &rprcnt, /* num_rparam */
111 : &rdata, /* rdata */
112 : 0, /* min_rdata */
113 : &rdrcnt); /* num_rdata */
114 0 : if (!NT_STATUS_IS_OK(status)) {
115 0 : cli->raw_status = status;
116 0 : return status;
117 : }
118 :
119 0 : result_code = SVAL(rparam,0);
120 0 : converter = SVAL(rparam,2); /* conversion factor */
121 :
122 0 : if (result_code == 0) {
123 0 : struct print_job_info job;
124 :
125 0 : p = (char *)rdata;
126 :
127 0 : for (i = 0; i < SVAL(rparam,4); ++i) {
128 0 : job.id = SVAL(p,0);
129 0 : job.priority = SVAL(p,2);
130 0 : fstrcpy(job.user,
131 : fix_char_ptr(SVAL(p,4), converter,
132 : (char *)rdata, rdrcnt));
133 0 : job.t = make_unix_date3(
134 0 : p + 12, smb1cli_conn_server_time_zone(cli->conn));
135 0 : job.size = IVAL(p,16);
136 0 : fstrcpy(job.name,fix_char_ptr(SVAL(p,24),
137 : converter,
138 : (char *)rdata, rdrcnt));
139 0 : fn(&job);
140 0 : p += 28;
141 : }
142 : }
143 :
144 : /* If any parameters or data were returned, free the storage. */
145 0 : TALLOC_FREE(rparam);
146 0 : TALLOC_FREE(rdata);
147 :
148 0 : return NT_STATUS_OK;
149 : }
150 :
151 : /****************************************************************************
152 : cancel a print job
153 : ****************************************************************************/
154 :
155 0 : NTSTATUS cli_printjob_del(struct cli_state *cli, int job)
156 : {
157 0 : uint8_t *rparam = NULL;
158 0 : uint8_t *rdata = NULL;
159 0 : char *p = NULL;
160 0 : uint32_t rdrcnt, rprcnt;
161 0 : int result_code;
162 0 : char param[1024];
163 0 : NTSTATUS status = NT_STATUS_OK;
164 :
165 0 : memset(param,'\0',sizeof(param));
166 :
167 0 : p = param;
168 0 : SSVAL(p,0,81); /* DosPrintJobDel() */
169 0 : p += 2;
170 0 : strlcpy_base(p,"W", param,sizeof(param));
171 0 : p = skip_string(param,sizeof(param),p);
172 0 : strlcpy_base(p,"", param,sizeof(param));
173 0 : p = skip_string(param,sizeof(param),p);
174 0 : SSVAL(p,0,job);
175 0 : p += 2;
176 :
177 0 : status = cli_trans(talloc_tos(),
178 : cli,
179 : SMBtrans, /* trans_cmd */
180 : "\\PIPE\\LANMAN", /* name */
181 : 0, /* fid */
182 : 0, /* function */
183 : 0, /* flags */
184 : NULL, /* setup */
185 : 0, /* num_setup */
186 : 0, /* max_setup */
187 : (uint8_t *)param, /* param */
188 0 : PTR_DIFF(p, param), /* num_param */
189 : 1024, /* max_param */
190 : NULL, /* data */
191 : 0, /* num_data */
192 : CLI_BUFFER_SIZE, /* max_data */
193 : NULL, /* recv_flags2 */
194 : NULL, /* rsetup */
195 : 0, /* min_rsetup */
196 : NULL, /* num_rsetup */
197 : &rparam, /* rparam */
198 : 8, /* min_rparam */
199 : &rprcnt, /* num_rparam */
200 : &rdata, /* rdata */
201 : 0, /* min_rdata */
202 : &rdrcnt); /* num_rdata */
203 0 : if (!NT_STATUS_IS_OK(status)) {
204 0 : cli->raw_status = status;
205 0 : return status;
206 : }
207 :
208 0 : result_code = SVAL(rparam, 0);
209 :
210 0 : TALLOC_FREE(rparam);
211 0 : TALLOC_FREE(rdata);
212 :
213 0 : if (result_code == ERRnosuchprintjob) {
214 0 : status = NT_STATUS_INVALID_PARAMETER;
215 0 : cli->raw_status = NT_STATUS_INVALID_PARAMETER;
216 : }
217 :
218 0 : return status;
219 : }
|