NetworkAPI.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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 uint NERR_Success = 0;
  16. public const uint NERR_UserNotFound = 2221;
  17. public const uint MAX_PREFERRED_LENGTH = 0xFFFFFFFF;
  18. public const uint FILTER_NORMAL_ACCOUNT = 2;
  19. public const uint 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 uint NetApiBufferFree(IntPtr buffer);
  51. // NetUserEnum - Obtains a list of all users on local machine or network
  52. [DllImport("Netapi32.dll")]
  53. public extern static uint NetUserEnum([MarshalAs(UnmanagedType.LPWStr)]string servername, uint level, uint filter, out IntPtr bufPtr, uint prefmaxlen, out uint entriesread, out uint totalentries, out uint resume_handle);
  54. // NetUserGetInfo - Retrieves information about a particular user account on a server
  55. [DllImport("Netapi32.dll")]
  56. public extern static uint NetUserGetInfo([MarshalAs(UnmanagedType.LPWStr)]string servername, [MarshalAs(UnmanagedType.LPWStr)]string userName, uint level, out IntPtr bufPtr);
  57. [DllImport("Netapi32.dll")]
  58. public extern static uint NetUserGetLocalGroups([MarshalAs(UnmanagedType.LPWStr)]string servername,[MarshalAs(UnmanagedType.LPWStr)] string username, uint level, uint flags, out IntPtr bufPtr, uint prefmaxlen, out uint entriesread, out uint totalentries);
  59. public static List<string> EnumerateGroups(string userName)
  60. {
  61. List<string> result = new List<string>();
  62. uint entriesRead;
  63. uint totalEntries;
  64. IntPtr bufPtr;
  65. uint level = 0;
  66. uint 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. uint entriesRead;
  89. uint totalEntries;
  90. uint resume;
  91. IntPtr bufPtr;
  92. uint level = 0;
  93. uint status = NetUserEnum(null, level, FILTER_NORMAL_ACCOUNT, out bufPtr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, out resume);
  94. if (status != NERR_Success)
  95. {
  96. throw new Exception("NetUserEnum failed, Error code: " + status.ToString());
  97. }
  98. if (entriesRead > 0)
  99. {
  100. USER_INFO_0[] Users = new USER_INFO_0[entriesRead];
  101. IntPtr iter = bufPtr;
  102. for (int i = 0; i < entriesRead; i++)
  103. {
  104. Users[i] = (USER_INFO_0)Marshal.PtrToStructure(iter, typeof(USER_INFO_0));
  105. iter = new IntPtr(iter.ToInt64() + Marshal.SizeOf(typeof(USER_INFO_0)));
  106. result.Add(Users[i].Username);
  107. }
  108. NetApiBufferFree(bufPtr);
  109. }
  110. return result;
  111. }
  112. public static List<string> EnumerateEnabledUsers()
  113. {
  114. List<string> result = new List<string>();
  115. uint entriesRead;
  116. uint totalEntries;
  117. uint resume;
  118. IntPtr bufPtr;
  119. uint level = 1;
  120. uint status = NetUserEnum(null, level, FILTER_NORMAL_ACCOUNT, out bufPtr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, out resume);
  121. if (status != NERR_Success)
  122. {
  123. throw new Exception("NetUserEnum failed, Error code: " + status.ToString());
  124. }
  125. if (entriesRead > 0)
  126. {
  127. USER_INFO_1[] Users = new USER_INFO_1[entriesRead];
  128. IntPtr iter = bufPtr;
  129. for (int i = 0; i < entriesRead; i++)
  130. {
  131. Users[i] = (USER_INFO_1)Marshal.PtrToStructure(iter, typeof(USER_INFO_1));
  132. iter = new IntPtr(iter.ToInt64() + Marshal.SizeOf(typeof(USER_INFO_1)));
  133. if ((Users[i].Flags & UF_ACCOUNTDISABLE) == 0)
  134. {
  135. result.Add(Users[i].Username);
  136. }
  137. }
  138. NetApiBufferFree(bufPtr);
  139. }
  140. return result;
  141. }
  142. public static bool IsUserExists(string userName)
  143. {
  144. uint level = 0;
  145. IntPtr bufPtr;
  146. uint result = NetUserGetInfo(null, userName, level, out bufPtr);
  147. if (result == NERR_Success)
  148. {
  149. NetApiBufferFree(bufPtr);
  150. return true;
  151. }
  152. else if (result == NERR_UserNotFound)
  153. {
  154. return false;
  155. }
  156. else
  157. {
  158. throw new Exception("NetUserGetInfo failed, Error code: " + result.ToString());
  159. }
  160. }
  161. public static List<string> EnumerateNetworkUsers()
  162. {
  163. List<string> result = new List<string>();
  164. List<string> users = EnumerateEnabledUsers();
  165. foreach (string userName in users)
  166. {
  167. List<string> groups = EnumerateGroups(userName);
  168. if (groups.Contains("Users") || groups.Contains("Administrators") || groups.Contains("Guests"))
  169. {
  170. result.Add(userName);
  171. }
  172. }
  173. return result;
  174. }
  175. }
  176. }