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