IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Détecter un compte admin (différence W7 et W10)


Sujet :

API, COM et SDKs Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2007
    Messages : 113
    Par défaut Détecter un compte admin (différence W7 et W10)
    Bonjour à tous

    je cherche à faire une fonction pour savoir si l'utilisateur connecté est un compte admin.

    J'ai trouvé un code ( voir plus bas ) sur le net, qui fonctionne bien sous Windows 7 avec Delphi 10.2.3 ( Tokyo ).

    ==> Fonction IsAdminLoggedOn.

    Sur un autre de mes PC, sous Windows 10, si je compile le même code ( avec le même Delphi 10.2.3 ) il ne fonctionne pas : un compte Admin n'est pas détecté comme tel.

    Pourquoi ? Utilisation d'API windows ?

    Sinon, comment savoir si un compte est admin ( fiable ) ?

    C'est quand même pénible ce genre de comportement...en 2018, il faut encore galérer juste pour savoir si un compte est admin...
    Puis vérifier si ça marche sous tous les windows...et aussi selon l'OS du compilateur ...

    Ha les joies de la prog ! ;-)

    Merci & Bonne année 2019 à tous :-)

    le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    function IsAdminLoggedOn: Boolean;
     
     
    implementation
     
    function IsMemberOfGroup(const DomainAliasRid: DWORD): Boolean;
    { Returns True if the logged-on user is a member of the specified local
      group. Always returns True on Windows 9x/Me. }
     
    {$DEFINE  Delphi3orHigher}
     
    const
      SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
        (Value: (0, 0, 0, 0, 0, 5));
      SECURITY_BUILTIN_DOMAIN_RID = $00000020;
      SE_GROUP_ENABLED           = $00000004;
      SE_GROUP_USE_FOR_DENY_ONLY = $00000010;
    var
      Sid: PSID;
      CheckTokenMembership: function(TokenHandle: THandle; SidToCheck: PSID;
        var IsMember: BOOL): BOOL; stdcall;
      IsMember: BOOL;
      Token: THandle;
      GroupInfoSize: DWORD;
      GroupInfo: PTokenGroups;
      I: Integer;
    begin
      if Win32Platform <> VER_PLATFORM_WIN32_NT then begin
        Result := True;
        Exit;
      end;
     
      Result := False;
     
      if not AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
         SECURITY_BUILTIN_DOMAIN_RID, DomainAliasRid,
         0, 0, 0, 0, 0, 0, Sid) then
        Exit;
      try
        { Use CheckTokenMembership if available. MSDN states:
          "The CheckTokenMembership function should be used with Windows 2000 and
          later to determine whether a specified SID is present and enabled in an
          access token. This function eliminates potential misinterpretations of
          the active group membership if changes to access tokens are made in
          future releases." }
        CheckTokenMembership := nil;
        if Lo(GetVersion) >= 5 then
          CheckTokenMembership := GetProcAddress(GetModuleHandle(advapi32),
            'CheckTokenMembership');
        if Assigned(CheckTokenMembership) then begin
          if CheckTokenMembership(0, Sid, IsMember) then
            Result := IsMember;
        end
        else begin
          GroupInfo := nil;
          if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
             {$IFDEF Delphi3orHigher}Token{$ELSE}@Token{$ENDIF}) then
            begin
            if GetLastError <> ERROR_NO_TOKEN then
              Exit;
            if not OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
               {$IFDEF Delphi3orHigher} Token {$ELSE} @Token {$ENDIF}) then
              Exit;
          end;
          try
            GroupInfoSize := 0;
            if not GetTokenInformation(Token, TokenGroups, nil, 0, GroupInfoSize) and
               (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then
              Exit;
     
            GetMem(GroupInfo, GroupInfoSize);
            if not GetTokenInformation(Token, TokenGroups, GroupInfo,
               GroupInfoSize, GroupInfoSize) then
              Exit;
     
            for I := 0 to GroupInfo.GroupCount-1 do begin
              if EqualSid(Sid, GroupInfo.Groups[I].Sid) and
                 (GroupInfo.Groups[I].Attributes and (SE_GROUP_ENABLED or
                  SE_GROUP_USE_FOR_DENY_ONLY) = SE_GROUP_ENABLED) then begin
                Result := True;
                Break;
              end;
            end;
          finally
            FreeMem(GroupInfo);
            CloseHandle(Token);
          end;
        end;
      finally
        FreeSid(Sid);
      end;
    end;
     
    function IsAdminLoggedOn: Boolean;
    { Returns True if the logged-on user is a member of the Administrators local
      group. Always returns True on Windows 9x/Me. }
    const
      DOMAIN_ALIAS_RID_ADMINS = $00000220;
    begin
      Result := IsMemberOfGroup(DOMAIN_ALIAS_RID_ADMINS);
    end;

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 934
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 934
    Par défaut
    Tu devrais avoir le même comportement sous Win7 à moins que l'UAC soit désactivé.

    Un admin n'a que des droits limités (un jeton "compte limité") tant qu'il n'y a pas eu d'élévation de privilèges. C'est seulement après l'élévation que tous les droits lui sont accordés (le jeton "administrateur").
    La fonction CheckTokenMembership (comme son nom ne l'indique pas) teste le jeton actuel de l'utilisateur et non son appartenance à un groupe (mais c'était le cas avant Vista puisque l'admin n'avait qu'un seul jeton à cette époque). Elle retourne donc une information différente en fonction de l'élévation.

    Ce que tu aimerais correspond à la deuxième partie de ta fonction. A l'aide de GetTokenInformation tu peux effectivement t'assurer que l'utilisateur fait partie du groupe administrateur.
    Il suffit donc de scinder cette fonction en deux : IsAdmin et IsAdminGroup.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    const
      SECURITY_NT_AUTHORITY :TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
      SECURITY_BUILTIN_DOMAIN_RID = $00000020;
      DOMAIN_ALIAS_RID_ADMINS     = $00000220;
     
    function IsAdmin :boolean;
    var
      CheckTokenMembership :function(TokenHandle: THandle; SidToCheck: PSID; var IsMember: BOOL): BOOL; stdcall;
      DLL      :THandle;
      SID      :Pointer;
      IsMember :BOOL;
     
    begin
      Result := FALSE;
     
      if AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, SID) then
      try
        DLL := LoadLibrary(advapi32);
     
        if DLL <> 0 then
        try
          CheckTokenMembership := GetProcAddress(DLL, 'CheckTokenMembership');
     
          if Assigned(CheckTokenMembership)         and
             CheckTokenMembership(0, SID, IsMember) then
            Result := IsMember;
     
        finally
          FreeLibrary(DLL);
        end;
     
      finally
        FreeSid(SID);
      end;
    end;
     
    function IsAdminGroup: boolean;
    var
      Token  :THandle;
      Groups :PTokenGroups;
      Len    :dword;
      SID    :pointer;
      i      :integer;
     
    begin
      if not OpenProcessToken(GetCurrentProcess, TOKEN_READ, Token) then Exit(FALSE);
     
      try
        GetTokenInformation(Token, TokenGroups, nil, 0, Len);
        GetMem(Groups, Len);
     
        try
          if not GetTokenInformation(Token, TokenGroups, Groups, Len, Len) then Exit(FALSE);
          if not AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, SID) then Exit(FALSE);
     
          try
            for i := 0 to Groups.GroupCount -1 do
              if EqualSID(SID, Groups.Groups[i].Sid) then
                Exit(TRUE);
     
            Result := FALSE;
     
          finally
            FreeSID(SID);
          end;
     
        finally
          FreeMem(Groups);
        end;
     
      finally
        CloseHandle(Token);
      end;
    end;
    Bien sûr, si tu dois accéder à des emplacements protégés sur le disque ou en BdR, il faut obligatoirement te baser sur IsAdmin. IsAdminGroup est surtout informatif.


    Bonne année à tous

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2007
    Messages : 113
    Par défaut
    Bonjour & Bonne année 2019 :-)

    Que viens faire l'UAC la dedans ? Désactivé ou pas, ça ne change pas la réponse à la question " l'utilisateur connecté est il admin ? , non ?

    Sinon, résultats sur ta proposition, scinder la fonction:

    Sous Windows 7 ( Delphi + le code test ) : tout OK, UAC désactivé

    Sous Windows 10 ( Delphi + le code test ) , UAC désactivé : IsAdmin : ne fonctionne pas, IsAdminGroup : OK

    Réponse pas simple pour une question simple...

    Merci, Pascal

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 934
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 934
    Par défaut
    Citation Envoyé par pascal07 Voir le message
    Que viens faire l'UAC la dedans ?
    C'est le douanier qui contrôle que ton visa est valide (même si toi tu le sais pertinemment)

    Citation Envoyé par pascal07 Voir le message
    l'utilisateur connecté est il admin ?
    La question ne se pose pas/plus vraiment en ces termes, ce serait plutôt " l'utilisateur connecté peut-il recevoir des droits administrateurs ? "

    Citation Envoyé par pascal07 Voir le message
    Sous Windows 7 ( Delphi + le code test ) : tout OK, UAC désactivé
    Sous Windows 10 ( Delphi + le code test ) , UAC désactivé : IsAdmin : ne fonctionne pas, IsAdminGroup : OK
    Il y a effectivement une différence de comportement avec l'UAC réglé au minimum. Sans doute depuis Windows 8 et les Universal Apps qui ne fonctionnent tout simplement pas sans lui.

    Mais UAC réglé au minimum ne veut pas dire désactivé. Pour cela, il faut modifier les stratégies de sécurité : gpedit.msc -> Stratégies locales -> Options de sécurité -> Contrôle de compte d’utilisateur : exécuter le comptes d'administrateurs en mode d'approbation d'administrateur (suivi d'un redémarrage bien sûr).

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2007
    Messages : 113
    Par défaut
    Bonjour

    N’empêche que je ne comprend pas, pourquoi sous Windows10:

    - Le compte admin utilisé pour compiler ( avec Delphi 10.2 Tokyo ) et tester est dans le groupe Admin ( fonction IsAdminGroup ) mais n'est pas admin ( fonction IsAdmin )

    pour moi c'est contradictoire, non ?

    Si les membres du groupe Admin ne sont pas admin...

    Merci

    Pascal

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 934
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 934
    Par défaut
    Citation Envoyé par pascal07 Voir le message
    pour moi c'est contradictoire, non ?
    Pas dans la logique actuelle où rien ne doit pouvoir être modifié/installé sans le consentement explicite de l'utilisateur.

Discussions similaires

  1. Compte admin disparu même sous Users
    Par zimoun dans le forum Mac OS X
    Réponses: 11
    Dernier message: 16/04/2010, 19h15
  2. Réponses: 6
    Dernier message: 08/12/2006, 14h59
  3. problème de compilation sous XP/Centrino?
    Par RalphH dans le forum C++Builder
    Réponses: 19
    Dernier message: 23/10/2004, 16h12
  4. problème de compilation sous visual C++
    Par fabmili dans le forum MFC
    Réponses: 4
    Dernier message: 08/02/2004, 19h52
  5. [TP]Probleme de compilation sous TP7
    Par yffick dans le forum Turbo Pascal
    Réponses: 7
    Dernier message: 18/12/2003, 20h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo