]> git.ipfire.org Git - thirdparty/squid.git/blame - lib/smblib/smblib-api.c
EDNS: type mismatch on min() ssize_t / int
[thirdparty/squid.git] / lib / smblib / smblib-api.c
CommitLineData
7c16470c
AJ
1/* UNIX SMBlib NetBIOS implementation
2
3 Version 1.0
4 SMB API Calls ...
5
6 Copyright (C) Richard Sharpe 1996
7
8*/
9
10/*
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/
25
26#include "smblib-priv.h"
27#include "../rfcnb/rfcnb.h"
28
29SMB_Tree_Handle SMBapi_Tree = NULL;
30
31/* Send an api request to the \\server\IPC$ tree, with a \PIPE\LANMAN api */
32/* request to change the user's password */
33
34#define SMB_LMAPI_SLOT "\\PIPE\\LANMAN"
35#define SMB_LMAPI_SUPW_DESC "zb16b16WW"
36
37int SMBapi_NetUserPasswordSet(SMB_Tree_Handle tree, char *user,
38 char *oldpass, char *newpass, int *apiStatus)
39
40{
41 struct RFCNB_Pkt *pkt;
42 int param_len, i, pkt_len, pad_api_name = FALSE;
43 char *p;
44
45 /* Get a packet, we need one with space for a transact plus. The calc */
46 /* below lays it all out as it is, including the empty string after the */
47 /* descriptor and before the username */
48
49 param_len = 2 + strlen(SMB_LMAPI_SUPW_DESC) + 1 +
50 1 /* for empty string :-) */ + strlen(user) +
51 1 + 16 + 16 + 2 + 2;
52
53 /* We have no setup words, wo we don't account for them */
54
55 pkt_len = SMB_trans_len + 2 /* for bcc */ + strlen(SMB_LMAPI_SLOT) + 1;
56
57 /* Pad things onto a word boundary ... */
58
59 if (pkt_len & 0x0001) {
60 pkt_len = pkt_len + 1;
61 pad_api_name = TRUE;
62 }
63
64
65 pkt_len = pkt_len + param_len;
66
67 /* Now allocate space for the packet, build it and send it */
68
69 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
70
71 if (pkt == NULL) {
72
73 SMBlib_errno = SMBlibE_NoSpace;
74 return(SMBlibE_BAD); /* Should handle the error */
75
76 }
77
78 bzero(SMB_Hdr(pkt), SMB_trans_len);
79 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
80 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtrans;
81 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
82 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
83 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
84 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
85 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 14;
86
87 SSVAL(SMB_Hdr(pkt), SMB_trans_tpc_offset, param_len);
88 SSVAL(SMB_Hdr(pkt), SMB_trans_tdc_offset, 0);
89 SSVAL(SMB_Hdr(pkt), SMB_trans_mpc_offset, 4);
90 SSVAL(SMB_Hdr(pkt), SMB_trans_mdc_offset, 0);
91 SSVAL(SMB_Hdr(pkt), SMB_trans_msc_offset, 0);
92 SSVAL(SMB_Hdr(pkt), SMB_trans_flg_offset, 0);
93 SIVAL(SMB_Hdr(pkt), SMB_trans_tmo_offset, 5000);
94 SSVAL(SMB_Hdr(pkt), SMB_trans_pbc_offset, param_len);
95 SSVAL(SMB_Hdr(pkt), SMB_trans_pbo_offset, SMB_trans_len + 2 +
96 strlen(SMB_LMAPI_SLOT) + 1);
97 SSVAL(SMB_Hdr(pkt), SMB_trans_dbc_offset, 0);
98 SSVAL(SMB_Hdr(pkt), SMB_trans_dbo_offset, 0);
99
100 /* Now put in the bcc and the rest of the info ... */
101
102 SSVAL(SMB_Hdr(pkt), SMB_trans_len, param_len + strlen(SMB_LMAPI_SLOT) + 1);
103
104 p = SMB_Hdr(pkt) + SMB_trans_len + 2; /* Skip the BCC and ect */
105
106 strcpy(p, SMB_LMAPI_SLOT);
107 p = p + strlen(SMB_LMAPI_SLOT) + 1;
108
109 if (pad_api_name == TRUE) /* Pad if we need to */
110 p = p + 1;
111
112 /* SSVAL(p, 0, 65000); /* Check the result */
113 SSVAL(p, 0, SMB_LMapi_UserPasswordSet); /* The api call */
114
115 p = p + 2;
116
117 strcpy(p, SMB_LMAPI_SUPW_DESC); /* Copy in the param desc */
118
119 p = p + strlen(SMB_LMAPI_SUPW_DESC) + 1;
120
121 *p = 0; /* Stick in that null string */
122 p = p + 1;
123
124 strcpy(p, user);
125
126 p = p + strlen(user) + 1;
127
128 strncpy(p, oldpass, 16);
129
130 p = p + 16;
131
132 strncpy(p, newpass, 16);
133
134 p = p + 16;
135
136 SSVAL(p, 0, 0); /* Seems to be zero always? */
137 SSVAL(p, 2, strlen(newpass)); /* Length of new password ...*/
138
139 /* Now send the lot and get a response ... */
140
141 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
142
143#ifdef DEBUG
144 fprintf(stderr, "Error sending Trans request\n");
145#endif
146
147 RFCNB_Free_Pkt(pkt);
148 SMBlib_errno = SMBlibE_SendFailed;
149 return(SMBlibE_BAD);
150
151 }
152
153 /* Now get the response ... */
154
155 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
156
157#ifdef DEBUG
158 fprintf(stderr, "Error receiving response to Trans request\n");
159#endif
160
161 RFCNB_Free_Pkt(pkt);
162 SMBlib_errno = SMBlibE_RecvFailed;
163 return(SMBlibE_BAD);
164
165 }
166
167 /* Check out the response type ... */
168
169 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
170
171#ifdef DEBUG
172 fprintf(stderr, "SMB_trans failed with errorclass = %i, Error Code = %i\n",
173 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
174 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
175#endif
176
177 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
178 RFCNB_Free_Pkt(pkt);
179 SMBlib_errno = SMBlibE_Remote;
180 return(SMBlibE_BAD);
181
182 }
183
184 /* All ok, pass back the status */
185
186 *apiStatus = SVAL(SMB_Hdr(pkt), SVAL(SMB_Hdr(pkt), SMB_transr_pbo_offset));
187 RFCNB_Free_Pkt(pkt);
188
189 return(0);
190
191}
192
193#define SMB_LMAPI_SUI_DESC "zWsTPWW"
194#define SMB_LMAPI_SUI_DATA_DESC "B16"
195
196
197/* Set user info ... specifically, password */
198
199int SMBapi_NetSetUserInfo(SMB_Tree_Handle tree, char *user,
200 char *newpass, int *apiStatus)
201
202{
203 struct RFCNB_Pkt *pkt;
204 int param_len, i, pkt_len, data_len, pad_api_name = FALSE;
205 int pad_params = FALSE;
206 char *p;
207
208 /* Get a packet, we need one with space for a transact plus. The calc */
209 /* below lays it all out as it is, including the empty string after the */
210 /* descriptor and before the username */
211
212 param_len = 2 + strlen(SMB_LMAPI_SUI_DESC) + 1 +
213 + strlen(SMB_LMAPI_SUI_DATA_DESC) + 1 + strlen(user) +
214 1 + 2 + 2 + 2 + 2;
215
216 data_len = 16;
217
218 /* We have no setup words, so we don't account for them */
219
220 pkt_len = SMB_trans_len + 2 /* for bcc */ + strlen(SMB_LMAPI_SLOT) + 1;
221
222 if (pkt_len & 0x0001) { /* Pad to a WORD boundary */
223
224 pad_api_name = TRUE;
225
226 }
227
228 if (param_len & 0x0001) { /* pad to a WORD boundary */
229
230 pad_params = TRUE;
231
232 }
233
234 pkt_len = pkt_len + param_len + data_len;
235
236 if (pad_api_name == TRUE) pkt_len = pkt_len + 1;
237 if (pad_params == TRUE) pkt_len = pkt_len + 1;
238
239 /* Now allocate space for the packet, build it and send it */
240
241 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
242
243 if (pkt == NULL) {
244
245 SMBlib_errno = SMBlibE_NoSpace;
246 return(SMBlibE_BAD); /* Should handle the error */
247
248 }
249
250 bzero(SMB_Hdr(pkt), SMB_trans_len);
251 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
252 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtrans;
253 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
254 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
255 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
256 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
257 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 14;
258
259 SSVAL(SMB_Hdr(pkt), SMB_trans_tpc_offset, param_len);
260 SSVAL(SMB_Hdr(pkt), SMB_trans_tdc_offset, data_len);
261 SSVAL(SMB_Hdr(pkt), SMB_trans_mpc_offset, 4);
262 SSVAL(SMB_Hdr(pkt), SMB_trans_mdc_offset, 0);
263 SSVAL(SMB_Hdr(pkt), SMB_trans_msc_offset, 0);
264 SSVAL(SMB_Hdr(pkt), SMB_trans_flg_offset, 0);
265 SIVAL(SMB_Hdr(pkt), SMB_trans_tmo_offset, 5000);
266 SSVAL(SMB_Hdr(pkt), SMB_trans_pbc_offset, param_len);
267 SSVAL(SMB_Hdr(pkt), SMB_trans_pbo_offset, SMB_trans_len + 2 +
268 strlen(SMB_LMAPI_SLOT) + 1);
269 SSVAL(SMB_Hdr(pkt), SMB_trans_dbc_offset, data_len);
270 SSVAL(SMB_Hdr(pkt), SMB_trans_dbo_offset, pkt_len - data_len);
271
272 /* Now put in the bcc and the rest of the info ... */
273
274 SSVAL(SMB_Hdr(pkt), SMB_trans_len, param_len + strlen(SMB_LMAPI_SLOT) +
275 1 + data_len);
276
277 p = SMB_Hdr(pkt) + SMB_trans_len + 2; /* Skip the BCC and ect */
278
279 strcpy(p, SMB_LMAPI_SLOT);
280 p = p + strlen(SMB_LMAPI_SLOT) + 1;
281
282 if (pad_api_name == TRUE) /* Pad to a word boundary */
283 p = p + 1;
284
285 /* SSVAL(p, 0, 65000); /* Check the result */
286 SSVAL(p, 0, SMB_LMapi_SetUserInfo); /* The api call */
287
288 p = p + 2;
289
290 strcpy(p, SMB_LMAPI_SUI_DESC); /* Copy in the param desc */
291
292 p = p + strlen(SMB_LMAPI_SUI_DESC) + 1;
293
294 strcpy(p, SMB_LMAPI_SUI_DATA_DESC); /* Copy in second descriptor */
295
296 p = p + strlen(SMB_LMAPI_SUI_DATA_DESC) + 1;
297
298 strcpy(p, user);
299
300 p = p + strlen(user) + 1;
301
302 SSVAL(p, 0, 1); /* Claim that we have a level 1 struct ? */
303
304 p = p + 2;
305
306 SSVAL(p, 0, 3); /* Set the password */
307 SSVAL(p, 2, 1); /* Seems to be one ... */
308 SSVAL(p, 4, strlen(newpass)); /* Length of new password ...*/
309
310 /* Now copy the data in ... */
311
312 p = p + 6;
313
314 if (pad_params == TRUE)
315 p = p + 1;
316
317 strcpy(p, newpass);
318
319 /* Now send the lot and get a response ... */
320
321 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
322
323#ifdef DEBUG
324 fprintf(stderr, "Error sending Trans SetUserInfo request\n");
325#endif
326
327 RFCNB_Free_Pkt(pkt);
328 SMBlib_errno = SMBlibE_SendFailed;
329 return(SMBlibE_BAD);
330
331 }
332
333 /* Now get the response ... */
334
335 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
336
337#ifdef DEBUG
338 fprintf(stderr, "Error receiving response to Trans SetUserInfo request\n");
339#endif
340
341 RFCNB_Free_Pkt(pkt);
342 SMBlib_errno = SMBlibE_RecvFailed;
343 return(SMBlibE_BAD);
344
345 }
346
347 /* Check out the response type ... */
348
349 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
350
351#ifdef DEBUG
352 fprintf(stderr, "SMB_trans SetUserInfo failed with errorclass = %i, Error Code = %i\n",
353 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
354 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
355#endif
356
357 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
358 RFCNB_Free_Pkt(pkt);
359 SMBlib_errno = SMBlibE_Remote;
360 return(SMBlibE_BAD);
361
362 }
363
364 /* All ok, pass back the status */
365
366 *apiStatus = SVAL(SMB_Hdr(pkt), SVAL(SMB_Hdr(pkt), SMB_transr_pbo_offset));
367 RFCNB_Free_Pkt(pkt);
368
369 return(0);
370
371}
372
373/* List all the shares available on a server */
374
375int SMBapi_NetShareEnum(SMB_Tree_Handle tree, char *enum_buf, int bufsiz,
376 int *shares_returned, int *shares_total)
377
378{
379
380
381}