ntlm_smb_lm_auth.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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 /*
10  * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>
11  * Distributed freely under the terms of the GNU General Public License,
12  * version 2 or later. See the file COPYING for licensing details
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
22  */
23 
24 #include "squid.h"
25 #include "base64.h"
26 #include "compat/debug.h"
28 #include "ntlmauth/ntlmauth.h"
30 #include "rfcnb/rfcnb.h"
31 #include "smblib/smblib.h"
32 
33 #include <cassert>
34 #include <cctype>
35 #include <cerrno>
36 #include <csignal>
37 #include <cstdlib>
38 #include <cstring>
39 #include <ctime>
40 #if HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43 #if HAVE_GETOPT_H
44 #include <getopt.h>
45 #endif
46 #if HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49 
50 /************* CONFIGURATION ***************/
51 
52 #define DEAD_DC_RETRY_INTERVAL 30
53 
54 /************* END CONFIGURATION ***************/
55 
56 /* A couple of harmless helper macros */
57 #define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");
58 #ifdef __GNUC__
59 #define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
60 #define SEND3(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
61 #else
62 /* no gcc, no debugging. varargs macros are a gcc extension */
63 #define SEND2 printf
64 #define SEND3 printf
65 #endif
66 
67 typedef struct _dc dc;
68 struct _dc {
69  char *domain;
70  char *controller;
71  time_t dead; /* 0 if it's alive, otherwise time of death */
72  dc *next;
73 };
74 
75 /* local functions */
76 static void usage(void);
77 static void process_options(int argc, char *argv[]);
78 static const char * obtain_challenge(void);
79 static void manage_request(void);
80 static const char *make_challenge(char *domain, char *controller);
81 static char *ntlm_check_auth(ntlm_authenticate * auth, int auth_length);
82 static void dc_disconnect(void);
83 
84 #define ENCODED_PASS_LEN 24
85 #define MAX_USERNAME_LEN 255
86 #define MAX_DOMAIN_LEN 255
87 #define MAX_PASSWD_LEN 31
88 
89 static unsigned char challenge[NTLM_NONCE_LEN];
90 static unsigned char lmencoded_empty_pass[ENCODED_PASS_LEN],
94 static char credentials[MAX_USERNAME_LEN+MAX_DOMAIN_LEN+2]; /* we can afford to waste */
95 static char my_domain[100], my_domain_controller[100];
96 static char errstr[1001];
97 #if DEBUG
98 char error_messages_buffer[NTLM_BLOB_BUFFER_SIZE];
99 #endif
101 dc *controllers = nullptr;
104 char smb_error_buffer[1000];
105 
106 /* Disconnects from the DC. A reconnection will be done upon the next request
107  */
108 static void
110 {
111  if (handle != NULL)
112  SMB_Discon(handle, 0);
113  handle = nullptr;
114 }
115 
116 /* returns 0 on success, > 0 on failure */
117 static int
118 init_challenge(char *domain, char *domain_controller)
119 {
120  int smberr;
121 
122  if (handle != NULL) {
123  return 0;
124  }
125  debug("Connecting to server %s domain %s\n", domain_controller, domain);
126  handle = SMB_Connect_Server(nullptr, domain_controller, domain);
127  smberr = SMB_Get_Last_Error();
128  SMB_Get_Error_Msg(smberr, errstr, 1000);
129 
130  if (handle == NULL) { /* couldn't connect */
131  debug("Couldn't connect to SMB Server. Error:%s\n", errstr);
132  return 1;
133  }
134  if (SMB_Negotiate(handle, SMB_Prots) < 0) { /* An error */
135  debug("Error negotiating protocol with SMB Server\n");
136  SMB_Discon(handle, 0);
137  handle = nullptr;
138  return 2;
139  }
140  if (handle->Security == 0) { /* share-level security, unusable */
141  debug("SMB Server uses share-level security .. we need user security.\n");
142  SMB_Discon(handle, 0);
143  handle = nullptr;
144  return 3;
145  }
147  SMBencrypt((unsigned char *)"",challenge,lmencoded_empty_pass);
148  SMBNTencrypt((unsigned char *)"",challenge,ntencoded_empty_pass);
149  return 0;
150 }
151 
152 static const char *
153 make_challenge(char *domain, char *domain_controller)
154 {
155  /* trying to circumvent some strange problem with pointers in SMBLib */
156  /* Ugly as hell, but the lib is going to be dropped... */
157  strncpy(my_domain, domain, sizeof(my_domain)-1);
158  my_domain[sizeof(my_domain)-1] = '\0';
159  strncpy(my_domain_controller, domain_controller, sizeof(my_domain_controller)-1);
160  my_domain_controller[sizeof(my_domain_controller)-1] = '\0';
161 
163  return nullptr;
164  }
165 
166  ntlm_challenge chal;
167  uint32_t flags = NTLM_REQUEST_NON_NT_SESSION_KEY |
174 
175  size_t len = sizeof(chal) - sizeof(chal.payload) + le16toh(chal.target.maxlen);
176  // for lack of a good NTLM token size limit, allow up to what the helper input can be
177  // validations later will expect to be limited to that size.
178  static char b64buf[HELPER_INPUT_BUFFER-10]; /* 10 for other line fields, delimiters and terminator */
179  if (base64_encode_len(len) < sizeof(b64buf)-1) {
180  debug("base64 encoding of the token challenge will exceed %zu bytes", sizeof(b64buf));
181  return nullptr;
182  }
183 
184  struct base64_encode_ctx ctx;
185  base64_encode_init(&ctx);
186  size_t blen = base64_encode_update(&ctx, b64buf, len, reinterpret_cast<const uint8_t *>(&chal));
187  blen += base64_encode_final(&ctx, b64buf+blen);
188  b64buf[blen] = '\0';
189  return b64buf;
190 }
191 
192 /* returns NULL on failure, or a pointer to
193  * the user's credentials (domain\\username)
194  * upon success. WARNING. It's pointing to static storage.
195  * In case of problem sets as side-effect ntlm_errno to one of the
196  * codes defined in ntlm.h
197  */
198 static char *
199 ntlm_check_auth(ntlm_authenticate * auth, int auth_length)
200 {
201  char pass[MAX_PASSWD_LEN+1];
202  char *domain = credentials;
203  char *user;
204  lstring tmp;
205 
206  if (handle == NULL) { /*if null we aren't connected, but it shouldn't happen */
207  debug("Weird, we've been disconnected\n");
209  return nullptr;
210  }
211 
212  /* debug("fetching domain\n"); */
213  tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->domain, auth->flags);
214  if (tmp.str == NULL || tmp.l == 0) {
215  debug("No domain supplied. Returning no-auth\n");
217  return nullptr;
218  }
219  if (tmp.l > MAX_DOMAIN_LEN) {
220  debug("Domain string exceeds %d bytes, rejecting\n", MAX_DOMAIN_LEN);
222  return nullptr;
223  }
224  memcpy(domain, tmp.str, tmp.l);
225  user = domain + tmp.l;
226  *user = '\0';
227  ++user;
228 
229  /* debug("fetching user name\n"); */
230  tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->user, auth->flags);
231  if (tmp.str == NULL || tmp.l == 0) {
232  debug("No username supplied. Returning no-auth\n");
234  return nullptr;
235  }
236  if (tmp.l > MAX_USERNAME_LEN) {
237  debug("Username string exceeds %d bytes, rejecting\n", MAX_USERNAME_LEN);
239  return nullptr;
240  }
241  memcpy(user, tmp.str, tmp.l);
242  *(user + tmp.l) = '\0';
243 
244  // grab the *response blobs. these are fixed length 24 bytes of binary
245  const ntlmhdr *packet = &(auth->hdr);
246  {
247  const strhdr * str = &auth->lmresponse;
248 
249  int16_t len = le16toh(str->len);
250  int32_t offset = le32toh(str->offset);
251 
252  if (len != ENCODED_PASS_LEN || offset + len > auth_length || offset == 0) {
253  debug("LM response: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", auth_length, len, offset);
255  return nullptr;
256  }
257  tmp.str = (char *)packet + offset;
258  tmp.l = len;
259  }
260  if (tmp.l > MAX_PASSWD_LEN) {
261  debug("Password string exceeds %d bytes, rejecting\n", MAX_PASSWD_LEN);
263  return nullptr;
264  }
265 
266  /* Authenticating against the NT response doesn't seem to work... in SMB LM helper. */
267  memcpy(pass, tmp.str, tmp.l);
268  pass[min(MAX_PASSWD_LEN,tmp.l)] = '\0';
269 
270  debug("Empty LM pass detection: user: '%s', ours:'%s', his: '%s' (length: %d)\n",
271  user,lmencoded_empty_pass,tmp.str,tmp.l);
272  if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) {
273  fprintf(stderr,"Empty LM password supplied for user %s\\%s. "
274  "No-auth\n",domain,user);
276  return nullptr;
277  }
278 
279  /* still fetch the NT response and check validity against empty password */
280  {
281  const strhdr * str = &auth->ntresponse;
282  int16_t len = le16toh(str->len);
283  // NT response field may be absent. that is okay.
284  if (len != 0) {
285  int32_t offset = le32toh(str->offset);
286 
287  if (len != ENCODED_PASS_LEN || offset + len > auth_length || offset == 0) {
288  debug("NT response: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", auth_length, len, offset);
290  return nullptr;
291  }
292  tmp.str = (char *)packet + offset;
293  tmp.l = len;
294 
295  debug("Empty NT pass detection: user: '%s', ours:'%s', his: '%s' (length: %d)\n",
296  user,ntencoded_empty_pass,tmp.str,tmp.l);
297  if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) {
298  fprintf(stderr,"ERROR: Empty NT password supplied for user %s\\%s. No-auth\n", domain, user);
300  return nullptr;
301  }
302  }
303  }
304 
305  debug("checking domain: '%s', user: '%s', pass='%s'\n", domain, user, pass);
306 
307  const auto rv = SMB_Logon_Server(handle, user, pass, domain, 1);
308  debug("Login attempt had result %d\n", rv);
309 
310  switch (rv) {
311  case SMBlibE_Success:
313  break;
314  case SMBlibE_BAD:
316  return nullptr;
317  case SMBlibE_ProtLow:
318  case SMBlibE_NoSpace:
319  case SMBlibE_BadParam:
320  case SMBlibE_NegNoProt:
321  case SMBlibE_LowerLayer:
322  case SMBlibE_SendFailed:
323  case SMBlibE_RecvFailed:
324  case SMBlibE_ProtUnknown:
325  case SMBlibE_NoSuchMsg:
327  return nullptr;
328  case SMBlibE_NotImpl:
329  case SMBlibE_CallFailed:
330  case SMBlibE_Remote:
332  return nullptr;
333  case SMBlibE_GuestOnly:
335  return nullptr;
336  default:
338  return nullptr;
339  }
340 
341  *(user - 1) = '\\'; /* hack. Performing, but ugly. */
342 
343  debug("credentials: %s\n", credentials);
344  return credentials;
345 }
346 
347 static char got_timeout = 0;
350 extern "C" void
352 {
353  dc_disconnect();
354 }
355 
356 /*
357  * options:
358  * -b try load-balancing the domain-controllers
359  * -f fail-over to another DC if DC connection fails.
360  * DEPRECATED and VERBOSELY IGNORED. This is on by default now.
361  * -l last-ditch-mode
362  * domain\controller ...
363  */
364 char *my_program_name = nullptr;
365 
366 static void
368 {
369  fprintf(stderr,
370  "%s usage:\n%s [-b] [-f] [-d] [-l] domain\\controller [domain\\controller ...]\n"
371  "-b enables load-balancing among controllers\n"
372  "-f enables failover among controllers (DEPRECATED and always active)\n"
373  "-d enables debugging statements if DEBUG was defined at build-time.\n\n"
374  "You MUST specify at least one Domain Controller.\n"
375  "You can use either \\ or / as separator between the domain name \n"
376  "and the controller name\n",
378 }
379 
380 /* int debug_enabled=0; defined in libcompat */
381 
382 static void
383 process_options(int argc, char *argv[])
384 {
385  int opt, j, had_error = 0;
386  dc *new_dc = nullptr, *last_dc = nullptr;
387  while (-1 != (opt = getopt(argc, argv, "bfld"))) {
388  switch (opt) {
389  case 'b':
390  load_balance = 1;
391  break;
392  case 'f':
393  fprintf(stderr,
394  "WARNING. The -f flag is DEPRECATED and always active.\n");
395  break;
396  case 'd':
397  debug_enabled=1;
398  break;
399  default:
400  fprintf(stderr, "unknown option: -%c. Exiting\n", opt);
401  usage();
402  had_error = 1;
403  }
404  }
405  if (had_error)
406  exit(EXIT_FAILURE);
407  /* Okay, now begin filling controllers up */
408  /* we can avoid memcpy-ing, and just reuse argv[] */
409  for (j = optind; j < argc; ++j) {
410  char *d, *c;
411  /* d will not be freed in case of non-error. Since we don't reconfigure,
412  * it's going to live as long as the process anyways */
413  d = static_cast<char*>(xmalloc(strlen(argv[j]) + 1));
414  strcpy(d, argv[j]);
415  debug("Adding domain-controller %s\n", d);
416  if (NULL == (c = strchr(d, '\\')) && NULL == (c = strchr(d, '/'))) {
417  fprintf(stderr, "Couldn't grok domain-controller %s\n", d);
418  free(d);
419  continue;
420  }
421  /* more than one delimiter is not allowed */
422  if (NULL != strchr(c + 1, '\\') || NULL != strchr(c + 1, '/')) {
423  fprintf(stderr, "Broken domain-controller %s\n", d);
424  free(d);
425  continue;
426  }
427  *c= '\0';
428  ++c;
429  new_dc = static_cast<dc *>(xmalloc(sizeof(dc)));
430  if (!new_dc) {
431  fprintf(stderr, "Malloc error while parsing DC options\n");
432  free(d);
433  continue;
434  }
435  /* capitalize */
436  uc(c);
437  uc(d);
438  ++numcontrollers;
439  new_dc->domain = d;
440  new_dc->controller = c;
441  new_dc->dead = 0;
442  if (controllers == NULL) { /* first controller */
443  controllers = new_dc;
444  last_dc = new_dc;
445  } else {
446  last_dc->next = new_dc; /* can't be null */
447  last_dc = new_dc;
448  }
449  }
450  if (numcontrollers == 0) {
451  fprintf(stderr, "You must specify at least one domain-controller!\n");
452  usage();
453  exit(EXIT_FAILURE);
454  }
455  last_dc->next = controllers; /* close the queue, now it's circular */
456 }
457 
462 static const char *
464 {
465  int j = 0;
466  const char *ch = nullptr;
467  for (j = 0; j < numcontrollers; ++j) {
468  debug("obtain_challenge: selecting %s\\%s (attempt #%d)\n",
470  if (current_dc->dead != 0) {
471  if (time(NULL) - current_dc->dead >= DEAD_DC_RETRY_INTERVAL) {
472  /* mark helper as retry-worthy if it's so. */
473  debug("Reviving DC\n");
474  current_dc->dead = 0;
475  } else { /* skip it */
476  debug("Skipping it\n");
477  continue;
478  }
479  }
480  /* else branch. Here we KNOW that the DC is fine */
481  debug("attempting challenge retrieval\n");
483  debug("make_challenge retuned %p\n", ch);
484  if (ch) {
485  debug("Got it\n");
486  return ch; /* All went OK, returning */
487  }
488  /* Huston, we've got a problem. Take this DC out of the loop */
489  debug("Marking DC as DEAD\n");
490  current_dc->dead = time(NULL);
491  /* Try with the next */
492  debug("moving on to next controller\n");
494  }
495  /* all DCs failed. */
496  return nullptr;
497 }
498 
499 static void
501 {
502  ntlmhdr *fast_header;
503  char buf[NTLM_BLOB_BUFFER_SIZE];
504  char decoded[NTLM_BLOB_BUFFER_SIZE];
505  char *ch2, *cred = nullptr;
506 
507  if (fgets(buf, NTLM_BLOB_BUFFER_SIZE, stdin) == NULL) {
508  fprintf(stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno,
509  strerror(errno));
510  exit(EXIT_FAILURE); /* BIIG buffer */
511  }
512  debug("managing request\n");
513  ch2 = (char*)memchr(buf, '\n', NTLM_BLOB_BUFFER_SIZE); /* safer against overrun than strchr */
514  if (ch2) {
515  *ch2 = '\0'; /* terminate the string at newline. */
516  }
517  debug("ntlm authenticator. Got '%s' from Squid\n", buf);
518 
519  if (memcmp(buf, "KK ", 3) == 0) { /* authenticate-request */
520  /* figure out what we got */
521  struct base64_decode_ctx ctx;
522  base64_decode_init(&ctx);
523  size_t dstLen = 0;
524  int decodedLen = 0;
525  if (!base64_decode_update(&ctx, &dstLen, reinterpret_cast<uint8_t*>(decoded), strlen(buf)-3, buf+3) ||
526  !base64_decode_final(&ctx)) {
527  SEND("NA Packet format error, couldn't base64-decode");
528  return;
529  }
530  decodedLen = dstLen;
531 
532  if ((size_t)decodedLen < sizeof(ntlmhdr)) { /* decoding failure, return error */
533  SEND("NA Packet format error, truncated packet header.");
534  return;
535  }
536  /* fast-track-decode request type. */
537  fast_header = (ntlmhdr *) decoded;
538 
539  /* sanity-check: it IS a NTLMSSP packet, isn't it? */
540  if (ntlm_validate_packet(fast_header, NTLM_ANY) < 0) {
541  SEND("NA Broken authentication packet");
542  return;
543  }
544  switch (le32toh(fast_header->type)) {
545  case NTLM_NEGOTIATE:
546  SEND("NA Invalid negotiation request received");
547  return;
548  /* notreached */
549  case NTLM_CHALLENGE:
550  SEND("NA Got a challenge. We refuse to have our authority disputed");
551  return;
552  /* notreached */
553  case NTLM_AUTHENTICATE:
554  /* check against the DC */
555  signal(SIGALRM, timeout_during_auth);
556  alarm(30);
557  cred = ntlm_check_auth((ntlm_authenticate *) decoded, decodedLen);
558  alarm(0);
559  signal(SIGALRM, SIG_DFL);
560  if (got_timeout != 0) {
561  fprintf(stderr, "ntlm-auth[%ld]: Timeout during authentication.\n", (long)getpid());
562  SEND("BH Timeout during authentication");
563  got_timeout = 0;
564  return;
565  }
566  if (cred == NULL) {
567  int smblib_err, smb_errorclass, smb_errorcode, nb_error;
568  if (ntlm_errno == NtlmError::LoginEror) { /* hackish */
569  SEND("NA Logon Failure");
570  return;
571  }
572  /* there was an error. We have two errno's to look at.
573  * libntlmssp's erno is insufficient, we'll have to look at
574  * the actual SMB library error codes, to actually figure
575  * out what's happening. The thing has braindamaged interfacess..*/
576  smblib_err = SMB_Get_Last_Error();
577  smb_errorclass = SMBlib_Error_Class(SMB_Get_Last_SMB_Err());
578  smb_errorcode = SMBlib_Error_Code(SMB_Get_Last_SMB_Err());
579  nb_error = RFCNB_Get_Last_Error();
580  debug("No creds. SMBlib error %d, SMB error class %d, SMB error code %d, NB error %d\n",
581  smblib_err, smb_errorclass, smb_errorcode, nb_error);
582  /* Should I use smblib_err? Actually it seems I can do as well
583  * without it.. */
584  if (nb_error != 0) { /* netbios-level error */
585  SEND("BH NetBios error!");
586  fprintf(stderr, "NetBios error code %d (%s)\n", nb_error,
587  RFCNB_Error_Strings[abs(nb_error)]);
588  return;
589  }
590  switch (smb_errorclass) {
591  case SMBC_SUCCESS:
592  debug("Huh? Got a SMB success code but could check auth..");
593  SEND("NA Authentication failed");
594  return;
595  case SMBC_ERRDOS:
596  /*this is the most important one for errors */
597  debug("DOS error\n");
598  switch (smb_errorcode) {
599  /* two categories matter to us: those which could be
600  * server errors, and those which are auth errors */
601  case SMBD_noaccess: /* 5 */
602  SEND("NA Access denied");
603  return;
604  case SMBD_badformat:
605  SEND("NA bad format in authentication packet");
606  return;
607  case SMBD_badaccess:
608  SEND("NA Bad access request");
609  return;
610  case SMBD_baddata:
611  SEND("NA Bad Data");
612  return;
613  default:
614  SEND("BH DOS Error");
615  return;
616  }
617  case SMBC_ERRSRV: /* server errors */
618  debug("Server error");
619  switch (smb_errorcode) {
620  /* mostly same as above */
621  case SMBV_badpw:
622  SEND("NA Bad password");
623  return;
624  case SMBV_access:
625  SEND("NA Server access error");
626  return;
627  default:
628  SEND("BH Server Error");
629  return;
630  }
631  case SMBC_ERRHRD: /* hardware errors don't really matter */
632  SEND("BH Domain Controller Hardware error");
633  return;
634  case SMBC_ERRCMD:
635  SEND("BH Domain Controller Command Error");
636  return;
637  }
638  SEND("BH unknown internal error.");
639  return;
640  }
641 
642  lc(cred); /* let's lowercase them for our convenience */
643  SEND2("AF %s", cred);
644  return;
645  default:
646  SEND("BH unknown authentication packet type");
647  return;
648  }
649  /* notreached */
650  return;
651  }
652  if (memcmp(buf, "YR", 2) == 0) { /* refresh-request */
653  dc_disconnect();
654  const char *ch = obtain_challenge();
655  /* Robert says we can afford to wait forever. I'll trust him on this
656  * one */
657  while (ch == NULL) {
658  sleep(30);
659  ch = obtain_challenge();
660  }
661  SEND2("TT %s", ch);
662  return;
663  }
664  SEND("BH Helper detected protocol error");
665  return;
666  /********* END ********/
667 
668 }
669 
670 int
671 main(int argc, char *argv[])
672 {
673  debug("%s " VERSION " " SQUID_BUILD_INFO " starting up...\n", argv[0]);
674 
675  my_program_name = argv[0];
676  process_options(argc, argv);
677 
678  debug("options processed OK\n");
679 
680  /* initialize FDescs */
681  setbuf(stdout, nullptr);
682  setbuf(stderr, nullptr);
683 
684  /* select the first domain controller we're going to use */
686  if (load_balance != 0 && numcontrollers > 1) {
687  int n;
688  pid_t pid = getpid();
689  n = pid % numcontrollers;
690  debug("load balancing. Selected controller #%d\n", n);
691  while (n > 0) {
693  --n;
694  }
695  }
696  while (1) {
697  manage_request();
698  }
699  /* notreached */
700  return EXIT_SUCCESS;
701 }
702 
#define SMBlibE_NoSuchMsg
static const char * make_challenge(char *domain, char *controller)
int SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle)
Definition: smblib.c:577
char Encrypt_Key[80]
static char my_domain[100]
#define SMBC_ERRHRD
Definition: smblib-common.h:55
dc * next
#define SMBlibE_NegNoProt
#define base64_encode_len(length)
Definition: base64.h:169
static void usage(void)
#define xmalloc
#define SEND(X)
int numcontrollers
void debug(const char *format,...)
Definition: debug.cc:19
static char got_timeout
char * str
Definition: ntlmauth.h:57
void base64_decode_init(struct base64_decode_ctx *ctx)
Definition: base64.c:54
#define NTLM_BLOB_BUFFER_SIZE
Definition: ntlmauth.h:21
#define NTLM_NEGOTIATE_ALWAYS_SIGN
Definition: ntlmauth.h:115
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
Definition: base64.c:308
char * controller
char payload[256]
Definition: ntlmauth.h:145
#define NTLM_NEGOTIATE
Definition: ntlmauth.h:69
#define SMBV_badpw
Definition: smblib-common.h:91
#define SMBC_ERRSRV
Definition: smblib-common.h:54
int SMB_Get_Last_Error()
Definition: smblib-util.c:755
static char * ntlm_check_auth(ntlm_authenticate *auth, int auth_length)
char smb_error_buffer[1000]
static const char * obtain_challenge(void)
#define SMBlibE_LowerLayer
#define ENCODED_PASS_LEN
#define SMBlibE_BadParam
static void process_options(int argc, char *argv[])
NtlmError
Definition: ntlmauth.h:31
#define le16toh(x)
static void dc_disconnect(void)
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition: getopt.c:62
#define NTLM_NEGOTIATE_ASCII
Definition: ntlmauth.h:104
#define SMBlibE_GuestOnly
char * strerror(int ern)
Definition: strerror.c:22
static pid_t pid
Definition: IcmpSquid.cc:34
#define SMBV_access
Definition: smblib-common.h:93
#define SMBlibE_CallFailed
int main(int argc, char *argv[])
#define DEAD_DC_RETRY_INTERVAL
#define NTLM_NEGOTIATE_USE_NTLM
Definition: ntlmauth.h:111
#define SMBD_badaccess
Definition: smblib-common.h:77
#define SMBC_ERRCMD
Definition: smblib-common.h:56
int base64_decode_final(struct base64_decode_ctx *ctx)
Definition: base64.c:159
#define NULL
Definition: types.h:145
static unsigned char lmencoded_empty_pass[ENCODED_PASS_LEN]
#define NTLM_AUTHENTICATE
Definition: ntlmauth.h:71
void lc(char *string)
#define SMBlib_Error_Class(p)
Definition: smblib-common.h:44
int SMB_Get_Last_SMB_Err()
Definition: smblib-util.c:766
int16_t len
Definition: ntlmauth.h:49
void SMB_Get_Error_Msg(int msg, char *msgbuf, int len)
Definition: smblib-util.c:798
SMB_Handle_Type handle
void uc(char *string)
int32_t l
Definition: ntlmauth.h:56
#define le32toh(x)
#define SMBlibE_NotImpl
#define SEND2
int debug_enabled
Definition: debug.cc:13
dc * controllers
char * SMB_Prots[]
Definition: find_password.c:29
uint32_t flags
Definition: ntlmauth.h:177
int base64_decode_update(struct base64_decode_ctx *ctx, size_t *dst_length, uint8_t *dst, size_t src_length, const char *src)
Definition: base64.c:129
#define MAX_DOMAIN_LEN
#define NTLM_NEGOTIATE_USE_LM
Definition: ntlmauth.h:109
#define MAX_PASSWD_LEN
#define NTLM_CHALLENGE
Definition: ntlmauth.h:70
time_t dead
char protocol_pedantic
#define SMBC_ERRDOS
Definition: smblib-common.h:53
void base64_encode_init(struct base64_encode_ctx *ctx)
Definition: base64.c:232
static char errstr[1001]
static unsigned char ntencoded_empty_pass[ENCODED_PASS_LEN]
#define MAX_USERNAME_LEN
static void manage_request(void)
char * domain
static int init_challenge(char *domain, char *domain_controller)
const char * RFCNB_Error_Strings[]
Definition: rfcnb-util.c:47
strhdr target
Definition: ntlmauth.h:140
int RFCNB_Get_Last_Error(void)
Definition: session.c:329
dc * current_dc
char * my_program_name
#define SMBD_badformat
Definition: smblib-common.h:76
#define HELPER_INPUT_BUFFER
Definition: UserRequest.cc:24
#define SMBlibE_ProtUnknown
SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, const char *server, const char *NTdomain)
Definition: smblib.c:101
int32_t type
Definition: ntlmauth.h:78
void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
Definition: smbencrypt.c:67
void timeout_during_auth(int)
static char credentials[MAX_USERNAME_LEN+MAX_DOMAIN_LEN+2]
#define SMBC_SUCCESS
Definition: smblib-common.h:52
int optind
Definition: getopt.c:48
static NtlmError ntlm_errno
int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, char *PassWord, const char *NtDomain, int PreCrypted)
Definition: smblib.c:332
#define NTLM_ANY
Definition: ntlmauth.h:68
#define SMBlibE_Remote
#define SMBlibE_ProtLow
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
Definition: base64.c:265
#define SMBD_baddata
Definition: smblib-common.h:78
#define SMBlibE_SendFailed
NtlmError ntlm_validate_packet(const ntlmhdr *hdr, const int32_t type)
Definition: ntlmauth.cc:67
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
Definition: smbencrypt.c:140
int32_t offset
Definition: ntlmauth.h:51
#define VERSION
lstring ntlm_fetch_string(const ntlmhdr *packet, const int32_t packet_size, const strhdr *str, const uint32_t flags)
Definition: ntlmauth.cc:98
int16_t maxlen
Definition: ntlmauth.h:50
int SMB_Negotiate(SMB_Handle_Type Con_Handle, const char *Prots[])
Definition: smblib-util.c:239
void ntlm_make_challenge(ntlm_challenge *ch, const char *domain, const char *, const char *challenge_nonce, const int challenge_nonce_len, const uint32_t flags)
Definition: ntlmauth.cc:209
#define SMBlibE_Success
#define SMBlibE_BAD
static char my_domain_controller[100]
const A & min(A const &lhs, A const &rhs)
char load_balance
#define NTLM_CHALLENGE_TARGET_IS_DOMAIN
Definition: ntlmauth.h:133
#define SMBlib_Error_Code(p)
Definition: smblib-common.h:48
#define NTLM_REQUEST_NON_NT_SESSION_KEY
Definition: ntlmauth.h:28
#define SMBlibE_RecvFailed
#define NTLM_NONCE_LEN
Definition: ntlmauth.h:130
#define SMBlibE_NoSpace
static unsigned char challenge[NTLM_NONCE_LEN]
#define SMBD_noaccess
Definition: smblib-common.h:70

 

Introduction

Documentation

Support

Miscellaneous