]>
Commit | Line | Data |
---|---|---|
04e4e140 | 1 | /* |
bf95c10a | 2 | * Copyright (C) 1996-2022 The Squid Software Foundation and contributors |
04e4e140 AJ |
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 | */ | |
7c16470c AJ |
8 | |
9 | /* UNIX SMBlib NetBIOS implementation | |
10 | ||
11 | Version 1.0 | |
12 | SMBlib Routines | |
13 | ||
14 | Copyright (C) Richard Sharpe 1996 | |
7c16470c AJ |
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 | ||
04e4e140 AJ |
33 | #include "squid.h" |
34 | ||
7c16470c AJ |
35 | int SMBlib_errno; |
36 | int SMBlib_SMB_Error; | |
37 | #define SMBLIB_ERRNO | |
38 | ||
7c16470c | 39 | #include "rfcnb/rfcnb.h" |
602d9612 A |
40 | #include "smblib/smblib-priv.h" |
41 | #include "smblib/smblib.h" | |
7c16470c AJ |
42 | |
43 | #include <signal.h> | |
44 | #if HAVE_STRING_H | |
45 | #include <string.h> | |
46 | #endif | |
47 | ||
48 | SMB_State_Types SMBlib_State; | |
49 | ||
50 | const char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", | |
3c96dd46 A |
51 | "MICROSOFT NETWORKS 1.03", |
52 | "MICROSOFT NETWORKS 3.0", | |
53 | "DOS LANMAN1.0", | |
54 | "LANMAN1.0", | |
55 | "DOS LM1.2X002", | |
56 | "LM1.2X002", | |
57 | "DOS LANMAN2.1", | |
58 | "LANMAN2.1", | |
59 | "Samba", | |
60 | "NT LM 0.12", | |
61 | "NT LANMAN 1.0", | |
62 | NULL | |
63 | }; | |
7c16470c | 64 | |
7c16470c AJ |
65 | /* Initialize the SMBlib package */ |
66 | ||
67 | int SMB_Init() | |
68 | ||
69 | { | |
70 | ||
71 | SMBlib_State = SMB_State_Started; | |
72 | ||
73 | signal(SIGPIPE, SIG_IGN); /* Ignore these ... */ | |
74 | ||
75 | /* If SMBLIB_Instrument is defines, turn on the instrumentation stuff */ | |
76 | #ifdef SMBLIB_INSTRUMENT | |
77 | ||
78 | SMBlib_Instrument_Init(); | |
79 | ||
80 | #endif | |
81 | ||
82 | return 0; | |
83 | ||
84 | } | |
85 | ||
7c16470c AJ |
86 | /* SMB_Create: Create a connection structure and return for later use */ |
87 | /* We have other helper routines to set variables */ | |
88 | ||
89 | SMB_Handle_Type SMB_Create_Con_Handle() | |
90 | ||
91 | { | |
92 | ||
93 | SMBlib_errno = SMBlibE_NotImpl; | |
94 | return(NULL); | |
95 | ||
96 | } | |
97 | ||
7c16470c AJ |
98 | /* SMB_Connect_Server: Connect to a server, but don't negotiate protocol */ |
99 | /* or anything else ... */ | |
100 | ||
101 | SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, | |
1de9145c | 102 | const char *server, const char *NTdomain) |
7c16470c AJ |
103 | |
104 | { | |
105 | SMB_Handle_Type con; | |
106 | char called[80], calling[80], *address; | |
107 | int i; | |
108 | ||
109 | /* Get a connection structure if one does not exist */ | |
110 | ||
111 | con = Con_Handle; | |
112 | ||
113 | if (Con_Handle == NULL) { | |
114 | ||
115 | if ((con = (struct SMB_Connect_Def *)malloc(sizeof(struct SMB_Connect_Def))) == NULL) { | |
116 | ||
7c16470c AJ |
117 | SMBlib_errno = SMBlibE_NoSpace; |
118 | return NULL; | |
119 | } | |
120 | ||
121 | } | |
122 | ||
123 | /* Init some things ... */ | |
124 | ||
125 | strcpy(con -> service, ""); | |
126 | strcpy(con -> username, ""); | |
127 | strcpy(con -> password, ""); | |
128 | strcpy(con -> sock_options, ""); | |
129 | strcpy(con -> address, ""); | |
cfe771a7 TH |
130 | strncpy(con -> desthost, server, sizeof(con->desthost)); |
131 | con->desthost[sizeof(con->desthost) - 1] = '\0'; | |
132 | strncpy(con -> PDomain, NTdomain, sizeof(con->PDomain)); | |
133 | con->PDomain[sizeof(con->PDomain) - 1] = '\0'; | |
7c16470c AJ |
134 | strcpy(con -> OSName, SMBLIB_DEFAULT_OSNAME); |
135 | strcpy(con -> LMType, SMBLIB_DEFAULT_LMTYPE); | |
136 | con -> first_tree = con -> last_tree = NULL; | |
137 | ||
138 | SMB_Get_My_Name(con -> myname, sizeof(con -> myname)); | |
139 | ||
140 | con -> port = 0; /* No port selected */ | |
141 | ||
142 | /* Get some things we need for the SMB Header */ | |
143 | ||
144 | con -> pid = getpid(); | |
145 | con -> mid = con -> pid; /* This will do for now ... */ | |
146 | con -> uid = 0; /* Until we have done a logon, no uid ... */ | |
147 | con -> gid = getgid(); | |
148 | ||
149 | /* Now connect to the remote end, but first upper case the name of the | |
150 | service we are going to call, sine some servers want it in uppercase */ | |
151 | ||
459bba24 | 152 | for (i=0; i < strlen(con -> desthost); i++) |
153 | called[i] = xtoupper(con -> desthost[i]); | |
7c16470c | 154 | |
459bba24 | 155 | called[strlen(con -> desthost)] = 0; /* Make it a string */ |
7c16470c AJ |
156 | |
157 | for (i=0; i < strlen(con -> myname); i++) | |
017b123a | 158 | calling[i] = xtoupper(con -> myname[i]); |
7c16470c AJ |
159 | |
160 | calling[strlen(con -> myname)] = 0; /* Make it a string */ | |
161 | ||
b9bb9562 | 162 | if (strlen(con -> address) == 0) |
7c16470c AJ |
163 | address = con -> desthost; |
164 | else | |
165 | address = con -> address; | |
166 | ||
167 | con -> Trans_Connect = RFCNB_Call(called, | |
168 | calling, | |
169 | address, /* Protocol specific */ | |
170 | con -> port); | |
171 | ||
172 | /* Did we get one? */ | |
173 | ||
174 | if (con -> Trans_Connect == NULL) { | |
175 | ||
176 | if (Con_Handle == NULL) { | |
177 | Con_Handle = NULL; | |
178 | free(con); | |
179 | } | |
180 | SMBlib_errno = -SMBlibE_CallFailed; | |
181 | return NULL; | |
182 | ||
183 | } | |
184 | ||
185 | return(con); | |
186 | ||
187 | } | |
188 | ||
189 | /* SMB_Connect: Connect to the indicated server */ | |
190 | /* If Con_Handle == NULL then create a handle and connect, otherwise */ | |
191 | /* use the handle passed */ | |
192 | ||
193 | const char *SMB_Prots_Restrict[] = {"PC NETWORK PROGRAM 1.0", | |
194 | NULL | |
195 | }; | |
196 | ||
7c16470c AJ |
197 | SMB_Handle_Type SMB_Connect(SMB_Handle_Type Con_Handle, |
198 | SMB_Tree_Handle *tree, | |
199 | char *service, | |
200 | char *username, | |
201 | char *password) | |
202 | ||
203 | { | |
204 | SMB_Handle_Type con; | |
205 | char *host, *address; | |
206 | char temp[80], called[80], calling[80]; | |
207 | int i; | |
208 | ||
209 | /* Get a connection structure if one does not exist */ | |
210 | ||
211 | con = Con_Handle; | |
212 | ||
213 | if (Con_Handle == NULL) { | |
214 | ||
215 | if ((con = (struct SMB_Connect_Def *)malloc(sizeof(struct SMB_Connect_Def))) == NULL) { | |
216 | ||
217 | SMBlib_errno = SMBlibE_NoSpace; | |
218 | return NULL; | |
219 | } | |
220 | ||
221 | } | |
222 | ||
223 | /* Init some things ... */ | |
224 | ||
cfe771a7 TH |
225 | strncpy(con -> service, service, sizeof(con -> service)); |
226 | con -> service[sizeof(con -> service) - 1] = '\0'; | |
227 | strncpy(con -> username, username, sizeof(con -> username)); | |
228 | con -> username[sizeof(con -> username) - 1] = '\0'; | |
229 | strncpy(con -> password, password, sizeof(con -> password)); | |
230 | con -> password[sizeof(con -> password) - 1] = '\0'; | |
7c16470c AJ |
231 | strcpy(con -> sock_options, ""); |
232 | strcpy(con -> address, ""); | |
233 | strcpy(con -> PDomain, SMBLIB_DEFAULT_DOMAIN); | |
234 | strcpy(con -> OSName, SMBLIB_DEFAULT_OSNAME); | |
235 | strcpy(con -> LMType, SMBLIB_DEFAULT_LMTYPE); | |
236 | con -> first_tree = con -> last_tree = NULL; | |
237 | ||
238 | SMB_Get_My_Name(con -> myname, sizeof(con -> myname)); | |
239 | ||
240 | con -> port = 0; /* No port selected */ | |
241 | ||
242 | /* Get some things we need for the SMB Header */ | |
243 | ||
244 | con -> pid = getpid(); | |
245 | con -> mid = con -> pid; /* This will do for now ... */ | |
246 | con -> uid = 0; /* Until we have done a logon, no uid */ | |
247 | con -> gid = getgid(); | |
248 | ||
249 | /* Now figure out the host portion of the service */ | |
250 | ||
cfe771a7 TH |
251 | strncpy(temp, service, sizeof(temp)); |
252 | temp[sizeof(temp) - 1] = '\0'; | |
7c16470c | 253 | host = strtok(temp, "/\\"); /* Separate host name portion */ |
cfe771a7 TH |
254 | if (!host) { |
255 | if (Con_Handle == NULL) { | |
256 | free(con); | |
257 | Con_Handle = NULL; | |
258 | } | |
259 | SMBlib_errno = -SMBlibE_CallFailed; | |
260 | return NULL; | |
261 | } | |
7830d88a FC |
262 | strncpy(con->desthost, host, sizeof(con->desthost)); |
263 | con->desthost[sizeof(con->desthost)-1]='\0'; | |
7c16470c AJ |
264 | |
265 | /* Now connect to the remote end, but first upper case the name of the | |
266 | service we are going to call, sine some servers want it in uppercase */ | |
267 | ||
459bba24 | 268 | for (i=0; i < strlen(con -> desthost); i++) |
269 | called[i] = xtoupper(con -> desthost[i]); | |
7c16470c | 270 | |
459bba24 | 271 | called[strlen(con -> desthost)] = 0; /* Make it a string */ |
7c16470c AJ |
272 | |
273 | for (i=0; i < strlen(con -> myname); i++) | |
017b123a | 274 | calling[i] = xtoupper(con -> myname[i]); |
7c16470c AJ |
275 | |
276 | calling[strlen(con -> myname)] = 0; /* Make it a string */ | |
277 | ||
b9bb9562 | 278 | if (strlen(con -> address) == 0) |
7c16470c AJ |
279 | address = con -> desthost; |
280 | else | |
281 | address = con -> address; | |
282 | ||
283 | con -> Trans_Connect = RFCNB_Call(called, | |
284 | calling, | |
285 | address, /* Protocol specific */ | |
286 | con -> port); | |
287 | ||
288 | /* Did we get one? */ | |
289 | ||
290 | if (con -> Trans_Connect == NULL) { | |
291 | ||
292 | if (Con_Handle == NULL) { | |
293 | free(con); | |
294 | Con_Handle = NULL; | |
295 | } | |
296 | SMBlib_errno = -SMBlibE_CallFailed; | |
297 | return NULL; | |
298 | ||
299 | } | |
300 | ||
301 | /* Now, negotiate the protocol */ | |
302 | ||
303 | if (SMB_Negotiate(con, SMB_Prots_Restrict) < 0) { | |
304 | ||
cfe771a7 TH |
305 | if (Con_Handle == NULL) { |
306 | free(con); | |
307 | } | |
308 | SMBlib_errno = -SMBlibE_NegNoProt; | |
7c16470c AJ |
309 | return NULL; |
310 | ||
311 | } | |
312 | ||
313 | /* Now connect to the service ... */ | |
314 | ||
315 | if ((*tree = SMB_TreeConnect(con, NULL, service, password, "A:")) == NULL) { | |
316 | ||
cfe771a7 TH |
317 | if (Con_Handle == NULL) { |
318 | free(con); | |
319 | } | |
320 | SMBlib_errno = -SMBlibE_BAD; | |
7c16470c AJ |
321 | return NULL; |
322 | ||
323 | } | |
324 | ||
325 | return(con); | |
326 | ||
327 | } | |
328 | ||
329 | /* Logon to the server. That is, do a session setup if we can. We do not do */ | |
330 | /* Unicode yet! */ | |
331 | ||
332 | int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, | |
333 | char *PassWord, const char *NtDomain, int PreCrypted) | |
334 | ||
335 | { | |
336 | struct RFCNB_Pkt *pkt; | |
337 | int param_len, pkt_len, pass_len; | |
338 | char *p, pword[128]; | |
339 | ||
340 | /* First we need a packet etc ... but we need to know what protocol has */ | |
341 | /* been negotiated to figure out if we can do it and what SMB format to */ | |
342 | /* use ... */ | |
343 | ||
344 | if (Con_Handle -> protocol < SMB_P_LanMan1) { | |
345 | ||
346 | SMBlib_errno = SMBlibE_ProtLow; | |
347 | return(SMBlibE_BAD); | |
348 | ||
349 | } | |
350 | ||
351 | if (PreCrypted) { | |
352 | pass_len = 24; | |
353 | memcpy(pword, PassWord, 24); | |
354 | } else { | |
cfe771a7 TH |
355 | strncpy(pword, PassWord, sizeof(pword)); |
356 | pword[sizeof(pword) - 1] = '\0'; | |
7c16470c AJ |
357 | #ifdef PAM_SMB_ENC_PASS |
358 | if (Con_Handle->encrypt_passwords) { | |
359 | pass_len = 24; | |
360 | SMBencrypt((uchar *) PassWord, (uchar *) Con_Handle->Encrypt_Key, (uchar *) pword); | |
361 | } else | |
362 | #endif | |
363 | pass_len = strlen(pword); | |
364 | } | |
365 | ||
366 | /* Now build the correct structure */ | |
367 | ||
368 | if (Con_Handle -> protocol < SMB_P_NT1) { | |
369 | ||
370 | /* We don't handle encrypted passwords ... */ | |
371 | ||
372 | param_len = strlen(UserName) + 1 + pass_len + 1 + | |
373 | (NtDomain!=NULL ? strlen(NtDomain) : strlen(Con_Handle->PDomain)) + 1 + | |
374 | strlen(Con_Handle -> OSName) + 1; | |
375 | ||
376 | pkt_len = SMB_ssetpLM_len + param_len; | |
377 | ||
378 | pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); | |
379 | ||
380 | if (pkt == NULL) { | |
381 | ||
382 | SMBlib_errno = SMBlibE_NoSpace; | |
383 | return(SMBlibE_BAD); /* Should handle the error */ | |
384 | ||
385 | } | |
386 | ||
387 | memset(SMB_Hdr(pkt), 0, SMB_ssetpLM_len); | |
388 | SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ | |
389 | *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; | |
390 | SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); | |
391 | SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); | |
392 | SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); | |
393 | SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid); | |
394 | *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10; | |
395 | *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF; /* No extra command */ | |
396 | SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0); | |
397 | ||
398 | SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT); | |
399 | SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2); | |
400 | SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid); | |
401 | SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0); | |
402 | SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, pass_len + 1); | |
403 | SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0); | |
404 | SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len); | |
405 | ||
406 | /* Now copy the param strings in with the right stuff */ | |
407 | ||
408 | p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset); | |
409 | ||
410 | /* Copy in password, then the rest. Password has a null at end */ | |
411 | ||
412 | memcpy(p, pword, pass_len); | |
413 | ||
414 | p = p + pass_len + 1; | |
415 | ||
416 | strcpy(p, UserName); | |
417 | p = p + strlen(UserName); | |
418 | *p = 0; | |
419 | ||
420 | p = p + 1; | |
421 | ||
cfe771a7 | 422 | if (NtDomain == NULL) { |
7c16470c AJ |
423 | strcpy(p, Con_Handle -> PDomain); |
424 | p = p + strlen(Con_Handle -> PDomain); | |
425 | } else { | |
426 | strcpy(p, NtDomain); | |
427 | p = p + strlen(NtDomain); | |
428 | } | |
429 | *p = 0; | |
430 | p = p + 1; | |
431 | ||
432 | strcpy(p, Con_Handle -> OSName); | |
433 | p = p + strlen(Con_Handle -> OSName); | |
434 | *p = 0; | |
435 | ||
436 | } else { | |
437 | ||
438 | /* We don't admit to UNICODE support ... */ | |
439 | ||
440 | param_len = strlen(UserName) + 1 + pass_len + | |
441 | strlen(Con_Handle -> PDomain) + 1 + | |
442 | strlen(Con_Handle -> OSName) + 1 + | |
443 | strlen(Con_Handle -> LMType) + 1; | |
444 | ||
445 | pkt_len = SMB_ssetpNTLM_len + param_len; | |
446 | ||
447 | pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); | |
448 | ||
449 | if (pkt == NULL) { | |
450 | ||
451 | SMBlib_errno = SMBlibE_NoSpace; | |
452 | return(-1); /* Should handle the error */ | |
453 | ||
454 | } | |
455 | ||
456 | memset(SMB_Hdr(pkt), 0, SMB_ssetpNTLM_len); | |
457 | SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ | |
458 | *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; | |
459 | SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); | |
460 | SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); | |
461 | SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); | |
462 | SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid); | |
463 | *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13; | |
464 | *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF; /* No extra command */ | |
465 | SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0); | |
466 | ||
467 | SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT); | |
468 | SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 0); | |
469 | SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 1); /* Thanks Tridge! */ | |
470 | SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0); | |
471 | SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, pass_len); | |
472 | SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0); | |
473 | SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0); | |
474 | SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0); | |
475 | SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len); | |
476 | ||
477 | /* Now copy the param strings in with the right stuff */ | |
478 | ||
479 | p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset); | |
480 | ||
481 | /* Copy in password, then the rest. Password has no null at end */ | |
482 | ||
483 | memcpy(p, pword, pass_len); | |
484 | ||
485 | p = p + pass_len; | |
486 | ||
487 | strcpy(p, UserName); | |
488 | p = p + strlen(UserName); | |
489 | *p = 0; | |
490 | ||
491 | p = p + 1; | |
492 | ||
493 | strcpy(p, Con_Handle -> PDomain); | |
494 | p = p + strlen(Con_Handle -> PDomain); | |
495 | *p = 0; | |
496 | p = p + 1; | |
497 | ||
498 | strcpy(p, Con_Handle -> OSName); | |
499 | p = p + strlen(Con_Handle -> OSName); | |
500 | *p = 0; | |
501 | p = p + 1; | |
502 | ||
503 | strcpy(p, Con_Handle -> LMType); | |
504 | p = p + strlen(Con_Handle -> LMType); | |
505 | *p = 0; | |
506 | ||
507 | } | |
508 | ||
509 | /* Now send it and get a response */ | |
510 | ||
511 | if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { | |
512 | ||
513 | #ifdef DEBUG | |
514 | fprintf(stderr, "Error sending SessSetupX request\n"); | |
515 | #endif | |
516 | ||
517 | RFCNB_Free_Pkt(pkt); | |
518 | SMBlib_errno = SMBlibE_SendFailed; | |
519 | return(SMBlibE_BAD); | |
520 | ||
521 | } | |
522 | ||
523 | /* Now get the response ... */ | |
524 | ||
525 | if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { | |
526 | ||
527 | #ifdef DEBUG | |
528 | fprintf(stderr, "Error receiving response to SessSetupAndX\n"); | |
529 | #endif | |
530 | ||
531 | RFCNB_Free_Pkt(pkt); | |
532 | SMBlib_errno = SMBlibE_RecvFailed; | |
533 | return(SMBlibE_BAD); | |
534 | ||
535 | } | |
536 | ||
537 | /* Check out the response type ... */ | |
538 | ||
539 | if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ | |
540 | ||
541 | #ifdef DEBUG | |
542 | fprintf(stderr, "SMB_SessSetupAndX failed with errorclass = %i, Error Code = %i\n", | |
543 | CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), | |
544 | SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); | |
545 | #endif | |
546 | ||
547 | SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); | |
548 | RFCNB_Free_Pkt(pkt); | |
549 | SMBlib_errno = SMBlibE_Remote; | |
550 | return(SMBlibE_BAD); | |
551 | ||
552 | } | |
553 | ||
554 | /** @@@ mdz: check for guest login { **/ | |
555 | if (SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset) & 0x1) { | |
556 | /* do we allow guest login? NO! */ | |
557 | return (SMBlibE_BAD); | |
558 | } | |
559 | /** @@@ mdz: } **/ | |
560 | ||
561 | #ifdef DEBUG | |
562 | fprintf(stderr, "SessSetupAndX response. Action = %i\n", | |
563 | SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset)); | |
564 | #endif | |
565 | ||
566 | /* Now pick up the UID for future reference ... */ | |
567 | ||
568 | Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset); | |
569 | RFCNB_Free_Pkt(pkt); | |
570 | ||
571 | return(0); | |
572 | ||
573 | } | |
574 | ||
7c16470c AJ |
575 | /* Disconnect from the server, and disconnect all tree connects */ |
576 | ||
577 | int SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle) | |
578 | ||
579 | { | |
580 | ||
581 | /* We just disconnect the connection for now ... */ | |
582 | ||
583 | RFCNB_Hangup(Con_Handle -> Trans_Connect); | |
584 | ||
585 | if (!KeepHandle) | |
586 | free(Con_Handle); | |
587 | ||
588 | return(0); | |
589 | ||
590 | } | |
f53969cc | 591 |