NetworkAPI.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Runtime.InteropServices;
  10. using Utilities;
  11. namespace SMBLibrary.Win32.Security
  12. {
  13. public class NetworkAPI
  14. {
  15. public const int NERR_Success = 0;
  16. public const uint NERR_UserNotFound = 2221;
  17. public const int MAX_PREFERRED_LENGTH = -1;
  18. public const int FILTER_NORMAL_ACCOUNT = 2;
  19. public const int UF_ACCOUNTDISABLE = 2;
  20. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  21. public struct USER_INFO_0
  22. {
  23. [MarshalAs(UnmanagedType.LPWStr)]
  24. public String Username;
  25. }
  26. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  27. public struct USER_INFO_1
  28. {
  29. [MarshalAs(UnmanagedType.LPWStr)]
  30. public string Username;
  31. [MarshalAs(UnmanagedType.LPWStr)]
  32. public string Password;
  33. public uint PasswordAge;
  34. public uint Priv;
  35. [MarshalAs(UnmanagedType.LPWStr)]
  36. public string Home_Dir;
  37. [MarshalAs(UnmanagedType.LPWStr)]
  38. public string Comment;
  39. public uint Flags;
  40. [MarshalAs(UnmanagedType.LPWStr)]
  41. public string ScriptPath;
  42. }
  43. [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
  44. public struct LOCALGROUP_USERS_INFO_0
  45. {
  46. public string groupname;
  47. }
  48. // NetAPIBufferFree - Used to free buffer allocation after NetUserEnum / NetUserGetInfo / NetUserGetLocalGroups
  49. [DllImport("Netapi32.dll")]
  50. public extern static int NetApiBufferFree(IntPtr buffer);
  51. // NetUserEnum - Obtains a list of all users on local machine or network
  52. [DllImport("Netapi32.dll")]
  53. public extern static int NetUserEnum([MarshalAs(UnmanagedType.LPWStr)]string servername, int level, int filter, out IntPtr bufPtr, int prefmaxlen, out int entriesread, out int totalentries, out int resume_handle);
  54. // NetUserGetInfo - Retrieves information about a particular user account on a server
  55. [DllImport("Netapi32.dll")]
  56. public extern static int NetUserGetInfo([MarshalAs(UnmanagedType.LPWStr)]string servername, [MarshalAs(UnmanagedType.LPWStr)]string userName, int level, out IntPtr bufPtr);
  57. [DllImport("Netapi32.dll")]
  58. public 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);
  59. public static List<string> EnumerateGroups(string userName)
  60. {
  61. List<string> result = new List<string>();
  62. int entriesRead;
  63. int totalEntries;
  64. IntPtr bufPtr;
  65. const int Level = 0;
  66. int status = NetUserGetLocalGroups(null, userName, Level, 0, out bufPtr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries);
  67. if (status != NERR_Success)
  68. {
  69. throw new Exception("NetUserGetLocalGroups failed, Error code: " + status.ToString());
  70. }
  71. if (entriesRead > 0)
  72. {
  73. LOCALGROUP_USERS_INFO_0[] RetGroups = new LOCALGROUP_USERS_INFO_0[entriesRead];
  74. IntPtr iter = bufPtr;
  75. for (int i = 0; i < entriesRead; i++)
  76. {
  77. RetGroups[i] = (LOCALGROUP_USERS_INFO_0)Marshal.PtrToStructure(iter, typeof(LOCALGROUP_USERS_INFO_0));
  78. iter = new IntPtr(iter.ToInt64() + Marshal.SizeOf(typeof(LOCALGROUP_USERS_INFO_0)));
  79. result.Add(RetGroups[i].groupname);
  80. }
  81. NetApiBufferFree(bufPtr);
  82. }
  83. return result;
  84. }
  85. public static List<string> EnumerateAllUsers()
  86. {
  87. List<string> result = new List<string>();
  88. int entriesRead;
  89. int totalEntries;
  90. int resume;
  91. IntPtr bufPtr;
  92. const int Level = 0;
  93. const int FILTER_NORMAL_ACCOUNT = 2;
  94. int status = NetUserEnum(null, Level, FILTER_NORMAL_ACCOUNT, out bufPtr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, out resume);
  95. if (status != NERR_Success)
  96. {
  97. throw new Exception("NetUserEnum failed, Error code: " + status.ToString());
  98. }
  99. if (entriesRead > 0)
  100. {
  101. USER_INFO_0[] Users = new USER_INFO_0[entriesRead];
  102. IntPtr iter = bufPtr;
  103. for (int i = 0; i < entriesRead; i++)
  104. {
  105. Users[i] = (USER_INFO_0)Marshal.PtrToStructure(iter, typeof(USER_INFO_0));
  106. iter = new IntPtr(iter.ToInt64() + Marshal.SizeOf(typeof(USER_INFO_0)));
  107. result.Add(Users[i].Username);
  108. }
  109. NetApiBufferFree(bufPtr);
  110. }
  111. return result;
  112. }
  113. public static List<string> EnumerateEnabledUsers()
  114. {
  115. List<string> result = new List<string>();
  116. int entriesRead;
  117. int totalEntries;
  118. int resume;
  119. IntPtr bufPtr;
  120. int level = 1;
  121. int status = NetUserEnum(null, level, FILTER_NORMAL_ACCOUNT, out bufPtr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, out resume);
  122. if (status != NERR_Success)
  123. {
  124. throw new Exception("NetUserEnum failed, Error code: " + status.ToString());
  125. }
  126. if (entriesRead > 0)
  127. {
  128. USER_INFO_1[] Users = new USER_INFO_1[entriesRead];
  129. IntPtr iter = bufPtr;
  130. for (int i = 0; i < entriesRead; i++)
  131. {
  132. Users[i] = (USER_INFO_1)Marshal.PtrToStructure(iter, typeof(USER_INFO_1));
  133. iter = new IntPtr(iter.ToInt64() + Marshal.SizeOf(typeof(USER_INFO_1)));
  134. if ((Users[i].Flags & UF_ACCOUNTDISABLE) == 0)
  135. {
  136. result.Add(Users[i].Username);
  137. }
  138. }
  139. NetApiBufferFree(bufPtr);
  140. }
  141. return result;
  142. }
  143. public static bool IsUserExists(string userName)
  144. {
  145. int level = 0;
  146. IntPtr bufPtr;
  147. int result = NetUserGetInfo(null, userName, level, out bufPtr);
  148. if (result == NERR_Success)
  149. {
  150. NetApiBufferFree(bufPtr);
  151. return true;
  152. }
  153. else if (result == NERR_UserNotFound)
  154. {
  155. return false;
  156. }
  157. else
  158. {
  159. throw new Exception("NetUserGetInfo failed, Error code: " + result.ToString());
  160. }
  161. }
  162. public static List<string> EnumerateNetworkUsers()
  163. {
  164. List<string> result = new List<string>();
  165. List<string> users = EnumerateEnabledUsers();
  166. foreach (string userName in users)
  167. {
  168. List<string> groups = EnumerateGroups(userName);
  169. if (groups.Contains("Users") || groups.Contains("Administrators") || groups.Contains("Guests"))
  170. {
  171. result.Add(userName);
  172. }
  173. }
  174. return result;
  175. }
  176. }
  177. }