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.

407 lines
12 KiB

  1. /*---------------------------------------------------------------------------
  2. File: ARUtil.cpp
  3. Comments: Helper functions and command-line parsing for Account Replicator
  4. (c) Copyright 1995-1998, Mission Critical Software, Inc., All Rights Reserved
  5. Proprietary and confidential to Mission Critical Software, Inc.
  6. REVISION LOG ENTRY
  7. Revision By: Christy Boles
  8. Revised on 6/23/98 4:26:54 PM
  9. ---------------------------------------------------------------------------
  10. */
  11. #include "StdAfx.h"
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #define INCL_NETUSER
  17. #define INCL_NETGROUP
  18. #define INCL_NETERRORS
  19. #include <lm.h>
  20. #include "Mcs.h"
  21. #include "Common.hpp"
  22. #include "TNode.hpp"
  23. #include "UString.hpp"
  24. #include "ErrDct.hpp"
  25. //#import "\bin\McsDctWorkerObjects.tlb"
  26. //#import "WorkObj.tlb" //#imported via ARUtil.hpp below
  27. #include "UserCopy.hpp"
  28. #include "ARUtil.hpp"
  29. #include "PWGen.hpp"
  30. #include "ResStr.h"
  31. #include <TxtSid.h>
  32. extern TErrorDct err;
  33. bool bAllowReplicateOnSelf;
  34. extern PSID srcSid; // SID of source domain
  35. /***************************************************************************************************
  36. CompVal: used as a compare function for TANode trees
  37. It compares a UNICODE string, with the name field in the node
  38. Return Values:
  39. 0 tn->acct_name == actname
  40. 1 tn->acct_name < actname
  41. -1 tn->acct_name > actname
  42. /***************************************************************************************************/
  43. int
  44. CompVal(
  45. const TNode * tn, //in -tree node
  46. const void * actname //in -name to look for
  47. )
  48. {
  49. LPWSTR str1 = ((TANode *)tn)->GetName();
  50. LPWSTR str2 = (LPWSTR) actname;
  51. return UStrICmp(str1,str2);
  52. }
  53. /***************************************************************************************************/
  54. /* CompNode: used as a compare function for TANode Trees
  55. It compares the name fields of TANodes
  56. Return Values:
  57. 0 t1->acct_name == t2->acct_name
  58. 1 t1->acct_name > t2->acct_name
  59. -1 t1->acct_name < t2->acct_name
  60. Error Handling:
  61. if given bad inputs, CompN displays an error message and returns 0
  62. /***************************************************************************************************/
  63. int
  64. CompNode(
  65. const TNode * v1, //in -first node to compare
  66. const TNode * v2 //in -second node to compare
  67. )
  68. {
  69. TANode * t1 = (TANode *)v1;
  70. TANode * t2 = (TANode *)v2;
  71. return UStrICmp(t1->GetName(),t2->GetName());
  72. }
  73. int
  74. CompareSid(
  75. PSID const sid1, // in - first SID to compare
  76. PSID const sid2 // in - second SID to compare
  77. )
  78. {
  79. DWORD len1,
  80. len2;
  81. int retval = 0;
  82. len1 = GetLengthSid(sid1);
  83. len2 = GetLengthSid(sid2);
  84. if ( len1 < len2 )
  85. {
  86. retval = -1;
  87. }
  88. if ( len1 > len2 )
  89. {
  90. retval = 1;
  91. }
  92. if ( len1 == len2 )
  93. {
  94. retval = memcmp(sid1,sid2,len1);
  95. }
  96. return retval;
  97. }
  98. int
  99. CompSid(
  100. const TNode * v1, // in -first node to compare
  101. const TNode * v2 // in -second node to compare
  102. )
  103. {
  104. TANode * t1 = (TANode *)v1;
  105. TANode * t2 = (TANode *)v2;
  106. return CompareSid(t1->GetSid(),t2->GetSid());
  107. }
  108. int
  109. CompSidVal(
  110. const TNode * tn, // in -node to compare
  111. const void * pVal // in -value to compare
  112. )
  113. {
  114. TANode * node = (TANode *)tn;
  115. PSID pSid = (PSID)pVal;
  116. return CompareSid(node->GetSid(),pSid);
  117. }
  118. BOOL // ret-TRUE if the password is successfully generated
  119. PasswordGenerate(
  120. Options const * options, // in -includes PW Generating options
  121. WCHAR * password, // out -buffer for generated password
  122. DWORD dwPWBufferLength, // in -DIM length of password buffer
  123. BOOL isAdminAccount // in -Whether to use the Admin rules
  124. )
  125. {
  126. DWORD rc = 0;
  127. DWORD dwMinUC; // minimum upper case chars
  128. DWORD dwMinLC; // minimum lower case chars
  129. DWORD dwMinDigit; // minimum numeric digits
  130. DWORD dwMinSpecial; // minimum special chars
  131. DWORD dwMaxConsecutiveAlpha; // maximum consecutive alpha chars
  132. DWORD dwMinLength; // minimum length
  133. WCHAR eaPassword[PWLEN+1]; // EA generated password
  134. DWORD dwEaBufferLength = DIM(eaPassword);// DIM length of newPassword
  135. // default values, if not enforcing PW strength through EA or MS DLL
  136. dwMinUC = 0;
  137. dwMinLC = 0;
  138. dwMinDigit = 1; // if no enforcement, require one digit (this is what the GUI does)
  139. dwMinSpecial = 0;
  140. dwMaxConsecutiveAlpha = 0;
  141. dwMinLength = options->minPwdLength;
  142. // Get password enforcement rules, if in effect
  143. dwMinUC = options->policyInfo.minUpper;
  144. dwMinLC = options->policyInfo.minLower;
  145. dwMinDigit = options->policyInfo.minDigits;
  146. dwMinSpecial = options->policyInfo.minSpecial;
  147. dwMaxConsecutiveAlpha = options->policyInfo.maxConsecutiveAlpha;
  148. rc = EaPasswordGenerate(dwMinUC,dwMinLC,dwMinDigit,dwMinSpecial,
  149. dwMaxConsecutiveAlpha,dwMinLength,eaPassword,dwEaBufferLength);
  150. if ( ! rc )
  151. {
  152. UStrCpy(password,eaPassword,dwPWBufferLength);
  153. }
  154. else
  155. {
  156. if ( dwPWBufferLength )
  157. password[0] = 0;
  158. }
  159. return rc;
  160. }
  161. PSID
  162. GetWellKnownSid(
  163. DWORD wellKnownAccount, // in - constant defined in this file, representing well-known account
  164. Options * opt, // in - migration options
  165. BOOL bTarget // in - flag, whether to use source or target domain information
  166. )
  167. {
  168. PSID pSid = NULL;
  169. PUCHAR numsubs = NULL;
  170. DWORD * rid = NULL;
  171. BOOL error = FALSE;
  172. DWORD rc;
  173. DWORD wellKnownRid = wellKnownAccount;
  174. BOOL bNeedToBuildDomainSid = FALSE;
  175. SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
  176. SID_IDENTIFIER_AUTHORITY creatorIA = SECURITY_CREATOR_SID_AUTHORITY;
  177. //
  178. // Sid is the same regardless of machine, since the well-known
  179. // BUILTIN domain is referenced.
  180. //
  181. switch ( wellKnownAccount )
  182. {
  183. case CREATOR_OWNER:
  184. if( ! AllocateAndInitializeSid(
  185. &creatorIA,
  186. 2,
  187. SECURITY_BUILTIN_DOMAIN_RID,
  188. SECURITY_CREATOR_OWNER_RID,
  189. 0, 0, 0, 0, 0, 0,
  190. &pSid
  191. ))
  192. {
  193. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  194. }
  195. break;
  196. case ADMINISTRATORS:
  197. if( ! AllocateAndInitializeSid(
  198. &sia,
  199. 2,
  200. SECURITY_BUILTIN_DOMAIN_RID,
  201. DOMAIN_ALIAS_RID_ADMINS,
  202. 0, 0, 0, 0, 0, 0,
  203. &pSid
  204. ))
  205. {
  206. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  207. }
  208. break;
  209. case ACCOUNT_OPERATORS:
  210. if( ! AllocateAndInitializeSid(
  211. &sia,
  212. 2,
  213. SECURITY_BUILTIN_DOMAIN_RID,
  214. DOMAIN_ALIAS_RID_ACCOUNT_OPS,
  215. 0, 0, 0, 0, 0, 0,
  216. &pSid
  217. ))
  218. {
  219. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  220. }
  221. break;
  222. case BACKUP_OPERATORS:
  223. if( ! AllocateAndInitializeSid(
  224. &sia,
  225. 2,
  226. SECURITY_BUILTIN_DOMAIN_RID,
  227. DOMAIN_ALIAS_RID_BACKUP_OPS,
  228. 0, 0, 0, 0, 0, 0,
  229. &pSid
  230. ))
  231. {
  232. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  233. }
  234. break;
  235. case DOMAIN_ADMINS:
  236. wellKnownRid = DOMAIN_GROUP_RID_ADMINS;
  237. bNeedToBuildDomainSid = TRUE;
  238. break;
  239. case DOMAIN_USERS:
  240. wellKnownRid = DOMAIN_GROUP_RID_USERS;
  241. bNeedToBuildDomainSid = TRUE;
  242. break;
  243. case DOMAIN_CONTROLLERS:
  244. wellKnownRid = DOMAIN_GROUP_RID_CONTROLLERS;
  245. bNeedToBuildDomainSid = TRUE;
  246. break;
  247. case DOMAIN_COMPUTERS:
  248. wellKnownRid = DOMAIN_GROUP_RID_COMPUTERS;
  249. bNeedToBuildDomainSid = TRUE;
  250. break;
  251. default:
  252. wellKnownRid = wellKnownAccount;
  253. bNeedToBuildDomainSid = TRUE;
  254. break;
  255. }
  256. if ( bNeedToBuildDomainSid )
  257. {
  258. // For the default case we can return a SID by using the wellKnownAccount parameter as a RID
  259. // this one is based on the sid for the domain
  260. // Get the domain SID
  261. USER_MODALS_INFO_2 * uinf = NULL;
  262. MCSASSERT(opt);
  263. srcSid = bTarget ? opt->tgtSid : opt->srcSid;
  264. if ( ! srcSid )
  265. {
  266. rc = NetUserModalsGet(bTarget ? opt->tgtComp :opt->srcComp,2,(LPBYTE*)&uinf);
  267. if ( rc )
  268. {
  269. err.SysMsgWrite(ErrE,rc,DCT_MSG_NO_DOMAIN_SID_SD,bTarget ? opt->tgtDomain :opt->srcDomain,rc );
  270. error = TRUE;
  271. srcSid = NULL;
  272. }
  273. else
  274. {
  275. srcSid = uinf->usrmod2_domain_id;
  276. // make a copy of the SID to keep in the Options structure for next time
  277. PSID temp = LocalAlloc(LPTR,GetLengthSid(srcSid));
  278. memcpy(temp,srcSid,GetLengthSid(srcSid));
  279. if ( bTarget )
  280. opt->tgtSid = temp;
  281. else
  282. opt->srcSid = temp;
  283. NetApiBufferFree(uinf);
  284. srcSid = temp;
  285. }
  286. }
  287. if ( srcSid )
  288. {
  289. numsubs = GetSidSubAuthorityCount(srcSid);
  290. if (! AllocateAndInitializeSid(
  291. &sia,
  292. (*numsubs)+1,
  293. 0,0,0,0,0,0,0,0,
  294. &pSid) )
  295. {
  296. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  297. }
  298. if ( ! CopySid(GetLengthSid(srcSid), pSid, srcSid) )
  299. {
  300. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_COPY_SID_FAILED_D,GetLastError());
  301. }
  302. // reset number of subauthorities in pSid, since we just overwrote it with information from srcSid
  303. numsubs = GetSidSubAuthorityCount(pSid);
  304. (*numsubs)++;
  305. rid = GetSidSubAuthority(pSid,(*numsubs)-1);
  306. *rid = wellKnownRid;
  307. }
  308. }
  309. if ( error )
  310. {
  311. LocalFree(pSid);
  312. pSid = NULL;
  313. }
  314. return pSid;
  315. }
  316. //---------------------------------------------------------------------------
  317. // GenerateSidAsString Function
  318. //
  319. // Synopsis
  320. // Generate a SID in string format from specifed domain and given RID.
  321. //
  322. // Arguments
  323. // IN pOptions - account replicator options structure
  324. // IN bTarget - specifies whether to use the target domain or source domain
  325. // IN dwRid - specified RID
  326. //
  327. // Return
  328. // The generated SID as a string if successfull or an empty string if not.
  329. //---------------------------------------------------------------------------
  330. _bstr_t __stdcall GenerateSidAsString(Options* pOptions, BOOL bTarget, DWORD dwRid)
  331. {
  332. _bstr_t strSid;
  333. PSID pSid = GetWellKnownSid(dwRid, pOptions, bTarget);
  334. if (pSid)
  335. {
  336. WCHAR szSid[LEN_Path];
  337. DWORD cchSid = DIM(szSid);
  338. if (GetTextualSid(pSid, szSid, &cchSid))
  339. {
  340. strSid = szSid;
  341. }
  342. FreeSid(pSid);
  343. }
  344. return strSid;
  345. }