smblib-util.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 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 Utility Routines
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 #include "smblib/smblib.h"
37 
38 #if HAVE_STRING_H
39 #include <string.h>
40 #endif
41 
51  SMB_P_NT1,
52  SMB_P_NT1,
53  SMB_P_NT1,
54  -1
55  };
56 
57 #if UNDEFINED
58 char *SMB_DOSTimToStr(int DOS_time);
59 char *SMB_AtrToStr(int attribs, BOOL verbose);
60 int SMB_Get_Tree_MBS(SMB_Tree_Handle tree);
61 int SMB_Get_Max_Buf_Siz(SMB_Handle_Type Con_Handle);
62 int SMB_Get_Protocol_IDX(SMB_Handle_Type Con_Handle);
63 #endif /* UNDEFINED */
64 int SMB_Get_Protocol(SMB_Handle_Type Con_Handle);
65 int SMB_Figure_Protocol(const char *dialects[], int prot_index);
66 int SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, BOOL discard);
67 
68 #if UNDEFINED
69 /* Print out an SMB pkt in all its gory detail ... */
70 
71 void SMB_Print_Pkt(FILE fd, RFCNB_Pkt *pkt, BOOL command, int Offset, int Len)
72 
73 {
74 
75  /* Well, just how do we do this ... print it I suppose */
76 
77  /* Print out the SMB header ... */
78 
79  /* Print the command */
80 
81  /* Print the other bits in the header */
82 
83  /* etc */
84 
85 }
86 #endif
87 
88 /* Convert a DOS Date_Time to a local host type date time for printing */
89 
90 #if UNDEFINED
91 char *SMB_DOSTimToStr(int DOS_time)
92 
93 {
94  static char SMB_Time_Temp[48];
95  int DOS_sec, DOS_min, DOS_hour, DOS_day, DOS_month, DOS_year;
96 
97  SMB_Time_Temp[0] = 0;
98 
99  DOS_sec = (DOS_time & 0x001F) * 2;
100  DOS_min = (DOS_time & 0x07E0) >> 5;
101  DOS_hour = ((DOS_time & 0xF800) >> 11);
102 
103  DOS_day = (DOS_time & 0x001F0000) >> 16;
104  DOS_month = (DOS_time & 0x01E00000) >> 21;
105  DOS_year = ((DOS_time & 0xFE000000) >> 25) + 80;
106 
107  snprintf(SMB_Time_Temp, 48, "%2d/%02d/%2d %2d:%02d:%02d", DOS_day, DOS_month,
108  DOS_year, DOS_hour, DOS_min, DOS_sec);
109 
110  return(SMB_Time_Temp);
111 
112 }
113 
114 /* Convert an attribute byte/word etc to a string ... We return a pointer
115  to a static string which we guarantee is long enough. If verbose is
116  true, we print out long form of strings ... */
117 
118 char *SMB_AtrToStr(int attribs, BOOL verbose)
119 
120 {
121  static char SMB_Attrib_Temp[128];
122 
123  SMB_Attrib_Temp[0] = 0;
124 
125  if (attribs & SMB_FA_ROF)
126  strcat(SMB_Attrib_Temp, (verbose?"Read Only ":"R"));
127 
128  if (attribs & SMB_FA_HID)
129  strcat(SMB_Attrib_Temp, (verbose?"Hidden ":"H"));
130 
131  if (attribs & SMB_FA_SYS)
132  strcat(SMB_Attrib_Temp, (verbose?"System ":"S"));
133 
134  if (attribs & SMB_FA_VOL)
135  strcat(SMB_Attrib_Temp, (verbose?"Volume ":"V"));
136 
137  if (attribs & SMB_FA_DIR)
138  strcat(SMB_Attrib_Temp, (verbose?"Directory ":"D"));
139 
140  if (attribs & SMB_FA_ARC)
141  strcat(SMB_Attrib_Temp, (verbose?"Archive ":"A"));
142 
143  return(SMB_Attrib_Temp);
144 
145 }
146 
147 /* Pick up the Max Buffer Size from the Tree Structure ... */
148 
149 int SMB_Get_Tree_MBS(SMB_Tree_Handle tree)
150 
151 {
152  if (tree != NULL) {
153  return(tree -> mbs);
154  } else {
155  return(SMBlibE_BAD);
156  }
157 }
158 
159 /* Pick up the Max buffer size */
160 
161 int SMB_Get_Max_Buf_Siz(SMB_Handle_Type Con_Handle)
162 
163 {
164  if (Con_Handle != NULL) {
165  return(Con_Handle -> max_xmit);
166  } else {
167  return(SMBlibE_BAD);
168  }
169 
170 }
171 /* Pickup the protocol index from the connection structure */
172 
173 int SMB_Get_Protocol_IDX(SMB_Handle_Type Con_Handle)
174 
175 {
176  if (Con_Handle != NULL) {
177  return(Con_Handle -> prot_IDX);
178  } else {
179  return(0xFFFF); /* Invalid protocol */
180  }
181 
182 }
183 #endif /* UNDEFINED */
184 
185 /* Pick up the protocol from the connection structure */
186 
188 
189 {
190  if (Con_Handle != NULL) {
191  return(Con_Handle -> protocol);
192  } else {
193  return(0xFFFF); /* Invalid protocol */
194  }
195 
196 }
197 
198 /* Figure out what protocol was accepted, given the list of dialect strings */
199 /* We offered, and the index back from the server. We allow for a user */
200 /* supplied list, and assume that it is a subset of our list */
201 
202 int SMB_Figure_Protocol(const char *dialects[], int prot_index)
203 
204 {
205  int i;
206 
207  // prot_index may be a value outside the table SMB_Types[]
208  // which holds data at offsets 0 to 11
209  int ourType = (prot_index < 0 || prot_index > 11);
210 
211  if (ourType && dialects == SMB_Prots) { /* The jobs is easy, just index into table */
212 
213  return(SMB_Types[prot_index]);
214  } else { /* Search through SMB_Prots looking for a match */
215 
216  for (i = 0; SMB_Prots[i] != NULL; i++) {
217 
218  if (strcmp(dialects[prot_index], SMB_Prots[i]) == 0) { /* A match */
219 
220  return(SMB_Types[i]);
221 
222  }
223 
224  }
225 
226  /* If we got here, then we are in trouble, because the protocol was not */
227  /* One we understand ... */
228 
229  return(SMB_P_Unknown);
230 
231  }
232 
233 }
234 
235 /* Negotiate the protocol we will use from the list passed in Prots */
236 /* we return the index of the accepted protocol in NegProt, -1 indicates */
237 /* none acceptible, and our return value is 0 if ok, <0 if problems */
238 
239 int SMB_Negotiate(SMB_Handle_Type Con_Handle, const char *Prots[])
240 
241 {
242 // struct SMB_Neg_Prot_Def *prot_pkt;
243 // struct SMB_Neg_Prot_Resp_Def *resp_pkt;
244  struct RFCNB_Pkt *pkt;
245  int prots_len, i, pkt_len, prot, alloc_len;
246  char *p;
247 
248  /* Figure out how long the prot list will be and allocate space for it */
249 
250  prots_len = 0;
251 
252  for (i = 0; Prots[i] != NULL; i++) {
253 
254  prots_len = prots_len + strlen(Prots[i]) + 2; /* Account for null etc */
255 
256  }
257 
258  /* The -1 accounts for the one byte smb_buf we have because some systems */
259  /* don't like char msg_buf[] */
260 
261  pkt_len = SMB_negp_len + prots_len;
262 
263  /* Make sure that the pkt len is long enough for the max response ... */
264  /* Which is a problem, because the encryption key len eec may be long */
265 
266  if (pkt_len < (SMB_hdr_wct_offset + (19 * 2) + 40)) {
267 
268  alloc_len = SMB_hdr_wct_offset + (19 * 2) + 40;
269 
270  } else {
271 
272  alloc_len = pkt_len;
273 
274  }
275 
276  pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(alloc_len);
277 
278  if (pkt == NULL) {
279 
281  return(SMBlibE_BAD);
282 
283  }
284 
285  /* Now plug in the bits we need */
286 
287  memset(SMB_Hdr(pkt), 0, SMB_negp_len);
288  SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
290  SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
291  SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
292  SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
293  SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
294  *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
295 
296  SSVAL(SMB_Hdr(pkt), SMB_negp_bcc_offset, prots_len);
297 
298  /* Now copy the prot strings in with the right stuff */
299 
300  p = (char *)(SMB_Hdr(pkt) + SMB_negp_buf_offset);
301 
302  for (i = 0; Prots[i] != NULL; i++) {
303 
304  *p = SMBdialectID;
305  strcpy(p + 1, Prots[i]);
306  p = p + strlen(Prots[i]) + 2; /* Adjust len of p for null plus dialectID */
307 
308  }
309 
310  /* Now send the packet and sit back ... */
311 
312  if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
313 
314 #ifdef DEBUG
315  fprintf(stderr, "Error sending negotiate protocol\n");
316 #endif
317 
318  RFCNB_Free_Pkt(pkt);
319  SMBlib_errno = -SMBlibE_SendFailed; /* Failed, check lower layer errno */
320  return(SMBlibE_BAD);
321 
322  }
323 
324  /* Now get the response ... */
325 
326  if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, alloc_len) < 0) {
327 
328 #ifdef DEBUG
329  fprintf(stderr, "Error receiving response to negotiate\n");
330 #endif
331 
332  RFCNB_Free_Pkt(pkt);
333  SMBlib_errno = -SMBlibE_RecvFailed; /* Failed, check lower layer errno */
334  return(SMBlibE_BAD);
335 
336  }
337 
338  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
339 
340 #ifdef DEBUG
341  fprintf(stderr, "SMB_Negotiate failed with errorclass = %i, Error Code = %i\n",
344 #endif
345 
347  RFCNB_Free_Pkt(pkt);
349  return(SMBlibE_BAD);
350 
351  }
352 
353  if (SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset) == 0xFFFF) {
354 
355 #ifdef DEBUG
356  fprintf(stderr, "None of our protocols was accepted ... ");
357 #endif
358 
359  RFCNB_Free_Pkt(pkt);
361  return(SMBlibE_BAD);
362 
363  }
364 
365  /* Now, unpack the info from the response, if any and evaluate the proto */
366  /* selected. We must make sure it is one we like ... */
367 
368  Con_Handle -> prot_IDX = prot = SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset);
369  Con_Handle -> protocol = SMB_Figure_Protocol(Prots, prot);
370 
371  if (Con_Handle -> protocol == SMB_P_Unknown) { /* No good ... */
372 
373  RFCNB_Free_Pkt(pkt);
375  return(SMBlibE_BAD);
376 
377  }
378 
379  switch (CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset)) {
380 
381  case 0x01: /* No more info ... */
382 
383  break;
384 
385  case 13: /* Up to and including LanMan 2.1 */
386 
387  Con_Handle -> Security = SVAL(SMB_Hdr(pkt), SMB_negrLM_sec_offset);
388  Con_Handle -> encrypt_passwords = ((Con_Handle -> Security & SMB_sec_encrypt_mask) != 0x00);
389  Con_Handle -> Security = Con_Handle -> Security & SMB_sec_user_mask;
390 
391  Con_Handle -> max_xmit = SVAL(SMB_Hdr(pkt), SMB_negrLM_mbs_offset);
392  Con_Handle -> MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrLM_mmc_offset);
393  Con_Handle -> MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrLM_mnv_offset);
394  Con_Handle -> Raw_Support = SVAL(SMB_Hdr(pkt), SMB_negrLM_rm_offset);
395  Con_Handle -> SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrLM_sk_offset);
396  Con_Handle -> SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrLM_stz_offset);
397  Con_Handle -> Encrypt_Key_Len = SVAL(SMB_Hdr(pkt), SMB_negrLM_ekl_offset);
398 
399  p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset);
400  memcpy(Con_Handle->Encrypt_Key, p, 8);
401 
402  p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset + Con_Handle -> Encrypt_Key_Len);
403 
404  strncpy(p, Con_Handle -> Svr_PDom, sizeof(Con_Handle -> Svr_PDom) - 1);
405 
406  break;
407 
408  case 17: /* NT LM 0.12 and LN LM 1.0 */
409 
410  Con_Handle -> Security = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_sec_offset);
411  Con_Handle -> encrypt_passwords = ((Con_Handle -> Security & SMB_sec_encrypt_mask) != 0x00);
412  Con_Handle -> Security = Con_Handle -> Security & SMB_sec_user_mask;
413 
414  Con_Handle -> max_xmit = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mbs_offset);
415  Con_Handle -> MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mmc_offset);
416  Con_Handle -> MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mnv_offset);
417  Con_Handle -> MaxRaw = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mrs_offset);
418  Con_Handle -> SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_sk_offset);
419  Con_Handle -> SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_stz_offset);
420  Con_Handle -> Encrypt_Key_Len = CVAL(SMB_Hdr(pkt), SMB_negrNTLM_ekl_offset);
421 
422  p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset);
423  memcpy(Con_Handle->Encrypt_Key, p, 8);
424 
425  p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset + Con_Handle -> Encrypt_Key_Len);
426 
427  strncpy(p, Con_Handle -> Svr_PDom, sizeof(Con_Handle -> Svr_PDom) - 1);
428 
429  break;
430 
431  default:
432 
433 #ifdef DEBUG
434  fprintf(stderr, "Unknown NegProt response format ... Ignored\n");
435  fprintf(stderr, " wct = %i\n", CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset));
436 #endif
437 
438  break;
439  }
440 
441 #ifdef DEBUG
442  fprintf(stderr, "Protocol selected is: %i:%s\n", prot, Prots[prot]);
443 #endif
444 
445  RFCNB_Free_Pkt(pkt);
446  return(0);
447 
448 }
449 
450 /* Get our hostname */
451 
452 void SMB_Get_My_Name(char *name, int len)
453 
454 {
455  if (gethostname(name, len) < 0) { /* Error getting name */
456 
457  strncpy(name, "unknown", len);
458 
459  /* Should check the error */
460 
461 #ifdef DEBUG
462  fprintf(stderr, "gethostname in SMB_Get_My_Name returned error:");
463  perror("");
464 #endif
465 
466  } else {
467  char *address;
468  /* only keep the portion up to the first "." */
469  if (NULL != (address = strchr(name, '.'))) {
470  *address = '\0'; /* truncate at first '.' */
471  }
472  }
473 }
474 
475 /* Send a TCON to the remote server ... */
476 
478  SMB_Tree_Handle Tree_Handle,
479  const char *path,
480  const char *password,
481  const char *device)
482 
483 {
484  struct RFCNB_Pkt *pkt;
485  int param_len, pkt_len;
486  char *p;
487  SMB_Tree_Handle tree;
488 
489  /* Figure out how much space is needed for path, password, dev ... */
490 
491  if ((path == NULL) | (password == NULL) | (device == NULL)) {
492 
493 #ifdef DEBUG
494  fprintf(stderr, "Bad parameter passed to SMB_TreeConnect\n");
495 #endif
496 
498  return(NULL);
499 
500  }
501 
502  /* The + 2 is because of the \0 and the marker ... */
503 
504  param_len = strlen(path) + 2 + strlen(password) + 2 + strlen(device) + 2;
505 
506  /* The -1 accounts for the one byte smb_buf we have because some systems */
507  /* don't like char msg_buf[] */
508 
509  pkt_len = SMB_tcon_len + param_len;
510 
511  pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
512 
513  if (pkt == NULL) {
514 
516  return(NULL); /* Should handle the error */
517 
518  }
519 
520  /* Now allocate a tree for this to go into ... */
521 
522  if (Tree_Handle == NULL) {
523 
524  tree = (SMB_Tree_Handle)malloc(sizeof(struct SMB_Tree_Structure));
525 
526  if (tree == NULL) {
527 
528  RFCNB_Free_Pkt(pkt);
530  return(NULL);
531 
532  }
533  } else {
534 
535  tree = Tree_Handle;
536 
537  }
538 
539  tree -> next = tree -> prev = NULL;
540  tree -> con = Con_Handle;
541  strncpy(tree -> path, path, sizeof(tree -> path));
542  strncpy(tree -> device_type, device, sizeof(tree -> device_type));
543 
544  /* Now plug in the values ... */
545 
546  memset(SMB_Hdr(pkt), 0, SMB_tcon_len);
547  SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
548  *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtcon;
549  SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
550  SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
551  SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
552  SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
553  *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
554 
555  SSVAL(SMB_Hdr(pkt), SMB_tcon_bcc_offset, param_len);
556 
557  /* Now copy the param strings in with the right stuff */
558 
559  p = (char *)(SMB_Hdr(pkt) + SMB_tcon_buf_offset);
560  *p = SMBasciiID;
561  strcpy(p + 1, path);
562  p = p + strlen(path) + 2;
563  *p = SMBasciiID;
564  strcpy(p + 1, password);
565  p = p + strlen(password) + 2;
566  *p = SMBasciiID;
567  strcpy(p + 1, device);
568 
569  /* Now send the packet and sit back ... */
570 
571  if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
572 
573 #ifdef DEBUG
574  fprintf(stderr, "Error sending TCon request\n");
575 #endif
576 
577  if (Tree_Handle == NULL)
578  free(tree);
579  RFCNB_Free_Pkt(pkt);
581  return(NULL);
582 
583  }
584 
585  /* Now get the response ... */
586 
587  if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
588 
589 #ifdef DEBUG
590  fprintf(stderr, "Error receiving response to TCon\n");
591 #endif
592 
593  if (Tree_Handle == NULL)
594  free(tree);
595  RFCNB_Free_Pkt(pkt);
597  return(NULL);
598 
599  }
600 
601  /* Check out the response type ... */
602 
603  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
604 
605 #ifdef DEBUG
606  fprintf(stderr, "SMB_TCon failed with errorclass = %i, Error Code = %i\n",
609 #endif
610 
611  if (Tree_Handle == NULL)
612  free(tree);
614  RFCNB_Free_Pkt(pkt);
616  return(NULL);
617 
618  }
619 
620  tree -> tid = SVAL(SMB_Hdr(pkt), SMB_tconr_tid_offset);
621  tree -> mbs = SVAL(SMB_Hdr(pkt), SMB_tconr_mbs_offset);
622 
623 #ifdef DEBUG
624  fprintf(stderr, "TConn succeeded, with TID=%i, Max Xmit=%i\n",
625  tree -> tid, tree -> mbs);
626 #endif
627 
628  /* Now link the Tree to the Server Structure ... */
629 
630  if (Con_Handle -> first_tree == NULL) {
631 
632  Con_Handle -> first_tree = tree;
633  Con_Handle -> last_tree = tree;
634 
635  } else {
636 
637  Con_Handle -> last_tree -> next = tree;
638  tree -> prev = Con_Handle -> last_tree;
639  Con_Handle -> last_tree = tree;
640 
641  }
642 
643  RFCNB_Free_Pkt(pkt);
644  return(tree);
645 
646 }
647 
648 int SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, BOOL discard)
649 
650 {
651  struct RFCNB_Pkt *pkt;
652  int pkt_len;
653 
654  pkt_len = SMB_tdis_len;
655 
656  pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
657 
658  if (pkt == NULL) {
659 
661  return(SMBlibE_BAD); /* Should handle the error */
662 
663  }
664 
665  /* Now plug in the values ... */
666 
667  memset(SMB_Hdr(pkt), 0, SMB_tdis_len);
668  SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
669  *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtdis;
670  SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Tree_Handle -> con -> pid);
671  SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Tree_Handle -> con -> mid);
672  SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Tree_Handle -> con -> uid);
673  *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
674 
675  SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, Tree_Handle -> tid);
677 
678  /* Now send the packet and sit back ... */
679 
680  if (RFCNB_Send(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) {
681 
682 #ifdef DEBUG
683  fprintf(stderr, "Error sending TDis request\n");
684 #endif
685 
686  RFCNB_Free_Pkt(pkt);
688  return(SMBlibE_BAD);
689 
690  }
691 
692  /* Now get the response ... */
693 
694  if (RFCNB_Recv(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) {
695 
696 #ifdef DEBUG
697  fprintf(stderr, "Error receiving response to TCon\n");
698 #endif
699 
700  RFCNB_Free_Pkt(pkt);
702  return(SMBlibE_BAD);
703 
704  }
705 
706  /* Check out the response type ... */
707 
708  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
709 
710 #ifdef DEBUG
711  fprintf(stderr, "SMB_TDis failed with errorclass = %i, Error Code = %i\n",
714 #endif
715 
717  RFCNB_Free_Pkt(pkt);
719  return(SMBlibE_BAD);
720 
721  }
722 
723  Tree_Handle -> tid = 0xFFFF; /* Invalid TID */
724  Tree_Handle -> mbs = 0; /* Invalid */
725 
726 #ifdef DEBUG
727 
728  fprintf(stderr, "Tree disconnect successful ...\n");
729 
730 #endif
731 
732  /* What about the tree handle ? */
733 
734  if (discard == TRUE) { /* Unlink it and free it ... */
735 
736  if (Tree_Handle -> next == NULL)
737  Tree_Handle -> con -> first_tree = Tree_Handle -> prev;
738  else
739  Tree_Handle -> next -> prev = Tree_Handle -> prev;
740 
741  if (Tree_Handle -> prev == NULL)
742  Tree_Handle -> con -> last_tree = Tree_Handle -> next;
743  else
744  Tree_Handle -> prev -> next = Tree_Handle -> next;
745 
746  }
747 
748  RFCNB_Free_Pkt(pkt);
749  return(0);
750 
751 }
752 
753 /* Pick up the last LMBlib error ... */
754 
756 
757 {
758 
759  return(SMBlib_errno);
760 
761 }
762 
763 /* Pick up the last error returned in an SMB packet */
764 /* We will need macros to extract error class and error code */
765 
767 
768 {
769 
770  return(SMBlib_SMB_Error);
771 
772 }
773 
774 /* Pick up the error message associated with an error from SMBlib */
775 
776 /* Keep this table in sync with the message codes in smblib-common.h */
777 
778 static const char *SMBlib_Error_Messages[] = {
779 
780  "Request completed successfully.",
781  "Server returned a non-zero SMB Error Class and Code.",
782  "A lower layer protocol error occurred.",
783  "Function not yet implemented.",
784  "The protocol negotiated does not support the request.",
785  "No space available for operation.",
786  "One or more bad parameters passed.",
787  "None of the protocols we offered were accepted.",
788  "The attempt to send an SMB request failed. See protocol error info.",
789  "The attempt to get an SMB response failed. See protocol error info.",
790  "The logon request failed, but you were logged in as guest.",
791  "The attempt to call the remote server failed. See protocol error info.",
792  "The protocol dialect specified in a NegProt and accepted by the server is unknown.",
793  /* This next one simplifies error handling */
794  "No such error code.",
795  NULL
796 };
797 
798 void SMB_Get_Error_Msg(int msg, char *msgbuf, int len)
799 
800 {
801 
802  if (msg >= 0) {
803 
804  strncpy(msgbuf,
805  SMBlib_Error_Messages[msg>SMBlibE_NoSuchMsg?SMBlibE_NoSuchMsg:msg],
806  len - 1);
807  msgbuf[len - 1] = 0; /* Make sure it is a string */
808  } else { /* Add the lower layer message ... */
809 
810  char prot_msg[1024];
811 
812  msg = -msg; /* Make it positive */
813 
814  strncpy(msgbuf,
815  SMBlib_Error_Messages[msg>SMBlibE_NoSuchMsg?SMBlibE_NoSuchMsg:msg],
816  len - 1);
817 
818  msgbuf[len - 1] = 0; /* make sure it is a string */
819 
820  if (strlen(msgbuf) < len) { /* If there is space, put rest in */
821 
822  strncat(msgbuf, "\n\t", len - strlen(msgbuf));
823 
824  RFCNB_Get_Error(prot_msg, sizeof(prot_msg) - 1);
825 
826  strncat(msgbuf, prot_msg, len - strlen(msgbuf));
827 
828  }
829  }
830 
831 }
832 
#define SMB_negrNTLM_mbs_offset
Definition: smblib-priv.h:241
#define SMB_P_DOSLanMan1
#define SMBC_SUCCESS
Definition: smblib-common.h:52
void RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt)
Definition: rfcnb-util.c:231
#define SMBlibE_NoSuchMsg
int SMBlib_SMB_Error
Definition: smblib.c:36
#define SMBlibE_RecvFailed
#define SMBlibE_NegNoProt
int SMB_Get_Last_Error()
Definition: smblib-util.c:755
#define SMB_negrNTLM_buf_offset
Definition: smblib-priv.h:251
#define SMB_hdr_pid_offset
Definition: smblib-priv.h:194
int SMB_Get_Last_SMB_Err()
Definition: smblib-util.c:766
#define SMB_negrLM_sk_offset
Definition: smblib-priv.h:227
int SMB_Figure_Protocol(const char *dialects[], int prot_index)
Definition: smblib-util.c:202
int SMB_Get_Protocol(SMB_Handle_Type Con_Handle)
Definition: smblib-util.c:187
#define SMBtdis
Definition: smblib-priv.h:74
#define SMBdialectID
Definition: smblib-priv.h:132
#define CVAL(buf, pos)
Definition: byteorder.h:49
struct SMB_Tree_Structure * SMB_Tree_Handle
#define SMB_hdr_idf_offset
Definition: smblib-priv.h:177
#define SMB_tcon_buf_offset
Definition: smblib-priv.h:256
int i
Definition: membanger.c:49
#define SMB_DEF_IDF
Definition: smblib-priv.h:50
#define SMB_hdr_com_offset
Definition: smblib-priv.h:178
#define SMBlibE_BadParam
#define SMB_tcon_len
Definition: smblib-priv.h:257
#define SMB_hdr_wct_offset
Definition: smblib-priv.h:197
#define SIVAL(buf, pos, val)
Definition: byteorder.h:61
#define SMB_negrNTLM_sec_offset
Definition: smblib-priv.h:238
char * p
Definition: membanger.c:43
#define SMB_negrLM_ekl_offset
Definition: smblib-priv.h:231
#define SMB_P_Core
void SMB_Get_Error_Msg(int msg, char *msgbuf, int len)
Definition: smblib-util.c:798
#define SMB_negrLM_mbs_offset
Definition: smblib-priv.h:221
typedef BOOL(WINAPI *PFChangeServiceConfig2)(SC_HANDLE
#define SMB_negp_len
Definition: smblib-priv.h:209
#define SMBnegprot
Definition: smblib-priv.h:75
struct RFCNB_Pkt * RFCNB_Alloc_Pkt(int n)
Definition: rfcnb-util.c:202
int SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, BOOL discard)
Definition: smblib-util.c:648
#define SMB_negp_buf_offset
Definition: smblib-priv.h:208
#define SMB_negrLM_mnv_offset
Definition: smblib-priv.h:223
#define SMB_negrNTLM_mrs_offset
Definition: smblib-priv.h:242
#define SMB_negrNTLM_stz_offset
Definition: smblib-priv.h:247
#define SMB_negrNTLM_mnv_offset
Definition: smblib-priv.h:240
#define SMB_negrLM_buf_offset
Definition: smblib-priv.h:235
#define SMB_hdr_rcls_offset
Definition: smblib-priv.h:179
#define SMB_tconr_tid_offset
Definition: smblib-priv.h:260
#define SMB_negrCP_idx_offset
Definition: smblib-priv.h:215
#define SMB_P_LanMan2
#define SMB_negrLM_mmc_offset
Definition: smblib-priv.h:222
void SMB_Get_My_Name(char *name, int len)
Definition: smblib-util.c:452
#define SVAL(buf, pos)
Definition: byteorder.h:54
#define SMB_hdr_uid_offset
Definition: smblib-priv.h:195
#define SMB_P_CorePlus
#define SMB_negp_bcc_offset
Definition: smblib-priv.h:207
int SMBlib_errno
Definition: smblib.c:35
#define TRUE
Definition: std-includes.h:55
#define SSVAL(buf, pos, val)
Definition: byteorder.h:60
#define SMBlibE_SendFailed
#define SMBlibE_ProtUnknown
int SMB_Negotiate(SMB_Handle_Type Con_Handle, const char *Prots[])
Definition: smblib-util.c:239
int unsigned int const char *desc STUB void int len
Definition: stub_fd.cc:20
#define SMB_negrLM_sec_offset
Definition: smblib-priv.h:218
#define SMBtcon
Definition: smblib-priv.h:73
#define SMB_P_NT1
static pid_t pid
Definition: IcmpSquid.cc:35
int RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length)
Definition: session.c:183
struct RFCNB_Pkt * next
Definition: rfcnb-common.h:46
int RFCNB_Recv(void *Con_Handle, struct RFCNB_Pkt *Data, int Length)
Definition: session.c:235
#define SMB_hdr_mid_offset
Definition: smblib-priv.h:196
#define SMB_P_DOSLanMan2
int SMB_Types[]
Definition: smblib-util.c:42
#define SMB_tcon_bcc_offset
Definition: smblib-priv.h:255
#define SMB_negrNTLM_sk_offset
Definition: smblib-priv.h:243
#define SMB_negrNTLM_mmc_offset
Definition: smblib-priv.h:239
#define SMB_P_LanMan1
char * SMB_Prots[]
Definition: find_password.c:29
void RFCNB_Get_Error(char *buffer, int buf_len)
Definition: session.c:316
#define SMBasciiID
Definition: smblib-priv.h:134
#define SMB_hdr_tid_offset
Definition: smblib-priv.h:193
#define SMB_P_LanMan2_1
#define SMB_negrLM_stz_offset
Definition: smblib-priv.h:230
SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type Con_Handle, SMB_Tree_Handle Tree_Handle, const char *path, const char *password, const char *device)
Definition: smblib-util.c:477
#define SMB_tdis_len
Definition: smblib-priv.h:280
#define SMBlibE_NoSpace
#define SMBlibE_BAD
#define SMB_Hdr(p)
Definition: smblib-priv.h:163
#define SMBlibE_Remote
char Encrypt_Key[80]
#define SMB_tconr_mbs_offset
Definition: smblib-priv.h:259
#define SMB_sec_encrypt_mask
Definition: smblib-priv.h:220
#define SMB_negrLM_rm_offset
Definition: smblib-priv.h:224
#define SMB_negrNTLM_ekl_offset
Definition: smblib-priv.h:248
#define IVAL(buf, pos)
Definition: byteorder.h:55
#define SMB_P_Unknown
#define SMB_sec_user_mask
Definition: smblib-priv.h:219
#define NULL
Definition: types.h:166
#define SMB_hdr_err_offset
Definition: smblib-priv.h:181
#define free(a)
Definition: hash.c:31

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors