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 */
37 int SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle
, char *UserName
,
43 struct RFCNB_Pkt
*pkt
;
44 int param_len
, i
, pkt_len
, andx_len
, andx_param_len
;
47 /* First we need a packet etc ... but we need to know what protocol has */
48 /* been negotiated to figure out if we can do it and what SMB format to */
51 /* Since we are going to do a LogonAndX with a TCon as the second command*/
52 /* We need the packet size correct. So TCon starts at wct field */
54 if (SMB_Types
[Con_Handle
-> protocol
] < SMB_P_LanMan1
) {
56 SMBlib_errno
= SMBlibE_ProtLow
;
61 /* Now build the correct structure */
63 if (SMB_Types
[Con_Handle
-> protocol
] < SMB_P_NT1
) {
65 param_len
= strlen(UserName
) + 1 + strlen(PassWord
) +
66 strlen(Con_Handle
-> PDomain
) + 1 +
67 strlen(Con_Handle
-> OSName
) + 1;
69 pkt_len
= SMB_ssetpLM_len
+ param_len
;
71 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
75 SMBlib_errno
= SMBlibE_NoSpace
;
76 return(SMBlibE_BAD
); /* Should handle the error */
80 memset(SMB_Hdr(pkt
), 0, SMB_ssetpLM_len
);
81 SIVAL(SMB_Hdr(pkt
), SMB_hdr_idf_offset
, SMB_DEF_IDF
); /* Plunk in IDF */
82 *(SMB_Hdr(pkt
) + SMB_hdr_com_offset
) = SMBsesssetupX
;
83 SSVAL(SMB_Hdr(pkt
), SMB_hdr_pid_offset
, Con_Handle
-> pid
);
84 SSVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
, 0);
85 SSVAL(SMB_Hdr(pkt
), SMB_hdr_mid_offset
, Con_Handle
-> mid
);
86 SSVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
, Con_Handle
-> uid
);
87 *(SMB_Hdr(pkt
) + SMB_hdr_wct_offset
) = 10;
88 *(SMB_Hdr(pkt
) + SMB_hdr_axc_offset
) = 0xFF; /* No extra command */
89 SSVAL(SMB_Hdr(pkt
), SMB_hdr_axo_offset
, 0);
91 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_mbs_offset
, SMBLIB_MAX_XMIT
);
92 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_mmc_offset
, 2);
93 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_vcn_offset
, Con_Handle
-> pid
);
94 SIVAL(SMB_Hdr(pkt
), SMB_ssetpLM_snk_offset
, 0);
95 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_pwl_offset
, strlen(PassWord
));
96 SIVAL(SMB_Hdr(pkt
), SMB_ssetpLM_res_offset
, 0);
97 SSVAL(SMB_Hdr(pkt
), SMB_ssetpLM_bcc_offset
, param_len
);
99 /* Now copy the param strings in with the right stuff */
101 p
= (char *)(SMB_Hdr(pkt
) + SMB_ssetpLM_buf_offset
);
103 /* Copy in password, then the rest. Password has no null at end */
107 p
= p
+ strlen(PassWord
);
110 p
= p
+ strlen(UserName
);
115 strcpy(p
, Con_Handle
-> PDomain
);
116 p
= p
+ strlen(Con_Handle
-> PDomain
);
120 strcpy(p
, Con_Handle
-> OSName
);
121 p
= p
+ strlen(Con_Handle
-> OSName
);
126 /* We don't admit to UNICODE support ... */
128 param_len
= strlen(UserName
) + 1 + strlen(PassWord
) +
129 strlen(Con_Handle
-> PDomain
) + 1 +
130 strlen(Con_Handle
-> OSName
) + 1;
132 andx_len
= SMB_tcon_len
- SMB_hdr_wct_offset
;
134 /* We send a null password as we sent one in the setup and X */
136 andx_param_len
= strlen(service
) + 2 + 2 + strlen(service_type
) + 2;
138 pkt_len
= SMB_ssetpNTLM_len
+ param_len
+ andx_len
+ andx_param_len
;
140 pkt
= (struct RFCNB_Pkt
*)RFCNB_Alloc_Pkt(pkt_len
);
144 SMBlib_errno
= SMBlibE_NoSpace
;
145 return(-1); /* Should handle the error */
149 memset(SMB_Hdr(pkt
), 0, SMB_ssetpNTLM_len
);
150 SIVAL(SMB_Hdr(pkt
), SMB_hdr_idf_offset
, SMB_DEF_IDF
); /* Plunk in IDF */
151 *(SMB_Hdr(pkt
) + SMB_hdr_com_offset
) = SMBsesssetupX
;
152 SSVAL(SMB_Hdr(pkt
), SMB_hdr_pid_offset
, Con_Handle
-> pid
);
153 SSVAL(SMB_Hdr(pkt
), SMB_hdr_tid_offset
, 0);
154 SSVAL(SMB_Hdr(pkt
), SMB_hdr_mid_offset
, Con_Handle
-> mid
);
155 SSVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
, Con_Handle
-> uid
);
156 *(SMB_Hdr(pkt
) + SMB_hdr_wct_offset
) = 13;
157 *(SMB_Hdr(pkt
) + SMB_hdr_axc_offset
) = SMBtcon
;
158 SSVAL(SMB_Hdr(pkt
), SMB_hdr_axo_offset
, SMB_ssetpNTLM_len
+ param_len
);
160 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_mbs_offset
, SMBLIB_MAX_XMIT
);
161 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_mmc_offset
, 2);
162 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_vcn_offset
, 0);
163 SIVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_snk_offset
, 0);
164 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_cipl_offset
, strlen(PassWord
));
165 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_cspl_offset
, 0);
166 SIVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_res_offset
, 0);
167 SIVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_cap_offset
, 0);
168 SSVAL(SMB_Hdr(pkt
), SMB_ssetpNTLM_bcc_offset
, param_len
);
170 /* Now copy the param strings in with the right stuff */
172 p
= (char *)(SMB_Hdr(pkt
) + SMB_ssetpNTLM_buf_offset
);
174 /* Copy in password, then the rest. Password has no null at end */
178 p
= p
+ strlen(PassWord
);
181 p
= p
+ strlen(UserName
);
186 strcpy(p
, Con_Handle
-> PDomain
);
187 p
= p
+ strlen(Con_Handle
-> PDomain
);
191 strcpy(p
, Con_Handle
-> OSName
);
192 p
= p
+ strlen(Con_Handle
-> OSName
);
195 /* Now set up the TCON Part ... from WCT, make up a pointer that will
198 AndXCom
= SMB_Hdr(pkt
) + SMB_ssetpNTLM_len
+ param_len
- SMB_hdr_wct_offset
;
200 *(AndXCom
+ SMB_hdr_wct_offset
) = 0; /* No Words */
202 SSVAL(AndXCom
, SMB_tcon_bcc_offset
, andx_param_len
);
204 p
= (char *)(AndXCom
+ SMB_tcon_buf_offset
);
207 strcpy(p
+ 1, service
);
208 p
= p
+ strlen(service
) + 2;
209 *p
= SMBasciiID
; /* No password ... */
213 strcpy(p
+ 1, service_type
);
217 /* Now send it and get a response */
219 if (RFCNB_Send(Con_Handle
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
222 fprintf(stderr
, "Error sending SessSetupAndTCon request\n");
226 SMBlib_errno
= SMBlibE_SendFailed
;
231 /* Now get the response ... */
233 if (RFCNB_Recv(Con_Handle
-> Trans_Connect
, pkt
, pkt_len
) < 0) {
236 fprintf(stderr
, "Error receiving response to SessSetupAndTCon\n");
240 SMBlib_errno
= SMBlibE_RecvFailed
;
245 /* Check out the response type ... */
247 if (CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
) != SMBC_SUCCESS
) { /* Process error */
250 fprintf(stderr
, "SMB_SessSetupAndTCon failed with errorclass = %i, Error Code = %i\n",
251 CVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
),
252 SVAL(SMB_Hdr(pkt
), SMB_hdr_err_offset
));
255 /* Note, here, that we have not properly handled the error processing */
256 /* and so we cannot tell how much of our request crapped out */
258 SMBlib_SMB_Error
= IVAL(SMB_Hdr(pkt
), SMB_hdr_rcls_offset
);
260 SMBlib_errno
= SMBlibE_Remote
;
266 fprintf(stderr
, "SessSetupAndX response. Action = %i\n",
267 SVAL(SMB_Hdr(pkt
), SMB_ssetpr_act_offset
));
270 /* Now pick up the UID for future reference ... */
272 Con_Handle
-> uid
= SVAL(SMB_Hdr(pkt
), SMB_hdr_uid_offset
);
274 /* And pick up the TID as well, which will be at offset 4? from wct */
276 AndXCom
= (char *)SMB_Hdr(pkt
) + SVAL(SMB_Hdr(pkt
), SMB_ssetpr_axo_offset
);
278 Con_Handle
-> tid
= SVAL(AndXCom
, 3); /* Naughty */
279 Con_Handle
-> max_xmit
= SVAL(AndXCom
, 1); /* And Again */