Exemplo n.º 1
0
SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleW(
 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse,
 PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
 PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;

    TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_w(pszPrincipal),
     debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
     pvGetKeyArgument, phCredential, ptsExpiry);
    if (pszPackage)
    {
        PSTR principal, package;

        principal = SECUR32_AllocMultiByteFromWide(pszPrincipal);
        package = SECUR32_AllocMultiByteFromWide(pszPackage);
        ret = AcquireCredentialsHandleA(principal, package, fCredentialsUse,
         pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
         ptsExpiry);
        HeapFree(GetProcessHeap(), 0, principal);
        HeapFree(GetProcessHeap(), 0, package);
    }
    else
        ret = SEC_E_SECPKG_NOT_FOUND;
    return ret;
}
Exemplo n.º 2
0
bool CSSPIHandler::ClientStart(bool encrypt, bool& more, const char *name, const char *pwd, const char *tokenSource /* = NULL */)
{
	char username[256];
	char domain[256];
	SECURITY_STATUS rc;
	TimeStamp useBefore;

	memset(&m_nameAndPwd,0,sizeof(m_nameAndPwd));

	if (name && *name)
	{
		strncpy(username,name,sizeof(username));
		char *p = strpbrk(username,"\\/");
		if(!p)
			domain[0]='\0';
		else
		{
			*p='\0';
			strcpy(domain,username);
			strcpy(username,p+1);
		}

		
		m_nameAndPwd.Domain = (BYTE*)domain;
		m_nameAndPwd.DomainLength = (DWORD)strlen(domain);
		m_nameAndPwd.User = (BYTE*)username;
		m_nameAndPwd.UserLength = (DWORD)strlen(username);
		m_nameAndPwd.Password = (BYTE*)(pwd?pwd:"");
		m_nameAndPwd.PasswordLength = (DWORD)(pwd?strlen(pwd):0); 
		m_nameAndPwd.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
	}
	else if(m_broken_file_sharing)
	{
		m_nameAndPwd.UserLength = sizeof(username);
		GetUserNameA(username,&m_nameAndPwd.UserLength);
		m_nameAndPwd.User= (BYTE*)username;
		m_nameAndPwd.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
	}

	rc = AcquireCredentialsHandleA( NULL, (char*)m_currentProtocol.c_str(), SECPKG_CRED_OUTBOUND, NULL, m_nameAndPwd.UserLength?&m_nameAndPwd:NULL, NULL, NULL, &m_credHandle, &useBefore );
	if(rc)
	{
		m_rc = rc;
		return false;
	}

	m_haveContext = false;
	m_tokenSource = tokenSource;
	m_ctxReq = ISC_REQ_MUTUAL_AUTH | ISC_REQ_DELEGATE | ISC_REQ_STREAM | ISC_REQ_EXTENDED_ERROR;
	if(encrypt)
		m_ctxReq |= ISC_REQ_REPLAY_DETECT  | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY;

	return ClientStep(more,NULL,0);
}
Exemplo n.º 3
0
OM_uint32  gss_acquire_cred (
        OM_uint32 *minor_status,
        gss_name_t desired_name,
        OM_uint32 time_req,
        gss_OID_set desired_mechs,
        int cred_usage,
        gss_cred_id_t *output_cred_handle,
        gss_OID_set *actual_mechs,
        OM_int32 *time_rec)
{
	*minor_status = 0;

	OM_uint32 ret = AcquireCredentialsHandleA(desired_name,"Kerberos",cred_usage,NULL,NULL,NULL,NULL,output_cred_handle,(TimeStamp*)time_rec);
	return ret;
}
Exemplo n.º 4
0
static void test_kerberos(void)
{
    SecPkgInfoA *info;
    TimeStamp ttl;
    CredHandle cred;
    SECURITY_STATUS status;

    SEC_CHAR provider[] = {'K','e','r','b','e','r','o','s',0};

    static const ULONG expected_flags =
          SECPKG_FLAG_INTEGRITY
        | SECPKG_FLAG_PRIVACY
        | SECPKG_FLAG_TOKEN_ONLY
        | SECPKG_FLAG_DATAGRAM
        | SECPKG_FLAG_CONNECTION
        | SECPKG_FLAG_MULTI_REQUIRED
        | SECPKG_FLAG_EXTENDED_ERROR
        | SECPKG_FLAG_IMPERSONATION
        | SECPKG_FLAG_ACCEPT_WIN32_NAME
        | SECPKG_FLAG_NEGOTIABLE
        | SECPKG_FLAG_GSS_COMPATIBLE
        | SECPKG_FLAG_LOGON
        | SECPKG_FLAG_MUTUAL_AUTH
        | SECPKG_FLAG_DELEGATION
        | SECPKG_FLAG_READONLY_WITH_CHECKSUM;
    static const ULONG optional_mask =
          SECPKG_FLAG_RESTRICTED_TOKENS
        | SECPKG_FLAG_APPCONTAINER_CHECKS;

    status = QuerySecurityPackageInfoA(provider, &info);
    ok(status == SEC_E_OK, "Kerberos package not installed, skipping test\n");
    if(status != SEC_E_OK)
        return;

    ok( (info->fCapabilities & ~optional_mask) == expected_flags, "got %08x, expected %08x\n", info->fCapabilities, expected_flags );
    ok( info->wVersion == 1, "got %u\n", info->wVersion );
    ok( info->wRPCID == RPC_C_AUTHN_GSS_KERBEROS, "got %u\n", info->wRPCID );
    ok( info->cbMaxToken >= 12000, "got %u\n", info->cbMaxToken );
    ok( !lstrcmpA( info->Name, "Kerberos" ), "got %s\n", info->Name );
    ok( !lstrcmpA( info->Comment, "Microsoft Kerberos V1.0" ), "got %s\n", info->Comment );
    FreeContextBuffer( info );

    status = AcquireCredentialsHandleA( NULL, provider, SECPKG_CRED_OUTBOUND, NULL,
                                        NULL, NULL, NULL, &cred, &ttl );
    todo_wine ok( status == SEC_E_OK, "AcquireCredentialsHandleA returned %08x\n", status );
    if(status == SEC_E_OK)
        FreeCredentialHandle( &cred );
}
Exemplo n.º 5
0
my_bool ma_tls_connect(MARIADB_TLS *ctls)
{
  my_bool blocking;
  MYSQL *mysql;
  SCHANNEL_CRED Cred;
  MARIADB_PVIO *pvio;
  my_bool rc= 1;
  SC_CTX *sctx;
  SECURITY_STATUS sRet;
  PCCERT_CONTEXT pRemoteCertContext = NULL,
                 pLocalCertContext= NULL;
  ALG_ID AlgId[MAX_ALG_ID]= {0};
  
  if (!ctls || !ctls->pvio)
    return 1;;
  
  pvio= ctls->pvio;
  sctx= (SC_CTX *)ctls->ssl;

  /* Set socket to blocking if not already set */
  if (!(blocking= pvio->methods->is_blocking(pvio)))
    pvio->methods->blocking(pvio, TRUE, 0);

  mysql= pvio->mysql;
 
  if (ma_tls_set_client_certs(ctls))
    goto end;

  ZeroMemory(&Cred, sizeof(SCHANNEL_CRED));

  /* Set cipher */
  if (mysql->options.ssl_cipher)
  {
    WORD validTokens = 0;
    char *token = strtok(mysql->options.ssl_cipher, ":");
    while (token)
    {
      struct st_cipher_suite *valid;
      for (valid = valid_ciphers; valid && valid->aid; valid++)
      {
        if (!strcmp(token, valid->cipher))
        {
          AlgId[validTokens++] = valid->aid;
          break;
        }
      }
      token = strtok(NULL, ":");
    }
  }
  Cred.palgSupportedAlgs = (ALG_ID *)&AlgId;
  
  Cred.dwVersion= SCHANNEL_CRED_VERSION;
  if (mysql->options.extension)
    Cred.dwMinimumCipherStrength = MAX(128, mysql->options.extension->tls_cipher_strength);
  else
    Cred.dwMinimumCipherStrength = 128;
  Cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK | SCH_SEND_ROOT_CERT |
    SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_MANUAL_CRED_VALIDATION;
  if (sctx->client_cert_ctx)
  {
    Cred.cCreds = 1;
    Cred.paCred = &sctx->client_cert_ctx;
  }
  if (mysql->options.extension && mysql->options.extension->tls_version)
  {
    Cred.grbitEnabledProtocols= 0;
    if (strstr("TLSv1.0", mysql->options.extension->tls_version))
      Cred.grbitEnabledProtocols|= SP_PROT_TLS1_0;
    if (strstr("TLSv1.1", mysql->options.extension->tls_version))
      Cred.grbitEnabledProtocols|= SP_PROT_TLS1_1;
    if (strstr("TLSv1.2", mysql->options.extension->tls_version))
      Cred.grbitEnabledProtocols|= SP_PROT_TLS1_2;
  }
  else
    Cred.grbitEnabledProtocols = SP_PROT_TLS1_0 |
                                 SP_PROT_TLS1_1 |
                                 SP_PROT_TLS1_2;

  if ((sRet= AcquireCredentialsHandleA(NULL, UNISP_NAME_A, SECPKG_CRED_OUTBOUND,
                                       NULL, &Cred, NULL, NULL, &sctx->CredHdl, NULL)) != SEC_E_OK)
  {
    ma_schannel_set_sec_error(pvio, sRet);
    goto end;
  }
  sctx->FreeCredHdl= 1;

  if (ma_schannel_client_handshake(ctls) != SEC_E_OK)
    goto end;

  sRet= QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pRemoteCertContext);
  if (sRet != SEC_E_OK)
  {
    ma_schannel_set_sec_error(pvio, sRet);
    goto end;
  }
  
  if (!ma_schannel_verify_certs(sctx, 0))
    goto end;
 
  return 0;

