]> git.ipfire.org Git - thirdparty/squid.git/blob - lib/smblib/bad-chain.c
SourceFormat Enforcement
[thirdparty/squid.git] / lib / smblib / bad-chain.c
1 #include "squid.h"
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
27 #include "rfcnb/rfcnb.h"
28 #include "smblib/smblib-priv.h"
29
30 #include <signal.h>
31 #if HAVE_STRING_H
32 #include <string.h>
33 #endif
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
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);
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
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);
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