/src/samba/source3/libsmb/cliprint.c
Line | Count | Source (jump to first uncovered line) |
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 "source3/include/client.h" |
22 | | #include "source3/libsmb/proto.h" |
23 | | #include "libsmb/clirap.h" |
24 | | #include "../libcli/smb/smbXcli_base.h" |
25 | | #include "lib/util/string_wrappers.h" |
26 | | |
27 | | /***************************************************************************** |
28 | | Convert a character pointer in a cli_call_api() response to a form we can use. |
29 | | This function contains code to prevent core dumps if the server returns |
30 | | invalid data. |
31 | | *****************************************************************************/ |
32 | | static const char *fix_char_ptr(unsigned int datap, unsigned int converter, |
33 | | char *rdata, int rdrcnt) |
34 | 0 | { |
35 | 0 | unsigned int offset; |
36 | |
|
37 | 0 | if (datap == 0) { |
38 | | /* turn NULL pointers into zero length strings */ |
39 | 0 | return ""; |
40 | 0 | } |
41 | | |
42 | 0 | offset = datap - converter; |
43 | |
|
44 | 0 | if (offset >= rdrcnt) { |
45 | 0 | DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>\n", |
46 | 0 | datap, converter, rdrcnt)); |
47 | 0 | return "<ERROR>"; |
48 | 0 | } |
49 | 0 | return &rdata[offset]; |
50 | 0 | } |
51 | | |
52 | | /**************************************************************************** |
53 | | call fn() on each entry in a print queue |
54 | | ****************************************************************************/ |
55 | | |
56 | | NTSTATUS cli_print_queue(struct cli_state *cli, |
57 | | void (*fn)(struct print_job_info *)) |
58 | 0 | { |
59 | 0 | uint8_t *rparam = NULL; |
60 | 0 | uint8_t *rdata = NULL; |
61 | 0 | char *p = NULL; |
62 | 0 | uint32_t rdrcnt, rprcnt; |
63 | 0 | char param[1024]; |
64 | 0 | int converter; |
65 | 0 | int result_code=0; |
66 | 0 | int i = -1; |
67 | 0 | NTSTATUS status; |
68 | |
|
69 | 0 | memset(param,'\0',sizeof(param)); |
70 | |
|
71 | 0 | p = param; |
72 | 0 | SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ |
73 | 0 | p += 2; |
74 | 0 | strlcpy_base(p,"zWrLeh", param, sizeof(param)); /* parameter description? */ |
75 | 0 | p = skip_string(param,sizeof(param),p); |
76 | 0 | strlcpy_base(p,"WWzWWDDzz", param, sizeof(param)); /* returned data format */ |
77 | 0 | p = skip_string(param,sizeof(param),p); |
78 | 0 | strlcpy_base(p,cli->share, param, sizeof(param)); /* name of queue */ |
79 | 0 | p = skip_string(param,sizeof(param),p); |
80 | 0 | SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ |
81 | 0 | SSVAL(p,2,1000); /* size of bytes of returned data buffer */ |
82 | 0 | p += 4; |
83 | 0 | strlcpy_base(p,"", param,sizeof(param)); /* subformat */ |
84 | 0 | p = skip_string(param,sizeof(param),p); |
85 | |
|
86 | 0 | DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); |
87 | |
|
88 | 0 | status = cli_trans( |
89 | 0 | talloc_tos(), |
90 | 0 | cli, |
91 | 0 | SMBtrans, /* trans_cmd */ |
92 | 0 | "\\PIPE\\LANMAN", /* name */ |
93 | 0 | 0, /* fid */ |
94 | 0 | 0, /* function */ |
95 | 0 | 0, /* flags */ |
96 | 0 | NULL, /* setup */ |
97 | 0 | 0, /* num_setup */ |
98 | 0 | 0, /* max_setup */ |
99 | 0 | (uint8_t *)param, /* param */ |
100 | 0 | PTR_DIFF(p,param), /* num_param */ |
101 | 0 | 1024, /* max_param */ |
102 | 0 | NULL, /* data */ |
103 | 0 | 0, /* num_data */ |
104 | 0 | CLI_BUFFER_SIZE, /* max_data */ |
105 | 0 | NULL, /* recv_flags2 */ |
106 | 0 | NULL, /* rsetup */ |
107 | 0 | 0, /* min_rsetup */ |
108 | 0 | NULL, /* num_rsetup */ |
109 | 0 | &rparam, /* rparam */ |
110 | 0 | 8, /* min_rparam */ |
111 | 0 | &rprcnt, /* num_rparam */ |
112 | 0 | &rdata, /* rdata */ |
113 | 0 | 0, /* min_rdata */ |
114 | 0 | &rdrcnt); /* num_rdata */ |
115 | 0 | if (!NT_STATUS_IS_OK(status)) { |
116 | 0 | return status; |
117 | 0 | } |
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 | 0 | fix_char_ptr(SVAL(p,4), converter, |
132 | 0 | (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 | 0 | converter, |
138 | 0 | (char *)rdata, rdrcnt)); |
139 | 0 | fn(&job); |
140 | 0 | p += 28; |
141 | 0 | } |
142 | 0 | } |
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 | 0 | } |
150 | | |
151 | | /**************************************************************************** |
152 | | cancel a print job |
153 | | ****************************************************************************/ |
154 | | |
155 | | NTSTATUS cli_printjob_del(struct cli_state *cli, int job) |
156 | 0 | { |
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 | 0 | cli, |
179 | 0 | SMBtrans, /* trans_cmd */ |
180 | 0 | "\\PIPE\\LANMAN", /* name */ |
181 | 0 | 0, /* fid */ |
182 | 0 | 0, /* function */ |
183 | 0 | 0, /* flags */ |
184 | 0 | NULL, /* setup */ |
185 | 0 | 0, /* num_setup */ |
186 | 0 | 0, /* max_setup */ |
187 | 0 | (uint8_t *)param, /* param */ |
188 | 0 | PTR_DIFF(p, param), /* num_param */ |
189 | 0 | 1024, /* max_param */ |
190 | 0 | NULL, /* data */ |
191 | 0 | 0, /* num_data */ |
192 | 0 | CLI_BUFFER_SIZE, /* max_data */ |
193 | 0 | NULL, /* recv_flags2 */ |
194 | 0 | NULL, /* rsetup */ |
195 | 0 | 0, /* min_rsetup */ |
196 | 0 | NULL, /* num_rsetup */ |
197 | 0 | &rparam, /* rparam */ |
198 | 0 | 8, /* min_rparam */ |
199 | 0 | &rprcnt, /* num_rparam */ |
200 | 0 | &rdata, /* rdata */ |
201 | 0 | 0, /* min_rdata */ |
202 | 0 | &rdrcnt); /* num_rdata */ |
203 | 0 | if (!NT_STATUS_IS_OK(status)) { |
204 | 0 | return status; |
205 | 0 | } |
206 | | |
207 | 0 | result_code = SVAL(rparam, 0); |
208 | |
|
209 | 0 | TALLOC_FREE(rparam); |
210 | 0 | TALLOC_FREE(rdata); |
211 | |
|
212 | 0 | if (result_code == ERRnosuchprintjob) { |
213 | 0 | status = NT_STATUS_INVALID_PARAMETER; |
214 | 0 | } |
215 | |
|
216 | 0 | return status; |
217 | 0 | } |