internal SAMGroupsSet(UnsafeNativeMethods.IADsMembers iADsMembers, SAMStoreCtx storeCtx, DirectoryEntry ctxBase) { this.atBeginning = true; this.groupsEnumerator = ((IEnumerable)iADsMembers).GetEnumerator(); this.storeCtx = storeCtx; this.ctxBase = ctxBase; }
internal SAMGroupsSet(UnsafeNativeMethods.IADsMembers iADsMembers, SAMStoreCtx storeCtx, DirectoryEntry ctxBase) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMGroupsSet", "SAMGroupsSet: creating for path={0}", ctxBase.Path); _groupsEnumerator = ((IEnumerable)iADsMembers).GetEnumerator(); _storeCtx = storeCtx; _ctxBase = ctxBase; }
internal SidList(UnsafeNativeMethods.SID_AND_ATTR[] sidAndAttr) { this.entries = new List<SidListEntry>(); int length = (int)sidAndAttr.Length; IntPtr[] intPtrArray = new IntPtr[length]; for (int i = 0; i < length; i++) { intPtrArray[i] = sidAndAttr[i].pSid; } this.TranslateSids(null, intPtrArray); }
internal SidList(UnsafeNativeMethods.SID_AND_ATTR[] sidAndAttr) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "SidList", "SidList: processing {0} Sid+Attr SIDs", sidAndAttr.Length); // Build the list of SIDs to resolve int sidCount = sidAndAttr.Length; IntPtr[] pSids = new IntPtr[sidCount]; for (int i = 0; i < sidCount; i++) { pSids[i] = sidAndAttr[i].pSid; } TranslateSids(null, pSids); }
internal SAMMembersSet(string groupPath, UnsafeNativeMethods.IADsGroup group, bool recursive, SAMStoreCtx storeCtx, DirectoryEntry ctxBase) { this.atBeginning = true; this.groupsVisited = new List<string>(); this.groupsToVisit = new List<string>(); this.foreignMembers = new List<DirectoryEntry>(); this.foreignGroups = new List<GroupPrincipal>(); this.storeCtx = storeCtx; this.ctxBase = ctxBase; this.@group = group; this.originalGroup = group; this.recursive = recursive; this.groupsVisited.Add(groupPath); UnsafeNativeMethods.IADsMembers aDsMember = group.Members(); this.membersEnumerator = ((IEnumerable)aDsMember).GetEnumerator(); }
internal SAMMembersSet(string groupPath, UnsafeNativeMethods.IADsGroup group, bool recursive, SAMStoreCtx storeCtx, DirectoryEntry ctxBase) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "SAMMembersSet: groupPath={0}, recursive={1}, base={2}", groupPath, recursive, ctxBase.Path); _storeCtx = storeCtx; _ctxBase = ctxBase; _group = group; _originalGroup = group; _recursive = recursive; _groupsVisited.Add(groupPath); // so we don't revisit it UnsafeNativeMethods.IADsMembers iADsMembers = group.Members(); _membersEnumerator = ((IEnumerable)iADsMembers).GetEnumerator(); }
private bool BindSam(string target, string userName, string password) { StringBuilder adsPath = new StringBuilder(); adsPath.Append("WinNT://"); adsPath.Append(_serverName); adsPath.Append(",computer"); Guid g = new Guid("fd8256d0-fd15-11ce-abc4-02608c9e7553"); // IID_IUnknown object value = null; // always attempt secure auth.. int authenticationType = 1; object unmanagedResult = null; try { if (Thread.CurrentThread.GetApartmentState() == ApartmentState.Unknown) { Thread.CurrentThread.SetApartmentState(ApartmentState.MTA); } // We need the credentials to be in the form <machine>\\<user> // if they just passed user then append the machine name here. if (null != userName) { int index = userName.IndexOf('\\'); if (index == -1) { userName = _serverName + "\\" + userName; } } int hr = UnsafeNativeMethods.ADsOpenObject(adsPath.ToString(), userName, password, (int)authenticationType, ref g, out value); if (hr != 0) { if (hr == unchecked ((int)(ExceptionHelper.ERROR_HRESULT_LOGON_FAILURE))) { // This is the invalid credetials case. We want to return false // instead of throwing an exception return(false); } else { throw ExceptionHelper.GetExceptionFromErrorCode(hr); } } unmanagedResult = ((UnsafeNativeMethods.IADs)value).Get("name"); } catch (System.Runtime.InteropServices.COMException e) { if (e.ErrorCode == unchecked ((int)(ExceptionHelper.ERROR_HRESULT_LOGON_FAILURE))) { return(false); } else { throw ExceptionHelper.GetExceptionFromCOMException(e); } } finally { if (value != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(value); } } return(true); }
public static extern int DsRoleGetPrimaryDomainInformation(IntPtr lpServer, UnsafeNativeMethods.DSROLE_PRIMARY_DOMAIN_INFO_LEVEL InfoLevel, out IntPtr Buffer);
public static extern bool AuthzInitializeContextFromSid(int Flags, IntPtr UserSid, IntPtr AuthzResourceManager, IntPtr pExpirationTime, UnsafeNativeMethods.LUID Identitifier, IntPtr DynamicGroupArgs, out IntPtr pAuthzClientContext);
protected void TranslateSids(string target, IntPtr[] pSids) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "SidList: processing {0} SIDs", pSids.Length); // if there are no SIDs to translate return if (pSids.Length == 0) { return; } // Build the list of SIDs to resolve int sidCount = pSids.Length; // Translate the SIDs in bulk IntPtr pOA = IntPtr.Zero; IntPtr pPolicyHandle = IntPtr.Zero; IntPtr pDomains = IntPtr.Zero; UnsafeNativeMethods.LSA_TRUST_INFORMATION[] domains; IntPtr pNames = IntPtr.Zero; UnsafeNativeMethods.LSA_TRANSLATED_NAME[] names; try { // // Get the policy handle // UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES oa = new UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES(); pOA = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES))); Marshal.StructureToPtr(oa, pOA, false); int err = 0; if (target == null) { err = UnsafeNativeMethods.LsaOpenPolicy( IntPtr.Zero, pOA, 0x800, // POLICY_LOOKUP_NAMES ref pPolicyHandle); } else { // Build an entry. Note that LSA_UNICODE_STRING.length is in bytes, // while PtrToStringUni expects a length in characters. UnsafeNativeMethods.LSA_UNICODE_STRING_Managed lsaTargetString = new UnsafeNativeMethods.LSA_UNICODE_STRING_Managed(); lsaTargetString.buffer = target; lsaTargetString.length = (ushort)(target.Length * 2); lsaTargetString.maximumLength = lsaTargetString.length; IntPtr lsaTargetPr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_UNICODE_STRING))); try { Marshal.StructureToPtr(lsaTargetString, lsaTargetPr, false); err = UnsafeNativeMethods.LsaOpenPolicy( lsaTargetPr, pOA, 0x800, // POLICY_LOOKUP_NAMES ref pPolicyHandle); } finally { if (lsaTargetPr != IntPtr.Zero) { UnsafeNativeMethods.LSA_UNICODE_STRING lsaTargetUnmanagedPtr = (UnsafeNativeMethods.LSA_UNICODE_STRING)Marshal.PtrToStructure(lsaTargetPr, typeof(UnsafeNativeMethods.LSA_UNICODE_STRING)); if (lsaTargetUnmanagedPtr.buffer != IntPtr.Zero) { Marshal.FreeHGlobal(lsaTargetUnmanagedPtr.buffer); lsaTargetUnmanagedPtr.buffer = IntPtr.Zero; } Marshal.FreeHGlobal(lsaTargetPr); } } } if (err != 0) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "SidList: couldn't get policy handle, err={0}", err); throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, SR.AuthZErrorEnumeratingGroups, SafeNativeMethods.LsaNtStatusToWinError(err))); } Debug.Assert(pPolicyHandle != IntPtr.Zero); // // Translate the SIDs // err = UnsafeNativeMethods.LsaLookupSids( pPolicyHandle, sidCount, pSids, out pDomains, out pNames); // ignore error STATUS_SOME_NOT_MAPPED = 0x00000107 and // STATUS_NONE_MAPPED = 0xC0000073 if (err != 0 && err != 263 && err != -1073741709) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "SidList: LsaLookupSids failed, err={0}", err); throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, SR.AuthZErrorEnumeratingGroups, SafeNativeMethods.LsaNtStatusToWinError(err))); } // // Get the group names in managed form // names = new UnsafeNativeMethods.LSA_TRANSLATED_NAME[sidCount]; IntPtr pCurrentName = pNames; for (int i = 0; i < sidCount; i++) { names[i] = (UnsafeNativeMethods.LSA_TRANSLATED_NAME) Marshal.PtrToStructure(pCurrentName, typeof(UnsafeNativeMethods.LSA_TRANSLATED_NAME)); pCurrentName = new IntPtr(pCurrentName.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_TRANSLATED_NAME))); } // // Get the domain names in managed form // // Extract LSA_REFERENCED_DOMAIN_LIST.Entries UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST referencedDomains = (UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST)Marshal.PtrToStructure(pDomains, typeof(UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST)); int domainCount = referencedDomains.entries; // Extract LSA_REFERENCED_DOMAIN_LIST.Domains, by iterating over the array and marshalling // each native LSA_TRUST_INFORMATION into a managed LSA_TRUST_INFORMATION. domains = new UnsafeNativeMethods.LSA_TRUST_INFORMATION[domainCount]; IntPtr pCurrentDomain = referencedDomains.domains; for (int i = 0; i < domainCount; i++) { domains[i] = (UnsafeNativeMethods.LSA_TRUST_INFORMATION)Marshal.PtrToStructure(pCurrentDomain, typeof(UnsafeNativeMethods.LSA_TRUST_INFORMATION)); pCurrentDomain = new IntPtr(pCurrentDomain.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_TRUST_INFORMATION))); } GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "SidList: got {0} groups in {1} domains", sidCount, domainCount); // // Build the list of entries // Debug.Assert(names.Length == sidCount); for (int i = 0; i < names.Length; i++) { UnsafeNativeMethods.LSA_TRANSLATED_NAME name = names[i]; // Build an entry. Note that LSA_UNICODE_STRING.length is in bytes, // while PtrToStringUni expects a length in characters. SidListEntry entry = new SidListEntry(); Debug.Assert(name.name.length % 2 == 0); entry.name = Marshal.PtrToStringUni(name.name.buffer, name.name.length / 2); // Get the domain associated with this name Debug.Assert(name.domainIndex < domains.Length); if (name.domainIndex >= 0) { UnsafeNativeMethods.LSA_TRUST_INFORMATION domain = domains[name.domainIndex]; Debug.Assert(domain.name.length % 2 == 0); entry.sidIssuerName = Marshal.PtrToStringUni(domain.name.buffer, domain.name.length / 2); } entry.pSid = pSids[i]; _entries.Add(entry); } // Sort the list so they are oriented by the issuer name. // this.entries.Sort( new SidListComparer()); } finally { if (pDomains != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(pDomains); } if (pNames != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(pNames); } if (pPolicyHandle != IntPtr.Zero) { UnsafeNativeMethods.LsaClose(pPolicyHandle); } if (pOA != IntPtr.Zero) { Marshal.FreeHGlobal(pOA); } } }
internal AuthZSet( byte[] userSid, NetCred credentials, ContextOptions contextOptions, string flatUserAuthority, StoreCtx userStoreCtx, object userCtxBase) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "AuthZSet: SID={0}, authority={1}, storeCtx={2}", Utils.ByteArrayToString(userSid), flatUserAuthority, userStoreCtx.GetType()); _userType = userStoreCtx.OwningContext.ContextType; _userCtxBase = userCtxBase; _userStoreCtx = userStoreCtx; _credentials = credentials; _contextOptions = contextOptions; // flatUserAuthority is flat domain name if userType == Domain, // flat host name if userType == LocalMachine _flatUserAuthority = flatUserAuthority; // Preload the PrincipalContext cache with the user's PrincipalContext _contexts[flatUserAuthority] = userStoreCtx.OwningContext; IntPtr hUser = IntPtr.Zero; // // Get the SIDs of the groups to which the user belongs // IntPtr pClientContext = IntPtr.Zero; IntPtr pResManager = IntPtr.Zero; IntPtr pBuffer = IntPtr.Zero; try { UnsafeNativeMethods.LUID luid = new UnsafeNativeMethods.LUID(); luid.low = 0; luid.high = 0; _psMachineSid = new SafeMemoryPtr(Utils.GetMachineDomainSid()); _psUserSid = new SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid)); bool f; int lastError = 0; GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Initializing resource manager"); // Create a resource manager f = UnsafeNativeMethods.AuthzInitializeResourceManager( UnsafeNativeMethods.AUTHZ_RM_FLAG.AUTHZ_RM_FLAG_NO_AUDIT, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out pResManager ); if (f) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting ctx from SID"); // Construct a context for the user based on the user's SID f = UnsafeNativeMethods.AuthzInitializeContextFromSid( 0, // default flags _psUserSid.DangerousGetHandle(), pResManager, IntPtr.Zero, luid, IntPtr.Zero, out pClientContext ); if (f) { int bufferSize = 0; GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx"); // Extract the group SIDs from the user's context. Determine the size of the buffer we need. f = UnsafeNativeMethods.AuthzGetInformationFromContext( pClientContext, 2, // AuthzContextInfoGroupsSids 0, out bufferSize, IntPtr.Zero ); if (!f && (bufferSize > 0) && (Marshal.GetLastWin32Error() == 122) /*ERROR_INSUFFICIENT_BUFFER*/) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx (size={0})", bufferSize); Debug.Assert(bufferSize > 0); // Set up the needed buffer pBuffer = Marshal.AllocHGlobal(bufferSize); // Extract the group SIDs from the user's context, into our buffer.0 f = UnsafeNativeMethods.AuthzGetInformationFromContext( pClientContext, 2, // AuthzContextInfoGroupsSids bufferSize, out bufferSize, pBuffer ); if (f) { // Marshall the native buffer into managed SID_AND_ATTR structures. // The native buffer holds a TOKEN_GROUPS structure: // // struct TOKEN_GROUPS { // DWORD GroupCount; // SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; // }; // // Extract TOKEN_GROUPS.GroupCount UnsafeNativeMethods.TOKEN_GROUPS tokenGroups = (UnsafeNativeMethods.TOKEN_GROUPS)Marshal.PtrToStructure(pBuffer, typeof(UnsafeNativeMethods.TOKEN_GROUPS)); int groupCount = tokenGroups.groupCount; GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Found {0} groups", groupCount); // Extract TOKEN_GROUPS.Groups, by iterating over the array and marshalling // each native SID_AND_ATTRIBUTES into a managed SID_AND_ATTR. UnsafeNativeMethods.SID_AND_ATTR[] groups = new UnsafeNativeMethods.SID_AND_ATTR[groupCount]; IntPtr currentItem = new IntPtr(pBuffer.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.TOKEN_GROUPS)) - IntPtr.Size); for (int i = 0; i < groupCount; i++) { groups[i] = (UnsafeNativeMethods.SID_AND_ATTR)Marshal.PtrToStructure(currentItem, typeof(UnsafeNativeMethods.SID_AND_ATTR)); currentItem = new IntPtr(currentItem.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.SID_AND_ATTR))); } _groupSidList = new SidList(groups); } else { lastError = Marshal.GetLastWin32Error(); } } else { lastError = Marshal.GetLastWin32Error(); // With a zero-length buffer, this should have never succeeded Debug.Assert(false); } } else { lastError = Marshal.GetLastWin32Error(); } } else { lastError = Marshal.GetLastWin32Error(); } if (!f) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "Failed to retrieve group list, {0}", lastError); throw new PrincipalOperationException( String.Format( CultureInfo.CurrentCulture, SR.AuthZFailedToRetrieveGroupList, lastError)); } // Save off the buffer since it still holds the native SIDs referenced by SidList _psBuffer = new SafeMemoryPtr(pBuffer); pBuffer = IntPtr.Zero; } catch (Exception e) { GlobalDebug.WriteLineIf(GlobalDebug.Error, "AuthZSet", "Caught exception {0} with message {1}", e.GetType(), e.Message); if (_psBuffer != null && !_psBuffer.IsInvalid) { _psBuffer.Close(); } if (_psUserSid != null && !_psUserSid.IsInvalid) { _psUserSid.Close(); } if (_psMachineSid != null && !_psMachineSid.IsInvalid) { _psMachineSid.Close(); } // We're on a platform that doesn't have the AuthZ library if (e is DllNotFoundException) { throw new NotSupportedException(SR.AuthZNotSupported, e); } if (e is EntryPointNotFoundException) { throw new NotSupportedException(SR.AuthZNotSupported, e); } throw; } finally { if (pClientContext != IntPtr.Zero) { UnsafeNativeMethods.AuthzFreeContext(pClientContext); } if (pResManager != IntPtr.Zero) { UnsafeNativeMethods.AuthzFreeResourceManager(pResManager); } if (pBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(pBuffer); } } }