Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
9.4 KiB

  1. /*++
  2. Microsoft Windows
  3. Copyright (C) Microsoft Corporation, 1981 - 1998
  4. Module Name:
  5. security.cxx
  6. Abstract:
  7. This file contains utility functions concerning file security, e.g.
  8. convertings SIDs to strings and back, getting the display name for
  9. a given sid or getting the sid, given the display name
  10. Author:
  11. Rahul Thombre (RahulTh) 9/28/1998
  12. Revision History:
  13. 9/28/1998 RahulTh Created this module.
  14. --*/
  15. #include "precomp.hxx"
  16. //+--------------------------------------------------------------------------
  17. //
  18. // Function: LoadSidAuthFromString
  19. //
  20. // Synopsis: given a string representing the SID authority (as it is
  21. // normally represented in string format, fill the SID_AUTH..
  22. // structure. For more details on the format of the string
  23. // representation of the sid authority, refer to ntseapi.h and
  24. // ntrtl.h
  25. //
  26. // Arguments: [in] pString : pointer to the unicode string
  27. // [out] pSidAuth : pointer to the SID_IDENTIFIER_AUTH.. that is
  28. // desired
  29. //
  30. // Returns: STATUS_SUCCESS if it succeeds
  31. // or an error code
  32. //
  33. // History: 9/29/1998 RahulTh created
  34. //
  35. // Notes:
  36. //
  37. //---------------------------------------------------------------------------
  38. NTSTATUS LoadSidAuthFromString (const WCHAR* pString,
  39. PSID_IDENTIFIER_AUTHORITY pSidAuth)
  40. {
  41. size_t len;
  42. int i;
  43. NTSTATUS Status;
  44. const ULONG LowByteMask = 0xFF;
  45. ULONG n;
  46. len = wcslen (pString);
  47. if (len > 2 && 'x' == pString[1])
  48. {
  49. //this is in hex.
  50. //so we must have exactly 14 characters
  51. //(2 each for each of the 6 bytes) + 2 for the leading 0x
  52. if (14 != len)
  53. {
  54. Status = ERROR_INVALID_SID;
  55. goto LoadAuthEnd;
  56. }
  57. for (i=0; i < 6; i++)
  58. {
  59. pString += 2; //we need to skip the leading 0x
  60. pSidAuth->Value[i] = (UCHAR)(((pString[0] - L'0') << 4) +
  61. (pString[1] - L'0'));
  62. }
  63. }
  64. else
  65. {
  66. //this is in decimal
  67. Status = GetIntFromUnicodeString (pString, 10, &n);
  68. if (Status != STATUS_SUCCESS)
  69. goto LoadAuthEnd;
  70. pSidAuth->Value[0] = pSidAuth->Value[1] = 0;
  71. for (i = 5; i >=2; i--, n>>=8)
  72. pSidAuth->Value[i] = (UCHAR)(n & LowByteMask);
  73. }
  74. Status = STATUS_SUCCESS;
  75. LoadAuthEnd:
  76. return Status;
  77. }
  78. //+--------------------------------------------------------------------------
  79. //
  80. // Function: AllocateAndInitSidFromString
  81. //
  82. // Synopsis: given the string representation of a SID, this function
  83. // allocate and initializes a SID which the string represents
  84. // For more information on the string representation of SIDs
  85. // refer to ntseapi.h & ntrtl.h
  86. //
  87. // Arguments: [in] lpszSidStr : the string representation of the SID
  88. // [out] pSID : the actual SID structure created from the string
  89. //
  90. // Returns: STATUS_SUCCESS : if the sid structure was successfully created
  91. // or an error code based on errors that might occur
  92. //
  93. // History: 9/30/1998 RahulTh created
  94. //
  95. // Notes:
  96. //
  97. //---------------------------------------------------------------------------
  98. NTSTATUS AllocateAndInitSidFromString (const WCHAR* lpszSidStr, PSID* ppSid)
  99. {
  100. CString SidStr;
  101. WCHAR* pSidStr;
  102. WCHAR* pString;
  103. NTSTATUS Status;
  104. WCHAR* pEnd;
  105. int count;
  106. BYTE SubAuthCount;
  107. DWORD SubAuths[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  108. ULONG n;
  109. int len;
  110. SID_IDENTIFIER_AUTHORITY Auth;
  111. SidStr = lpszSidStr;
  112. len = SidStr.GetLength();
  113. pSidStr = SidStr.GetBuffer (len);
  114. pString = pSidStr;
  115. *ppSid = NULL;
  116. count = 0;
  117. do
  118. {
  119. pString = wcschr (pString, '-');
  120. if (NULL == pString)
  121. break;
  122. count++;
  123. pString++;
  124. } while (1);
  125. SubAuthCount = (BYTE)(count - 2);
  126. if (0 > SubAuthCount || 8 < SubAuthCount)
  127. {
  128. Status = ERROR_INVALID_SID;
  129. goto AllocAndInitSidFromStr_End;
  130. }
  131. pString = wcschr (pSidStr, L'-');
  132. pString++;
  133. pString = wcschr (pString, L'-'); //ignore the revision #
  134. pString++;
  135. pEnd = wcschr (pString, L'-'); //go to the beginning of subauths.
  136. if (NULL != pEnd) *pEnd = L'\0';
  137. Status = LoadSidAuthFromString (pString, &Auth);
  138. if (STATUS_SUCCESS != Status)
  139. goto AllocAndInitSidFromStr_End;
  140. for (count = 0; count < SubAuthCount; count++)
  141. {
  142. pString = pEnd + 1;
  143. pEnd = wcschr (pString, L'-');
  144. if (pEnd)
  145. *pEnd = L'\0';
  146. Status = GetIntFromUnicodeString (pString, 10, &n);
  147. if (STATUS_SUCCESS != Status)
  148. goto AllocAndInitSidFromStr_End;
  149. SubAuths[count] = n;
  150. }
  151. Status = RtlAllocateAndInitializeSid (&Auth, SubAuthCount,
  152. SubAuths[0], SubAuths[1], SubAuths[2],
  153. SubAuths[3], SubAuths[4], SubAuths[5],
  154. SubAuths[6], SubAuths[7], ppSid);
  155. AllocAndInitSidFromStr_End:
  156. return Status;
  157. }
  158. //+--------------------------------------------------------------------------
  159. //
  160. // Function: GetFriendlyNameFromStringSid
  161. //
  162. // Synopsis: given a sid in string format, this function returns
  163. // the friendly name for it and the container in which
  164. // occurs. For more details on the string representation
  165. // of a sid, see ntseapi.h & ntrtl.h
  166. //
  167. // Arguments: [in] pSidStr : sid represented as a unicode string
  168. // [out] szDir : the container in which the account occurs
  169. // [out] szAcct : the account name
  170. //
  171. // Returns: STATUS_SUCCESS : if successful
  172. // or an error code
  173. //
  174. // History: 9/29/1998 RahulTh created
  175. //
  176. // Notes:
  177. //
  178. //---------------------------------------------------------------------------
  179. NTSTATUS GetFriendlyNameFromStringSid (const WCHAR* pSidStr,
  180. CString& szDir,
  181. CString& szAcct
  182. )
  183. {
  184. NTSTATUS Status;
  185. PSID pSid = NULL;
  186. WCHAR szName[MAX_PATH];
  187. WCHAR szDomain [MAX_PATH];
  188. DWORD dwNameLen;
  189. DWORD dwDomLen;
  190. SID_NAME_USE eUse;
  191. Status = AllocateAndInitSidFromString (pSidStr, &pSid);
  192. if (STATUS_SUCCESS != Status)
  193. goto GetFriendlyName_End;
  194. dwNameLen = dwDomLen = MAX_PATH;
  195. if (!LookupAccountSid (NULL, pSid, szName, &dwNameLen, szDomain, &dwDomLen,
  196. &eUse))
  197. goto GetFriendlyName_Err;
  198. //we have got the container and the name of the account
  199. szDir = szDomain;
  200. szAcct = szName;
  201. Status = STATUS_SUCCESS;
  202. goto GetFriendlyName_End;
  203. GetFriendlyName_Err:
  204. Status = GetLastError();
  205. GetFriendlyName_End:
  206. if (pSid)
  207. FreeSid (pSid);
  208. return Status;
  209. }
  210. //+--------------------------------------------------------------------------
  211. //
  212. // Function: GetFriendlyNameFromSid
  213. //
  214. // Synopsis: give a pointer to a sid, this function gets the friendly name
  215. // of the account to which the sid belongs and its friendly name
  216. //
  217. // Arguments: [in] pSid : pointer to the SID
  218. // [out] szDir : the domain to which the account belongs
  219. // [out] szAcct : the friendly name of the account
  220. // [out] peUse : pointer to a sid_name_use structure that
  221. // identifies the type of the account
  222. //
  223. // Returns: STATUS_SUCCESS : if successful
  224. // an error code otherwise
  225. //
  226. // History: 10/1/1998 RahulTh created
  227. //
  228. // Notes:
  229. //
  230. //---------------------------------------------------------------------------
  231. NTSTATUS GetFriendlyNameFromSid (PSID pSid,
  232. CString& szDir,
  233. CString& szAcct,
  234. SID_NAME_USE* peUse)
  235. {
  236. ASSERT (peUse);
  237. TCHAR szName[MAX_PATH];
  238. TCHAR szDomain [MAX_PATH];
  239. DWORD dwNameLen;
  240. DWORD dwDomLen;
  241. DWORD Status = STATUS_SUCCESS;
  242. dwNameLen = dwDomLen = MAX_PATH;
  243. if (!LookupAccountSid (NULL, pSid, szName, &dwNameLen, szDomain, &dwDomLen,
  244. peUse))
  245. {
  246. Status = GetLastError();
  247. }
  248. else
  249. {
  250. szDir = szDomain;
  251. szAcct = szName;
  252. }
  253. return Status;
  254. }
  255. //+--------------------------------------------------------------------------
  256. //
  257. // Function: GetStringFromSid
  258. //
  259. // Synopsis: given a SID, this function gets its string representation
  260. // for more information on string representations of sids,
  261. // refer to ntsecapi.h & ntrtl.h
  262. //
  263. // Arguments: [in] pSid : pointer to a SID
  264. // [out] szStringSid : the string representation of the SID
  265. //
  266. // Returns: STATUS_SUCCESS if successful
  267. // an error code otherwise
  268. //
  269. // History: 10/1/1998 RahulTh created
  270. //
  271. // Notes:
  272. //
  273. //---------------------------------------------------------------------------
  274. NTSTATUS GetStringFromSid (PSID pSid, CString& szStringSid)
  275. {
  276. UNICODE_STRING stringW;
  277. DWORD Status;
  278. Status = RtlConvertSidToUnicodeString (&stringW, pSid, TRUE);
  279. if (STATUS_SUCCESS == Status)
  280. {
  281. szStringSid = stringW.Buffer;
  282. }
  283. RtlFreeUnicodeString (&stringW);
  284. return Status;
  285. }