2 /* UNIX SMBlib NetBIOS implementation
5 SMBlib Routines. Experimental Section ...
7 Copyright (C) Richard Sharpe 1996
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.
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.
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.
27 #include "smblib/smblib-priv.h"
28 #include "rfcnb/rfcnb.h"
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 ... */
38 SMB_Tree_Handle
SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle
,
39 SMB_Tree_Handle Tree_Handle
,
46 struct RFCNB_Pkt
*pkt
;
47 int param_len
, i
, pkt_len
, andx_len
, andx_param_len
;
51 /* Lets create a tree if we need one ... */
53 if (Tree_Handle
== NULL
) {
55 tree
= (SMB_Tree_Handle
)malloc(sizeof(struct SMB_Tree_Structure
));
59 SMBlib_errno
= SMBlibE_NoSpace
;
62 } else { /* Initialize the tree */
64 tree
-> con
= Con_Handle
;
65 tree
-> prev
= tree
-> next
= NULL
;
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 */
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 */
78 if (Con_Handle
-> protocol
< SMB_P_LanMan1
) {
80 SMBlib_errno
= SMBlibE_ProtLow
;
81 if (Tree_Handle
== NULL
)
87 /* Now build the correct structure */
89 andx_len
= SMB_tconx_len
- SMB_hdr_wct_offset
;
91 /* We send a null password as we sent one in the setup and X */
93 andx_param_len
= strlen(service
) + 1 + strlen(service_type
) + 1;
95 if (Con_Handle
-> protocol
< SMB_P_NT1
) {
98 fprintf(stderr
, "Doing an LM session setup etc ...\n");
101 /* We don't do encrypted passwords ... */
103 param_len
= strlen(UserName
) + 1 + strlen(PassWord
) + 1 +
104 strlen(Con_Handle
-> PDomain
) + 1 +
105 strlen(Con_Handle
-> OSName
) + 1;
107 pkt_len
= SMB_ssetpLM_len
+ param_len
+ andx_len
+ andx_param_len
;
109 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
113 SMBlib_errno
= SMBlibE_NoSpace
;
114 if (Tree_Handle
== NULL
)
116 return(NULL
); /* Should handle the error */
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
);
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
);
139 /* Now copy the param strings in with the right stuff */
141 p
= (char *)(SMB_Hdr(pkt
) + SMB_ssetpLM_buf_offset
);
143 /* Copy in password, then the rest. Password has no null at end */
147 p
= p
+ strlen(PassWord
) + 1;
150 p
= p
+ strlen(UserName
);
155 strcpy(p
, Con_Handle
-> PDomain
);
156 p
= p
+ strlen(Con_Handle
-> PDomain
);
160 strcpy(p
, Con_Handle
-> OSName
);
161 p
= p
+ strlen(Con_Handle
-> OSName
);
164 AndXCom
= SMB_Hdr(pkt
) + SMB_ssetpLM_len
+ param_len
- SMB_hdr_wct_offset
;
168 /* We don't admit to UNICODE support ... */
171 fprintf(stderr
, "Doing NT LM Sess Setup etc ... \n");
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;
179 pkt_len
= SMB_ssetpNTLM_len
+ param_len
+ andx_len
+ andx_param_len
;
181 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
185 SMBlib_errno
= SMBlibE_NoSpace
;
186 if (Tree_Handle
== NULL
)
188 return(NULL
); /* Should handle the error */
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
);
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
);
213 /* Now copy the param strings in with the right stuff */
215 p
= (char *)(SMB_Hdr(pkt
) + SMB_ssetpNTLM_buf_offset
);
217 /* Copy in password, then the rest. Password has no null at end */
221 p
= p
+ strlen(PassWord
);
224 p
= p
+ strlen(UserName
);
229 strcpy(p
, Con_Handle
-> PDomain
);
230 p
= p
+ strlen(Con_Handle
-> PDomain
);
234 strcpy(p
, Con_Handle
-> OSName
);
235 p
= p
+ strlen(Con_Handle
-> OSName
);
239 strcpy(p
, Con_Handle
-> LMType
);
240 p
= p
+ strlen(Con_Handle
-> LMType
);
243 /* Now set up the TCON Part ... from WCT, make up a pointer that will
246 AndXCom
= SMB_Hdr(pkt
) + SMB_ssetpNTLM_len
+ param_len
- SMB_hdr_wct_offset
;
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
);
256 p
= (char *)(AndXCom
+ SMB_tconx_buf_offset
);
261 p
= p
+ strlen(service
) + 1;
262 strcpy(p
, service_type
);
264 /* Now send it and get a response */
266 if (RFCNB_Send(Con_Handle
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
269 fprintf(stderr
, "Error sending SessSetupAndTCon request\n");
274 SMBlib_errno
= SMBlibE_SendFailed
;
279 /* Now get the response ... */
281 if (RFCNB_Recv(Con_Handle
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
284 fprintf(stderr
, "Error receiving response to SessSetupAndTCon\n");
289 SMBlib_errno
= SMBlibE_RecvFailed
;
294 /* Check out the response type ... */
296 if (CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
) != SMBC_SUCCESS
) { /* Process error */
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
));
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 */
307 SMBlib_SMB_Error
= IVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
);
310 SMBlib_errno
= SMBlibE_Remote
;
316 fprintf(stderr
, "SessSetupAndX response. Action = %i\n",
317 SVAL(SMB_Hdr(pkt
), SMB_ssetpr_act_offset
));
320 /* Now pick up the UID for future reference ... */
322 Con_Handle
-> uid
= SVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
);
324 /* And pick up the TID as well */
326 tree
-> tid
= SVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
);
328 tree
-> mbs
= Con_Handle
-> max_xmit
;
330 /* Link the tree into the list in con */
332 if (Con_Handle
-> first_tree
== NULL
) {
334 Con_Handle
-> first_tree
== tree
;
335 Con_Handle
-> last_tree
== tree
;
339 Con_Handle
-> last_tree
-> next
= tree
;
340 tree
-> prev
= Con_Handle
-> last_tree
;
341 Con_Handle
-> last_tree
= tree
;
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 */
354 int SMB_Logon_TCon_Open(SMB_Handle_Type Con_Handle
, char *UserName
,
358 SMB_Tree_Handle
*Tree_Handle
,
362 SMB_File
**File_Handle
)
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
;
372 /* First, we need a tree STRUCTURE as we are going to tree connect */
374 tree
= (SMB_Tree_Handle
)malloc(sizeof(struct SMB_Tree_Structure
));
378 SMBlib_errno
= SMBlibE_NoSpace
;
383 tree
-> con
= Con_Handle
;
384 tree
-> next
= tree
-> prev
= NULL
;
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 ... */
391 if ((file_tmp
= (SMB_File
*)malloc(sizeof(SMB_File
))) == NULL
) {
394 fprintf(stderr
, "Could not allocate file handle space ...");
397 SMBlib_errno
= SMBlibE_NoSpace
;
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 */
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 */
410 if (Con_Handle
-> protocol
< SMB_P_LanMan1
) {
414 SMBlib_errno
= SMBlibE_ProtLow
;
419 /* Now build the correct structure */
421 /* We send a null password in the TconAndX ... */
423 tcon_len
= SMB_tconx_len
- SMB_hdr_wct_offset
;
424 tcon_param_len
= strlen(service
) + 1 + strlen(service_type
) + 1;
426 open_len
= SMB_openx_len
- SMB_hdr_wct_offset
;
427 open_param_len
= 1 + strlen(filename
) + 1; /* AsciiID + null */
429 if (Con_Handle
-> protocol
< SMB_P_NT1
) {
431 /* We don't do encrypted passwords yet */
433 param_len
= strlen(UserName
) + 1 + strlen(PassWord
) + 1 +
434 strlen(Con_Handle
-> PDomain
) + 1 +
435 strlen(Con_Handle
-> OSName
) + 1;
437 header_len
= SMB_ssetpLM_len
+ param_len
;
439 pkt_len
= header_len
+ tcon_len
+ tcon_param_len
+
440 open_len
+ open_param_len
;
442 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
446 SMBlib_errno
= SMBlibE_NoSpace
;
449 return(SMBlibE_BAD
); /* Should handle the error */
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
);
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
);
472 /* Now copy the param strings in with the right stuff */
474 p
= (char *)(SMB_Hdr(pkt
) + SMB_ssetpLM_buf_offset
);
476 /* Copy in password, then the rest. Password has no null at end */
480 p
= p
+ strlen(PassWord
) + 1;
483 p
= p
+ strlen(UserName
);
488 strcpy(p
, Con_Handle
-> PDomain
);
489 p
= p
+ strlen(Con_Handle
-> PDomain
);
493 strcpy(p
, Con_Handle
-> OSName
);
494 p
= p
+ strlen(Con_Handle
-> OSName
);
497 AndXCom
= SMB_Hdr(pkt
) + SMB_ssetpLM_len
+ param_len
- SMB_hdr_wct_offset
;
501 /* We don't admit to UNICODE support ... */
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;
508 header_len
= SMB_ssetpNTLM_len
+ param_len
;
510 pkt_len
= header_len
+ tcon_len
+ tcon_param_len
+
511 open_len
+ open_param_len
;
513 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
517 SMBlib_errno
= SMBlibE_NoSpace
;
519 free(file_tmp
); /* Should only do if we created one ... */
520 return(-1); /* Should handle the error */
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
);
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
);
545 /* Now copy the param strings in with the right stuff */
547 p
= (char *)(SMB_Hdr(pkt
) + SMB_ssetpNTLM_buf_offset
);
549 /* Copy in password, then the rest. Password has no null at end */
553 p
= p
+ strlen(PassWord
);
556 p
= p
+ strlen(UserName
);
561 strcpy(p
, Con_Handle
-> PDomain
);
562 p
= p
+ strlen(Con_Handle
-> PDomain
);
566 strcpy(p
, Con_Handle
-> OSName
);
567 p
= p
+ strlen(Con_Handle
-> OSName
);
571 strcpy(p
, Con_Handle
-> LMType
);
572 p
= p
+ strlen(Con_Handle
-> LMType
);
575 /* Now set up the TCON Part ... from WCT, make up a pointer that will
578 AndXCom
= SMB_Hdr(pkt
) + SMB_ssetpNTLM_len
+ param_len
- SMB_hdr_wct_offset
;
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
);
590 p
= (char *)(AndXCom
+ SMB_tconx_buf_offset
);
595 p
= p
+ strlen(service
) + 1;
596 strcpy(p
, service_type
);
598 /* Now the open bit ... */
600 AndXCom
= AndXCom
+ tcon_len
+ tcon_param_len
; /* Should get us there */
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
);
615 p
= (char *)(AndXCom
+ SMB_openx_buf_offset
);
617 /* *p = SMBasciiID; */
620 /* Now send it and get a response */
622 if (RFCNB_Send(Con_Handle
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
625 fprintf(stderr
, "Error sending SessSetupAndTCon request\n");
631 SMBlib_errno
= SMBlibE_SendFailed
;
636 /* Now get the response ... */
638 if (RFCNB_Recv(Con_Handle
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
641 fprintf(stderr
, "Error receiving response to SessSetupAndTCon\n");
647 SMBlib_errno
= SMBlibE_RecvFailed
;
652 /* Check out the response type ... */
654 if (CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
) != SMBC_SUCCESS
) { /* Process error */
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
));
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 */
665 SMBlib_SMB_Error
= IVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
);
669 SMBlib_errno
= SMBlibE_Remote
;
675 fprintf(stderr
, "SessSetupAndX response. Action = %i\n",
676 SVAL(SMB_Hdr(pkt
), SMB_ssetpr_act_offset
));
679 /* Now pick up the UID for future reference ... */
681 Con_Handle
-> uid
= SVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
);
683 /* And pick up the TID as well */
685 tree
-> tid
= SVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
);
686 tree
-> mbs
= Con_Handle
-> max_xmit
; /* We need this */
689 fprintf(stderr
, "mbs=%i\n", tree
-> mbs
);
692 /* Now we populate the file hanble and pass it back ... */
694 strncpy(file_tmp
-> filename
, filename
, sizeof(file_tmp
-> filename
) - 1);
695 file_tmp
-> tree
= tree
;
697 /* Pick up a pointer to the right part ... */
699 AndXCom
= SMB_Hdr(pkt
) + SVAL(SMB_Hdr(pkt
), SMB_hdr_axo_offset
) -
702 /* Now skip the response to the TConX */
704 AndXCom
= SMB_Hdr(pkt
) + SVAL(AndXCom
, SMB_tconxr_axo_offset
) -
708 fprintf(stderr
, "Word Params = %x, AXO = %x\n",
709 CVAL(AndXCom
, SMB_hdr_wct_offset
),
710 SVAL(AndXCom
, SMB_openxr_axo_offset
));
713 /* Now pick up the things from the openX response that we need */
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;
721 *File_Handle
= file_tmp
;
723 /* Now link the tree into the right place ... */
725 if (Con_Handle
-> first_tree
== NULL
) {
727 Con_Handle
-> first_tree
== tree
;
728 Con_Handle
-> last_tree
== tree
;
732 Con_Handle
-> last_tree
-> next
= tree
;
733 tree
-> prev
= Con_Handle
-> last_tree
;
734 Con_Handle
-> last_tree
= tree
;