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