2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* UNIX SMBlib NetBIOS implementation
12 SMBlib Routines. Experimental Section ...
14 Copyright (C) Richard Sharpe 1996
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or
21 (at your option) any later version.
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 #include "rfcnb/rfcnb.h"
35 #include "smblib/smblib-priv.h"
42 /* Logon and tree connect to the server. If a tree handle was given to us, */
43 /* we use it and return it, otherwise we create one ... */
45 SMB_Tree_Handle
SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle
,
46 SMB_Tree_Handle Tree_Handle
,
53 struct RFCNB_Pkt
*pkt
;
54 int param_len
, i
, pkt_len
, andx_len
, andx_param_len
;
58 /* Lets create a tree if we need one ... */
60 if (Tree_Handle
== NULL
) {
62 tree
= (SMB_Tree_Handle
)malloc(sizeof(struct SMB_Tree_Structure
));
66 SMBlib_errno
= SMBlibE_NoSpace
;
69 } else { /* Initialize the tree */
71 tree
-> con
= Con_Handle
;
72 tree
-> prev
= tree
-> next
= NULL
;
78 /* First we need a packet etc ... but we need to know what protocol has */
79 /* been negotiated to figure out if we can do it and what SMB format to */
82 /* Since we are going to do a LogonAndX with a TCon as the second command*/
83 /* We need the packet size correct. So TCon starts at wct field */
85 if (Con_Handle
-> protocol
< SMB_P_LanMan1
) {
87 SMBlib_errno
= SMBlibE_ProtLow
;
88 if (Tree_Handle
== NULL
)
94 /* Now build the correct structure */
96 andx_len
= SMB_tconx_len
- SMB_hdr_wct_offset
;
98 /* We send a null password as we sent one in the setup and X */
100 andx_param_len
= strlen(service
) + 1 + strlen(service_type
) + 1;
102 if (Con_Handle
-> protocol
< SMB_P_NT1
) {
105 fprintf(stderr
, "Doing an LM session setup etc ...\n");
108 /* We don't do encrypted passwords ... */
110 param_len
= strlen(UserName
) + 1 + strlen(PassWord
) + 1 +
111 strlen(Con_Handle
-> PDomain
) + 1 +
112 strlen(Con_Handle
-> OSName
) + 1;
114 pkt_len
= SMB_ssetpLM_len
+ param_len
+ andx_len
+ andx_param_len
;
116 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
120 SMBlib_errno
= SMBlibE_NoSpace
;
121 if (Tree_Handle
== NULL
)
123 return(NULL
); /* Should handle the error */
127 memset(SMB_Hdr(pkt
), 0, SMB_ssetpLM_len
);
128 SIVAL(SMB_Hdr(pkt
), SMB_hdr_idf_offset
, SMB_DEF_IDF
); /* Plunk in IDF */
129 *(SMB_Hdr(pkt
) + SMB_hdr_com_offset
) = SMBsesssetupX
;
130 SSVAL(SMB_Hdr(pkt
), SMB_hdr_pid_offset
, Con_Handle
-> pid
);
131 SSVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
, 0);
132 SSVAL(SMB_Hdr(pkt
), SMB_hdr_mid_offset
, Con_Handle
-> mid
);
133 SSVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
, 0);
134 *(SMB_Hdr(pkt
) + SMB_hdr_wct_offset
) = 10;
135 *(SMB_Hdr(pkt
) + SMB_hdr_axc_offset
) = SMBtconX
;
136 SSVAL(SMB_Hdr(pkt
), SMB_hdr_axo_offset
, SMB_ssetpLM_len
+ param_len
);
138 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_mbs_offset
, SMBLIB_MAX_XMIT
);
139 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_mmc_offset
, 2);
140 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_vcn_offset
, Con_Handle
-> pid
);
141 SIVAL(SMB_Hdr(pkt
), SMB_ssetpLM_snk_offset
, 0);
142 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_pwl_offset
, strlen(PassWord
) + 1);
143 SIVAL(SMB_Hdr(pkt
), SMB_ssetpLM_res_offset
, 0);
144 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_bcc_offset
, param_len
);
146 /* Now copy the param strings in with the right stuff */
148 p
= (char *)(SMB_Hdr(pkt
) + SMB_ssetpLM_buf_offset
);
150 /* Copy in password, then the rest. Password has no null at end */
154 p
= p
+ strlen(PassWord
) + 1;
157 p
= p
+ strlen(UserName
);
162 strcpy(p
, Con_Handle
-> PDomain
);
163 p
= p
+ strlen(Con_Handle
-> PDomain
);
167 strcpy(p
, Con_Handle
-> OSName
);
168 p
= p
+ strlen(Con_Handle
-> OSName
);
171 AndXCom
= SMB_Hdr(pkt
) + SMB_ssetpLM_len
+ param_len
- SMB_hdr_wct_offset
;
175 /* We don't admit to UNICODE support ... */
178 fprintf(stderr
, "Doing NT LM Sess Setup etc ... \n");
181 param_len
= strlen(UserName
) + 1 + strlen(PassWord
) +
182 strlen(Con_Handle
-> PDomain
) + 1 +
183 strlen(Con_Handle
-> OSName
) + 1 +
184 strlen(Con_Handle
-> LMType
) + 1;
186 pkt_len
= SMB_ssetpNTLM_len
+ param_len
+ andx_len
+ andx_param_len
;
188 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
192 SMBlib_errno
= SMBlibE_NoSpace
;
193 if (Tree_Handle
== NULL
)
195 return(NULL
); /* Should handle the error */
199 memset(SMB_Hdr(pkt
), 0, SMB_ssetpNTLM_len
);
200 SIVAL(SMB_Hdr(pkt
), SMB_hdr_idf_offset
, SMB_DEF_IDF
); /* Plunk in IDF */
201 *(SMB_Hdr(pkt
) + SMB_hdr_com_offset
) = SMBsesssetupX
;
202 SSVAL(SMB_Hdr(pkt
), SMB_hdr_pid_offset
, Con_Handle
-> pid
);
203 SSVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
, 0);
204 SSVAL(SMB_Hdr(pkt
), SMB_hdr_mid_offset
, Con_Handle
-> mid
);
205 SSVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
, 0);
206 *(SMB_Hdr(pkt
) + SMB_hdr_wct_offset
) = 13;
207 *(SMB_Hdr(pkt
) + SMB_hdr_axc_offset
) = SMBtconX
;
208 SSVAL(SMB_Hdr(pkt
), SMB_hdr_axo_offset
, SMB_ssetpNTLM_len
+ param_len
);
210 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_mbs_offset
, SMBLIB_MAX_XMIT
);
211 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_mmc_offset
, 2);
212 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_vcn_offset
, 0);
213 SIVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_snk_offset
, 0);
214 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_cipl_offset
, strlen(PassWord
));
215 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_cspl_offset
, 0);
216 SIVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_res_offset
, 0);
217 SIVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_cap_offset
, 0);
218 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_bcc_offset
, param_len
);
220 /* Now copy the param strings in with the right stuff */
222 p
= (char *)(SMB_Hdr(pkt
) + SMB_ssetpNTLM_buf_offset
);
224 /* Copy in password, then the rest. Password has no null at end */
228 p
= p
+ strlen(PassWord
);
231 p
= p
+ strlen(UserName
);
236 strcpy(p
, Con_Handle
-> PDomain
);
237 p
= p
+ strlen(Con_Handle
-> PDomain
);
241 strcpy(p
, Con_Handle
-> OSName
);
242 p
= p
+ strlen(Con_Handle
-> OSName
);
246 strcpy(p
, Con_Handle
-> LMType
);
247 p
= p
+ strlen(Con_Handle
-> LMType
);
250 /* Now set up the TCON Part ... from WCT, make up a pointer that will
253 AndXCom
= SMB_Hdr(pkt
) + SMB_ssetpNTLM_len
+ param_len
- SMB_hdr_wct_offset
;
256 *(AndXCom
+ SMB_hdr_wct_offset
) = 4;
257 *(AndXCom
+ SMB_tconx_axc_offset
) = 0xFF; /* No command */
258 SSVAL(AndXCom
, SMB_tconx_axo_offset
, 0);
259 SSVAL(AndXCom
, SMB_tconx_flg_offset
, 0); /* Don't disconnect TID */
260 SSVAL(AndXCom
, SMB_tconx_pwl_offset
, 0); /* No password, */
261 SSVAL(AndXCom
, SMB_tconx_bcc_offset
, andx_param_len
);
263 p
= (char *)(AndXCom
+ SMB_tconx_buf_offset
);
268 p
= p
+ strlen(service
) + 1;
269 strcpy(p
, service_type
);
271 /* Now send it and get a response */
273 if (RFCNB_Send(Con_Handle
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
276 fprintf(stderr
, "Error sending SessSetupAndTCon request\n");
281 SMBlib_errno
= SMBlibE_SendFailed
;
286 /* Now get the response ... */
288 if (RFCNB_Recv(Con_Handle
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
291 fprintf(stderr
, "Error receiving response to SessSetupAndTCon\n");
296 SMBlib_errno
= SMBlibE_RecvFailed
;
301 /* Check out the response type ... */
303 if (CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
) != SMBC_SUCCESS
) { /* Process error */
306 fprintf(stderr
, "SMB_SessSetupAndTCon failed with errorclass = %i, Error Code = %i\n",
307 CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
),
308 SVAL(SMB_Hdr(pkt
), SMB_hdr_err_offset
));
311 /* Note, here, that we have not properly handled the error processing */
312 /* and so we cannot tell how much of our request crapped out */
314 SMBlib_SMB_Error
= IVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
);
317 SMBlib_errno
= SMBlibE_Remote
;
323 fprintf(stderr
, "SessSetupAndX response. Action = %i\n",
324 SVAL(SMB_Hdr(pkt
), SMB_ssetpr_act_offset
));
327 /* Now pick up the UID for future reference ... */
329 Con_Handle
-> uid
= SVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
);
331 /* And pick up the TID as well */
333 tree
-> tid
= SVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
);
335 tree
-> mbs
= Con_Handle
-> max_xmit
;
337 /* Link the tree into the list in con */
339 if (Con_Handle
-> first_tree
== NULL
) {
341 Con_Handle
-> first_tree
== tree
;
342 Con_Handle
-> last_tree
== tree
;
346 Con_Handle
-> last_tree
-> next
= tree
;
347 tree
-> prev
= Con_Handle
-> last_tree
;
348 Con_Handle
-> last_tree
= tree
;
358 /* Logon and TCon and Open to a file on the server, but we need to pass */
359 /* back a file pointer, so we better have one in the parameter list */
361 int SMB_Logon_TCon_Open(SMB_Handle_Type Con_Handle
, char *UserName
,
365 SMB_Tree_Handle
*Tree_Handle
,
369 SMB_File
**File_Handle
)
372 struct RFCNB_Pkt
*pkt
;
373 int param_len
, i
, pkt_len
, tcon_len
, tcon_param_len
, open_len
,
374 open_param_len
, header_len
;
375 struct SMB_File_Def
*file_tmp
;
376 SMB_Tree_Handle tree
;
379 /* First, we need a tree STRUCTURE as we are going to tree connect */
381 tree
= (SMB_Tree_Handle
)malloc(sizeof(struct SMB_Tree_Structure
));
385 SMBlib_errno
= SMBlibE_NoSpace
;
390 tree
-> con
= Con_Handle
;
391 tree
-> next
= tree
-> prev
= NULL
;
395 /* Next, we need a file handle as we are going to pass one back ... */
396 /* Hmm, there is a bug here ... We should check on File_Handle ... */
398 if ((file_tmp
= (SMB_File
*)malloc(sizeof(SMB_File
))) == NULL
) {
401 fprintf(stderr
, "Could not allocate file handle space ...");
404 SMBlib_errno
= SMBlibE_NoSpace
;
410 /* Next we need a packet etc ... but we need to know what protocol has */
411 /* been negotiated to figure out if we can do it and what SMB format to */
414 /* Since we are going to do a LogonAndX with a TCon as the second command*/
415 /* We need the packet size correct. So TCon starts at wct field */
417 if (Con_Handle
-> protocol
< SMB_P_LanMan1
) {
421 SMBlib_errno
= SMBlibE_ProtLow
;
426 /* Now build the correct structure */
428 /* We send a null password in the TconAndX ... */
430 tcon_len
= SMB_tconx_len
- SMB_hdr_wct_offset
;
431 tcon_param_len
= strlen(service
) + 1 + strlen(service_type
) + 1;
433 open_len
= SMB_openx_len
- SMB_hdr_wct_offset
;
434 open_param_len
= 1 + strlen(filename
) + 1; /* AsciiID + null */
436 if (Con_Handle
-> protocol
< SMB_P_NT1
) {
438 /* We don't do encrypted passwords yet */
440 param_len
= strlen(UserName
) + 1 + strlen(PassWord
) + 1 +
441 strlen(Con_Handle
-> PDomain
) + 1 +
442 strlen(Con_Handle
-> OSName
) + 1;
444 header_len
= SMB_ssetpLM_len
+ param_len
;
446 pkt_len
= header_len
+ tcon_len
+ tcon_param_len
+
447 open_len
+ open_param_len
;
449 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
453 SMBlib_errno
= SMBlibE_NoSpace
;
456 return(SMBlibE_BAD
); /* Should handle the error */
460 memset(SMB_Hdr(pkt
), 0, SMB_ssetpLM_len
);
461 SIVAL(SMB_Hdr(pkt
), SMB_hdr_idf_offset
, SMB_DEF_IDF
); /* Plunk in IDF */
462 *(SMB_Hdr(pkt
) + SMB_hdr_com_offset
) = SMBsesssetupX
;
463 SSVAL(SMB_Hdr(pkt
), SMB_hdr_pid_offset
, Con_Handle
-> pid
);
464 SSVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
, 0);
465 SSVAL(SMB_Hdr(pkt
), SMB_hdr_mid_offset
, Con_Handle
-> mid
);
466 SSVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
, 0);
467 *(SMB_Hdr(pkt
) + SMB_hdr_wct_offset
) = 10;
468 *(SMB_Hdr(pkt
) + SMB_hdr_axc_offset
) = SMBtconX
;
469 SSVAL(SMB_Hdr(pkt
), SMB_hdr_axo_offset
, SMB_ssetpLM_len
+ param_len
);
471 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_mbs_offset
, SMBLIB_MAX_XMIT
);
472 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_mmc_offset
, 2);
473 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_vcn_offset
, Con_Handle
-> pid
);
474 SIVAL(SMB_Hdr(pkt
), SMB_ssetpLM_snk_offset
, 0);
475 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_pwl_offset
, strlen(PassWord
) + 1);
476 SIVAL(SMB_Hdr(pkt
), SMB_ssetpLM_res_offset
, 0);
477 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_bcc_offset
, param_len
);
479 /* Now copy the param strings in with the right stuff */
481 p
= (char *)(SMB_Hdr(pkt
) + SMB_ssetpLM_buf_offset
);
483 /* Copy in password, then the rest. Password has no null at end */
487 p
= p
+ strlen(PassWord
) + 1;
490 p
= p
+ strlen(UserName
);
495 strcpy(p
, Con_Handle
-> PDomain
);
496 p
= p
+ strlen(Con_Handle
-> PDomain
);
500 strcpy(p
, Con_Handle
-> OSName
);
501 p
= p
+ strlen(Con_Handle
-> OSName
);
504 AndXCom
= SMB_Hdr(pkt
) + SMB_ssetpLM_len
+ param_len
- SMB_hdr_wct_offset
;
508 /* We don't admit to UNICODE support ... */
510 param_len
= strlen(UserName
) + 1 + strlen(PassWord
) +
511 strlen(Con_Handle
-> PDomain
) + 1 +
512 strlen(Con_Handle
-> OSName
) + 1 +
513 strlen(Con_Handle
-> LMType
) + 1;
515 header_len
= SMB_ssetpNTLM_len
+ param_len
;
517 pkt_len
= header_len
+ tcon_len
+ tcon_param_len
+
518 open_len
+ open_param_len
;
520 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
524 SMBlib_errno
= SMBlibE_NoSpace
;
526 free(file_tmp
); /* Should only do if we created one ... */
527 return(-1); /* Should handle the error */
531 memset(SMB_Hdr(pkt
), 0, SMB_ssetpNTLM_len
);
532 SIVAL(SMB_Hdr(pkt
), SMB_hdr_idf_offset
, SMB_DEF_IDF
); /* Plunk in IDF */
533 *(SMB_Hdr(pkt
) + SMB_hdr_com_offset
) = SMBsesssetupX
;
534 SSVAL(SMB_Hdr(pkt
), SMB_hdr_pid_offset
, Con_Handle
-> pid
);
535 SSVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
, 0);
536 SSVAL(SMB_Hdr(pkt
), SMB_hdr_mid_offset
, Con_Handle
-> mid
);
537 SSVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
, 0);
538 *(SMB_Hdr(pkt
) + SMB_hdr_wct_offset
) = 13;
539 *(SMB_Hdr(pkt
) + SMB_hdr_axc_offset
) = SMBtconX
;
540 SSVAL(SMB_Hdr(pkt
), SMB_hdr_axo_offset
, SMB_ssetpNTLM_len
+ param_len
);
542 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_mbs_offset
, SMBLIB_MAX_XMIT
);
543 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_mmc_offset
, 2);
544 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_vcn_offset
, 0);
545 SIVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_snk_offset
, 0);
546 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_cipl_offset
, strlen(PassWord
));
547 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_cspl_offset
, 0);
548 SIVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_res_offset
, 0);
549 SIVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_cap_offset
, 0);
550 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_bcc_offset
, param_len
);
552 /* Now copy the param strings in with the right stuff */
554 p
= (char *)(SMB_Hdr(pkt
) + SMB_ssetpNTLM_buf_offset
);
556 /* Copy in password, then the rest. Password has no null at end */
560 p
= p
+ strlen(PassWord
);
563 p
= p
+ strlen(UserName
);
568 strcpy(p
, Con_Handle
-> PDomain
);
569 p
= p
+ strlen(Con_Handle
-> PDomain
);
573 strcpy(p
, Con_Handle
-> OSName
);
574 p
= p
+ strlen(Con_Handle
-> OSName
);
578 strcpy(p
, Con_Handle
-> LMType
);
579 p
= p
+ strlen(Con_Handle
-> LMType
);
582 /* Now set up the TCON Part ... from WCT, make up a pointer that will
585 AndXCom
= SMB_Hdr(pkt
) + SMB_ssetpNTLM_len
+ param_len
- SMB_hdr_wct_offset
;
589 *(AndXCom
+ SMB_hdr_wct_offset
) = 4;
590 *(AndXCom
+ SMB_tconx_axc_offset
) = SMBopenX
;
591 SSVAL(AndXCom
, SMB_tconx_axo_offset
, (header_len
+
592 tcon_len
+ tcon_param_len
));
593 SSVAL(AndXCom
, SMB_tconx_flg_offset
, 0); /* Don't disconnect TID */
594 SSVAL(AndXCom
, SMB_tconx_pwl_offset
, 0); /* No password */
595 SSVAL(AndXCom
, SMB_tconx_bcc_offset
, tcon_param_len
);
597 p
= (char *)(AndXCom
+ SMB_tconx_buf_offset
);
602 p
= p
+ strlen(service
) + 1;
603 strcpy(p
, service_type
);
605 /* Now the open bit ... */
607 AndXCom
= AndXCom
+ tcon_len
+ tcon_param_len
; /* Should get us there */
609 *(AndXCom
+ SMB_hdr_wct_offset
) = 15;
610 *(AndXCom
+ SMB_openx_axc_offset
) = 0xFF;
611 *(AndXCom
+ SMB_openx_axr_offset
) = 0;
612 SSVAL(AndXCom
, SMB_openx_axo_offset
, 0);
613 SSVAL(AndXCom
, SMB_openx_flg_offset
, 0);
614 SSVAL(AndXCom
, SMB_openx_mod_offset
, mode
);
615 SSVAL(AndXCom
, SMB_openx_atr_offset
, search
);
616 SSVAL(AndXCom
, SMB_openx_fat_offset
, 0);
617 SIVAL(AndXCom
, SMB_openx_tim_offset
, 0);
618 SSVAL(AndXCom
, SMB_openx_ofn_offset
, 0x0011); /* Create or open */
619 SIVAL(AndXCom
, SMB_openx_als_offset
, 0);
620 SSVAL(AndXCom
, SMB_openx_bcc_offset
, open_param_len
);
622 p
= (char *)(AndXCom
+ SMB_openx_buf_offset
);
624 /* *p = SMBasciiID; */
627 /* Now send it and get a response */
629 if (RFCNB_Send(Con_Handle
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
632 fprintf(stderr
, "Error sending SessSetupAndTCon request\n");
638 SMBlib_errno
= SMBlibE_SendFailed
;
643 /* Now get the response ... */
645 if (RFCNB_Recv(Con_Handle
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
648 fprintf(stderr
, "Error receiving response to SessSetupAndTCon\n");
654 SMBlib_errno
= SMBlibE_RecvFailed
;
659 /* Check out the response type ... */
661 if (CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
) != SMBC_SUCCESS
) { /* Process error */
664 fprintf(stderr
, "SMB_SessSetupAndTCon failed with errorclass = %i, Error Code = %i\n",
665 CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
),
666 SVAL(SMB_Hdr(pkt
), SMB_hdr_err_offset
));
669 /* Note, here, that we have not properly handled the error processing */
670 /* and so we cannot tell how much of our request crapped out */
672 SMBlib_SMB_Error
= IVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
);
676 SMBlib_errno
= SMBlibE_Remote
;
682 fprintf(stderr
, "SessSetupAndX response. Action = %i\n",
683 SVAL(SMB_Hdr(pkt
), SMB_ssetpr_act_offset
));
686 /* Now pick up the UID for future reference ... */
688 Con_Handle
-> uid
= SVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
);
690 /* And pick up the TID as well */
692 tree
-> tid
= SVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
);
693 tree
-> mbs
= Con_Handle
-> max_xmit
; /* We need this */
696 fprintf(stderr
, "mbs=%i\n", tree
-> mbs
);
699 /* Now we populate the file hanble and pass it back ... */
701 strncpy(file_tmp
-> filename
, filename
, sizeof(file_tmp
-> filename
) - 1);
702 file_tmp
-> tree
= tree
;
704 /* Pick up a pointer to the right part ... */
706 AndXCom
= SMB_Hdr(pkt
) + SVAL(SMB_Hdr(pkt
), SMB_hdr_axo_offset
) -
709 /* Now skip the response to the TConX */
711 AndXCom
= SMB_Hdr(pkt
) + SVAL(AndXCom
, SMB_tconxr_axo_offset
) -
715 fprintf(stderr
, "Word Params = %x, AXO = %x\n",
716 CVAL(AndXCom
, SMB_hdr_wct_offset
),
717 SVAL(AndXCom
, SMB_openxr_axo_offset
));
720 /* Now pick up the things from the openX response that we need */
722 file_tmp
-> fid
= SVAL(AndXCom
, SMB_openxr_fid_offset
);
723 file_tmp
-> lastmod
= IVAL(AndXCom
, SMB_openxr_tim_offset
);
724 file_tmp
-> size
= IVAL(AndXCom
, SMB_openxr_fsz_offset
);
725 file_tmp
-> access
= SVAL(AndXCom
, SMB_openxr_acc_offset
);
726 file_tmp
-> fileloc
= 0;
728 *File_Handle
= file_tmp
;
730 /* Now link the tree into the right place ... */
732 if (Con_Handle
-> first_tree
== NULL
) {
734 Con_Handle
-> first_tree
== tree
;
735 Con_Handle
-> last_tree
== tree
;
739 Con_Handle
-> last_tree
-> next
= tree
;
740 tree
-> prev
= Con_Handle
-> last_tree
;
741 Con_Handle
-> last_tree
= tree
;