]> git.ipfire.org Git - thirdparty/squid.git/blob - lib/smblib/smblib-api.c
SourceFormat Enforcement
[thirdparty/squid.git] / lib / smblib / smblib-api.c
1 #include "squid.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 pkt_len = pkt_len + param_len;
70
71 /* Now allocate space for the packet, build it and send it */
72
73 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
74
75 if (pkt == NULL) {
76
77 SMBlib_errno = SMBlibE_NoSpace;
78 return(SMBlibE_BAD); /* Should handle the error */
79
80 }
81
82 memset(SMB_Hdr(pkt), 0, SMB_trans_len);
83 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
84 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtrans;
85 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
86 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
87 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
88 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
89 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 14;
90
91 SSVAL(SMB_Hdr(pkt), SMB_trans_tpc_offset, param_len);
92 SSVAL(SMB_Hdr(pkt), SMB_trans_tdc_offset, 0);
93 SSVAL(SMB_Hdr(pkt), SMB_trans_mpc_offset, 4);
94 SSVAL(SMB_Hdr(pkt), SMB_trans_mdc_offset, 0);
95 SSVAL(SMB_Hdr(pkt), SMB_trans_msc_offset, 0);
96 SSVAL(SMB_Hdr(pkt), SMB_trans_flg_offset, 0);
97 SIVAL(SMB_Hdr(pkt), SMB_trans_tmo_offset, 5000);
98 SSVAL(SMB_Hdr(pkt), SMB_trans_pbc_offset, param_len);
99 SSVAL(SMB_Hdr(pkt), SMB_trans_pbo_offset, SMB_trans_len + 2 +
100 strlen(SMB_LMAPI_SLOT) + 1);
101 SSVAL(SMB_Hdr(pkt), SMB_trans_dbc_offset, 0);
102 SSVAL(SMB_Hdr(pkt), SMB_trans_dbo_offset, 0);
103
104 /* Now put in the bcc and the rest of the info ... */
105
106 SSVAL(SMB_Hdr(pkt), SMB_trans_len, param_len + strlen(SMB_LMAPI_SLOT) + 1);
107
108 p = SMB_Hdr(pkt) + SMB_trans_len + 2; /* Skip the BCC and ect */
109
110 strcpy(p, SMB_LMAPI_SLOT);
111 p = p + strlen(SMB_LMAPI_SLOT) + 1;
112
113 if (pad_api_name == TRUE) /* Pad if we need to */
114 p = p + 1;
115
116 /* SSVAL(p, 0, 65000); /* Check the result */
117 SSVAL(p, 0, SMB_LMapi_UserPasswordSet); /* The api call */
118
119 p = p + 2;
120
121 strcpy(p, SMB_LMAPI_SUPW_DESC); /* Copy in the param desc */
122
123 p = p + strlen(SMB_LMAPI_SUPW_DESC) + 1;
124
125 *p = 0; /* Stick in that null string */
126 p = p + 1;
127
128 strcpy(p, user);
129
130 p = p + strlen(user) + 1;
131
132 strncpy(p, oldpass, 16);
133
134 p = p + 16;
135
136 strncpy(p, newpass, 16);
137
138 p = p + 16;
139
140 SSVAL(p, 0, 0); /* Seems to be zero always? */
141 SSVAL(p, 2, strlen(newpass)); /* Length of new password ...*/
142
143 /* Now send the lot and get a response ... */
144
145 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
146
147 #ifdef DEBUG
148 fprintf(stderr, "Error sending Trans request\n");
149 #endif
150
151 RFCNB_Free_Pkt(pkt);
152 SMBlib_errno = SMBlibE_SendFailed;
153 return(SMBlibE_BAD);
154
155 }
156
157 /* Now get the response ... */
158
159 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
160
161 #ifdef DEBUG
162 fprintf(stderr, "Error receiving response to Trans request\n");
163 #endif
164
165 RFCNB_Free_Pkt(pkt);
166 SMBlib_errno = SMBlibE_RecvFailed;
167 return(SMBlibE_BAD);
168
169 }
170
171 /* Check out the response type ... */
172
173 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
174
175 #ifdef DEBUG
176 fprintf(stderr, "SMB_trans failed with errorclass = %i, Error Code = %i\n",
177 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
178 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
179 #endif
180
181 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
182 RFCNB_Free_Pkt(pkt);
183 SMBlib_errno = SMBlibE_Remote;
184 return(SMBlibE_BAD);
185
186 }
187
188 /* All ok, pass back the status */
189
190 *apiStatus = SVAL(SMB_Hdr(pkt), SVAL(SMB_Hdr(pkt), SMB_transr_pbo_offset));
191 RFCNB_Free_Pkt(pkt);
192
193 return(0);
194
195 }
196
197 #define SMB_LMAPI_SUI_DESC "zWsTPWW"
198 #define SMB_LMAPI_SUI_DATA_DESC "B16"
199
200 /* Set user info ... specifically, password */
201
202 int SMBapi_NetSetUserInfo(SMB_Tree_Handle tree, char *user,
203 char *newpass, int *apiStatus)
204
205 {
206 struct RFCNB_Pkt *pkt;
207 int param_len, i, pkt_len, data_len, pad_api_name = FALSE;
208 int pad_params = FALSE;
209 char *p;
210
211 /* Get a packet, we need one with space for a transact plus. The calc */
212 /* below lays it all out as it is, including the empty string after the */
213 /* descriptor and before the username */
214
215 param_len = 2 + strlen(SMB_LMAPI_SUI_DESC) + 1 +
216 + strlen(SMB_LMAPI_SUI_DATA_DESC) + 1 + strlen(user) +
217 1 + 2 + 2 + 2 + 2;
218
219 data_len = 16;
220
221 /* We have no setup words, so we don't account for them */
222
223 pkt_len = SMB_trans_len + 2 /* for bcc */ + strlen(SMB_LMAPI_SLOT) + 1;
224
225 if (pkt_len & 0x0001) { /* Pad to a WORD boundary */
226
227 pad_api_name = TRUE;
228
229 }
230
231 if (param_len & 0x0001) { /* pad to a WORD boundary */
232
233 pad_params = TRUE;
234
235 }
236
237 pkt_len = pkt_len + param_len + data_len;
238
239 if (pad_api_name == TRUE) pkt_len = pkt_len + 1;
240 if (pad_params == TRUE) pkt_len = pkt_len + 1;
241
242 /* Now allocate space for the packet, build it and send it */
243
244 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
245
246 if (pkt == NULL) {
247
248 SMBlib_errno = SMBlibE_NoSpace;
249 return(SMBlibE_BAD); /* Should handle the error */
250
251 }
252
253 memset(SMB_Hdr(pkt), 0, SMB_trans_len);
254 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
255 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtrans;
256 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
257 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
258 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
259 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
260 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 14;
261
262 SSVAL(SMB_Hdr(pkt), SMB_trans_tpc_offset, param_len);
263 SSVAL(SMB_Hdr(pkt), SMB_trans_tdc_offset, data_len);
264 SSVAL(SMB_Hdr(pkt), SMB_trans_mpc_offset, 4);
265 SSVAL(SMB_Hdr(pkt), SMB_trans_mdc_offset, 0);
266 SSVAL(SMB_Hdr(pkt), SMB_trans_msc_offset, 0);
267 SSVAL(SMB_Hdr(pkt), SMB_trans_flg_offset, 0);
268 SIVAL(SMB_Hdr(pkt), SMB_trans_tmo_offset, 5000);
269 SSVAL(SMB_Hdr(pkt), SMB_trans_pbc_offset, param_len);
270 SSVAL(SMB_Hdr(pkt), SMB_trans_pbo_offset, SMB_trans_len + 2 +
271 strlen(SMB_LMAPI_SLOT) + 1);
272 SSVAL(SMB_Hdr(pkt), SMB_trans_dbc_offset, data_len);
273 SSVAL(SMB_Hdr(pkt), SMB_trans_dbo_offset, pkt_len - data_len);
274
275 /* Now put in the bcc and the rest of the info ... */
276
277 SSVAL(SMB_Hdr(pkt), SMB_trans_len, param_len + strlen(SMB_LMAPI_SLOT) +
278 1 + data_len);
279
280 p = SMB_Hdr(pkt) + SMB_trans_len + 2; /* Skip the BCC and ect */
281
282 strcpy(p, SMB_LMAPI_SLOT);
283 p = p + strlen(SMB_LMAPI_SLOT) + 1;
284
285 if (pad_api_name == TRUE) /* Pad to a word boundary */
286 p = p + 1;
287
288 /* SSVAL(p, 0, 65000); /* Check the result */
289 SSVAL(p, 0, SMB_LMapi_SetUserInfo); /* The api call */
290
291 p = p + 2;
292
293 strcpy(p, SMB_LMAPI_SUI_DESC); /* Copy in the param desc */
294
295 p = p + strlen(SMB_LMAPI_SUI_DESC) + 1;
296
297 strcpy(p, SMB_LMAPI_SUI_DATA_DESC); /* Copy in second descriptor */
298
299 p = p + strlen(SMB_LMAPI_SUI_DATA_DESC) + 1;
300
301 strcpy(p, user);
302
303 p = p + strlen(user) + 1;
304
305 SSVAL(p, 0, 1); /* Claim that we have a level 1 struct ? */
306
307 p = p + 2;
308
309 SSVAL(p, 0, 3); /* Set the password */
310 SSVAL(p, 2, 1); /* Seems to be one ... */
311 SSVAL(p, 4, strlen(newpass)); /* Length of new password ...*/
312
313 /* Now copy the data in ... */
314
315 p = p + 6;
316
317 if (pad_params == TRUE)
318 p = p + 1;
319
320 strcpy(p, newpass);
321
322 /* Now send the lot and get a response ... */
323
324 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
325
326 #ifdef DEBUG
327 fprintf(stderr, "Error sending Trans SetUserInfo request\n");
328 #endif
329
330 RFCNB_Free_Pkt(pkt);
331 SMBlib_errno = SMBlibE_SendFailed;
332 return(SMBlibE_BAD);
333
334 }
335
336 /* Now get the response ... */
337
338 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
339
340 #ifdef DEBUG
341 fprintf(stderr, "Error receiving response to Trans SetUserInfo request\n");
342 #endif
343
344 RFCNB_Free_Pkt(pkt);
345 SMBlib_errno = SMBlibE_RecvFailed;
346 return(SMBlibE_BAD);
347
348 }
349
350 /* Check out the response type ... */
351
352 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
353
354 #ifdef DEBUG
355 fprintf(stderr, "SMB_trans SetUserInfo failed with errorclass = %i, Error Code = %i\n",
356 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
357 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
358 #endif
359
360 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
361 RFCNB_Free_Pkt(pkt);
362 SMBlib_errno = SMBlibE_Remote;
363 return(SMBlibE_BAD);
364
365 }
366
367 /* All ok, pass back the status */
368
369 *apiStatus = SVAL(SMB_Hdr(pkt), SVAL(SMB_Hdr(pkt), SMB_transr_pbo_offset));
370 RFCNB_Free_Pkt(pkt);
371
372 return(0);
373
374 }
375
376 /* List all the shares available on a server */
377
378 int SMBapi_NetShareEnum(SMB_Tree_Handle tree, char *enum_buf, int bufsiz,
379 int *shares_returned, int *shares_total)
380
381 {
382
383 }