public void Save() { int count = 0; IntPtr records = (IntPtr)0; int currentCount = 0; IntPtr tmpPtr = (IntPtr)0; IntPtr forestInfo = (IntPtr)0; PolicySafeHandle handle = null; LSA_UNICODE_STRING trustedDomainName; IntPtr collisionInfo = (IntPtr)0; ArrayList ptrList = new ArrayList(); ArrayList sidList = new ArrayList(); bool impersonated = false; IntPtr target = (IntPtr)0; string serverName = null; IntPtr fileTime = (IntPtr)0; // first get the count of all the records int toplevelNamesCount = TopLevelNames.Count; int excludedNamesCount = ExcludedTopLevelNames.Count; int trustedDomainCount = TrustedDomainInformation.Count; int binaryDataCount = 0; checked { count += toplevelNamesCount; count += excludedNamesCount; count += trustedDomainCount; if (_binaryData.Count != 0) { binaryDataCount = _binaryData.Count; // for the ForestTrustRecordTypeLast record count++; count += binaryDataCount; } // allocate the memory for all the records records = Marshal.AllocHGlobal(count * Marshal.SizeOf(typeof(IntPtr))); } try { try { IntPtr ptr = (IntPtr)0; fileTime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileTime))); UnsafeNativeMethods.GetSystemTimeAsFileTime(fileTime); // set the time FileTime currentTime = new FileTime(); Marshal.PtrToStructure(fileTime, currentTime); for (int i = 0; i < toplevelNamesCount; i++) { // now begin to construct top leve name record LSA_FOREST_TRUST_RECORD record = new LSA_FOREST_TRUST_RECORD(); record.Flags = (int)_topLevelNames[i].Status; record.ForestTrustType = LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustTopLevelName; TopLevelName TLN = _topLevelNames[i]; record.Time = TLN.time; record.TopLevelName = new LSA_UNICODE_STRING(); ptr = Marshal.StringToHGlobalUni(TLN.Name); ptrList.Add(ptr); UnsafeNativeMethods.RtlInitUnicodeString(record.TopLevelName, ptr); tmpPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_RECORD))); ptrList.Add(tmpPtr); Marshal.StructureToPtr(record, tmpPtr, false); Marshal.WriteIntPtr(records, Marshal.SizeOf(typeof(IntPtr)) * currentCount, tmpPtr); currentCount++; } for (int i = 0; i < excludedNamesCount; i++) { // now begin to construct excluded top leve name record LSA_FOREST_TRUST_RECORD record = new LSA_FOREST_TRUST_RECORD(); record.Flags = 0; record.ForestTrustType = LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustTopLevelNameEx; if (_excludedNameTime.Contains(_excludedNames[i])) { record.Time = (LARGE_INTEGER)_excludedNameTime[i]; } else { record.Time = new LARGE_INTEGER(); record.Time.lowPart = currentTime.lower; record.Time.highPart = currentTime.higher; } record.TopLevelName = new LSA_UNICODE_STRING(); ptr = Marshal.StringToHGlobalUni(_excludedNames[i]); ptrList.Add(ptr); UnsafeNativeMethods.RtlInitUnicodeString(record.TopLevelName, ptr); tmpPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_RECORD))); ptrList.Add(tmpPtr); Marshal.StructureToPtr(record, tmpPtr, false); Marshal.WriteIntPtr(records, Marshal.SizeOf(typeof(IntPtr)) * currentCount, tmpPtr); currentCount++; } for (int i = 0; i < trustedDomainCount; i++) { // now begin to construct domain info record LSA_FOREST_TRUST_RECORD record = new LSA_FOREST_TRUST_RECORD(); record.Flags = (int)_domainInfo[i].Status; record.ForestTrustType = LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustDomainInfo; ForestTrustDomainInformation tmp = _domainInfo[i]; record.Time = tmp.time; IntPtr pSid = (IntPtr)0; IntPtr stringSid = (IntPtr)0; stringSid = Marshal.StringToHGlobalUni(tmp.DomainSid); ptrList.Add(stringSid); int result = UnsafeNativeMethods.ConvertStringSidToSidW(stringSid, ref pSid); if (result == 0) { throw ExceptionHelper.GetExceptionFromErrorCode(Marshal.GetLastWin32Error()); } record.DomainInfo = new LSA_FOREST_TRUST_DOMAIN_INFO(); record.DomainInfo.sid = pSid; sidList.Add(pSid); record.DomainInfo.DNSNameBuffer = Marshal.StringToHGlobalUni(tmp.DnsName); ptrList.Add(record.DomainInfo.DNSNameBuffer); record.DomainInfo.DNSNameLength = (short)(tmp.DnsName == null ? 0 : tmp.DnsName.Length * 2); // sizeof(WCHAR) record.DomainInfo.DNSNameMaximumLength = (short)(tmp.DnsName == null ? 0 : tmp.DnsName.Length * 2); record.DomainInfo.NetBIOSNameBuffer = Marshal.StringToHGlobalUni(tmp.NetBiosName); ptrList.Add(record.DomainInfo.NetBIOSNameBuffer); record.DomainInfo.NetBIOSNameLength = (short)(tmp.NetBiosName == null ? 0 : tmp.NetBiosName.Length * 2); record.DomainInfo.NetBIOSNameMaximumLength = (short)(tmp.NetBiosName == null ? 0 : tmp.NetBiosName.Length * 2); tmpPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_RECORD))); ptrList.Add(tmpPtr); Marshal.StructureToPtr(record, tmpPtr, false); Marshal.WriteIntPtr(records, Marshal.SizeOf(typeof(IntPtr)) * currentCount, tmpPtr); currentCount++; } if (binaryDataCount > 0) { // now begin to construct ForestTrustRecordTypeLast LSA_FOREST_TRUST_RECORD lastRecord = new LSA_FOREST_TRUST_RECORD(); lastRecord.Flags = 0; lastRecord.ForestTrustType = LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustRecordTypeLast; tmpPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_RECORD))); ptrList.Add(tmpPtr); Marshal.StructureToPtr(lastRecord, tmpPtr, false); Marshal.WriteIntPtr(records, Marshal.SizeOf(typeof(IntPtr)) * currentCount, tmpPtr); currentCount++; for (int i = 0; i < binaryDataCount; i++) { // now begin to construct excluded top leve name record LSA_FOREST_TRUST_RECORD record = new LSA_FOREST_TRUST_RECORD(); record.Flags = 0; record.Time = (LARGE_INTEGER)_binaryDataTime[i]; record.Data.Length = ((byte[])_binaryData[i]).Length; if (record.Data.Length == 0) { record.Data.Buffer = (IntPtr)0; } else { record.Data.Buffer = Marshal.AllocHGlobal(record.Data.Length); ptrList.Add(record.Data.Buffer); Marshal.Copy((byte[])_binaryData[i], 0, record.Data.Buffer, record.Data.Length); } tmpPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_RECORD))); ptrList.Add(tmpPtr); Marshal.StructureToPtr(record, tmpPtr, false); Marshal.WriteIntPtr(records, Marshal.SizeOf(typeof(IntPtr)) * currentCount, tmpPtr); currentCount++; } } // finally construct the LSA_FOREST_TRUST_INFORMATION LSA_FOREST_TRUST_INFORMATION trustInformation = new LSA_FOREST_TRUST_INFORMATION(); trustInformation.RecordCount = count; trustInformation.Entries = records; forestInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_INFORMATION))); Marshal.StructureToPtr(trustInformation, forestInfo, false); // get policy server name serverName = Utils.GetPolicyServerName(context, true, true, SourceName); // do impersonation first impersonated = Utils.Impersonate(context); // get the policy handle handle = new PolicySafeHandle(Utils.GetPolicyHandle(serverName)); // get the target name trustedDomainName = new LSA_UNICODE_STRING(); target = Marshal.StringToHGlobalUni(TargetName); UnsafeNativeMethods.RtlInitUnicodeString(trustedDomainName, target); // call the unmanaged function int error = UnsafeNativeMethods.LsaSetForestTrustInformation(handle, trustedDomainName, forestInfo, 1, out collisionInfo); if (error != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(UnsafeNativeMethods.LsaNtStatusToWinError(error), serverName); } // there is collision, throw proper exception so user can deal with it if (collisionInfo != (IntPtr)0) { throw ExceptionHelper.CreateForestTrustCollisionException(collisionInfo); } // commit the changes error = UnsafeNativeMethods.LsaSetForestTrustInformation(handle, trustedDomainName, forestInfo, 0, out collisionInfo); if (error != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(error, serverName); } // now next time property is invoked, we need to go to the server retrieved = false; } finally { if (impersonated) { Utils.Revert(); } // release the memory for (int i = 0; i < ptrList.Count; i++) { Marshal.FreeHGlobal((IntPtr)ptrList[i]); } for (int i = 0; i < sidList.Count; i++) { UnsafeNativeMethods.LocalFree((IntPtr)sidList[i]); } if (records != (IntPtr)0) { Marshal.FreeHGlobal(records); } if (forestInfo != (IntPtr)0) { Marshal.FreeHGlobal(forestInfo); } if (collisionInfo != (IntPtr)0) { UnsafeNativeMethods.LsaFreeMemory(collisionInfo); } if (target != (IntPtr)0) { Marshal.FreeHGlobal(target); } if (fileTime != (IntPtr)0) { Marshal.FreeHGlobal(fileTime); } } } catch { throw; } }
public void Save() { IntPtr intPtr; IntPtr hGlobalUni; object length; object obj; object length1; object obj1; int count = 0; int num = 0; IntPtr intPtr1 = (IntPtr)0; IntPtr intPtr2 = (IntPtr)0; ArrayList arrayLists = new ArrayList(); ArrayList arrayLists1 = new ArrayList(); bool flag = false; IntPtr hGlobalUni1 = (IntPtr)0; IntPtr intPtr3 = (IntPtr)0; count = count + this.TopLevelNames.Count; count = count + this.ExcludedTopLevelNames.Count; count = count + this.TrustedDomainInformation.Count; if (this.binaryData.Count != 0) { count++; count = count + this.binaryData.Count; } IntPtr intPtr4 = Marshal.AllocHGlobal(count * Marshal.SizeOf(typeof(IntPtr))); try { try { intPtr3 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileTime))); UnsafeNativeMethods.GetSystemTimeAsFileTime(intPtr3); FileTime fileTime = new FileTime(); Marshal.PtrToStructure(intPtr3, fileTime); for (int i = 0; i < this.topLevelNames.Count; i++) { LSA_FOREST_TRUST_RECORD lSAFORESTTRUSTRECORD = new LSA_FOREST_TRUST_RECORD(); lSAFORESTTRUSTRECORD.Flags = (int)this.topLevelNames[i].Status; lSAFORESTTRUSTRECORD.ForestTrustType = LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustTopLevelName; TopLevelName item = this.topLevelNames[i]; lSAFORESTTRUSTRECORD.Time = item.time; lSAFORESTTRUSTRECORD.TopLevelName = new LSA_UNICODE_STRING(); hGlobalUni = Marshal.StringToHGlobalUni(item.Name); arrayLists.Add(hGlobalUni); UnsafeNativeMethods.RtlInitUnicodeString(lSAFORESTTRUSTRECORD.TopLevelName, hGlobalUni); intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_RECORD))); arrayLists.Add(intPtr); Marshal.StructureToPtr(lSAFORESTTRUSTRECORD, intPtr, false); Marshal.WriteIntPtr(intPtr4, Marshal.SizeOf(typeof(IntPtr)) * num, intPtr); num++; } for (int j = 0; j < this.excludedNames.Count; j++) { LSA_FOREST_TRUST_RECORD lARGEINTEGER = new LSA_FOREST_TRUST_RECORD(); lARGEINTEGER.Flags = 0; lARGEINTEGER.ForestTrustType = LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustTopLevelNameEx; if (!this.excludedNameTime.Contains(this.excludedNames[j])) { lARGEINTEGER.Time = new LARGE_INTEGER(); lARGEINTEGER.Time.lowPart = fileTime.lower; lARGEINTEGER.Time.highPart = fileTime.higher; } else { lARGEINTEGER.Time = (LARGE_INTEGER)this.excludedNameTime[(object)j]; } lARGEINTEGER.TopLevelName = new LSA_UNICODE_STRING(); hGlobalUni = Marshal.StringToHGlobalUni(this.excludedNames[j]); arrayLists.Add(hGlobalUni); UnsafeNativeMethods.RtlInitUnicodeString(lARGEINTEGER.TopLevelName, hGlobalUni); intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_RECORD))); arrayLists.Add(intPtr); Marshal.StructureToPtr(lARGEINTEGER, intPtr, false); Marshal.WriteIntPtr(intPtr4, Marshal.SizeOf(typeof(IntPtr)) * num, intPtr); num++; } int num1 = 0; while (num1 < this.domainInfo.Count) { LSA_FOREST_TRUST_RECORD status = new LSA_FOREST_TRUST_RECORD(); status.Flags = (int)this.domainInfo[num1].Status; status.ForestTrustType = LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustDomainInfo; ForestTrustDomainInformation forestTrustDomainInformation = this.domainInfo[num1]; status.Time = forestTrustDomainInformation.time; IntPtr intPtr5 = (IntPtr)0; IntPtr hGlobalUni2 = Marshal.StringToHGlobalUni(forestTrustDomainInformation.DomainSid); arrayLists.Add(hGlobalUni2); int sidW = UnsafeNativeMethods.ConvertStringSidToSidW(hGlobalUni2, ref intPtr5); if (sidW != 0) { status.DomainInfo = new LSA_FOREST_TRUST_DOMAIN_INFO(); status.DomainInfo.sid = intPtr5; arrayLists1.Add(intPtr5); status.DomainInfo.DNSNameBuffer = Marshal.StringToHGlobalUni(forestTrustDomainInformation.DnsName); arrayLists.Add(status.DomainInfo.DNSNameBuffer); LSA_FOREST_TRUST_DOMAIN_INFO domainInfo = status.DomainInfo; if (forestTrustDomainInformation.DnsName == null) { length = null; } else { length = forestTrustDomainInformation.DnsName.Length * 2; } domainInfo.DNSNameLength = (short)length; LSA_FOREST_TRUST_DOMAIN_INFO lSAFORESTTRUSTDOMAININFO = status.DomainInfo; if (forestTrustDomainInformation.DnsName == null) { obj = null; } else { obj = forestTrustDomainInformation.DnsName.Length * 2; } lSAFORESTTRUSTDOMAININFO.DNSNameMaximumLength = (short)obj; status.DomainInfo.NetBIOSNameBuffer = Marshal.StringToHGlobalUni(forestTrustDomainInformation.NetBiosName); arrayLists.Add(status.DomainInfo.NetBIOSNameBuffer); LSA_FOREST_TRUST_DOMAIN_INFO domainInfo1 = status.DomainInfo; if (forestTrustDomainInformation.NetBiosName == null) { length1 = null; } else { length1 = forestTrustDomainInformation.NetBiosName.Length * 2; } domainInfo1.NetBIOSNameLength = (short)length1; LSA_FOREST_TRUST_DOMAIN_INFO lSAFORESTTRUSTDOMAININFO1 = status.DomainInfo; if (forestTrustDomainInformation.NetBiosName == null) { obj1 = null; } else { obj1 = forestTrustDomainInformation.NetBiosName.Length * 2; } lSAFORESTTRUSTDOMAININFO1.NetBIOSNameMaximumLength = (short)obj1; intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_RECORD))); arrayLists.Add(intPtr); Marshal.StructureToPtr(status, intPtr, false); Marshal.WriteIntPtr(intPtr4, Marshal.SizeOf(typeof(IntPtr)) * num, intPtr); num++; num1++; } else { throw ExceptionHelper.GetExceptionFromErrorCode(Marshal.GetLastWin32Error()); } } if (this.binaryData.Count > 0) { LSA_FOREST_TRUST_RECORD lSAFORESTTRUSTRECORD1 = new LSA_FOREST_TRUST_RECORD(); lSAFORESTTRUSTRECORD1.Flags = 0; lSAFORESTTRUSTRECORD1.ForestTrustType = LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustRecordTypeLast; intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_RECORD))); arrayLists.Add(intPtr); Marshal.StructureToPtr(lSAFORESTTRUSTRECORD1, intPtr, false); Marshal.WriteIntPtr(intPtr4, Marshal.SizeOf(typeof(IntPtr)) * num, intPtr); num++; for (int k = 0; k < this.binaryData.Count; k++) { LSA_FOREST_TRUST_RECORD item1 = new LSA_FOREST_TRUST_RECORD(); item1.Flags = 0; item1.Time = (LARGE_INTEGER)this.binaryDataTime[k]; item1.Data.Length = (int)((byte[])this.binaryData[k]).Length; if (item1.Data.Length != 0) { item1.Data.Buffer = Marshal.AllocHGlobal(item1.Data.Length); arrayLists.Add(item1.Data.Buffer); Marshal.Copy((byte[])this.binaryData[k], 0, item1.Data.Buffer, item1.Data.Length); } else { item1.Data.Buffer = (IntPtr)0; } intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_RECORD))); arrayLists.Add(intPtr); Marshal.StructureToPtr(item1, intPtr, false); Marshal.WriteIntPtr(intPtr4, Marshal.SizeOf(typeof(IntPtr)) * num, intPtr); num++; } } LSA_FOREST_TRUST_INFORMATION lSAFORESTTRUSTINFORMATION = new LSA_FOREST_TRUST_INFORMATION(); lSAFORESTTRUSTINFORMATION.RecordCount = count; lSAFORESTTRUSTINFORMATION.Entries = intPtr4; intPtr1 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_FOREST_TRUST_INFORMATION))); Marshal.StructureToPtr(lSAFORESTTRUSTINFORMATION, intPtr1, false); string policyServerName = Utils.GetPolicyServerName(this.context, true, true, base.SourceName); flag = Utils.Impersonate(this.context); PolicySafeHandle policySafeHandle = new PolicySafeHandle(Utils.GetPolicyHandle(policyServerName)); LSA_UNICODE_STRING lSAUNICODESTRING = new LSA_UNICODE_STRING(); hGlobalUni1 = Marshal.StringToHGlobalUni(base.TargetName); UnsafeNativeMethods.RtlInitUnicodeString(lSAUNICODESTRING, hGlobalUni1); int num2 = UnsafeNativeMethods.LsaSetForestTrustInformation(policySafeHandle, lSAUNICODESTRING, intPtr1, 1, out intPtr2); if (num2 == 0) { if (intPtr2 == (IntPtr)0) { num2 = UnsafeNativeMethods.LsaSetForestTrustInformation(policySafeHandle, lSAUNICODESTRING, intPtr1, 0, out intPtr2); if (num2 == 0) { this.retrieved = false; } else { throw ExceptionHelper.GetExceptionFromErrorCode(num2, policyServerName); } } else { throw ExceptionHelper.CreateForestTrustCollisionException(intPtr2); } } else { throw ExceptionHelper.GetExceptionFromErrorCode(UnsafeNativeMethods.LsaNtStatusToWinError(num2), policyServerName); } } finally { if (flag) { Utils.Revert(); } for (int l = 0; l < arrayLists.Count; l++) { Marshal.FreeHGlobal((IntPtr)arrayLists[l]); } for (int m = 0; m < arrayLists1.Count; m++) { UnsafeNativeMethods.LocalFree((IntPtr)arrayLists1[m]); } if (intPtr4 != (IntPtr)0) { Marshal.FreeHGlobal(intPtr4); } if (intPtr1 != (IntPtr)0) { Marshal.FreeHGlobal(intPtr1); } if (intPtr2 != (IntPtr)0) { UnsafeNativeMethods.LsaFreeMemory(intPtr2); } if (hGlobalUni1 != (IntPtr)0) { Marshal.FreeHGlobal(hGlobalUni1); } if (intPtr3 != (IntPtr)0) { Marshal.FreeHGlobal(intPtr3); } } } catch { throw; } }