Lister les groupes auquels appartient un utilisateur (winnt et supérieurs)

Soyez le premier à donner votre avis sur cette source.

Snippet vu 21 353 fois - Téléchargée 32 fois

Contenu du snippet

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

A voir également

Ajouter un commentaire

Commentaires

Messages postés
14
Date d'inscription
jeudi 20 novembre 2003
Statut
Membre
Dernière intervention
29 août 2006

juste pour dire merci.
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
84
ok, mais dans mon cas je ne peux pas l'utiliser :-)
Messages postés
473
Date d'inscription
mercredi 7 août 2002
Statut
Membre
Dernière intervention
10 juin 2015

exact, ca permet de tout lister (sites web, utilisateurs domaine, active directory, netware, machines sur le réseau) c'est une pure merveille
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
84
ads : Active Directory Service je suppose ?
Je devais utiliser ça sur un réseau de 3 postes en workgroup, pas en domaine
Messages postés
473
Date d'inscription
mercredi 7 août 2002
Statut
Membre
Dernière intervention
10 juin 2015

En vb (je ne sais pas l'équivalent de GetObject en c#) pour lister les utilisateurs et les groupes tu fais.
Bien sûr il faut récupérer les références vers WMI (c'est du dcom)

dim ads as iads = getObject("WinNT://domainName")
for each GroupsAndUsers as iads in ads
Console.Out.WriteLine (GroupsAndUser.Name)
next
Afficher les 7 commentaires

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.