Domanda

Sto cercando di convalidare le credenziali di Windows di un utente su un computer che non è unito al dominio. Sembra che questo dovrebbe essere possibile fare utilizzando l'API SSPI, ma non sono stato in grado di farlo funzionare.

ho inserito il codice che ho provato (pulizia risorsa omesse per brevità). Questi sono i pezzi importanti di informazioni:

controller di dominio: control.dundermifflin.com
Domain: DUNDERMIFFLIN
Utente: jim_halpert
Passo: Beesly

(sto testando su una rete-air gap, quindi non c'è alcun conflitto DNS con il reale dundermifflin.com.)

L'errore che ottengo è SEC_E_LOGON_DENIED. Sono positivo che il nome utente e la password sono corretti, dato che posso accedere a tale utente con altre applicazioni. Qualcuno mi può punto nella giusta direzione?

#include <Windows.h>
#define SECURITY_WIN32
#include <Security.h>
#include <crtdbg.h>

#pragma comment( lib, "Secur32.lib" )

int main()
{
    SEC_CHAR* principal = "HOST/control.dundermifflin.com";
    SEC_CHAR* spn       = NULL;

    SEC_CHAR* domain = "DUNDERMIFFLIN";
    SEC_CHAR* user   = "jim_halpert";
    SEC_CHAR* pass   = "beesly";

    /////////////////////////////////////////////
    // Fill out the authentication information //
    /////////////////////////////////////////////

    SEC_WINNT_AUTH_IDENTITY auth;
    auth.Domain         = reinterpret_cast<unsigned char*>( domain );
    auth.DomainLength   = strlen( domain );
    auth.User           = reinterpret_cast<unsigned char*>( user );
    auth.UserLength     = strlen( user );
    auth.Password       = reinterpret_cast<unsigned char*>( pass );
    auth.PasswordLength = strlen( pass );
    auth.Flags          = SEC_WINNT_AUTH_IDENTITY_ANSI;

    ////////////////////////////////////////////
    // Allocate the client and server buffers //
    ////////////////////////////////////////////

    char clientOutBufferData[8192];
    char serverOutBufferData[8192];

    SecBuffer     clientOutBuffer;
    SecBufferDesc clientOutBufferDesc;

    SecBuffer     serverOutBuffer;
    SecBufferDesc serverOutBufferDesc;

    ///////////////////////////////////////////
    // Get the client and server credentials //
    ///////////////////////////////////////////

    CredHandle clientCredentials;
    CredHandle serverCredentials;

    SECURITY_STATUS status;

    status = ::AcquireCredentialsHandle( principal,
                                         "Negotiate",
                                         SECPKG_CRED_OUTBOUND,
                                         NULL,
                                         &auth,
                                         NULL,
                                         NULL,
                                         &clientCredentials,
                                         NULL );

    _ASSERT( status == SEC_E_OK );

    status = ::AcquireCredentialsHandle( principal,
                                         "Negotiate",
                                         SECPKG_CRED_INBOUND,
                                         NULL,
                                         NULL,
                                         NULL,
                                         NULL,
                                         &serverCredentials,
                                         NULL );

    _ASSERT( status == SEC_E_OK );

    //////////////////////////////////////
    // Initialize the security contexts //
    //////////////////////////////////////

    CtxtHandle clientContext = {};
    unsigned long clientContextAttr = 0;

    CtxtHandle serverContext = {};
    unsigned long serverContextAttr = 0;

    /////////////////////////////
    // Clear the client buffer //
    /////////////////////////////

    clientOutBuffer.BufferType = SECBUFFER_TOKEN;
    clientOutBuffer.cbBuffer   = sizeof clientOutBufferData;
    clientOutBuffer.pvBuffer   = clientOutBufferData;

    clientOutBufferDesc.cBuffers  = 1;
    clientOutBufferDesc.pBuffers  = &clientOutBuffer;
    clientOutBufferDesc.ulVersion = SECBUFFER_VERSION;

    ///////////////////////////////////
    // Initialize the client context //
    ///////////////////////////////////

    status = InitializeSecurityContext( &clientCredentials,
                                        NULL,
                                        spn,
                                        0,
                                        0,
                                        SECURITY_NATIVE_DREP,
                                        NULL,
                                        0,
                                        &clientContext,
                                        &clientOutBufferDesc,
                                        &clientContextAttr,
                                        NULL );

    _ASSERT( status == SEC_I_CONTINUE_NEEDED );

    /////////////////////////////
    // Clear the server buffer //
    /////////////////////////////

    serverOutBuffer.BufferType = SECBUFFER_TOKEN;
    serverOutBuffer.cbBuffer   = sizeof serverOutBufferData;
    serverOutBuffer.pvBuffer   = serverOutBufferData;

    serverOutBufferDesc.cBuffers  = 1;
    serverOutBufferDesc.pBuffers  = &serverOutBuffer;
    serverOutBufferDesc.ulVersion = SECBUFFER_VERSION;

    //////////////////////////////////////////////////////
    // Accept the client security context on the server //
    //////////////////////////////////////////////////////

    status = AcceptSecurityContext( &serverCredentials,
                                    NULL,
                                    &clientOutBufferDesc,
                                    0,
                                    SECURITY_NATIVE_DREP,
                                    &serverContext,
                                    &serverOutBufferDesc,
                                    &serverContextAttr,
                                    NULL );

    _ASSERT( status == SEC_I_CONTINUE_NEEDED );

    /////////////////////////////
    // Clear the client buffer //
    /////////////////////////////

    clientOutBuffer.BufferType = SECBUFFER_TOKEN;
    clientOutBuffer.cbBuffer   = sizeof clientOutBufferData;
    clientOutBuffer.pvBuffer   = clientOutBufferData;

    clientOutBufferDesc.cBuffers  = 1;
    clientOutBufferDesc.pBuffers  = &clientOutBuffer;
    clientOutBufferDesc.ulVersion = SECBUFFER_VERSION;

    ///////////////////////////////////////
    // Give the client the server buffer //
    ///////////////////////////////////////

    status = InitializeSecurityContext( &clientCredentials,
                                        &clientContext,
                                        spn,
                                        0,
                                        0,
                                        SECURITY_NATIVE_DREP,
                                        &serverOutBufferDesc,
                                        0,
                                        &clientContext,
                                        &clientOutBufferDesc,
                                        &clientContextAttr,
                                        NULL );

    _ASSERT( status == SEC_E_OK );

    //////////////////////////////////////////////////////
    // Accept the client security context on the server //
    //////////////////////////////////////////////////////

    status = AcceptSecurityContext( &serverCredentials,
                                    &serverContext,
                                    &clientOutBufferDesc,
                                    0,
                                    SECURITY_NATIVE_DREP,
                                    &serverContext,
                                    &serverOutBufferDesc,
                                    &serverContextAttr,
                                    NULL );

    _ASSERT( status == SEC_E_LOGON_DENIED );
}
È stato utile?

Soluzione

Questo non è andare a lavorare, dal momento che sono sulla stessa macchina che non conosce il dominio control.dundermifflin.com.

Se si desidera confermare il nome utente e la password, il modo più semplice è quello di autenticare ad una macchina nel dominio effettivo. Può essere facile come "net use \ dc \ netlogon / u: username password", ma lei non ha citato se si tratta di un must per essere fatto attraverso SSPI. Se lo è, è necessario trovare un servizio sul DC per l'autenticazione. È possibile utilizzare LDAP per esempio.

Un altro modo che può funzionare è quello di raccontare la vostra macchina non di dominio per il dominio che si sta tentando di raggiungere. Questo può essere fatto utilizzando lo strumento ksetup. Essa vi permetterà di configurare un nome host KDC per il dominio che hai. Guarda l'opzione / AddKdc. Questo vi permetterà di Kerberos sapere che per il regno in dotazione (alias dominio) dovrebbe andare al nome host fornito come per le richieste di KDC.

Spero che questo aiuta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top