Il peut être utile des fois de déterminer si un utilisateur est membre d'un groupe ou de lister les groupes auquel appartient un utilisateur.
Voici donc 2 méthodes permettant de le faire : GetLocalGroupsFor et UserIsMemberOf
Méthodes de l'API Netapi32 utilisées : NetApiBufferFree et NetUserGetLocalGroups
Struct : LOCALGROUP_USERS_INFO_0
Source / Exemple :
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace Utils
{
public class UserInfo
{
#region API - Methods
[DllImport("Netapi32.dll")]
private extern static int NetApiBufferFree(
IntPtr Buffer
);
[DllImport("Netapi32.dll")]
private extern static int NetUserGetLocalGroups(
[MarshalAs(UnmanagedType.LPWStr)] string servername,
[MarshalAs(UnmanagedType.LPWStr)] string username,
int level,
int flags,
out IntPtr bufptr,
int prefmaxlen,
out int entriesread,
out int totalentries
);
#endregion
#region API - Consts
private const int MAX_PREFERRED_LENGTH = -1;
private const int LG_INCLUDE_INDIRECT = 0x0001;
private const int NERR_BASE = 2100;
private const int NERR_Success = 0; // Succes.
private const int NERR_InvalidComputer = NERR_BASE + 251; // The computer name is invalid.
private const int NERR_UserNotFound = NERR_BASE + 121; // The user name could not be found.
private const int ERROR_ACCESS_DENIED = 5; // The user does not have access to the requested information.
private const int ERROR_MORE_DATA = 234; // More entries are available. Specify a large enough buffer to receive all entries.
#endregion
#region API - Structs
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
private struct LOCALGROUP_USERS_INFO_0
{
public string groupname;
}
#endregion
/// <overloads>Obtient la liste des groupes dont l'utilisateur est membre.</overloads>
/// <summary>
/// Obtient la liste des groupes dont l'utilisateur est membre, sans inclure les groupes dont l'utilisateur est membre indirectement.
/// </summary>
/// --- PARAMS ---
/// <param name="userName">Nom d'utilisateur.</param>
/// --- EXCEPTIONS ---
/// <exception cref="NotSupportedException">
/// <para>Echec de l'appel à NetUserGetLocalGroups.</para>
/// <para><i>ou</i></para>
/// <para>Cette méthode ne peut s'executer que sur WinNT ou supérieur.</para>
/// </exception>
/// <exception cref="ArgumentNullException"><c>userName</c> est une référence nulle.</exception>
/// <exception cref="ArgumentException">
/// <para>Utilisateur introuvable.</para>
/// <para><i>ou</i></para>
/// <para>Nom d'utilsateur invalide.</para>
/// </exception>
/// <exception cref="SecurityException">Droits insuffisants pour effectuer l'opération.</exception>
/// --- RETURN ---
/// <returns>Liste des groupes dont est membre l'utilisateur.</returns>
public static string[] GetLocalGroupsFor(string userName)
{
try
{
return GetLocalGroupsFor(userName, false);
}
catch
{
throw;
}
}
/// <summary>
/// Obtient la liste des groupes dont l'utilisateur est membre.
/// </summary>
/// --- PARAMS ---
/// <param name="userName">Nom d'utilisateur.</param>
/// <param name="includeIndirect"><c>true</c> pour inclure les groupes dont l'utilisateur est membre indirectement, sinon <c>false</c>.</param>
/// --- EXCEPTIONS ---
/// <exception cref="NotSupportedException">
/// <para>Echec de l'appel à NetUserGetLocalGroups.</para>
/// <para><i>ou</i></para>
/// <para>Cette méthode ne peut s'executer que sur WinNT ou supérieur.</para>
/// </exception>
/// <exception cref="ArgumentNullException"><c>userName</c> est une référence nulle.</exception>
/// <exception cref="ArgumentException">
/// <para>Utilisateur introuvable.</para>
/// <para><i>ou</i></para>
/// <para>Nom d'utilsateur invalide.</para>
/// </exception>
/// <exception cref="SecurityException">Droits insuffisants pour effectuer l'opération.</exception>
/// --- RETURN ---
/// <returns>Liste des groupes dont est membre l'utilisateur.</returns>
public static string[] GetLocalGroupsFor(string userName, bool includeIndirect)
{
if ( Environment.OSVersion.Platform != PlatformID.Win32NT )
throw new NotSupportedException("Cette méthode ne peut s'executer que sur WinNT ou supérieur.");
if ( userName == null )
throw new ArgumentNullException("userName", "Ce paramètre ne peut être une référence nulle.");
int flags = 0;
if ( includeIndirect )
flags = LG_INCLUDE_INDIRECT;
string[] groups;
IntPtr bufptr = IntPtr.Zero;
int entriesread = 0;
int totalentries = 0;
try
{
// récupération des données pour l'utilisateur
int ret = NetUserGetLocalGroups(
null, // sur cette machine
userName, // nom d'utilisateur
0, // level
flags,
out bufptr, // buffer qui sera alloué par le systeme pour y placer les informations
MAX_PREFERRED_LENGTH, // le buffer sera alloué de manière à y stocker toutes les informations
out entriesread,
out totalentries
);
#region Gestion d'erreurs
if ( ret != NERR_Success )
{
if ( ret == ERROR_ACCESS_DENIED )
{
throw new System.Security.SecurityException("Droits insuffisants pour effectuer l'opération.");
}
else if ( ret == NERR_UserNotFound )
{
throw new ArgumentException(userName + " : utilisateur introuvable.");
}
}
#endregion
groups = new string[totalentries];
Type typeOfStruct = typeof(LOCALGROUP_USERS_INFO_0);
int sizeOfStruct = Marshal.SizeOf(typeOfStruct);
LOCALGROUP_USERS_INFO_0 LGInfo;
IntPtr currentStructPtr;
// parcours du buffer
for ( int i=0; i < totalentries; i++ )
{
// définition du pointeur de lecture dans le buffer
currentStructPtr = new IntPtr( (int)bufptr+(i*sizeOfStruct) );
// récupération de l'instance de LOCALGROUP_USERS_INFO_0
LGInfo = (LOCALGROUP_USERS_INFO_0)Marshal.PtrToStructure(currentStructPtr, typeOfStruct);
groups[i] = LGInfo.groupname;
}
}
catch ( Win32Exception ex )
{
throw new NotSupportedException("Echec de l'appel à NetUserGetLocalGroups : " + ex.Message, ex);
}
finally
{
// même en cas d'erreur, la mémoire doit être libérée
NetApiBufferFree(bufptr);
}
return groups;
}
/// <overloads>Détermine si l'utilisateur est membre d'un groupe.</overloads>
/// <summary>
/// Détermine si l'utilisateur est membre d'un groupe, sans inclure les groupes dont l'utilisateur est membre indirectement.
/// </summary>
/// --- PARAMS ---
/// <param name="userName">Nom d'utilisateur.</param>
/// <param name="groupName">Nom du groupe.</param>
/// <param name="includeIndirect"><c>true</c> pour inclure les groupes dont l'utilisateur est membre indirectement, sinon <c>false</c>.</param>
/// --- EXCEPTIONS ---
/// <exception cref="NotSupportedException">
/// <para>Echec de l'appel à NetUserGetLocalGroups.</para>
/// <para><i>ou</i></para>
/// <para>Cette méthode ne peut s'executer que sur WinNT ou supérieur.</para>
/// </exception>
/// <exception cref="ArgumentNullException"><c>userName</c> est une référence nulle.</exception>
/// <exception cref="ArgumentException">
/// <para>Utilisateur introuvable.</para>
/// <para><i>ou</i></para>
/// <para>Nom d'utilsateur invalide.</para>
/// </exception>
/// <exception cref="SecurityException">Droits insuffisants pour effectuer l'opération.</exception>
/// --- RETURN ---
/// <returns><c>true</c> si l'utilisateur est membre du groupe, sinon <c>false</c>.</returns>
public static bool UserIsMemberOf(string userName, string groupName)
{
try
{
return UserIsMemberOf(userName, groupName, false);
}
catch
{
throw;
}
}
/// <summary>
/// Détermine si l'utilisateur est membre d'un groupe.
/// </summary>
/// --- PARAMS ---
/// <param name="userName">Nom d'utilisateur.</param>
/// <param name="groupName">Nom du groupe.</param>
/// <param name="includeIndirect"><c>true</c> pour inclure les groupes dont l'utilisateur est membre indirectement, sinon <c>false</c>.</param>
/// --- EXCEPTIONS ---
/// <exception cref="NotSupportedException">
/// <para>Echec de l'appel à NetUserGetLocalGroups.</para>
/// <para><i>ou</i></para>
/// <para>Cette méthode ne peut s'executer que sur WinNT ou supérieur.</para>
/// </exception>
/// <exception cref="ArgumentNullException"><c>userName</c> est une référence nulle.</exception>
/// <exception cref="ArgumentException">
/// <para>Utilisateur introuvable.</para>
/// <para><i>ou</i></para>
/// <para>Nom d'utilsateur invalide.</para>
/// </exception>
/// <exception cref="SecurityException">Droits insuffisants pour effectuer l'opération.</exception>
/// --- RETURN ---
/// <returns><c>true</c> si l'utilisateur est membre du groupe, sinon <c>false</c>.</returns>
public static bool UserIsMemberOf(string userName, string groupName, bool includeIndirect)
{
try
{
// récupération de la liste des groupes pour l'utilisateur.
string[] groups = GetLocalGroupsFor(userName, includeIndirect);
if ( groups.Length == 0 )
return false;
System.Collections.Specialized.StringCollection strCol = new System.Collections.Specialized.StringCollection();
strCol.AddRange(groups);
return strCol.Contains(groupName);
}
catch
{
throw;
}
}
}
}
Conclusion :
Docs :
NetUserGetLocalGroups :
http://msdn.microsoft.com/en-us/library/aa370655.aspx
NetApiBufferFree :
http://msdn.microsoft.com/en-us/library/aa370304.aspx
LOCALGROUP_USERS_INFO_0 :
http://msdn.microsoft.com/en-us/library/aa370282.aspx
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.