ntlm_sspi_auth.cc
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 /*
10  * ntlm_sspi_auth: helper for NTLM Authentication for Squid Cache
11  *
12  * (C)2002,2005 Guido Serassio - Acme Consulting S.r.l.
13  *
14  * Authors:
15  * Guido Serassio <guido.serassio@acmeconsulting.it>
16  * Acme Consulting S.r.l., Italy <http://www.acmeconsulting.it>
17  *
18  * With contributions from others mentioned in the change history section
19  * below.
20  *
21  * Based on previous work of Francesco Chemolli and Robert Collins.
22  *
23  * Dependencies: Windows NT4 SP4 and later.
24  *
25  * This program is free software; you can redistribute it and/or modify
26  * it under the terms of the GNU General Public License as published by
27  * the Free Software Foundation; either version 2 of the License, or
28  * (at your option) any later version.
29  *
30  * This program is distributed in the hope that it will be useful,
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33  * GNU General Public License for more details.
34  *
35  * You should have received a copy of the GNU General Public License
36  * along with this program; if not, write to the Free Software
37  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
38  *
39  * History:
40  *
41  * Version 1.22
42  * 29-10-2005 Guido Serassio
43  * Updated for Negotiate auth support.
44  * Version 1.21
45  * 21-02-2004 Guido Serassio
46  * Removed control of use of NTLM NEGOTIATE packet from
47  * command line, now the support is automatic.
48  * Version 1.20
49  * 30-11-2003 Guido Serassio
50  * Added support for NTLM local calls.
51  * Added control of use of NTLM NEGOTIATE packet from
52  * command line.
53  * Updated documentation.
54  * Version 1.10
55  * 07-09-2003 Guido Serassio
56  * Now is true NTLM authenticator.
57  * More debug info.
58  * Updated documentation.
59  * Version 1.0
60  * 29-06-2002 Guido Serassio
61  * First release.
62  *
63  *
64  */
65 
66 /************* CONFIGURATION ***************/
67 
68 #define FAIL_DEBUG 0
69 
70 /************* END CONFIGURATION ***************/
71 
72 //typedef unsigned char uchar;
73 
74 #include "squid.h"
75 #include "base64.h"
77 #include "ntlmauth/ntlmauth.h"
79 #include "sspwin32.h"
80 #include "util.h"
81 
82 #include <windows.h>
83 #include <sspi.h>
84 #include <security.h>
85 #if HAVE_CTYPE_H
86 #include <ctype.h>
87 #endif
88 #if HAVE_GETOPT_H
89 #include <getopt.h>
90 #endif
91 #include <lm.h>
92 #include <ntsecapi.h>
93 
95 static int have_challenge;
100 
101 #if FAIL_DEBUG
102 int fail_debug_enabled = 0;
103 #endif
104 
105 /* returns 1 on success, 0 on failure */
106 int
107 Valid_Group(char *UserName, char *Group)
108 {
109  int result = FALSE;
110  WCHAR wszUserName[UNLEN+1]; // Unicode user name
111  WCHAR wszGroup[GNLEN+1]; // Unicode Group
112 
113  LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
114  LPLOCALGROUP_USERS_INFO_0 pTmpBuf;
115  DWORD dwLevel = 0;
116  DWORD dwFlags = LG_INCLUDE_INDIRECT;
117  DWORD dwPrefMaxLen = -1;
118  DWORD dwEntriesRead = 0;
119  DWORD dwTotalEntries = 0;
120  NET_API_STATUS nStatus;
121  DWORD i;
122  DWORD dwTotalCount = 0;
123 
124  /* Convert ANSI User Name and Group to Unicode */
125 
126  MultiByteToWideChar(CP_ACP, 0, UserName,
127  strlen(UserName) + 1, wszUserName,
128  sizeof(wszUserName) / sizeof(wszUserName[0]));
129  MultiByteToWideChar(CP_ACP, 0, Group,
130  strlen(Group) + 1, wszGroup, sizeof(wszGroup) / sizeof(wszGroup[0]));
131 
132  /*
133  * Call the NetUserGetLocalGroups function
134  * specifying information level 0.
135  *
136  * The LG_INCLUDE_INDIRECT flag specifies that the
137  * function should also return the names of the local
138  * groups in which the user is indirectly a member.
139  */
140  nStatus = NetUserGetLocalGroups(NULL,
141  wszUserName,
142  dwLevel,
143  dwFlags,
144  (LPBYTE *) & pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries);
145  /*
146  * If the call succeeds,
147  */
148  if (nStatus == NERR_Success) {
149  if ((pTmpBuf = pBuf) != NULL) {
150  for (i = 0; i < dwEntriesRead; ++i) {
151  if (pTmpBuf == NULL) {
152  result = FALSE;
153  break;
154  }
155  if (wcscmp(pTmpBuf->lgrui0_name, wszGroup) == 0) {
156  result = TRUE;
157  break;
158  }
159  ++pTmpBuf;
160  ++dwTotalCount;
161  }
162  }
163  } else
164  result = FALSE;
165  /*
166  * Free the allocated memory.
167  */
168  if (pBuf != NULL)
169  NetApiBufferFree(pBuf);
170  return result;
171 }
172 
173 char * AllocStrFromLSAStr(LSA_UNICODE_STRING LsaStr)
174 {
175  size_t len;
176  static char * target;
177 
178  len = LsaStr.Length/sizeof(WCHAR) + 1;
179 
180  /* allocate buffer for str + null termination */
181  safe_free(target);
182  target = (char *)xmalloc(len);
183  if (target == NULL)
184  return NULL;
185 
186  /* copy unicode buffer */
187  WideCharToMultiByte(CP_ACP, 0, LsaStr.Buffer, LsaStr.Length, target, len, NULL, NULL );
188 
189  /* add null termination */
190  target[len-1] = '\0';
191  return target;
192 }
193 
194 char * GetDomainName(void)
195 
196 {
197  LSA_HANDLE PolicyHandle;
198  LSA_OBJECT_ATTRIBUTES ObjectAttributes;
199  NTSTATUS status;
200  PPOLICY_PRIMARY_DOMAIN_INFO ppdiDomainInfo;
201  PWKSTA_INFO_100 pwkiWorkstationInfo;
202  DWORD netret;
203  char * DomainName = NULL;
204 
205  /*
206  * Always initialize the object attributes to all zeroes.
207  */
208  memset(&ObjectAttributes, '\0', sizeof(ObjectAttributes));
209 
210  /*
211  * You need the local workstation name. Use NetWkstaGetInfo at level
212  * 100 to retrieve a WKSTA_INFO_100 structure.
213  *
214  * The wki100_computername field contains a pointer to a UNICODE
215  * string containing the local computer name.
216  */
217  netret = NetWkstaGetInfo(NULL, 100, (LPBYTE *)&pwkiWorkstationInfo);
218  if (netret == NERR_Success) {
219  /*
220  * We have the workstation name in:
221  * pwkiWorkstationInfo->wki100_computername
222  *
223  * Next, open the policy object for the local system using
224  * the LsaOpenPolicy function.
225  */
226  status = LsaOpenPolicy(
227  NULL,
228  &ObjectAttributes,
229  GENERIC_READ | POLICY_VIEW_LOCAL_INFORMATION,
230  &PolicyHandle
231  );
232 
233  /*
234  * Error checking.
235  */
236  if (status) {
237  debug("OpenPolicy Error: %ld\n", status);
238  } else {
239 
240  /*
241  * You have a handle to the policy object. Now, get the
242  * domain information using LsaQueryInformationPolicy.
243  */
244  status = LsaQueryInformationPolicy(PolicyHandle,
245  PolicyPrimaryDomainInformation,
246  (void **)&ppdiDomainInfo);
247  if (status) {
248  debug("LsaQueryInformationPolicy Error: %ld\n", status);
249  } else {
250 
251  /* Get name in useable format */
252  DomainName = AllocStrFromLSAStr(ppdiDomainInfo->Name);
253 
254  /*
255  * Check the Sid pointer, if it is null, the
256  * workstation is either a stand-alone computer
257  * or a member of a workgroup.
258  */
259  if (ppdiDomainInfo->Sid) {
260 
261  /*
262  * Member of a domain. Display it in debug mode.
263  */
264  debug("Member of Domain %s\n",DomainName);
265  } else {
266  DomainName = NULL;
267  }
268  }
269  }
270 
271  /*
272  * Clean up all the memory buffers created by the LSA and
273  * Net* APIs.
274  */
275  NetApiBufferFree(pwkiWorkstationInfo);
276  LsaFreeMemory((LPVOID)ppdiDomainInfo);
277  } else
278  debug("NetWkstaGetInfo Error: %ld\n", netret);
279  return DomainName;
280 }
281 
282 /*
283  * Fills auth with the user's credentials.
284  *
285  * In case of problem returns one of the
286  * codes defined in libntlmauth/ntlmauth.h
287  */
288 int
289 ntlm_check_auth(ntlm_authenticate * auth, char *user, char *domain, int auth_length)
290 {
291  int x;
292  int rv;
293  char credentials[DNLEN+UNLEN+2]; /* we can afford to waste */
294 
295  if (!NTLM_LocalCall) {
296 
297  user[0] = '\0';
298  domain[0] = '\0';
299  x = ntlm_unpack_auth(auth, user, domain, auth_length);
300 
301  if (x != NTLM_ERR_NONE)
302  return x;
303 
304  if (domain[0] == '\0') {
305  debug("No domain supplied. Returning no-auth\n");
306  return NTLM_BAD_REQUEST;
307  }
308  if (user[0] == '\0') {
309  debug("No username supplied. Returning no-auth\n");
310  return NTLM_BAD_REQUEST;
311  }
312  debug("checking domain: '%s', user: '%s'\n", domain, user);
313 
314  } else
315  debug("checking local user\n");
316 
317  snprintf(credentials, DNLEN+UNLEN+2, "%s\\%s", domain, user);
318 
319  rv = SSP_ValidateNTLMCredentials(auth, auth_length, credentials);
320 
321  debug("Login attempt had result %d\n", rv);
322 
323  if (!rv) { /* failed */
324  return NTLM_SSPI_ERROR;
325  }
326 
327  if (UseAllowedGroup) {
328  if (!Valid_Group(credentials, NTAllowedGroup)) {
329  debug("User %s not in allowed Group %s\n", credentials, NTAllowedGroup);
330  return NTLM_BAD_NTGROUP;
331  }
332  }
333  if (UseDisallowedGroup) {
334  if (Valid_Group(credentials, NTDisAllowedGroup)) {
335  debug("User %s is in denied Group %s\n", credentials, NTDisAllowedGroup);
336  return NTLM_BAD_NTGROUP;
337  }
338  }
339 
340  debug("credentials: %s\n", credentials);
341  return NTLM_ERR_NONE;
342 }
343 
344 void
345 helperfail(const char *reason)
346 {
347 #if FAIL_DEBUG
348  fail_debug_enabled =1;
349 #endif
350  SEND_BH(reason);
351 }
352 
353 /*
354  options:
355  -d enable debugging.
356  -v enable verbose NTLM packet debugging.
357  -A can specify a Windows Local Group name allowed to authenticate.
358  -D can specify a Windows Local Group name not allowed to authenticate.
359  */
361 
362 void
364 {
365  fprintf(stderr,
366  "Usage: %s [-d] [-v] [-A|D LocalUserGroup] [-h]\n"
367  " -d enable debugging.\n"
368  " -v enable verbose NTLM packet debugging.\n"
369  " -A specify a Windows Local Group name allowed to authenticate\n"
370  " -D specify a Windows Local Group name not allowed to authenticate\n"
371  " -h this message\n\n",
373 }
374 
375 void
376 process_options(int argc, char *argv[])
377 {
378  int opt, had_error = 0;
379 
380  opterr =0;
381  while (-1 != (opt = getopt(argc, argv, "hdvA:D:"))) {
382  switch (opt) {
383  case 'A':
386  UseAllowedGroup = 1;
387  break;
388  case 'D':
391  UseDisallowedGroup = 1;
392  break;
393  case 'd':
394  debug_enabled = 1;
395  break;
396  case 'v':
397  debug_enabled = 1;
399  break;
400  case 'h':
401  usage();
402  exit(EXIT_SUCCESS);
403  case '?':
404  opt = optopt;
405  /* fall thru to default */
406  default:
407  fprintf(stderr, "unknown option: -%c. Exiting\n", opt);
408  usage();
409  had_error = 1;
410  }
411  }
412  if (had_error)
413  exit(EXIT_FAILURE);
414 }
415 
416 static bool
417 token_decode(size_t *decodedLen, uint8_t decoded[], const char *buf)
418 {
419  struct base64_decode_ctx ctx;
420  base64_decode_init(&ctx);
421  if (!base64_decode_update(&ctx, decodedLen, decoded, strlen(buf), reinterpret_cast<const uint8_t*>(buf)) ||
422  !base64_decode_final(&ctx)) {
423  SEND_BH("message=\"base64 decode failed\"");
424  fprintf(stderr, "ERROR: base64 decoding failed for: '%s'\n", buf);
425  return false;
426  }
427  return true;
428 }
429 
430 int
432 {
433  ntlmhdr *fast_header;
434  char buf[HELPER_INPUT_BUFFER];
435  uint8_t decoded[HELPER_INPUT_BUFFER];
436  size_t decodedLen = 0;
437  char helper_command[3];
438  int oversized = 0;
439  char * ErrorMessage;
440  static ntlm_negotiate local_nego;
441  char domain[DNLEN+1];
442  char user[UNLEN+1];
443 
444  /* NP: for some reason this helper sometimes needs to accept
445  * from clients that send no negotiate packet. */
446  if (memcpy(local_nego.hdr.signature, "NTLMSSP", 8) != 0) {
447  memset(&local_nego, 0, sizeof(ntlm_negotiate)); /* reset */
448  memcpy(local_nego.hdr.signature, "NTLMSSP", 8); /* set the signature */
449  local_nego.hdr.type = le32toh(NTLM_NEGOTIATE); /* this is a challenge */
454  }
455 
456  do {
457  if (fgets(buf, sizeof(buf), stdin) == NULL)
458  return 0;
459 
460  char *c = static_cast<char*>(memchr(buf, '\n', sizeof(buf)));
461  if (c) {
462  if (oversized) {
463  helperfail("messge=\"illegal request received\"");
464  fprintf(stderr, "Illegal request received: '%s'\n", buf);
465  return 1;
466  }
467  *c = '\0';
468  } else {
469  fprintf(stderr, "No newline in '%s'\n", buf);
470  oversized = 1;
471  continue;
472  }
473  } while (false);
474 
475  if ((strlen(buf) > 3) && NTLM_packet_debug_enabled) {
476  if (!token_decode(&decodedLen, decoded, buf+3))
477  return 1;
478  strncpy(helper_command, buf, 2);
479  debug("Got '%s' from Squid with data:\n", helper_command);
480  hex_dump(reinterpret_cast<unsigned char*>(decoded), decodedLen);
481  } else
482  debug("Got '%s' from Squid\n", buf);
483  if (memcmp(buf, "YR", 2) == 0) { /* refresh-request */
484  /* figure out what we got */
485  if (strlen(buf) > 3) {
486  if (!decodedLen /* already decoded*/ && !token_decode(&decodedLen, decoded, buf+3))
487  return 1;
488  } else {
489  debug("Negotiate packet not supplied - self generated\n");
490  memcpy(decoded, &local_nego, sizeof(local_nego));
491  decodedLen = sizeof(local_nego);
492  }
493  if ((size_t)decodedLen < sizeof(ntlmhdr)) { /* decoding failure, return error */
494  SEND_ERR("message=\"Packet format error\"");
495  return 1;
496  }
497  /* fast-track-decode request type. */
498  fast_header = (struct _ntlmhdr *) decoded;
499 
500  /* sanity-check: it IS a NTLMSSP packet, isn't it? */
501  if (ntlm_validate_packet(fast_header, NTLM_ANY) != NTLM_ERR_NONE) {
502  SEND_ERR("message=\"Broken authentication packet\"");
503  return 1;
504  }
505  switch (fast_header->type) {
506  case NTLM_NEGOTIATE: {
507  /* Obtain challenge against SSPI */
508  debug("attempting SSPI challenge retrieval\n");
509  char *c = (char *) SSP_MakeChallenge((ntlm_negotiate *) decoded, decodedLen);
510  if (c) {
511  SEND_TT(c);
513  if (!token_decode(&decodedLen, decoded, c))
514  return 1;
515  debug("send 'TT' to squid with data:\n");
516  hex_dump(reinterpret_cast<unsigned char*>(decoded), decodedLen);
517  if (NTLM_LocalCall) {
518  debug("NTLM Local Call detected\n");
519  }
520  }
521  have_challenge = 1;
522  } else
523  helperfail("message=\"can't obtain challenge\"");
524 
525  return 1;
526  }
527  /* notreached */
528  case NTLM_CHALLENGE:
529  SEND_ERR("message=\"Got a challenge. We refuse to have our authority disputed\"");
530  return 1;
531  /* notreached */
532  case NTLM_AUTHENTICATE:
533  SEND_ERR("message=\"Got authentication request instead of negotiate request\"");
534  return 1;
535  /* notreached */
536  default:
537  helperfail("message=\"unknown refresh-request packet type\"");
538  return 1;
539  }
540  return 1;
541  }
542  if (memcmp(buf, "KK ", 3) == 0) { /* authenticate-request */
543  if (!have_challenge) {
544  helperfail("message=\"invalid challenge\"");
545  return 1;
546  }
547  /* figure out what we got */
548  if (!decodedLen /* already decoded*/ && !token_decode(&decodedLen, decoded, buf+3))
549  return 1;
550 
551  if ((size_t)decodedLen < sizeof(ntlmhdr)) { /* decoding failure, return error */
552  SEND_ERR("message=\"Packet format error\"");
553  return 1;
554  }
555  /* fast-track-decode request type. */
556  fast_header = (struct _ntlmhdr *) decoded;
557 
558  /* sanity-check: it IS a NTLMSSP packet, isn't it? */
559  if (ntlm_validate_packet(fast_header, NTLM_ANY) != NTLM_ERR_NONE) {
560  SEND_ERR("message=\"Broken authentication packet\"");
561  return 1;
562  }
563  switch (fast_header->type) {
564  case NTLM_NEGOTIATE:
565  SEND_ERR("message=\"Invalid negotiation request received\"");
566  return 1;
567  /* notreached */
568  case NTLM_CHALLENGE:
569  SEND_ERR("message=\"Got a challenge. We refuse to have our authority disputed\"");
570  return 1;
571  /* notreached */
572  case NTLM_AUTHENTICATE: {
573  /* check against SSPI */
574  int err = ntlm_check_auth((ntlm_authenticate *) decoded, user, domain, decodedLen);
575  have_challenge = 0;
576  if (err != NTLM_ERR_NONE) {
577 #if FAIL_DEBUG
578  fail_debug_enabled =1;
579 #endif
580  switch (err) {
581  case NTLM_ERR_NONE:
582  break;
583  case NTLM_BAD_NTGROUP:
584  SEND_ERR("message=\"Incorrect Group Membership\"");
585  return 1;
586  case NTLM_BAD_REQUEST:
587  SEND_ERR("message=\"Incorrect Request Format\"");
588  return 1;
589  case NTLM_SSPI_ERROR:
590  FormatMessage(
591  FORMAT_MESSAGE_ALLOCATE_BUFFER |
592  FORMAT_MESSAGE_FROM_SYSTEM |
593  FORMAT_MESSAGE_IGNORE_INSERTS,
594  NULL,
595  GetLastError(),
596  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
597  (LPTSTR) &ErrorMessage,
598  0,
599  NULL);
600  if (ErrorMessage[strlen(ErrorMessage) - 1] == '\n')
601  ErrorMessage[strlen(ErrorMessage) - 1] = '\0';
602  if (ErrorMessage[strlen(ErrorMessage) - 1] == '\r')
603  ErrorMessage[strlen(ErrorMessage) - 1] = '\0';
604  SEND_ERR(ErrorMessage); // TODO update to new syntax
605  LocalFree(ErrorMessage);
606  return 1;
607  default:
608  SEND_ERR("message=\"Unknown Error\"");
609  return 1;
610  }
611  }
612  /* let's lowercase them for our convenience */
613  lc(domain);
614  lc(user);
615  fprintf(stdout, "OK user=\"%s\\%s\"", domain, user);
616  return 1;
617  }
618  default:
619  helperfail("message=\"unknown authentication packet type\"");
620  return 1;
621  }
622  return 1;
623  } else { /* not an auth-request */
624  helperfail("message=\"illegal request received\"");
625  fprintf(stderr, "Illegal request received: '%s'\n", buf);
626  return 1;
627  }
628  helperfail("message=\"detected protocol error\"");
629  return 1;
630  /********* END ********/
631 }
632 
633 int
634 main(int argc, char *argv[])
635 {
636  my_program_name = argv[0];
637 
638  process_options(argc, argv);
639 
640  debug("%s " VERSION " " SQUID_BUILD_INFO " starting up...\n", my_program_name);
641 
642  if (LoadSecurityDll(SSP_NTLM, NTLM_PACKAGE_NAME) == NULL) {
643  fprintf(stderr, "FATAL, can't initialize SSPI, exiting.\n");
644  exit(EXIT_FAILURE);
645  }
646  debug("SSPI initialized OK\n");
647 
648  atexit(UnloadSecurityDll);
649 
650  /* initialize FDescs */
651  setbuf(stdout, NULL);
652  setbuf(stderr, NULL);
653 
654  while (manage_request()) {
655  /* everything is done within manage_request */
656  }
657  return EXIT_SUCCESS;
658 }
659 
uint32_t flags
Definition: ntlmauth.h:124
int Valid_Group(char *UserName, char *Group)
int ntlm_validate_packet(const ntlmhdr *hdr, const int32_t type)
Definition: ntlmauth.cc:66
struct _ntlmhdr ntlmhdr
HMODULE LoadSecurityDll(int mode, const char *SSP_Package)
Definition: sspwin32.cc:84
#define NTLM_NEGOTIATE_ALWAYS_SIGN
Definition: ntlmauth.h:119
void lc(char *string)
static int have_challenge
char * NTDisAllowedGroup
int debug_enabled
Definition: debug.cc:13
int i
Definition: membanger.c:49
#define xstrdup
#define NTLM_NEGOTIATE
Definition: ntlmauth.h:73
#define safe_free(x)
Definition: xalloc.h:73
static bool token_decode(size_t *decodedLen, uint8_t decoded[], const char *buf)
void base64_decode_init(struct base64_decode_ctx *ctx)
Definition: base64.c:58
char signature[8]
Definition: ntlmauth.h:81
#define le32toh(x)
#define NTLM_NEGOTIATE_ASCII
Definition: ntlmauth.h:108
int manage_request()
#define HELPER_INPUT_BUFFER
Definition: UserRequest.cc:26
#define NTLM_AUTHENTICATE
Definition: ntlmauth.h:75
int32_t type
Definition: ntlmauth.h:82
int opterr
Definition: getopt.c:47
ntlmhdr hdr
Definition: ntlmauth.h:123
int UseDisallowedGroup
void process_options(int argc, char *argv[])
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition: getopt.c:62
#define NTLM_NEGOTIATE_USE_NTLM
Definition: ntlmauth.h:115
#define NTLM_ERR_NONE
Definition: ntlmauth.h:38
#define NTLM_CHALLENGE
Definition: ntlmauth.h:74
char * NTAllowedGroup
#define NTLM_NEGOTIATE_USE_LM
Definition: ntlmauth.h:113
static int debug
Definition: tcp-banger3.c:105
typedef LPVOID
Definition: WinSvc.cc:73
#define TRUE
Definition: std-includes.h:55
const char *WINAPI SSP_MakeChallenge(PVOID PNegotiateBuf, int NegotiateLen)
Definition: sspwin32.cc:458
int unsigned int const char *desc STUB void int len
Definition: stub_fd.cc:20
#define NTLM_BAD_NTGROUP
Definition: ntlmauth.h:47
void const char * buf
Definition: stub_helper.cc:16
void hex_dump(unsigned char *data, int size)
int ntlm_unpack_auth(const ntlm_authenticate *auth, char *user, char *domain, const int32_t size)
Definition: ntlmauth.cc:236
typedef DWORD
Definition: WinSvc.cc:73
#define SEND_TT(x)
#define FALSE
Definition: std-includes.h:56
int ntlm_check_auth(ntlm_authenticate *auth, char *user, char *domain, int auth_length)
static char credentials[MAX_USERNAME_LEN+MAX_DOMAIN_LEN+2]
#define xmalloc
char * AllocStrFromLSAStr(LSA_UNICODE_STRING LsaStr)
#define SEND_BH(x)
BOOL WINAPI SSP_ValidateNTLMCredentials(PVOID PAutenticateBuf, int AutenticateLen, char *credentials)
Definition: sspwin32.cc:505
#define VERSION
int UseAllowedGroup
#define NTLM_SSPI_ERROR
Definition: ntlmauth.h:46
void usage()
void helperfail(const char *reason)
int main(int argc, char *argv[])
char * GetDomainName(void)
int NTLM_packet_debug_enabled
int base64_decode_update(struct base64_decode_ctx *ctx, size_t *dst_length, uint8_t *dst, size_t src_length, const uint8_t *src)
Definition: base64.c:107
#define NTLM_ANY
Definition: ntlmauth.h:72
int optopt
Definition: getopt.c:48
#define SEND_ERR(x)
int base64_decode_final(struct base64_decode_ctx *ctx)
Definition: base64.c:137
BOOL NTLM_LocalCall
Definition: sspwin32.cc:40
char * optarg
Definition: getopt.c:51
#define NTLM_BAD_REQUEST
Definition: ntlmauth.h:48
char * my_program_name
#define NULL
Definition: types.h:166
void UnloadSecurityDll(void)
Definition: sspwin32.cc:57

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors