]>
Commit | Line | Data |
---|---|---|
f7f3304a | 1 | #include "squid.h" |
7c16470c AJ |
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 | ||
0ab648c9 AJ |
27 | #include "smblib/smblib-priv.h" |
28 | #include "rfcnb/rfcnb.h" | |
7c16470c AJ |
29 | |
30 | #include <signal.h> | |
0ab648c9 AJ |
31 | #if HAVE_STRING_H |
32 | #include <string.h> | |
33 | #endif | |
7c16470c AJ |
34 | |
35 | /* Logon and tree connect to the server */ | |
36 | ||
37 | int SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle, char *UserName, | |
38 | char *PassWord, | |
39 | char *service, | |
40 | char *service_type) | |
41 | ||
42 | { | |
43 | struct RFCNB_Pkt *pkt; | |
44 | int param_len, i, pkt_len, andx_len, andx_param_len; | |
45 | char *p, *AndXCom; | |
46 | ||
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 */ | |
49 | /* use ... */ | |
50 | ||
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 */ | |
53 | ||
54 | if (SMB_Types[Con_Handle -> protocol] < SMB_P_LanMan1) { | |
55 | ||
56 | SMBlib_errno = SMBlibE_ProtLow; | |
57 | return(SMBlibE_BAD); | |
58 | ||
59 | } | |
60 | ||
61 | /* Now build the correct structure */ | |
62 | ||
63 | if (SMB_Types[Con_Handle -> protocol] < SMB_P_NT1) { | |
64 | ||
65 | param_len = strlen(UserName) + 1 + strlen(PassWord) + | |
66 | strlen(Con_Handle -> PDomain) + 1 + | |
67 | strlen(Con_Handle -> OSName) + 1; | |
68 | ||
69 | pkt_len = SMB_ssetpLM_len + param_len; | |
70 | ||
71 | pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); | |
72 | ||
73 | if (pkt == NULL) { | |
74 | ||
75 | SMBlib_errno = SMBlibE_NoSpace; | |
76 | return(SMBlibE_BAD); /* Should handle the error */ | |
77 | ||
78 | } | |
79 | ||
0ab648c9 | 80 | memset(SMB_Hdr(pkt), 0, SMB_ssetpLM_len); |
7c16470c AJ |
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); | |
90 | ||
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); | |
98 | ||
99 | /* Now copy the param strings in with the right stuff */ | |
100 | ||
101 | p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset); | |
102 | ||
103 | /* Copy in password, then the rest. Password has no null at end */ | |
104 | ||
105 | strcpy(p, PassWord); | |
106 | ||
107 | p = p + strlen(PassWord); | |
108 | ||
109 | strcpy(p, UserName); | |
110 | p = p + strlen(UserName); | |
111 | *p = 0; | |
112 | ||
113 | p = p + 1; | |
114 | ||
115 | strcpy(p, Con_Handle -> PDomain); | |
116 | p = p + strlen(Con_Handle -> PDomain); | |
117 | *p = 0; | |
118 | p = p + 1; | |
119 | ||
120 | strcpy(p, Con_Handle -> OSName); | |
121 | p = p + strlen(Con_Handle -> OSName); | |
122 | *p = 0; | |
123 | ||
124 | } else { | |
125 | ||
126 | /* We don't admit to UNICODE support ... */ | |
127 | ||
128 | param_len = strlen(UserName) + 1 + strlen(PassWord) + | |
129 | strlen(Con_Handle -> PDomain) + 1 + | |
130 | strlen(Con_Handle -> OSName) + 1; | |
131 | ||
132 | andx_len = SMB_tcon_len - SMB_hdr_wct_offset; | |
133 | ||
134 | /* We send a null password as we sent one in the setup and X */ | |
135 | ||
136 | andx_param_len = strlen(service) + 2 + 2 + strlen(service_type) + 2; | |
137 | ||
138 | pkt_len = SMB_ssetpNTLM_len + param_len + andx_len + andx_param_len; | |
139 | ||
140 | pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); | |
141 | ||
142 | if (pkt == NULL) { | |
143 | ||
144 | SMBlib_errno = SMBlibE_NoSpace; | |
145 | return(-1); /* Should handle the error */ | |
146 | ||
147 | } | |
148 | ||
0ab648c9 | 149 | memset(SMB_Hdr(pkt), 0, SMB_ssetpNTLM_len); |
7c16470c AJ |
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); | |
159 | ||
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); | |
169 | ||
170 | /* Now copy the param strings in with the right stuff */ | |
171 | ||
172 | p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset); | |
173 | ||
174 | /* Copy in password, then the rest. Password has no null at end */ | |
175 | ||
176 | strcpy(p, PassWord); | |
177 | ||
178 | p = p + strlen(PassWord); | |
179 | ||
180 | strcpy(p, UserName); | |
181 | p = p + strlen(UserName); | |
182 | *p = 0; | |
183 | ||
184 | p = p + 1; | |
185 | ||
186 | strcpy(p, Con_Handle -> PDomain); | |
187 | p = p + strlen(Con_Handle -> PDomain); | |
188 | *p = 0; | |
189 | p = p + 1; | |
190 | ||
191 | strcpy(p, Con_Handle -> OSName); | |
192 | p = p + strlen(Con_Handle -> OSName); | |
193 | *p = 0; | |
194 | ||
195 | /* Now set up the TCON Part ... from WCT, make up a pointer that will | |
196 | help us ... */ | |
197 | ||
198 | AndXCom = SMB_Hdr(pkt) + SMB_ssetpNTLM_len + param_len - SMB_hdr_wct_offset; | |
199 | ||
200 | *(AndXCom + SMB_hdr_wct_offset) = 0; /* No Words */ | |
201 | ||
202 | SSVAL(AndXCom, SMB_tcon_bcc_offset, andx_param_len); | |
203 | ||
204 | p = (char *)(AndXCom + SMB_tcon_buf_offset); | |
205 | ||
206 | *p = SMBasciiID; | |
207 | strcpy(p + 1, service); | |
208 | p = p + strlen(service) + 2; | |
209 | *p = SMBasciiID; /* No password ... */ | |
210 | *(p + 1) = 0; | |
211 | p = p + 2; | |
212 | *p = SMBasciiID; | |
213 | strcpy(p + 1, service_type); | |
214 | ||
215 | } | |
216 | ||
217 | /* Now send it and get a response */ | |
218 | ||
219 | if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { | |
220 | ||
221 | #ifdef DEBUG | |
222 | fprintf(stderr, "Error sending SessSetupAndTCon request\n"); | |
223 | #endif | |
224 | ||
225 | RFCNB_Free_Pkt(pkt); | |
226 | SMBlib_errno = SMBlibE_SendFailed; | |
227 | return(SMBlibE_BAD); | |
228 | ||
229 | } | |
230 | ||
231 | /* Now get the response ... */ | |
232 | ||
233 | if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { | |
234 | ||
235 | #ifdef DEBUG | |
236 | fprintf(stderr, "Error receiving response to SessSetupAndTCon\n"); | |
237 | #endif | |
238 | ||
239 | RFCNB_Free_Pkt(pkt); | |
240 | SMBlib_errno = SMBlibE_RecvFailed; | |
241 | return(SMBlibE_BAD); | |
242 | ||
243 | } | |
244 | ||
245 | /* Check out the response type ... */ | |
246 | ||
247 | if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ | |
248 | ||
249 | #ifdef DEBUG | |
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)); | |
253 | #endif | |
254 | ||
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 */ | |
257 | ||
258 | SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); | |
259 | RFCNB_Free_Pkt(pkt); | |
260 | SMBlib_errno = SMBlibE_Remote; | |
261 | return(SMBlibE_BAD); | |
262 | ||
263 | } | |
264 | ||
265 | #ifdef DEBUG | |
266 | fprintf(stderr, "SessSetupAndX response. Action = %i\n", | |
267 | SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset)); | |
268 | #endif | |
269 | ||
270 | /* Now pick up the UID for future reference ... */ | |
271 | ||
272 | Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset); | |
273 | ||
274 | /* And pick up the TID as well, which will be at offset 4? from wct */ | |
275 | ||
276 | AndXCom = (char *)SMB_Hdr(pkt) + SVAL(SMB_Hdr(pkt), SMB_ssetpr_axo_offset); | |
277 | ||
278 | Con_Handle -> tid = SVAL(AndXCom, 3); /* Naughty */ | |
279 | Con_Handle -> max_xmit = SVAL(AndXCom, 1); /* And Again */ | |
280 | ||
281 | RFCNB_Free_Pkt(pkt); | |
282 | ||
283 | return(0); | |
284 | ||
285 | } | |
286 |