Exemple #1
0
bool LdapUtils::getDcName(const char* domain, StringBuffer& dc)
{
    bool ret = false;
#ifdef _WIN32
    PDOMAIN_CONTROLLER_INFO psInfo = NULL;
    DWORD dwErr = DsGetDcName(NULL, domain, NULL, NULL, DS_FORCE_REDISCOVERY | DS_DIRECTORY_SERVICE_REQUIRED, &psInfo);
    if( dwErr == NO_ERROR)
    {
        const char* dcname = psInfo->DomainControllerName;
        if(dcname != NULL)
        {
            while(*dcname == '\\')
                dcname++;

            dc.append(dcname);
            ret = true;
        }
        NetApiBufferFree(psInfo);
    }
    else
    {
        DBGLOG("Error getting domain controller, error = %d", dwErr);
        ret = false;
    }
#endif
    return ret;
}
// Creates a spn if the user hasn't specified one.
void MakeSpn(unsigned char **pszSpn)
{
    DWORD status = ERROR_SUCCESS;
    ULONG ulSpn = 1;
    unsigned char ** arrSpn = NULL;
    HANDLE hDS;
    PDOMAIN_CONTROLLER_INFO pDomainControllerInfo;
    char lpCompDN[128];
    ULONG ulCompDNSize = sizeof(lpCompDN);
    BOOL NoFailure = TRUE;

    status = DsGetSpn(DS_SPN_NB_HOST,
                      "dynept",
                      NULL, // DN of this service.
                      0, // Use the default instance port.
                      0, // Number of additional instance names.
                      NULL, // No additional instance names.
                      NULL, // No additional instance ports.
                      &ulSpn, // Size of SPN array.
                      &arrSpn); // Returned SPN(s).	
				  
    printf_s("DsGetSpn returned 0x%x\n", status);
    if (status != ERROR_SUCCESS) {
        exit(status);
    }
	
    // Get the name of domain if it is domain-joined
    if (status = DsGetDcName(NULL,
                             NULL,
                             NULL,
                             NULL,
                             DS_RETURN_DNS_NAME,
                             &pDomainControllerInfo) != NO_ERROR) {
        printf_s("DsGetDcName returned %d\n", GetLastError());
        NoFailure = FALSE;
    }
	
    // if it is domain joined 
    if (NoFailure) {
        // Bind to the domain controller for our domain 
        if ((status = DsBind(NULL,
                             pDomainControllerInfo->DomainName,
                             &hDS)) != ERROR_SUCCESS) {
            printf_s("DsBind returned %d\n", GetLastError());
            NoFailure = FALSE;
        }
    }

    if (NoFailure) {
        if ((status = NetApiBufferFree(pDomainControllerInfo)) != NERR_Success) {
            printf_s("NetApiBufferFree returned %d\n", status);
            exit(status);
        }

        if (GetComputerObjectName(NameFullyQualifiedDN, lpCompDN, &ulCompDNSize) == 0) {
            printf_s("GetComputerObjectName returned %d\n", GetLastError());
            exit(status);
        }

        /* We could check whether the SPN is already registered for this
        computer's DN, but we don't have to.  Modification is performed
        permissiely by this function, so that adding a value that already 
        exists does not return an error.  This way we can opt for the internal
        check instead of doing it ourselves. */
	
        status = DsWriteAccountSpn(hDS, DS_SPN_ADD_SPN_OP, lpCompDN, ulSpn, arrSpn);
        if (status != NO_ERROR) {
            printf_s("DsWriteAccountSpn returned %d\n", status);
            exit(status);
        }
        DsUnBind(&hDS);
    }

    *pszSpn = *arrSpn;
}
Exemple #3
0
int smpd_register_spn(const char *dc, const char *dn, const char *dh)
{
    DWORD len;
    char err_msg[256];
    LPSTR *spns;
    HANDLE ds;
    DWORD result;
    char domain_controller[SMPD_MAX_HOST_LENGTH] = "";
    char domain_name[SMPD_MAX_HOST_LENGTH] = "";
    char domain_host[SMPD_MAX_HOST_LENGTH] = "";
    char host[SMPD_MAX_HOST_LENGTH] = "";
    int really = 0;
    char *really_env;
    PDOMAIN_CONTROLLER_INFO pInfo;

    result = DsGetDcName(NULL/*local computer*/, NULL, NULL, NULL,
	/*DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME | DS_DIRECTORY_SERVICE_REQUIRED, */
	DS_DIRECTORY_SERVICE_REQUIRED | DS_KDC_REQUIRED,
	&pInfo);
    if (result == ERROR_SUCCESS)
    {
	strcpy(domain_controller, pInfo->DomainControllerName);
	strcpy(domain_name, pInfo->DomainName);
	NetApiBufferFree(pInfo);
    }

    if (dc && *dc != '\0')
    {
	strcpy(domain_controller, dc);
    }
    if (dn && *dn != '\0')
    {
	strcpy(domain_name, dn);
    }
    if (dh && *dh != '\0')
    {
	strcpy(domain_host, dh);
    }
    if (domain_host[0] == '\0')
    {
	smpd_get_hostname(host, SMPD_MAX_HOST_LENGTH);
	if (domain_name[0] != '\0')
	{
	    sprintf(domain_host, "%s\\%s", domain_name, host);
	}
	else
	{
	    strcpy(domain_host, host);
	}
    }

    printf("DsBind(%s, %s, ...)\n", domain_controller[0] == '\0' ? NULL : domain_controller, domain_name[0] == '\0' ? NULL : domain_name);
    result = DsBind(
	domain_controller[0] == '\0' ? NULL : domain_controller,
	domain_name[0] == '\0' ? NULL : domain_name, &ds);
    if (result != ERROR_SUCCESS)
    {
	smpd_translate_win_error(result, err_msg, 256, NULL);
	smpd_err_printf("DsBind failed: %s\n", err_msg);
	return SMPD_FAIL;
    }

    really_env = getenv("really");
    if (really_env)
	really = 1;

#if 1
    len = 1;
    /*result = DsGetSpn(DS_SPN_SERVICE, SMPD_SERVICE_NAME, SMPD_SERVICE_NAME, 0, 0, NULL, NULL, &len, &spns);*/
    result = DsGetSpn(DS_SPN_DNS_HOST, SMPD_SERVICE_NAME, NULL, SMPD_LISTENER_PORT, 0, NULL, NULL, &len, &spns);
    if (result != ERROR_SUCCESS)
    {
	smpd_translate_win_error(result, err_msg, 256, NULL);
	smpd_err_printf("DsGetSpn failed: %s\n", err_msg);
	return SMPD_FAIL;
    }
    if (really)
    {
	printf("registering: %s\n", spns[0]);
	len = SMPD_MAX_HOST_LENGTH;
	GetComputerObjectName(NameFullyQualifiedDN, domain_host, &len);
	printf("on account: %s\n", domain_host);
	result = DsWriteAccountSpn(ds, DS_SPN_ADD_SPN_OP, domain_host, 1, (LPCSTR*)spns);
	if (result != ERROR_SUCCESS)
	{
	    DsFreeSpnArray(1, spns);
	    smpd_translate_win_error(result, err_msg, 256, NULL);
	    smpd_err_printf("DsWriteAccountSpn failed: %s\n", err_msg);
	    return SMPD_FAIL;
	}
    }
    else
    {
	printf("would register '%s' on %s\n", spns[0], domain_host);
    }
    DsFreeSpnArray(1, spns);
#else
    if (really)
    {
	result = DsServerRegisterSpn(DS_SPN_ADD_SPN_OP, SMPD_SERVICE_NAME, domain_host);
	if (result != ERROR_SUCCESS)
	{
	    smpd_translate_win_error(result, err_msg, 256, NULL);
	    smpd_err_printf("DsServerRegisterSpn failed: %s\n", err_msg);
	    return SMPD_FAIL;
	}
    }
    else
    {
	printf("would register '%s' on %s\n", SMPD_SERVICE_NAME, domain_host);
    }
#endif
    result = DsUnBind(&ds);
    return SMPD_SUCCESS;
}
Exemple #4
0
int main(int argc, char * argv[])
{
	EncryptionKey userKey;
	LPCSTR szUser, szDomain, szTarget, szService, szPassword = NULL, szKey = NULL, szSid, szRid, szKdc = NULL, szFilename = NULL;
	PSID sid = NULL, domainSid = NULL;
	DWORD ret, rid = 0;
	PDOMAIN_CONTROLLER_INFO cInfo = NULL;

	kprintf("\n"
		"  .#####.   " MIMIKATZ_FULL "\n"
		" .## ^ ##.  \n"
		" ## / \\ ##  /* * *\n"
		" ## \\ / ##   Benjamin DELPY `gentilkiwi` ( [email protected] )\n"
		" '## v ##'   http://blog.gentilkiwi.com                      (oe.eo)\n"
		"  '#####'    ...   with thanks to Tom Maddock & Sylvain Monne * * */\n\n");
	
	if(init())
	{
		if(!kull_m_string_args_byName(argc, argv, "ptt", NULL, NULL))
			kull_m_string_args_byName(argc, argv, "ticket", &szFilename, TICKET_FILENAME);

		if(kull_m_string_args_byName(argc, argv, "target", &szTarget, NULL))
		{
			if(kull_m_string_args_byName(argc, argv, "service", &szService, NULL))
			{
				if(kull_m_string_args_byName(argc, argv, "user", &szUser, NULL))
				{
					if(kull_m_string_args_byName(argc, argv, "domain", &szDomain, NULL))
					{
						if(kull_m_string_args_byName(argc, argv, "key", &szKey, NULL) || kull_m_string_args_byName(argc, argv, "password", &szPassword, NULL))
						{
							if(kull_m_string_args_byName(argc, argv, "aes256", NULL, NULL))
								userKey.keytype = KERB_ETYPE_AES256_CTS_HMAC_SHA1_96;
							else if(kull_m_string_args_byName(argc, argv, "aes128", NULL, NULL))
								userKey.keytype = KERB_ETYPE_AES128_CTS_HMAC_SHA1_96;
							else
								userKey.keytype = KERB_ETYPE_RC4_HMAC_NT;

							if(NT_SUCCESS(kull_m_kerberos_asn1_helper_util_stringToKey(szUser, szDomain, szPassword, szKey, &userKey)))
							{
								if(!kull_m_string_args_byName(argc, argv, "kdc", &szKdc, NULL))
								{
									ret = DsGetDcName(NULL, szDomain, NULL, NULL, DS_IS_DNS_NAME | DS_RETURN_DNS_NAME, &cInfo);
									if(ret == ERROR_SUCCESS)
									{
										szKdc = cInfo->DomainControllerName + 2;
										kprintf("[KDC] \'%s\' will be the main server\n", szKdc);
									}
									else PRINT_ERROR("[KDC] DsGetDcName: %u\n", ret);
								}

								if(szKdc)
								{
									if(kull_m_string_args_byName(argc, argv, "sid", &szSid, NULL) && kull_m_string_args_byName(argc, argv, "rid", &szRid, NULL))
									{
										if(ConvertStringSidToSid(szSid, &sid))
											rid = strtoul(szRid, NULL, 0);
										else PRINT_ERROR_AUTO("ConvertStringSidToSid");
									}

									if(!(sid && rid))
									{
										if(szPassword)
										{
#pragma warning(push)
#pragma warning(disable:4996)
											impersonateToGetData(szUser, szDomain, szPassword, szKdc,&sid, &rid, _pgmptr);
#pragma warning(pop)
										}
										else PRINT_ERROR("Impersonate is only supported with a password (you need KDC, SID & RID)\n");
									}

									if(sid && rid)
									{
										kprintf("\n"
											"user     : %s\n"
											"domain   : %s\n"
											"password : %s\n"
											"sid      : "
											, szUser, szDomain, szKey ? "<NULL>" : "***");
										kull_m_string_displaySID(sid);
										kprintf("\n"
											"target   : %s\n"
											"service  : %s\n"
											"rid      : %u\n"
											"key      : "
											, szTarget, szService, rid);
										kull_m_string_printf_hex(userKey.keyvalue.value, userKey.keyvalue.length, 0);
										kprintf(" (%s)\n"
											"ticket   : %s\n"
											, kull_m_kerberos_asn1_helper_util_etypeToString(userKey.keytype), szFilename ? szFilename : "** Pass The Ticket **");

										if(szKdc)
										{
											kprintf("kdc      : %s\n\n", szKdc);
											makeInception(szUser, szDomain, sid, rid, szTarget, szService, &userKey, szKdc, 88, szFilename);
										}
										else PRINT_ERROR("No KDC at all\n");

										LocalFree(sid);
									}
									else PRINT_ERROR("Missing valid SID & RID (argument or auto)\n");
								}
								else PRINT_ERROR("Missing one valid DC (argument or auto)\n");

								if(cInfo)
									NetApiBufferFree(cInfo);

								LocalFree(userKey.keyvalue.value);
							}
						}
						else PRINT_ERROR("Missing password/key argument\n");
					}
					else PRINT_ERROR("Missing domain argument\n");
				}
				else PRINT_ERROR("Missing user argument\n");
			}
			else PRINT_ERROR("Missing service argument\n");
		}
		else PRINT_ERROR("Missing target argument\n");
	}
	else PRINT_ERROR("init() failed\n");
	term();
	return 0;
}
/* returns 1 on success, 0 on failure */
int
Valid_Global_Groups(char *UserName, const char **Groups)
{
    int result = 0;
    WCHAR wszUserName[UNLEN + 1];	// Unicode user name

    WCHAR wszDomainControllerName[UNCLEN + 1];

    char NTDomain[DNLEN + UNLEN + 2];
    char *domain_qualify = NULL;
    char User[UNLEN + 1];
    size_t j;

    LPGROUP_USERS_INFO_0 pUsrBuf = NULL;
    LPGROUP_USERS_INFO_0 pTmpBuf;
    PDOMAIN_CONTROLLER_INFO pDCInfo = NULL;
    DWORD dwLevel = 0;
    DWORD dwPrefMaxLen = -1;
    DWORD dwEntriesRead = 0;
    DWORD dwTotalEntries = 0;
    NET_API_STATUS nStatus;
    DWORD i;
    DWORD dwTotalCount = 0;
    LPBYTE pBufTmp = NULL;

    strncpy(NTDomain, UserName, sizeof(NTDomain));

    for (j = 0; j < strlen(NTV_VALID_DOMAIN_SEPARATOR); j++) {
        if ((domain_qualify = strchr(NTDomain, NTV_VALID_DOMAIN_SEPARATOR[j])) != NULL)
            break;
    }
    if (domain_qualify == NULL) {
        strcpy(User, NTDomain);
        strcpy(NTDomain, DefaultDomain);
    } else {
        strcpy(User, domain_qualify + 1);
        domain_qualify[0] = '\0';
        strlwr(NTDomain);
    }

    debug("Valid_Global_Groups: checking group membership of '%s\\%s'.\n", NTDomain, User);

    /* Convert ANSI User Name to Unicode */

    MultiByteToWideChar(CP_ACP, 0, User,
                        strlen(User) + 1, wszUserName,
                        sizeof(wszUserName) / sizeof(wszUserName[0]));

    /* Query AD for a DC */

    if (DsGetDcName(NULL, NTDomain, NULL, NULL, DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME, &pDCInfo) != NO_ERROR) {
        fprintf(stderr, "%s DsGetDcName() failed.'\n", myname);
        if (pDCInfo != NULL)
            NetApiBufferFree(pDCInfo);
        return result;
    }
    /* Convert ANSI Domain Controller Name to Unicode */

    MultiByteToWideChar(CP_ACP, 0, pDCInfo->DomainControllerName,
                        strlen(pDCInfo->DomainControllerName) + 1, wszDomainControllerName,
                        sizeof(wszDomainControllerName) / sizeof(wszDomainControllerName[0]));

    debug("Using '%S' as DC for '%s' user's domain.\n", wszDomainControllerName, NTDomain);
    debug("DC Active Directory Site is %s\n", pDCInfo->DcSiteName);
    debug("Machine Active Directory Site is %s\n", pDCInfo->ClientSiteName);

    /*
     * Call the NetUserGetGroups function
     * specifying information level 0.
     */
    dwLevel = 0;
    pBufTmp = NULL;
    nStatus = NetUserGetGroups(wszDomainControllerName,
                               wszUserName,
                               dwLevel,
                               &pBufTmp,
                               dwPrefMaxLen,
                               &dwEntriesRead,
                               &dwTotalEntries);
    pUsrBuf = (LPGROUP_USERS_INFO_0) pBufTmp;
    /*
     * If the call succeeds,
     */
    if (nStatus == NERR_Success) {
        if ((pTmpBuf = pUsrBuf) != NULL) {
            for (i = 0; i < dwEntriesRead; i++) {
                assert(pTmpBuf != NULL);
                if (pTmpBuf == NULL) {
                    result = 0;
                    break;
                }
                if (wcstrcmparray(pTmpBuf->grui0_name, Groups) == 0) {
                    result = 1;
                    break;
                }
                pTmpBuf++;
                dwTotalCount++;
            }
        }
    } else {
        result = 0;
        fprintf(stderr, "%s NetUserGetGroups() failed.'\n", myname);
    }
    /*
     * Free the allocated memory.
     */
    if (pUsrBuf != NULL)
        NetApiBufferFree(pUsrBuf);
    if (pDCInfo != NULL)
        NetApiBufferFree((LPVOID) pDCInfo);
    return result;
}
OperationDomainPaths::OperationDomainPaths(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
	// exit if there are not enough arguments to parse
	std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList);

	// initialize com only
	static HRESULT hComInit = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	if (hComInit != S_OK && hComInit != S_FALSE)
	{
		wprintf(L"ERROR: Could not initialize COM.\n");
		exit(-1);
	}

	// find a domain controller for the specified domain
	PDOMAIN_CONTROLLER_INFO tDomainControllerInfo;
	if (DsGetDcName(NULL, sSubArgs[0].c_str(), NULL, NULL,
		DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME | DS_TRY_NEXTCLOSEST_SITE | DS_FORCE_REDISCOVERY,
		&tDomainControllerInfo) != ERROR_SUCCESS)
	{
		wprintf(L"ERROR: Could not locate domain controller for domain '%s'\n", sSubArgs[0].c_str());
		exit(-1);
	}

	// create a string 
	std::wstring sPath = std::wstring(L"LDAP://") + (wcsrchr(tDomainControllerInfo->DomainControllerName, '\\') + 1);

	// grab the dns suffix for later use
	std::wstring sSuffix = tDomainControllerInfo->DomainName;
	NetApiBufferFree(tDomainControllerInfo);

	// bind to global catalog
	CComPtr<IDirectorySearch> oSearch;
	if (FAILED(ADsOpenObject(sPath.c_str(), NULL, NULL, ADS_SECURE_AUTHENTICATION,
		IID_IDirectorySearch, (void**)&oSearch)))
	{
		wprintf(L"ERROR: Could not establish search for domain '%s'\n", sSubArgs[0].c_str());
		exit(-1);
	}

	// setup preferences to search entire tree
	ADS_SEARCHPREF_INFO SearchPref;
	SearchPref.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
	SearchPref.vValue.dwType = ADSTYPE_INTEGER;
	SearchPref.vValue.Integer = ADS_SCOPE_SUBTREE;

	// set the search preference.
	if (FAILED(oSearch->SetSearchPreference(&SearchPref, 1)))
	{
		wprintf(L"ERROR: Could not set search preference for domain '%s'\n", sSubArgs[0].c_str());
		exit(-1);

	}

	// create the search filter
	WCHAR sSearchFilter[] = L"(&(objectCategory=computer)(|(operatingSystem=*server*)(operatingSystem=*ontap*)(operatingSystem=*netapp*))" \
		"(!(userAccountControl:1.2.840.113556.1.4.803:=8192))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(msDS-isRODC=true)))";

	// execute the search.
	LPWSTR sAttributes[] = { L"cn" };
	ADS_SEARCH_HANDLE hSearch;
	if (FAILED(oSearch->ExecuteSearch(sSearchFilter, sAttributes, _countof(sAttributes), &hSearch)))
	{
		wprintf(L"ERROR: Could not execute search for domain '%s'\n", sSubArgs[0].c_str());
		exit(-1);
	}

	// enumerate results
	std::vector<std::wstring> sServers;
	for (HRESULT hResult = oSearch->GetFirstRow(hSearch); hResult == S_OK; hResult = oSearch->GetNextRow(hSearch))
	{
		// get the data from the column
		ADS_SEARCH_COLUMN oColumn;
		if (FAILED(oSearch->GetColumn(hSearch, sAttributes[0], &oColumn)) ||
			oColumn.dwADsType != ADSTYPE_CASE_IGNORE_STRING)
		{
			continue;
		}

		// add the server to our list
		oArgList.push(L"/SharePaths");
		oArgList.push(std::wstring(oColumn.pADsValues->CaseIgnoreString) + L"." + sSuffix + 
			((sSubArgs.size() == 2) ? (L":" + sSubArgs[1]) : L""));

		// free the column.
		oSearch->FreeColumn(&oColumn);
	}

	// close search handle
	if (oSearch->CloseSearchHandle(hSearch) != NULL)
	{
		wprintf(L"ERROR: Could not close search for domain '%s'\n", sSubArgs[0].c_str());
		exit(-1);
	}
};
Exemple #7
0
static auth_result_t do_windows_system_authentication(const char *username,
                                              const char *password,
                                              char ***pppszUID,
                                              char ***pppszGID,
                                              char ***pppszGroupNames,
                                              int  *nGIDs,
                                              error_handler_t *error_handler)
{
   auth_result_t ret     = JUTI_AUTH_SUCCESS;
   HANDLE        hToken  = INVALID_HANDLE_VALUE;
   int           nUIDs   = 0;
   char          *domain;
   char          *userbuf;
   char          *user;
   char          *backslash;
   char          *buf = NULL;
   DWORD         buf_size = 0;
   DOMAIN_CONTROLLER_INFO *pbuf;
   DWORD         dwRes;

   /*
    * username can be in format "domain\username", split it up.
    */
   userbuf = strdup(username);
   user=userbuf;
   backslash = strchr(user, '\\');
   if(backslash != NULL) {
      domain = user;
      user = backslash+1;
      *backslash = '\0';
   } else {
      /*
       * if no domain was provided, use primary domain by default
       */
      dwRes = DsGetDcName(NULL, NULL, NULL, NULL,
                 DS_RETURN_FLAT_NAME|DS_PDC_REQUIRED, &pbuf);

      if(dwRes == ERROR_SUCCESS && pbuf->DomainName != NULL) {
         domain = pbuf->DomainName;
      } else {
         /*
          * no primary domain, use local host as domain
          */
         domain = ".";
      }
   }

   
   if(!LogonUser(
      user,
      domain,
      password,
      LOGON32_LOGON_INTERACTIVE,
      LOGON32_PROVIDER_DEFAULT,
      &hToken)) {
         ret = JUTI_AUTH_ERROR;
         error_handler->error(MSG_AUTHUSER_WRONG_USER_OR_PASSWORD);
         goto error;
   }
   GetSidStrings(hToken, TokenOwner,  pppszUID, NULL, &nUIDs);
   GetSidStrings(hToken, TokenGroups, pppszGID, pppszGroupNames, nGIDs);

   CloseHandle(hToken);

error:
   free(userbuf);
   if(pbuf != NULL) {
      NetApiBufferFree(pbuf);
   }
   return ret;

}
LDAPAUTHNT4_API
BOOL CUGP(char * userin,char *password,char *machine,char *groupin,int locdom)
{

	{
	//Handle the command line arguments.
	LPOLESTR pszBuffer = new OLECHAR[MAX_PATH*2];
	LPOLESTR pszBuffer2 = new OLECHAR[MAX_PATH*2];
	LPOLESTR pszBuffer3 = new OLECHAR[MAX_PATH*2];
	LPOLESTR pszBuffer4 = new OLECHAR[MAX_PATH*2];
	mbstowcs( (wchar_t *) pszBuffer, userin, MAX_PATH );
	mbstowcs( (wchar_t *) pszBuffer2, password, MAX_PATH );
	mbstowcs( (wchar_t *) pszBuffer3, machine, MAX_PATH );
	mbstowcs( (wchar_t *) pszBuffer4, groupin, MAX_PATH );
	HRESULT hr = S_OK;
	//Get rootDSE and the domain container's DN.
	IADs *pObject = NULL;
	IADs *pObjectUser = NULL;
	IADs *pObjectGroup = NULL;
	IDirectorySearch *pDS = NULL;
	LPOLESTR szPath = new OLECHAR[MAX_PATH];
	LPOLESTR myPath = new OLECHAR[MAX_PATH];
	VARIANT var;
	////////////FIND SERVER NEEDED FOR NT4
	DWORD dwRet;
	PDOMAIN_CONTROLLER_INFO pdci;
	dwRet = DsGetDcName(NULL, NULL, NULL, NULL	, DS_PDC_REQUIRED, &pdci);
	if (ERROR_SUCCESS!=dwRet) 
		{
			wprintf(L"PDC not found try a rediscover \n");
			dwRet = DsGetDcName(NULL, NULL, NULL, NULL	, DS_DIRECTORY_SERVICE_REQUIRED|DS_FORCE_REDISCOVERY, &pdci);
			if (ERROR_SUCCESS!=dwRet)
			{
				wprintf(L"PDC not found \n");
				delete [] pszBuffer;
				delete [] pszBuffer2;
				delete [] pszBuffer3;
				delete [] pszBuffer4;
				delete [] szPath;
				delete [] myPath;
				return false;
			}
		}
	//////////////////////////////////////////
	wcscpy(szPath,L"LDAP://");
	wcscat(szPath,pdci->DomainControllerName+2);
	wcscat(szPath,L"/rootDSE");
	wprintf(szPath);
	wprintf(L"\n");

	hr = ADsOpenObject(szPath,
					pszBuffer,
					pszBuffer2,
					ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
					IID_IADs,
					(void**)&pObject);
	if (FAILED(hr))
		{
			bool result=false;
			delete [] pszBuffer;
			delete [] pszBuffer2;
			delete [] pszBuffer3;
			delete [] pszBuffer4;
			delete [] szPath;
			delete [] myPath;
			return result;
		}
	hr = pObject->Get(L"defaultNamingContext",&var);

	if (SUCCEEDED(hr))
		{
			wcscpy(szPath,L"LDAP://");
			wcscat(szPath,pdci->DomainControllerName+2);
			wcscat(szPath,L"/");
			wcscat(szPath,var.bstrVal);
			VariantClear(&var);
			if (pObject)
				{
					pObject->Release();
					pObject = NULL;
				}
			wprintf( szPath);
			wprintf(L"\n");
			//Bind to the root of the current domain.
			hr = ADsOpenObject(szPath,pszBuffer,pszBuffer2,
					 ADS_SECURE_AUTHENTICATION,IID_IDirectorySearch,(void**)&pDS);
			if (SUCCEEDED(hr))
				{
					if (SUCCEEDED(hr))
						{
							hr =  FindUserByName(pDS, pszBuffer, &pObjectUser );
							if (FAILED(hr))
								{
									delete [] pszBuffer;
									delete [] pszBuffer2;
									delete [] pszBuffer3;
									delete [] pszBuffer4;
									delete [] szPath;
									delete [] myPath;
									if (pDS) pDS->Release();
									if (pObjectUser) pObjectUser->Release();
									return false;
								}
							if (pObjectUser) pObjectUser->Release();
							///////////////////// VNCACCESS
							hr =  FindGroup(pDS, pszBuffer, &pObjectGroup,pszBuffer4);
							if (pObjectGroup)
										{
											pObjectGroup->Release();
											pObjectGroup = NULL;
										}
							if (SUCCEEDED(hr))
								{
									wprintf(L"FindGroup OK\n");
									IADsGroup *     pIADsG;
									hr = ADsOpenObject( gbsGroup,pszBuffer, pszBuffer2, 
											ADS_SECURE_AUTHENTICATION,IID_IADsGroup, (void**) &pIADsG);
									if (SUCCEEDED(hr))
										{
											VARIANT_BOOL bMember = FALSE;  
											hr = pIADsG->IsMember(gbsMember,&bMember);
											if (SUCCEEDED(hr))
												{
													if (bMember == -1)
														{
															wprintf(L"Object \n\n%s\n\n IS a member of the following Group:\n\n%s\n\n",gbsMember,gbsGroup);
															delete [] pszBuffer;
															delete [] pszBuffer2;
															delete [] pszBuffer3;
															delete [] pszBuffer4;
															delete [] szPath;
															delete [] myPath;
															if (pDS) pDS->Release();
															return true;
														}
													else
														{
															BSTR bsMemberGUID = NULL;
															IDirectoryObject * pDOMember = NULL;
															hr = ADsOpenObject( gbsMember,pszBuffer, pszBuffer2, 
																	ADS_SECURE_AUTHENTICATION,IID_IDirectoryObject, (void**) &pDOMember);
															if (SUCCEEDED(hr))
																{
																	hr = GetObjectGuid(pDOMember,bsMemberGUID);
																	pDOMember->Release();
																	pDOMember  = NULL;
																	if (RecursiveIsMember(pIADsG,bsMemberGUID,gbsMember,true, pszBuffer, pszBuffer2))
																		{
																			delete [] pszBuffer;
																			delete [] pszBuffer2;
																			delete [] pszBuffer3;
																			delete [] pszBuffer4;
																			delete [] szPath;
																			delete [] myPath;
																			if (pDS) pDS->Release();
																			return true;
																		}
																}
													}//else bmember
											}//ismember
									}//iadsgroup 
							}//Findgroup
							
						}//user
				}
		if (pDS) pDS->Release();
		}
	delete [] pszBuffer;
	delete [] pszBuffer2;
	delete [] pszBuffer3;
	delete [] pszBuffer4;
	delete [] szPath;
	delete [] myPath;
	return false;
	}
	return false;
}
/*
 * Class:     sun_security_krb5_Credentials
 * Method:    acquireDefaultNativeCreds
 * Signature: ()Lsun/security/krb5/Credentials;
 */
JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds(
		JNIEnv *env,
		jclass krbcredsClass) {

   HANDLE LogonHandle = NULL;
   ULONG PackageId;
	PKERB_RETRIEVE_TKT_REQUEST CacheRequest = NULL;
	PKERB_RETRIEVE_TKT_RESPONSE CacheResponse = NULL;
	ULONG rspSize = 0;
	DWORD errorCode;
	NTSTATUS Status,SubStatus;
	PUCHAR pEncodedTicket = NULL;
	jobject ticket, clientPrincipal, targetPrincipal, encryptionKey;
	jobject ticketFlags, startTime, endTime, krbCreds = NULL;
   jobject authTime, renewTillTime, hostAddresses = NULL;
	UNICODE_STRING Target = {0};
	UNICODE_STRING Target2 = {0};
	PDOMAIN_CONTROLLER_INFO DomainControllerInfo = NULL;
	WCHAR *tgtName = L"krbtgt";
	WCHAR *fullName;

	while (TRUE) {

	if (krbcredsConstructor == 0) {
		krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>", 
       "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V");
		if (krbcredsConstructor == 0) {
			printf("Couldn't find com.ibm.security.krb5.Credentials constructor\n");
			break;
		}
	}

	//printf("Found KrbCreds constructor\n");

    //
    // Get the logon handle and package ID from the
    // Kerberos package
    //
    if(!PackageConnectLookup(&LogonHandle, &PackageId))
        break;

	#ifdef DEBUG
	printf("Got handle to Kerberos package\n");
   #endif /* DEBUG */

	//InitUnicodeString(&Target2, L"krbtgt"); // this doesn't work 'cause I need the domain name too
	// OK, I don't give up that easily
	// Go get the current domain name
	errorCode = DsGetDcName(
					(LPCTSTR) NULL, // machine name
					(LPCTSTR) NULL, // DomainName, if NULL, I'm asking what it is
					(GUID *)  NULL, // DomainGuid,
					(LPCTSTR) NULL, // SiteName,
					DS_GC_SERVER_REQUIRED, //Flags
					&DomainControllerInfo);
	if (errorCode != NO_ERROR) {
		printf("DsGetDcName returned %d\n", errorCode);
		break;
	}

	#ifdef DEBUG
	printf("The domain name is %S\n", DomainControllerInfo->DomainName);
   #endif /* DEBUG */
	// Build a fully-qualified name
	fullName = (WCHAR *) LocalAlloc(LMEM_ZEROINIT,((wcslen(tgtName)+wcslen(L"/")+wcslen(DomainControllerInfo->DomainName)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)));
	wcscat(fullName, tgtName);
	wcscat(fullName, L"/");
	wcscat(fullName, DomainControllerInfo->DomainName);
	#ifdef DEBUG
	printf("The fully-qualified name is %S\n", fullName);
   #endif /* DEBUG */
	InitUnicodeString(&Target2, fullName);       

    CacheRequest = (PKERB_RETRIEVE_TKT_REQUEST)
            LocalAlloc(LMEM_ZEROINIT, Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST));

    CacheRequest->MessageType = KerbRetrieveEncodedTicketMessage ;
 
    Target.Buffer = (LPWSTR) (CacheRequest + 1);
    Target.Length = Target2.Length;
    Target.MaximumLength = Target2.MaximumLength;

    CopyMemory(
        Target.Buffer,
        Target2.Buffer,
        Target2.Length
        );

    CacheRequest->TargetName = Target;	
    CacheRequest->EncryptionType = KERB_ETYPE_DES_CBC_MD5; // mdu

	Status = LsaCallAuthenticationPackage(
                LogonHandle,
                PackageId,
                CacheRequest,
                Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST),
                (PVOID *) &CacheResponse,
                &rspSize,
                &SubStatus
                );

	#ifdef DEBUG
	printf("Response size is %d\n", rspSize);
   #endif /* DEBUG */
	LocalFree(fullName);

	if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus))
    {
        if (!LSA_SUCCESS(Status)) {
			ShowNTError("LsaCallAuthenticationPackage", Status);
		}
		else {
			ShowNTError("Protocol status", SubStatus);
		}
		break;
    }

	// Now we need to skip over most of the junk in the buffer to get to the ticket
	// Here's what we're looking at...

