]> git.ipfire.org Git - thirdparty/squid.git/blob - lib/smblib/exper.c
merge from trunk
[thirdparty/squid.git] / lib / smblib / exper.c
1 #include "squid.h"
2 /* UNIX SMBlib NetBIOS implementation
3
4 Version 1.0
5 SMBlib Routines. Experimental Section ...
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 "rfcnb/rfcnb.h"
28 #include "smblib/smblib-priv.h"
29
30 #include <signal.h>
31 #if HAVE_STRING_H
32 #include <string.h>
33 #endif
34
35 /* Logon and tree connect to the server. If a tree handle was given to us, */
36 /* we use it and return it, otherwise we create one ... */
37
38 SMB_Tree_Handle SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle,
39 SMB_Tree_Handle Tree_Handle,
40 char *UserName,
41 char *PassWord,
42 char *service,
43 char *service_type)
44
45 {
46 struct RFCNB_Pkt *pkt;
47 int param_len, i, pkt_len, andx_len, andx_param_len;
48 char *p, *AndXCom;
49 SMB_Tree_Handle tree;
50
51 /* Lets create a tree if we need one ... */
52
53 if (Tree_Handle == NULL) {
54
55 tree = (SMB_Tree_Handle)malloc(sizeof(struct SMB_Tree_Structure));
56
57 if (tree == NULL) {
58
59 SMBlib_errno = SMBlibE_NoSpace;
60 return(tree);
61
62 } else { /* Initialize the tree */
63
64 tree -> con = Con_Handle;
65 tree -> prev = tree -> next = NULL;
66
67 }
68 } else
69 tree = Tree_Handle;
70
71 /* First we need a packet etc ... but we need to know what protocol has */
72 /* been negotiated to figure out if we can do it and what SMB format to */
73 /* use ... */
74
75 /* Since we are going to do a LogonAndX with a TCon as the second command*/
76 /* We need the packet size correct. So TCon starts at wct field */
77
78 if (Con_Handle -> protocol < SMB_P_LanMan1) {
79
80 SMBlib_errno = SMBlibE_ProtLow;
81 if (Tree_Handle == NULL)
82 free(tree);
83 return(NULL);
84
85 }
86
87 /* Now build the correct structure */
88
89 andx_len = SMB_tconx_len - SMB_hdr_wct_offset;
90
91 /* We send a null password as we sent one in the setup and X */
92
93 andx_param_len = strlen(service) + 1 + strlen(service_type) + 1;
94
95 if (Con_Handle -> protocol < SMB_P_NT1) {
96
97 #ifdef SMBLIB_DEBUG
98 fprintf(stderr, "Doing an LM session setup etc ...\n");
99 #endif
100
101 /* We don't do encrypted passwords ... */
102
103 param_len = strlen(UserName) + 1 + strlen(PassWord) + 1 +
104 strlen(Con_Handle -> PDomain) + 1 +
105 strlen(Con_Handle -> OSName) + 1;
106
107 pkt_len = SMB_ssetpLM_len + param_len + andx_len + andx_param_len;
108
109 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
110
111 if (pkt == NULL) {
112
113 SMBlib_errno = SMBlibE_NoSpace;
114 if (Tree_Handle == NULL)
115 free(tree);
116 return(NULL); /* Should handle the error */
117
118 }
119
120 memset(SMB_Hdr(pkt), 0, SMB_ssetpLM_len);
121 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
122 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
123 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
124 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
125 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
126 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, 0);
127 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10;
128 *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtconX;
129 SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpLM_len + param_len);
130
131 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT);
132 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2);
133 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid);
134 SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0);
135 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, strlen(PassWord) + 1);
136 SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0);
137 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len);
138
139 /* Now copy the param strings in with the right stuff */
140
141 p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset);
142
143 /* Copy in password, then the rest. Password has no null at end */
144
145 strcpy(p, PassWord);
146
147 p = p + strlen(PassWord) + 1;
148
149 strcpy(p, UserName);
150 p = p + strlen(UserName);
151 *p = 0;
152
153 p = p + 1;
154
155 strcpy(p, Con_Handle -> PDomain);
156 p = p + strlen(Con_Handle -> PDomain);
157 *p = 0;
158 p = p + 1;
159
160 strcpy(p, Con_Handle -> OSName);
161 p = p + strlen(Con_Handle -> OSName);
162 *p = 0;
163
164 AndXCom = SMB_Hdr(pkt) + SMB_ssetpLM_len + param_len - SMB_hdr_wct_offset;
165
166 } else {
167
168 /* We don't admit to UNICODE support ... */
169
170 #ifdef SMBLIB_DEBUG
171 fprintf(stderr, "Doing NT LM Sess Setup etc ... \n");
172 #endif
173
174 param_len = strlen(UserName) + 1 + strlen(PassWord) +
175 strlen(Con_Handle -> PDomain) + 1 +
176 strlen(Con_Handle -> OSName) + 1 +
177 strlen(Con_Handle -> LMType) + 1;
178
179 pkt_len = SMB_ssetpNTLM_len + param_len + andx_len + andx_param_len;
180
181 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
182
183 if (pkt == NULL) {
184
185 SMBlib_errno = SMBlibE_NoSpace;
186 if (Tree_Handle == NULL)
187 free(tree);
188 return(NULL); /* Should handle the error */
189
190 }
191
192 memset(SMB_Hdr(pkt), 0, SMB_ssetpNTLM_len);
193 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
194 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
195 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
196 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
197 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
198 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, 0);
199 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13;
200 *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtconX;
201 SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpNTLM_len + param_len);
202
203 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT);
204 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 2);
205 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0);
206 SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0);
207 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, strlen(PassWord));
208 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0);
209 SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0);
210 SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0);
211 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len);
212
213 /* Now copy the param strings in with the right stuff */
214
215 p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset);
216
217 /* Copy in password, then the rest. Password has no null at end */
218
219 strcpy(p, PassWord);
220
221 p = p + strlen(PassWord);
222
223 strcpy(p, UserName);
224 p = p + strlen(UserName);
225 *p = 0;
226
227 p = p + 1;
228
229 strcpy(p, Con_Handle -> PDomain);
230 p = p + strlen(Con_Handle -> PDomain);
231 *p = 0;
232 p = p + 1;
233
234 strcpy(p, Con_Handle -> OSName);
235 p = p + strlen(Con_Handle -> OSName);
236 *p = 0;
237 p = p + 1;
238
239 strcpy(p, Con_Handle -> LMType);
240 p = p + strlen(Con_Handle -> LMType);
241 *p = 0;
242
243 /* Now set up the TCON Part ... from WCT, make up a pointer that will
244 help us ... */
245
246 AndXCom = SMB_Hdr(pkt) + SMB_ssetpNTLM_len + param_len - SMB_hdr_wct_offset;
247
248 }
249 *(AndXCom + SMB_hdr_wct_offset) = 4;
250 *(AndXCom + SMB_tconx_axc_offset) = 0xFF; /* No command */
251 SSVAL(AndXCom, SMB_tconx_axo_offset, 0);
252 SSVAL(AndXCom, SMB_tconx_flg_offset, 0); /* Don't disconnect TID */
253 SSVAL(AndXCom, SMB_tconx_pwl_offset, 0); /* No password, */
254 SSVAL(AndXCom, SMB_tconx_bcc_offset, andx_param_len);
255
256 p = (char *)(AndXCom + SMB_tconx_buf_offset);
257
258 /**p = 0;
259 p = p + 1; */
260 strcpy(p, service);
261 p = p + strlen(service) + 1;
262 strcpy(p, service_type);
263
264 /* Now send it and get a response */
265
266 if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
267
268 #ifdef DEBUG
269 fprintf(stderr, "Error sending SessSetupAndTCon request\n");
270 #endif
271
272 RFCNB_Free_Pkt(pkt);
273 free(tree);
274 SMBlib_errno = SMBlibE_SendFailed;
275 return(NULL);
276
277 }
278
279 /* Now get the response ... */
280
281 if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
282
283 #ifdef DEBUG
284 fprintf(stderr, "Error receiving response to SessSetupAndTCon\n");
285 #endif
286
287 RFCNB_Free_Pkt(pkt);
288 free(tree);
289 SMBlib_errno = SMBlibE_RecvFailed;
290 return(NULL);
291
292 }
293
294 /* Check out the response type ... */
295
296 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
297
298 #ifdef DEBUG
299 fprintf(stderr, "SMB_SessSetupAndTCon failed with errorclass = %i, Error Code = %i\n",
300 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
301 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
302 #endif
303
304 /* Note, here, that we have not properly handled the error processing */
305 /* and so we cannot tell how much of our request crapped out */
306
307 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
308 free(tree);
309 RFCNB_Free_Pkt(pkt);
310 SMBlib_errno = SMBlibE_Remote;
311 return(NULL);
312
313 }
314
315 #ifdef DEBUG
316 fprintf(stderr, "SessSetupAndX response. Action = %i\n",
317 SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset));
318 #endif
319
320 /* Now pick up the UID for future reference ... */
321
322 Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset);
323
324 /* And pick up the TID as well */
325
326 tree -> tid = SVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset);
327
328 tree -> mbs = Con_Handle -> max_xmit;
329
330 /* Link the tree into the list in con */
331
332 if (Con_Handle -> first_tree == NULL) {
333
334 Con_Handle -> first_tree == tree;
335 Con_Handle -> last_tree == tree;
336
337 } else {
338
339 Con_Handle -> last_tree -> next = tree;
340 tree -> prev = Con_Handle -> last_tree;
341 Con_Handle -> last_tree = tree;
342
343 }
344
345 RFCNB_Free_Pkt(pkt);
346
347 return(tree);
348
349 }
350
351 /* Logon and TCon and Open to a file on the server, but we need to pass */
352 /* back a file pointer, so we better have one in the parameter list */
353
354 int SMB_Logon_TCon_Open(SMB_Handle_Type Con_Handle, char *UserName,
355 char *PassWord,
356 char *service,
357 char *service_type,
358 SMB_Tree_Handle *Tree_Handle,
359 char *filename,
360 WORD mode,
361 WORD search,
362 SMB_File **File_Handle)
363
364 {
365 struct RFCNB_Pkt *pkt;
366 int param_len, i, pkt_len, tcon_len, tcon_param_len, open_len,
367 open_param_len, header_len;
368 struct SMB_File_Def *file_tmp;
369 SMB_Tree_Handle tree;
370 char *p, *AndXCom;
371
372 /* First, we need a tree STRUCTURE as we are going to tree connect */
373
374 tree = (SMB_Tree_Handle)malloc(sizeof(struct SMB_Tree_Structure));
375
376 if (tree == NULL) {
377
378 SMBlib_errno = SMBlibE_NoSpace;
379 return(SMBlibE_BAD);
380
381 } else {
382
383 tree -> con = Con_Handle;
384 tree -> next = tree -> prev = NULL;
385
386 }
387
388 /* Next, we need a file handle as we are going to pass one back ... */
389 /* Hmm, there is a bug here ... We should check on File_Handle ... */
390
391 if ((file_tmp = (SMB_File *)malloc(sizeof(SMB_File))) == NULL) {
392
393 #ifdef DEBUG
394 fprintf(stderr, "Could not allocate file handle space ...");
395 #endif
396
397 SMBlib_errno = SMBlibE_NoSpace;
398 free(tree);
399 return(SMBlibE_BAD);
400
401 }
402
403 /* Next we need a packet etc ... but we need to know what protocol has */
404 /* been negotiated to figure out if we can do it and what SMB format to */
405 /* use ... */
406
407 /* Since we are going to do a LogonAndX with a TCon as the second command*/
408 /* We need the packet size correct. So TCon starts at wct field */
409
410 if (Con_Handle -> protocol < SMB_P_LanMan1) {
411
412 free(tree);
413 free(file_tmp);
414 SMBlib_errno = SMBlibE_ProtLow;
415 return(SMBlibE_BAD);
416
417 }
418
419 /* Now build the correct structure */
420
421 /* We send a null password in the TconAndX ... */
422
423 tcon_len = SMB_tconx_len - SMB_hdr_wct_offset;
424 tcon_param_len = strlen(service) + 1 + strlen(service_type) + 1;
425
426 open_len = SMB_openx_len - SMB_hdr_wct_offset;
427 open_param_len = 1 + strlen(filename) + 1; /* AsciiID + null */
428
429 if (Con_Handle -> protocol < SMB_P_NT1) {
430
431 /* We don't do encrypted passwords yet */
432
433 param_len = strlen(UserName) + 1 + strlen(PassWord) + 1 +
434 strlen(Con_Handle -> PDomain) + 1 +
435 strlen(Con_Handle -> OSName) + 1;
436
437 header_len = SMB_ssetpLM_len + param_len;
438
439 pkt_len = header_len + tcon_len + tcon_param_len +
440 open_len + open_param_len;
441
442 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
443
444 if (pkt == NULL) {
445
446 SMBlib_errno = SMBlibE_NoSpace;
447 free(tree);
448 free(file_tmp);
449 return(SMBlibE_BAD); /* Should handle the error */
450
451 }
452
453 memset(SMB_Hdr(pkt), 0, SMB_ssetpLM_len);
454 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
455 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
456 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
457 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
458 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
459 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, 0);
460 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10;
461 *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtconX;
462 SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpLM_len + param_len);
463
464 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT);
465 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2);
466 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid);
467 SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0);
468 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, strlen(PassWord) + 1);
469 SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0);
470 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len);
471
472 /* Now copy the param strings in with the right stuff */
473
474 p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset);
475
476 /* Copy in password, then the rest. Password has no null at end */
477
478 strcpy(p, PassWord);
479
480 p = p + strlen(PassWord) + 1;
481
482 strcpy(p, UserName);
483 p = p + strlen(UserName);
484 *p = 0;
485
486 p = p + 1;
487
488 strcpy(p, Con_Handle -> PDomain);
489 p = p + strlen(Con_Handle -> PDomain);
490 *p = 0;
491 p = p + 1;
492
493 strcpy(p, Con_Handle -> OSName);
494 p = p + strlen(Con_Handle -> OSName);
495 *p = 0;
496
497 AndXCom = SMB_Hdr(pkt) + SMB_ssetpLM_len + param_len - SMB_hdr_wct_offset;
498
499 } else {
500
501 /* We don't admit to UNICODE support ... */
502
503 param_len = strlen(UserName) + 1 + strlen(PassWord) +
504 strlen(Con_Handle -> PDomain) + 1 +
505 strlen(Con_Handle -> OSName) + 1 +
506 strlen(Con_Handle -> LMType) + 1;
507
508 header_len = SMB_ssetpNTLM_len + param_len;
509
510 pkt_len = header_len + tcon_len + tcon_param_len +
511 open_len + open_param_len;
512
513 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
514
515 if (pkt == NULL) {
516
517 SMBlib_errno = SMBlibE_NoSpace;
518 free(tree);
519 free(file_tmp); /* Should only do if we created one ... */
520 return(-1); /* Should handle the error */
521
522 }
523
524 memset(SMB_Hdr(pkt), 0, SMB_ssetpNTLM_len);
525 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
526 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
527 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
528 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
529 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
530 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, 0);
531 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13;
532 *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtconX;
533 SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpNTLM_len + param_len);
534
535 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT);
536 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 2);
537 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0);
538 SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0);
539 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, strlen(PassWord));
540 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0);
541 SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0);
542 SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0);
543 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len);
544
545 /* Now copy the param strings in with the right stuff */
546
547 p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset);
548
549 /* Copy in password, then the rest. Password has no null at end */
550
551 strcpy(p, PassWord);
552
553 p = p + strlen(PassWord);
554
555 strcpy(p, UserName);
556 p = p + strlen(UserName);
557 *p = 0;
558
559 p = p + 1;
560
561 strcpy(p, Con_Handle -> PDomain);
562 p = p + strlen(Con_Handle -> PDomain);
563 *p = 0;
564 p = p + 1;
565
566 strcpy(p, Con_Handle -> OSName);
567 p = p + strlen(Con_Handle -> OSName);
568 *p = 0;
569 p = p + 1;
570
571 strcpy(p, Con_Handle -> LMType);
572 p = p + strlen(Con_Handle -> LMType);
573 *p = 0;
574
575 /* Now set up the TCON Part ... from WCT, make up a pointer that will
576 help us ... */
577
578 AndXCom = SMB_Hdr(pkt) + SMB_ssetpNTLM_len + param_len - SMB_hdr_wct_offset;
579
580 }
581
582 *(AndXCom + SMB_hdr_wct_offset) = 4;
583 *(AndXCom + SMB_tconx_axc_offset) = SMBopenX;
584 SSVAL(AndXCom, SMB_tconx_axo_offset, (header_len +
585 tcon_len + tcon_param_len));
586 SSVAL(AndXCom, SMB_tconx_flg_offset, 0); /* Don't disconnect TID */
587 SSVAL(AndXCom, SMB_tconx_pwl_offset, 0); /* No password */
588 SSVAL(AndXCom, SMB_tconx_bcc_offset, tcon_param_len);
589
590 p = (char *)(AndXCom + SMB_tconx_buf_offset);
591
592 /* *p = 0;
593 p = p + 1; */
594 strcpy(p, service);
595 p = p + strlen(service) + 1;
596 strcpy(p, service_type);
597
598 /* Now the open bit ... */
599
600 AndXCom = AndXCom + tcon_len + tcon_param_len; /* Should get us there */
601
602 *(AndXCom + SMB_hdr_wct_offset) = 15;
603 *(AndXCom + SMB_openx_axc_offset) = 0xFF;
604 *(AndXCom + SMB_openx_axr_offset) = 0;
605 SSVAL(AndXCom, SMB_openx_axo_offset, 0);
606 SSVAL(AndXCom, SMB_openx_flg_offset, 0);
607 SSVAL(AndXCom, SMB_openx_mod_offset, mode);
608 SSVAL(AndXCom, SMB_openx_atr_offset, search);
609 SSVAL(AndXCom, SMB_openx_fat_offset, 0);
610 SIVAL(AndXCom, SMB_openx_tim_offset, 0);
611 SSVAL(AndXCom, SMB_openx_ofn_offset, 0x0011); /* Create or open */
612 SIVAL(AndXCom, SMB_openx_als_offset, 0);
613 SSVAL(AndXCom, SMB_openx_bcc_offset, open_param_len);
614
615 p = (char *)(AndXCom + SMB_openx_buf_offset);
616
617 /* *p = SMBasciiID; */
618 strcpy(p, filename);
619
620 /* Now send it and get a response */
621
622 if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
623
624 #ifdef DEBUG
625 fprintf(stderr, "Error sending SessSetupAndTCon request\n");
626 #endif
627
628 RFCNB_Free_Pkt(pkt);
629 free(tree);
630 free(file_tmp);
631 SMBlib_errno = SMBlibE_SendFailed;
632 return(SMBlibE_BAD);
633
634 }
635
636 /* Now get the response ... */
637
638 if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
639
640 #ifdef DEBUG
641 fprintf(stderr, "Error receiving response to SessSetupAndTCon\n");
642 #endif
643
644 RFCNB_Free_Pkt(pkt);
645 free(tree);
646 free(file_tmp);
647 SMBlib_errno = SMBlibE_RecvFailed;
648 return(SMBlibE_BAD);
649
650 }
651
652 /* Check out the response type ... */
653
654 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
655
656 #ifdef DEBUG
657 fprintf(stderr, "SMB_SessSetupAndTCon failed with errorclass = %i, Error Code = %i\n",
658 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
659 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
660 #endif
661
662 /* Note, here, that we have not properly handled the error processing */
663 /* and so we cannot tell how much of our request crapped out */
664
665 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
666 RFCNB_Free_Pkt(pkt);
667 free(tree);
668 free(file_tmp);
669 SMBlib_errno = SMBlibE_Remote;
670 return(SMBlibE_BAD);
671
672 }
673
674 #ifdef DEBUG
675 fprintf(stderr, "SessSetupAndX response. Action = %i\n",
676 SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset));
677 #endif
678
679 /* Now pick up the UID for future reference ... */
680
681 Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset);
682
683 /* And pick up the TID as well */
684
685 tree -> tid = SVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset);
686 tree -> mbs = Con_Handle -> max_xmit; /* We need this */
687
688 #ifdef DEBUG
689 fprintf(stderr, "mbs=%i\n", tree -> mbs);
690 #endif
691
692 /* Now we populate the file hanble and pass it back ... */
693
694 strncpy(file_tmp -> filename, filename, sizeof(file_tmp -> filename) - 1);
695 file_tmp -> tree = tree;
696
697 /* Pick up a pointer to the right part ... */
698
699 AndXCom = SMB_Hdr(pkt) + SVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset) -
700 SMB_hdr_wct_offset;
701
702 /* Now skip the response to the TConX */
703
704 AndXCom = SMB_Hdr(pkt) + SVAL(AndXCom, SMB_tconxr_axo_offset) -
705 SMB_hdr_wct_offset;
706
707 #ifdef DEBUG
708 fprintf(stderr, "Word Params = %x, AXO = %x\n",
709 CVAL(AndXCom, SMB_hdr_wct_offset),
710 SVAL(AndXCom, SMB_openxr_axo_offset));
711 #endif
712
713 /* Now pick up the things from the openX response that we need */
714
715 file_tmp -> fid = SVAL(AndXCom, SMB_openxr_fid_offset);
716 file_tmp -> lastmod = IVAL(AndXCom, SMB_openxr_tim_offset);
717 file_tmp -> size = IVAL(AndXCom, SMB_openxr_fsz_offset);
718 file_tmp -> access = SVAL(AndXCom, SMB_openxr_acc_offset);
719 file_tmp -> fileloc = 0;
720
721 *File_Handle = file_tmp;
722
723 /* Now link the tree into the right place ... */
724
725 if (Con_Handle -> first_tree == NULL) {
726
727 Con_Handle -> first_tree == tree;
728 Con_Handle -> last_tree == tree;
729
730 } else {
731
732 Con_Handle -> last_tree -> next = tree;
733 tree -> prev = Con_Handle -> last_tree;
734 Con_Handle -> last_tree = tree;
735
736 }
737
738 RFCNB_Free_Pkt(pkt);
739
740 *Tree_Handle = tree;
741
742 return(0);
743
744 }
745