Come si determina a livello di codice se un computer Windows è membro di un dominio?

StackOverflow https://stackoverflow.com/questions/206172

  •  03-07-2019
  •  | 
  •  

Domanda

Ho bisogno di un modo per determinare se il computer che esegue il mio programma è unito a qualsiasi dominio. Non importa di quale dominio specifico faccia parte, solo se è collegato a qualcosa. Sto codificando in vc ++ con l'API Win32.

È stato utile?

Soluzione

Direttamente da Microsoft:

Come determinare se un computer Windows NT / Windows 2000 è un membro di dominio

Questo approccio utilizza l'API di Windows. Dal riassunto dell'articolo:

  

Questo articolo descrive come   determinare se un computer che è   che esegue Windows NT 4.0 o Windows 2000   è un membro di un dominio, è un membro   di un gruppo di lavoro o è autonomo   computer che utilizza la sicurezza locale   API di autorità.

L'articolo fornisce anche un codice di esempio per un piccolo programma che indica se il computer su cui è in esecuzione il programma fa parte di un dominio, parte di un gruppo di lavoro o un computer autonomo.

Altri suggerimenti

Penso che la funzione NetServerEnum ti aiuterà in quello che vuoi; Chiederei i controller di dominio primari con la costante SV_TYPE_DOMAIN_CTRL per il parametro servertype . Se non ne ottieni, non sei in un dominio.

È possibile controllare la chiave di registro HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Winlogon per il valore di "CachePrimaryDomain".

Il codice nell'esempio MSDN è un po 'obsoleto. Questa è la funzione che mi è venuta in mente che funziona.

bool ComputerBelongsToDomain()
{
    bool ret = false;

    LSA_OBJECT_ATTRIBUTES objectAttributes;
    LSA_HANDLE policyHandle;
    NTSTATUS status;
    PPOLICY_PRIMARY_DOMAIN_INFO info;

    // Object attributes are reserved, so initialize to zeros.
    ZeroMemory(&objectAttributes, sizeof(objectAttributes));

    status = LsaOpenPolicy(NULL, &objectAttributes, GENERIC_READ | POLICY_VIEW_LOCAL_INFORMATION, &policyHandle);
    if (!status)
    {
        status = LsaQueryInformationPolicy(policyHandle, PolicyPrimaryDomainInformation, (LPVOID*)&info);
        if (!status)
        {
            if (info->Sid)
                ret = true;

            LsaFreeMemory(info);
        }

        LsaClose(policyHandle);
    }

    return ret;
}

Ecco un semplice approccio morto che non vedo menzionato.

TCHAR UserDnsDomain[128] = { 0 }; 
DWORD Result = 0;

Result = GetEnvironmentVariable("USERDNSDOMAIN", UserDnsDomain, sizeof(UserDnsDomain));

if (Result == 0 || Result >= sizeof(UserDnsDomain) || GetLastError() == ERROR_ENVVAR_NOT_FOUND)
{
    return(FALSE); // Not logged in to a domain
}

Questo si basa sull'idea che se l'utente che esegue questo codice non è attualmente connesso a un dominio, la variabile di ambiente USERDNSDOMAIN sarà vuota o non disponibile. Ma ci sono alcuni avvertimenti a cui dovresti pensare.

Pro:

  • Molto facile da implementare.
  • affidabile al 99%.

Contro:

  • Potrebbe non riuscire o restituire risultati falsi se il computer fa parte del dominio, ma l'utente che esegue questo codice è connesso a quel computer con un account locale.
  • Potrebbe non riuscire o restituire risultati falsi se il computer fa parte del dominio, ma la connettività di rete a un controller di dominio non era disponibile al momento dell'accesso / accesso dell'utente con credenziali memorizzate nella cache.

Evita LSA che è un metodo sbagliato. Devi utilizzare DS api (2 righe di codice)

che dire dal nome del computer?

modifica: questa era una "risposta" schifosa dal lontano passato. Ciò che intendevo era scegliere il modulo domain \ name nel nome del computer. Ciò ovviamente implica che conosci il nome del dominio, non risolve il problema di sapere se il computer si trova in un dominio.

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