/*

typedef struct _KERB_RETRIEVE_TKT_RESPONSE {
    KERB_EXTERNAL_TICKET Ticket;
} KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE;

typedef struct _KERB_EXTERNAL_TICKET {
    PKERB_EXTERNAL_NAME ServiceName;
    PKERB_EXTERNAL_NAME TargetName;
    PKERB_EXTERNAL_NAME ClientName;
    UNICODE_STRING DomainName;
    UNICODE_STRING TargetDomainName;
    UNICODE_STRING AltTargetDomainName;
    KERB_CRYPTO_KEY SessionKey;
    ULONG TicketFlags;
    ULONG Flags;
    LARGE_INTEGER KeyExpirationTime;
    LARGE_INTEGER StartTime;
    LARGE_INTEGER EndTime;
    LARGE_INTEGER RenewUntil;
    LARGE_INTEGER TimeSkew;
    ULONG EncodedTicketSize;
    PUCHAR EncodedTicket;					<========== Here's the good stuff
} KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET;

typedef struct _KERB_EXTERNAL_NAME {
    SHORT NameType;
    USHORT NameCount;
    UNICODE_STRING Names[ANYSIZE_ARRAY];
} KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME;

typedef struct _LSA_UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING;

typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;

typedef struct KERB_CRYPTO_KEY {
    LONG KeyType;
    ULONG Length;
    PUCHAR Value;
} KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY;

*/

	// Build a com.ibm.security.krb5.Ticket
	ticket = BuildTicket(env, CacheResponse->Ticket.EncodedTicket, CacheResponse->Ticket.EncodedTicketSize);
	if (ticket == NULL) {
		break;
	}
	// OK, have a Ticket, now need to get the client name
	clientPrincipal = BuildClientPrincipal(env, CacheResponse->Ticket.ClientName); // mdu
	if (clientPrincipal == NULL) break;
	// and the "name" of tgt
	targetPrincipal = BuildTGSPrincipal(env, CacheResponse->Ticket.TargetDomainName); // mdu
	if (targetPrincipal == NULL) break;
	// Get the encryption key
	encryptionKey = BuildEncryptionKey(env, &(CacheResponse->Ticket.SessionKey));
	if (encryptionKey == NULL) break;
	// and the ticket flags
	ticketFlags = BuildTicketFlags(env, &(CacheResponse->Ticket.TicketFlags));
	if (ticketFlags == NULL) break;
	// Get the start time
	startTime = BuildKerberosTime(env, &(CacheResponse->Ticket.StartTime));
	if (startTime == NULL) break;
	/*
	 * mdu: No point storing the eky expiration time in the auth
	 * time field. Set it to be same as startTime. Looks like
	 * windows does not have post-dated tickets.
	 */
	authTime = startTime;
	// and the end time
	endTime = BuildKerberosTime(env, &(CacheResponse->Ticket.EndTime));
	if (endTime == NULL) break;
	// Get the renew till time
	renewTillTime = BuildKerberosTime(env, &(CacheResponse->Ticket.RenewUntil));
	if (renewTillTime == NULL) break;
	// and now go build a KrbCreds object
	krbCreds = (*env)->NewObject(
		env,
		krbcredsClass,
		krbcredsConstructor,
		ticket,
		clientPrincipal,
		targetPrincipal,
		encryptionKey,
		ticketFlags,
		authTime, // mdu
		startTime,
		endTime,
		renewTillTime, //mdu
		hostAddresses);
	break;
	} // end of WHILE

	if (DomainControllerInfo != NULL) {
		NetApiBufferFree(DomainControllerInfo);
	}
    if (CacheResponse != NULL) {
        LsaFreeReturnBuffer(CacheResponse);
    }
    if (CacheRequest) {
        LocalFree(CacheRequest);
    }
	return krbCreds;
}