Leaked source code of windows server 2003
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.

305 lines
7.8 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. #include "precomp.h"
  3. #include "chklist.h"
  4. #include "Principal.h"
  5. #include "CHString1.h"
  6. //-------------------------------------------------------------
  7. CPrincipal::CPrincipal(CWbemClassObject &userInst, SecurityStyle secStyle) :
  8. m_secStyle(secStyle),
  9. m_perms(0),
  10. m_inheritedPerms(0),
  11. m_editable(true)
  12. {
  13. //------------------------------------------------
  14. // figure out what security strategy we're dealing with and load it
  15. // into my "generic" definition.
  16. memset(m_name, 0, 100 * sizeof(TCHAR));
  17. _tcsncpy(m_name, (LPCTSTR)userInst.GetString("Name"), 100);
  18. memset(m_domain, 0, 100 * sizeof(TCHAR));
  19. _tcsncpy(m_domain, (LPCTSTR)userInst.GetString("Authority"), 100);
  20. // if pre-M3 security...
  21. if(m_secStyle == RootSecStyle)
  22. {
  23. // this is the only instance for this guy so save it.
  24. // convert the convoluted "bits" into my real "generic" bits.
  25. m_perms |= (userInst.GetBool("EditSecurity") ? ACL_WRITE_DAC : 0);
  26. m_perms |= (userInst.GetBool("Enabled") ? ACL_ENABLE : 0);
  27. m_perms |= (userInst.GetBool("ExecuteMethods") ? ACL_METHOD_EXECUTE : 0);
  28. // NOTE: each "level" implies all the levels below so I INTENTIONALLY
  29. // left out the 'breaks' so the bits would fall through and accumulate.
  30. switch(userInst.GetLong("Permissions"))
  31. {
  32. case 2: // class write
  33. m_perms |= ACL_CLASS_WRITE;
  34. case 1: // instance write
  35. m_perms |= ACL_INSTANCE_WRITE;
  36. }
  37. // remember for dirty bit processing later.
  38. m_origPerms = m_perms;
  39. }
  40. else //new M3+ security
  41. {
  42. // ACL bits perfectly match m_perms.
  43. // NOTE: this securityStyle can have multiple aces per principal.
  44. AddAce(userInst);
  45. }
  46. }
  47. //------------------------------------------
  48. // move m_perms into the checkboxes
  49. void CPrincipal::LoadChecklist(HWND list, int OSType)
  50. {
  51. INT_PTR itemCount = CBL_GetItemCount(list);
  52. CPermission *permItem = 0;
  53. UINT state;
  54. ::EnableWindow(list, m_editable);
  55. // for each permission item...
  56. for(INT_PTR x = 0; x < itemCount; x++)
  57. {
  58. // which permission item is this
  59. permItem = (CPermission *)CBL_GetItemData(list, x);
  60. state = BST_UNCHECKED; // and enabled (local)
  61. // if its a local perm...
  62. if(IS_BITSET(m_perms, permItem->m_permBit))
  63. {
  64. // local perms override inherited perms.
  65. state = BST_CHECKED;
  66. }
  67. else if(IS_BITSET(m_inheritedPerms, permItem->m_permBit))
  68. {
  69. // you got it from your parent.
  70. state = CLST_CHECKDISABLED;
  71. }
  72. // set it.
  73. CBL_SetState(list, x, ALLOW_COL, state);
  74. } //endfor
  75. }
  76. //------------------------------------------
  77. // move the checkboxes into m_perms.
  78. void CPrincipal::SaveChecklist(HWND list, int OSType)
  79. {
  80. INT_PTR itemCount = CBL_GetItemCount(list);
  81. CPermission *permItem = 0;
  82. LPARAM state = 0, state1 = 0;
  83. // clear this principal's perm bits.
  84. m_perms = 0;
  85. // for each perm...
  86. for(INT_PTR x = 0; x < itemCount; x++)
  87. {
  88. // get permission item.
  89. permItem = (CPermission *)CBL_GetItemData(list, x);
  90. // what's the check state?
  91. state = CBL_GetState(list, x, ALLOW_COL);
  92. // if its enabled (local) & checked, set the matching bit.
  93. // NOTE: This "explicit compare will eliminate CLST_DISABLEDed states which
  94. // shouldn't be saved off.
  95. if((state == BST_CHECKED) ||
  96. ((state == CLST_CHECKDISABLED) && (OSType != OSTYPE_WINNT)))
  97. {
  98. m_perms |= permItem->m_permBit;
  99. }
  100. } //endfor
  101. }
  102. //------------------------------------------
  103. // WARNING: this logic assumes it will only be called when the principal is
  104. // being read in. If you want to add aces interactively, its a whole different
  105. // game.
  106. void CPrincipal::AddAce(CWbemClassObject &princ)
  107. {
  108. DWORD flags = princ.GetLong("Flags");
  109. // if inherited...
  110. if(IS_BITSET(flags, INHERITED_ACE))
  111. {
  112. // simply accumulate bits.
  113. m_inheritedPerms |= princ.GetLong("Mask");
  114. m_editable = false;
  115. }
  116. else if(flags == CONTAINER_INHERIT_ACE)
  117. {
  118. m_perms |= princ.GetLong("Mask");
  119. // this is the first local ace, we can edit it so save the source instance.
  120. // NOTE: Any additional "local" aces that exactly match CONTAINER_INHERIT_ACE
  121. // will be merged in but the the ClassObject will be tossed.
  122. //if(!(bool)m_userInst)
  123. //{
  124. // m_userInst = princ;
  125. // }
  126. // remember for dirty bit processing later.
  127. m_origPerms = m_perms;
  128. }
  129. else
  130. {
  131. // this will disable the checklist control for this principal.
  132. m_editable = false;
  133. }
  134. }
  135. //------------------------------------------
  136. HRESULT CPrincipal::DeleteSelf(CWbemServices &service)
  137. {
  138. HRESULT hr = S_OK;
  139. if(m_secStyle == RootSecStyle)
  140. {
  141. CHString1 path, fmt("__NTLMuser.Name=\"%s\",Authority=\"%s\"");
  142. path.Format(fmt, m_name, m_domain);
  143. hr = service.DeleteInstance((LPCTSTR)path);
  144. }
  145. return hr;
  146. }
  147. //------------------------------------------
  148. // move m_perms into the checkboxes
  149. HRESULT CPrincipal::Put(CWbemServices &service, CWbemClassObject &userInst)
  150. {
  151. HRESULT hr = E_FAIL;
  152. if(m_editable)
  153. {
  154. // if pre-M3 security...
  155. if(m_secStyle == RootSecStyle)
  156. {
  157. DWORD perm = 0;
  158. // convert my "generic" bits back to convoluted "bits".
  159. userInst = service.CreateInstance("__NTLMUser");
  160. userInst.Put("Name", (bstr_t)m_name);
  161. userInst.Put("Authority", (bstr_t)m_domain);
  162. userInst.Put("EditSecurity", (bool)((m_perms & ACL_WRITE_DAC) != 0));
  163. userInst.Put("Enabled", (bool)((m_perms & ACL_ENABLE) != 0));
  164. userInst.Put("ExecuteMethods", (bool)((m_perms & ACL_METHOD_EXECUTE) != 0));
  165. if(m_perms & ACL_CLASS_WRITE)
  166. {
  167. perm = 2;
  168. }
  169. else if(m_perms & ACL_INSTANCE_WRITE)
  170. {
  171. perm = 1;
  172. }
  173. else
  174. {
  175. perm = 0;
  176. }
  177. userInst.Put("Permissions", (long)perm);
  178. hr = service.PutInstance(userInst);
  179. }
  180. else //new M3+ security
  181. {
  182. // ACL bits perfectly match m_perms.
  183. userInst = service.CreateInstance("__NTLMUser9x");
  184. userInst.Put("Name", (bstr_t)m_name);
  185. userInst.Put("Authority", (bstr_t)m_domain);
  186. userInst.Put("Flags", (long)CONTAINER_INHERIT_ACE);
  187. userInst.Put("Mask", (long)m_perms);
  188. userInst.Put("Type", (long)ACCESS_ALLOWED_ACE_TYPE);
  189. hr = S_OK;
  190. }
  191. }
  192. return hr;
  193. }
  194. //-----------------------------------------------------------------------------
  195. // Indexes into the SID image list IDB_SID_ICONS.
  196. #define IDB_GROUP 0
  197. #define IDB_USER 1
  198. #define IDB_ALIAS 2
  199. #define IDB_UNKNOWN 3
  200. #define IDB_SYSTEM 4
  201. #define IDB_REMOTE 5
  202. #define IDB_WORLD 6
  203. #define IDB_CREATOR_OWNER 7
  204. #define IDB_NETWORK 8
  205. #define IDB_INTERACTIVE 9
  206. #define IDB_DELETEDACCOUNT 10
  207. //TODO: match the magic strings when provider catches up.
  208. int CPrincipal::GetImageIndex(void)
  209. {
  210. UINT idBitmap = 0;
  211. return IDB_USER;
  212. /*
  213. switch (m_SidType)
  214. {
  215. case SidTypeUser:
  216. return IDB_USER;
  217. break;
  218. case SidTypeGroup:
  219. return IDB_GROUP;
  220. break;
  221. case SidTypeAlias:
  222. return IDB_ALIAS;
  223. break;
  224. case SidTypeWellKnownGroup:
  225. if(_tcsicmp(m_name, _T("Everyone")) == 0)
  226. {
  227. return IDB_WORLD;
  228. }
  229. else if(_tcsicmp(m_name, _T("Creator Owner")) == 0)
  230. {
  231. return IDB_CREATOR_OWNER;
  232. }
  233. else if(_tcsicmp(m_name, _T("NETWORK")) == 0)
  234. {
  235. return IDB_NETWORK;
  236. }
  237. else if(_tcsicmp(m_name, _T("INTERACTIVE")) == 0)
  238. {
  239. return IDB_INTERACTIVE;
  240. }
  241. else if(_tcsicmp(m_name, _T("SYSTEM")) == 0)
  242. {
  243. return IDB_SYSTEM;
  244. }
  245. else
  246. {
  247. // wasn't that well known afterall :)
  248. return IDB_GROUP;
  249. }
  250. break;
  251. case SidTypeDeletedAccount:
  252. return IDB_DELETEDACCOUNT;
  253. break;
  254. case SidTypeInvalid:
  255. case SidTypeUnknown:
  256. return IDB_UNKNOWN;
  257. break;
  258. case SidTypeDomain:
  259. default:
  260. // Should never get here.
  261. return IDB_UNKNOWN;
  262. break;
  263. }
  264. return IDB_UNKNOWN;
  265. */
  266. }