]> git.ipfire.org Git - thirdparty/squid.git/blob - lib/smblib/bad-chain.c
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / lib / smblib / bad-chain.c
1 /*
2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9 /* UNIX SMBlib NetBIOS implementation
10
11 Version 1.0
12 SMBlib Routines. Experimental Section ...
13
14 Copyright (C) Richard Sharpe 1996
15 */
16
17 /*
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.
22
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.
27
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.
31 */
32
33 #include "squid.h"
34 #include "rfcnb/rfcnb.h"
35 #include "smblib/smblib-priv.h"
36
37 #include <signal.h>
38 #if HAVE_STRING_H
39 #include <string.h>
40 #endif
41
42 /* Logon and tree connect to the server */
43
44 int SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle, char *UserName,
45 char *PassWord,
46 char *service,
47 char *service_type)
48
49 {
50 struct RFCNB_Pkt *pkt;
51 int param_len, i, pkt_len, andx_len, andx_param_len;
52 char *p, *AndXCom;
53
54 /* First we need a packet etc ... but we need to know what protocol has */
55 /* been negotiated to figure out if we can do it and what SMB format to */
56 /* use ... */
57
58 /* Since we are going to do a LogonAndX with a TCon as the second command*/
59 /* We need the packet size correct. So TCon starts at wct field */
60
61 if (SMB_Types[Con_Handle -> protocol] < SMB_P_LanMan1) {
62
63 SMBlib_errno = SMBlibE_ProtLow;
64 return(SMBlibE_BAD);
65
66 }
67
68 /* Now build the correct structure */
69
70 if (SMB_Types[Con_Handle -> protocol] < SMB_P_NT1) {
71
72 param_len = strlen(UserName) + 1 + strlen(PassWord) +
73 strlen(Con_Handle -> PDomain) + 1 +
74 strlen(Con_Handle -> OSName) + 1;
75
76 pkt_len = SMB_ssetpLM_len + param_len;
77
78 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
79
80 if (pkt == NULL) {
81
82 SMBlib_errno = SMBlibE_NoSpace;
83 return(SMBlibE_BAD); /* Should handle the error */
84
85 }
86
87 memset(SMB_Hdr(pkt), 0, SMB_ssetpLM_len);
88 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
89 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
90 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
91 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
92 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
93 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
94 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10;
95 *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF; /* No extra command */
96 SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);
97
98 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT);
99 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2);
100 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid);
101 SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0);
102 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, strlen(PassWord));
103 SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0);
104 SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len);
105
106 /* Now copy the param strings in with the right stuff */
107
108 p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset);
109
110 /* Copy in password, then the rest. Password has no null at end */
111
112 strcpy(p, PassWord);
113
114 p = p + strlen(PassWord);
115
116 strcpy(p, UserName);
117 p = p + strlen(UserName);
118 *p = 0;
119
120 p = p + 1;
121
122 strcpy(p, Con_Handle -> PDomain);
123 p = p + strlen(Con_Handle -> PDomain);
124 *p = 0;
125 p = p + 1;
126
127 strcpy(p, Con_Handle -> OSName);
128 p = p + strlen(Con_Handle -> OSName);
129 *p = 0;
130
131 } else {
132
133 /* We don't admit to UNICODE support ... */
134
135 param_len = strlen(UserName) + 1 + strlen(PassWord) +
136 strlen(Con_Handle -> PDomain) + 1 +
137 strlen(Con_Handle -> OSName) + 1;
138
139 andx_len = SMB_tcon_len - SMB_hdr_wct_offset;
140
141 /* We send a null password as we sent one in the setup and X */
142
143 andx_param_len = strlen(service) + 2 + 2 + strlen(service_type) + 2;
144
145 pkt_len = SMB_ssetpNTLM_len + param_len + andx_len + andx_param_len;
146
147 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
148
149 if (pkt == NULL) {
150
151 SMBlib_errno = SMBlibE_NoSpace;
152 return(-1); /* Should handle the error */
153
154 }
155
156 memset(SMB_Hdr(pkt), 0, SMB_ssetpNTLM_len);
157 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
158 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
159 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
160 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
161 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
162 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
163 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13;
164 *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtcon;
165 SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpNTLM_len + param_len);
166
167 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT);
168 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 2);
169 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0);
170 SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0);
171 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, strlen(PassWord));
172 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0);
173 SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0);
174 SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0);
175 SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len);
176
177 /* Now copy the param strings in with the right stuff */
178
179 p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset);
180
181 /* Copy in password, then the rest. Password has no null at end */
182
183 strcpy(p, PassWord);
184
185 p = p + strlen(PassWord);
186
187 strcpy(p, UserName);
188 p = p + strlen(UserName);
189 *p = 0;
190
191 p = p + 1;
192
193 strcpy(p, Con_Handle -> PDomain);
194 p = p + strlen(Con_Handle -> PDomain);
195 *p = 0;
196 p = p + 1;
197
198 strcpy(p, Con_Handle -> OSName);
199 p = p + strlen(Con_Handle -> OSName);
200 *p = 0;
201
202 /* Now set up the TCON Part ... from WCT, make up a pointer that will
203 help us ... */
204
205 AndXCom = SMB_Hdr(pkt) + SMB_ssetpNTLM_len + param_len - SMB_hdr_wct_offset;
206
207 *(AndXCom + SMB_hdr_wct_offset) = 0; /* No Words */
208
209 SSVAL(AndXCom, SMB_tcon_bcc_offset, andx_param_len);
210
211 p = (char *)(AndXCom + SMB_tcon_buf_offset);
212
213 *p = SMBasciiID;
214 strcpy(p + 1, service);
215 p = p + strlen(service) + 2;
216 *p = SMBasciiID; /* No password ... */
217 *(p + 1) = 0;
218 p = p + 2;
219 *p = SMBasciiID;
220 strcpy(p + 1, service_type);
221
222 }
223
224 /* Now send it and get a response */
225
226 if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
227
228 #ifdef DEBUG
229 fprintf(stderr, "Error sending SessSetupAndTCon request\n");
230 #endif
231
232 RFCNB_Free_Pkt(pkt);
233 SMBlib_errno = SMBlibE_SendFailed;
234 return(SMBlibE_BAD);
235
236 }
237
238 /* Now get the response ... */
239
240 if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
241
242 #ifdef DEBUG
243 fprintf(stderr, "Error receiving response to SessSetupAndTCon\n");
244 #endif
245
246 RFCNB_Free_Pkt(pkt);
247 SMBlib_errno = SMBlibE_RecvFailed;
248 return(SMBlibE_BAD);
249
250 }
251
252 /* Check out the response type ... */
253
254 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
255
256 #ifdef DEBUG
257 fprintf(stderr, "SMB_SessSetupAndTCon failed with errorclass = %i, Error Code = %i\n",
258 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
259 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
260 #endif
261
262 /* Note, here, that we have not properly handled the error processing */
263 /* and so we cannot tell how much of our request crapped out */
264
265 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
266 RFCNB_Free_Pkt(pkt);
267 SMBlib_errno = SMBlibE_Remote;
268 return(SMBlibE_BAD);
269
270 }
271
272 #ifdef DEBUG
273 fprintf(stderr, "SessSetupAndX response. Action = %i\n",
274 SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset));
275 #endif
276
277 /* Now pick up the UID for future reference ... */
278
279 Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset);
280
281 /* And pick up the TID as well, which will be at offset 4? from wct */
282
283 AndXCom = (char *)SMB_Hdr(pkt) + SVAL(SMB_Hdr(pkt), SMB_ssetpr_axo_offset);
284
285 Con_Handle -> tid = SVAL(AndXCom, 3); /* Naughty */
286 Con_Handle -> max_xmit = SVAL(AndXCom, 1); /* And Again */
287
288 RFCNB_Free_Pkt(pkt);
289
290 return(0);
291
292 }
293