end:
  if (pRemoteCertContext)
    CertFreeCertificateContext(pRemoteCertContext);
  if (rc && sctx->IoBufferSize)
    LocalFree(sctx->IoBuffer);
  sctx->IoBufferSize= 0;
  if (sctx->client_cert_ctx)
    CertFreeCertificateContext(sctx->client_cert_ctx);
  sctx->client_cert_ctx= 0;
  return 1;
}
Exemplo n.º 6
0
INT
auth_sspi_client_init(SEC_CHAR* service,
                      SEC_CHAR* principal,
                      ULONG flags,
                      SEC_CHAR* user,
                      SEC_CHAR* domain,
                      SEC_CHAR* password,
                      sspi_client_state* state) {
    SECURITY_STATUS status;
    SEC_WINNT_AUTH_IDENTITY_A authIdentity;
    TimeStamp ignored;

    state->response = NULL;
    state->username = NULL;
    state->flags = flags;
    state->haveCred = 0;
    state->haveCtx = 0;
    state->spn = _strdup(service);
    if (state->spn == NULL) {
        PyErr_SetNone(PyExc_MemoryError);
        return AUTH_GSS_ERROR;
    }
    /* Convert RFC-2078 format to SPN */
    if (!strchr(state->spn, '/')) {
        SEC_CHAR* ptr = strchr(state->spn, '@');
        if (ptr) {
            *ptr = '/';
        }
    }

    if (user) {
        authIdentity.User = user;
        authIdentity.UserLength = (ULONG)strlen(user);
        authIdentity.Domain = NULL;
        authIdentity.DomainLength = 0;
        authIdentity.Password = NULL;
        authIdentity.PasswordLength = 0;
        if (domain) {
            authIdentity.Domain = domain;
            authIdentity.DomainLength = (ULONG)strlen(domain);
        }
        if (password) {
            authIdentity.Password = password;
            authIdentity.PasswordLength = (ULONG)strlen(password);
        }
        authIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
    }

    status = AcquireCredentialsHandleA(/* Principal (NULL means current user) */
                                       principal,
                                       /* Security package name */
                                       "kerberos",
                                       /* Credentials Use */
                                       SECPKG_CRED_OUTBOUND,
                                       /* LogonID (We don't use this) */
                                       NULL,
                                       /* AuthData */
                                       user ? &authIdentity : NULL,
                                       /* Always NULL */
                                       NULL,
                                       /* Always NULL */
                                       NULL,
                                       /* CredHandle */
                                       &state->cred,
                                       /* Expiry (Required but unused by us) */
                                       &ignored);
    if (status != SEC_E_OK) {
        set_krberror(status, "AcquireCredentialsHandle");
        return AUTH_GSS_ERROR;
    }
    state->haveCred = 1;
    return AUTH_GSS_COMPLETE;
}
Exemplo n.º 7
0
BOOL DoAuthentication (void)
{
	SECURITY_STATUS   	ss;
	DWORD 			  	cbIn;
	DWORD		      	cbOut;
	DWORD 			  	g_cbMaxMessage;
	BOOL              	done = FALSE;
	BOOL		      	fDone = FALSE;
	BOOL              	fNewConversation = TRUE;
	TimeStamp         	Lifetime;
	PSecPkgInfoA	  	pkgInfo;
	CredHandle        	hcred;
	CredHandle 	      	hCcred;
	struct _SecHandle 	hctxt;
	struct _SecHandle 	hCctxt;
	PBYTE 			  	g_pInBuf = NULL;
	PBYTE 			  	g_pOutBuf = NULL;
	SEC_CHAR          	g_lpPackageName[1024];
	PBYTE				nonce, clientnonce, lmhash, nthash;
	PCHAR pUserName = NULL;
	DWORD cbUserName = 0;



	lstrcpynA (g_lpPackageName, "NTLM",5);
	ss = QuerySecurityPackageInfoA ( g_lpPackageName, &pkgInfo);
	if (!SEC_SUCCESS(ss)) MyHandleError("Could not query package");

	g_cbMaxMessage = pkgInfo->cbMaxToken;
	FreeContextBuffer(pkgInfo);
	g_pInBuf = (PBYTE) malloc (g_cbMaxMessage);
	g_pOutBuf = (PBYTE) malloc (g_cbMaxMessage);
   
	if (NULL == g_pInBuf || NULL == g_pOutBuf) MyHandleError("Memory allocation");

	ss = AcquireCredentialsHandleA (NULL, g_lpPackageName, SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &hcred, &Lifetime);

	if (!SEC_SUCCESS (ss)) MyHandleError("AcquireCreds failed");
	cbOut = g_cbMaxMessage;

	if (!GenClientContext ( NULL, 0, g_pOutBuf, &cbOut, &fDone, "NTLM", &hCcred, &hCctxt))
		MyHandleError("Cant't generate client context");

	printf ("Type%hhd message (%lu bytes):\n",g_pOutBuf[8], cbOut);//type1
	PrintHexDump (cbOut, (PBYTE)g_pOutBuf);

	memcpy(g_pInBuf,g_pOutBuf, cbOut);
	cbIn = cbOut;
	cbOut = g_cbMaxMessage;


	if (!GenServerContext (g_pInBuf, cbIn, g_pOutBuf, &cbOut, &done, fNewConversation, &hcred, &hctxt))
		MyHandleError("GenServerContext failed");

	fNewConversation = FALSE;

	printf ("Type%hhd message (%lu bytes):\n",g_pOutBuf[8], cbOut); //type2
	PrintHexDump (cbOut, (PBYTE)g_pOutBuf);
	
	memcpy(g_pInBuf,g_pOutBuf, cbOut);
	cbIn = cbOut;
	cbOut = g_cbMaxMessage;

	nonce = (PBYTE) malloc (16);
	memcpy (nonce, (void *)&g_pOutBuf[24], 8);
	
	if (!GenClientContext (g_pInBuf, cbIn, g_pOutBuf, &cbOut, &fDone, "NTLM", &hCcred, &hCctxt))
		MyHandleError("GenClientContext failed");

	printf ("Type%hhd message (%lu bytes):\n",g_pOutBuf[8], cbOut);//type3
	PrintHexDump (cbOut, (PBYTE)g_pOutBuf);

	GetUserNameExA(NameSamCompatible, pUserName, &cbUserName);
	pUserName = (PCHAR) malloc (cbUserName);
	GetUserNameExA(NameSamCompatible, pUserName, &cbUserName);
	cbUserName = (DWORD)((int)strchr(pUserName,'\\'));
	*(char *)cbUserName = 0;

	printf("g_pOutBuf[22]=%d\n",g_pOutBuf[22]);

	if (g_pOutBuf[22] > 24) 
	{
		printf("NTLMv2\n");
		nthash = (PBYTE) malloc (16);
		cbIn = g_pOutBuf[24] + (g_pOutBuf[25] << 8);
		memcpy (nthash, (void *)&g_pOutBuf[cbIn], 16);

		cbIn += 16;
		clientnonce = (PBYTE) malloc (cbOut - cbIn - 16);
		//memcpy (clientnonce, (void *)&g_pOutBuf[cbIn], 84);
		memcpy (clientnonce, (void *)&g_pOutBuf[cbIn], cbOut - cbIn - 16);

		printf("Nonce:  ");
		PrintHex (8, nonce);
		printf("\nClientNonce: ");
		PrintHex (cbOut - cbIn - 16, clientnonce);
		printf("\nNThash: ");
		PrintHex (16, nthash);
		printf("\n");
		
		printf("\nJTR: %s::%s", (unsigned char *)((int)cbUserName+1), (unsigned char *)pUserName);
		printf(":");
		PrintHex (8, nonce);
		printf(":");
		PrintHex (16, nthash);
		printf(":");
		PrintHex (cbOut - cbIn - 16, clientnonce);

		printf("\n");
	}
	else if (g_pOutBuf[22] == 24)
	{
		printf("NTLM\n");
		lmhash = (PBYTE) malloc (24);
		cbIn = g_pOutBuf[16] + (g_pOutBuf[17] << 8);
		memcpy (lmhash, (void *)&g_pOutBuf[cbIn], 24);

		nthash = (PBYTE) malloc (24);
		cbIn = g_pOutBuf[24] + (g_pOutBuf[25] << 8);
		memcpy (nthash, (void *)&g_pOutBuf[cbIn], 24);

		printf("\nNonce:  ");
		PrintHex (8, nonce);
		printf("\nLMhash: ");
		PrintHex (24, lmhash);
		printf("\nNThash: ");
		PrintHex (24, nthash);

		printf("\nJTR: %s::%s", (unsigned char *)((int)cbUserName+1), (unsigned char *)pUserName);
		printf(":");
		PrintHex (24, lmhash);
		printf(":");
		PrintHex (24, nthash);
		printf(":");
		PrintHex (8, nonce);
		printf("\n");
		
	}
	else
	{
		printf("Unknown hashtype");
	}


	return(TRUE);
}
Exemplo n.º 8
0
OM_uint32  gss_init_sec_context (
        OM_uint32 *minor_status,
        gss_cred_id_t claimant_cred_handle,
        gss_ctx_id_t *context_handle,
        gss_name_t target_name,
        gss_OID mech_type,
        int req_flags,
        int time_req,
        gss_channel_bindings_t input_channel_bindings,
        gss_buffer_t input_token,
        gss_OID *actual_mech_types,
        gss_buffer_t output_token,
        int *ret_flags,
        OM_int32 *time_rec)
{
	SecPkgInfoA *secPackInfo = NULL;
	gss_cred_id_t credhandle={0};
	gss_ctx_id_t *pctx;

	// SECBUFFER_TOKEN
	// This buffer type is used to indicate the security token portion of the message. 
	// This is read-only for input parameters or read/write for output parameters.
	SecBuffer InputBuf[1] = {input_token?input_token->length:0,SECBUFFER_TOKEN,input_token?input_token->value:0};
	SecBuffer OutputBuf[1] = {0,SECBUFFER_TOKEN,NULL};
	SecBufferDesc InBuffer[1] = {SECBUFFER_VERSION, 1, InputBuf};
	SecBufferDesc OutBuffer[1] = {SECBUFFER_VERSION, 1, OutputBuf};
	OM_uint32 ret;
	TimeStamp tr;
	unsigned long rf;
	SECURITY_STATUS retq;

	//
	// Previously gserver passed ISC_REQ_ALLOCATE_MEMORY to InitializeSecurityContext
	// but it returns SEC_E_BUFFER_TOO_SMALL - I think this is because
	// only Digest and Schannel will allocate output buffers for you, even though the documentation
	// doesn't make that clear for InitializeSecurityContext (see AcquireCredentialsHandle doco).
	//
	if((retq=QuerySecurityPackageInfoA( "Kerberos", &secPackInfo )) != SEC_E_OK)
		return 0;

	OutputBuf->BufferType = SECBUFFER_TOKEN; // preping a token here
	OutputBuf->cbBuffer = secPackInfo->cbMaxToken;
	OutputBuf->pvBuffer = malloc(secPackInfo->cbMaxToken);

	if(claimant_cred_handle.dwLower==0 && claimant_cred_handle.dwUpper==0)
	{
		static gss_cred_id_t global_client_cred={0};
		if(global_client_cred.dwLower==0 || global_client_cred.dwUpper==0)
		{
			ret = AcquireCredentialsHandleA(NULL,"Kerberos",SECPKG_CRED_OUTBOUND,NULL,NULL,NULL,NULL,&global_client_cred,NULL);
			if(ret)
				return ret;
		}
		credhandle = global_client_cred;
	}
	else
		credhandle = claimant_cred_handle;

	if(context_handle->dwLower==0 && context_handle->dwUpper==0)
		pctx = NULL;
	else
		pctx = context_handle;

	// note - only Digest and Schannel will allocate output buffers for you. 
	// so kerberos and other security contexts should not use ISC_REQ_ALLOCATE_MEMORY
	// and also should not free them by calling the FreeContextBuffer function.
	ret = InitializeSecurityContextA(
		&credhandle, pctx, target_name, req_flags, 0, SECURITY_NETWORK_DREP,
		input_token?InBuffer:NULL,0, pctx?NULL:context_handle, OutBuffer, &rf, &tr); 

	// really need to return if that didn't work...
	if (ret != SEC_E_OK /*GSS_S_COMPLETE*/ && ret != SEC_I_CONTINUE_NEEDED /*GSS_S_CONTINUE_NEEDED*/ )
	{
		free(OutputBuf->pvBuffer);
		OutputBuf->pvBuffer = NULL;
		return ret;
	}

	output_token->length = OutputBuf[0].cbBuffer;
	output_token->value = malloc((OutputBuf[0].cbBuffer)+100);
	if (output_token->value!=NULL)
		memcpy(output_token->value,OutputBuf[0].pvBuffer,output_token->length);
	
	// only call this if InitializeSecurityContext successfully created the buffers for us
	// FreeContextBuffer(OutBuffer);

	// manually made the memory, so manually release it...
	free(OutputBuf->pvBuffer);
	OutputBuf->pvBuffer = NULL;

	*minor_status = 0;
	if(time_rec)
		*time_rec=tr.LowPart;
	if(ret_flags)
		*ret_flags=rf;
	return ret;
}
Exemplo n.º 9
-1
BOOL GenClientContext (BYTE *pIn, DWORD cbIn, BYTE *pOut, DWORD *pcbOut, BOOL *pfDone, SEC_CHAR *pszTarget, CredHandle *hCred, struct _SecHandle *hCtxt)
{
	SECURITY_STATUS   ss;
	TimeStamp         Lifetime;
	SecBufferDesc     OutBuffDesc;
	SecBuffer         OutSecBuff;
	SecBufferDesc     InBuffDesc;
	SecBuffer         InSecBuff;
	ULONG             ContextAttributes;
	SEC_CHAR	      lpPackageName[1024];
	_SEC_WINNT_AUTH_IDENTITY	auth_data;
	PCHAR pUserName = NULL;
	DWORD cbUserName = 0;
	DWORD dw;


	if( NULL == pIn )  
	{   
		GetUserNameExA(NameSamCompatible, pUserName, &cbUserName);
		pUserName = (PCHAR) malloc (cbUserName);
		GetUserNameExA(NameSamCompatible, pUserName, &cbUserName);

		cbUserName = (DWORD)((int)strchr(pUserName,'\\'));
		*(char *)cbUserName = 0;
		auth_data.Domain = (unsigned char *)pUserName;
		auth_data.User = (unsigned char *)((int)cbUserName+1);
		printf("%s@%s\n",(char *)auth_data.User,(char *)auth_data.Domain);

		auth_data.UserLength = strlen((char *)auth_data.User);
		auth_data.DomainLength = strlen((char *)auth_data.Domain);
		auth_data.Password = NULL;
		auth_data.PasswordLength = 0;
		auth_data.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

	   	lstrcpynA (lpPackageName, "NTLM", 5);
	   	ss = AcquireCredentialsHandleA (NULL, lpPackageName, SECPKG_CRED_OUTBOUND, NULL, &auth_data, NULL, NULL, hCred, &Lifetime);
	   	if (!(SEC_SUCCESS (ss))) MyHandleError("AcquireCreds failed ");
	}

	OutBuffDesc.ulVersion = 0;
	OutBuffDesc.cBuffers  = 1;
	OutBuffDesc.pBuffers  = &OutSecBuff;

	OutSecBuff.cbBuffer   = *pcbOut;
	OutSecBuff.BufferType = SECBUFFER_TOKEN;
	OutSecBuff.pvBuffer   = pOut;

	if (pIn)
	{
		 InBuffDesc.ulVersion = 0;
		 InBuffDesc.cBuffers  = 1;
		 InBuffDesc.pBuffers  = &InSecBuff;

		 InSecBuff.cbBuffer   = cbIn;
		 InSecBuff.BufferType = SECBUFFER_TOKEN;
		 InSecBuff.pvBuffer   = pIn;
		ss = InitializeSecurityContextA (hCred,	hCtxt,	pszTarget,	ISC_REQ_CONFIDENTIALITY, 0,	SECURITY_NATIVE_DREP,	&InBuffDesc,	0, 	hCtxt,	&OutBuffDesc, &ContextAttributes,	&Lifetime);
	}
	else
	{
		 ss = InitializeSecurityContextA (hCred, NULL, pszTarget, ISC_REQ_CONFIDENTIALITY, 0, SECURITY_NATIVE_DREP, NULL, 0, hCtxt, &OutBuffDesc, &ContextAttributes, &Lifetime);
	}

	if (!SEC_SUCCESS (ss)) MyHandleError ("InitializeSecurityContext failed " );

	*pcbOut = OutSecBuff.cbBuffer;
	*pfDone = !((SEC_I_CONTINUE_NEEDED == ss) ||(SEC_I_COMPLETE_AND_CONTINUE == ss));
	return TRUE;
}