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