예제 #1
0
        internal static UnsafeNativeMethods.DomainControllerInfo GetDcName(string computerName, string domainName, string siteName, int flags)
        {
            IntPtr domainControllerInfoPtr = IntPtr.Zero;

            try
            {
                int err = UnsafeNativeMethods.DsGetDcName(computerName, domainName, IntPtr.Zero, siteName, flags, out domainControllerInfoPtr);

                if (err != 0)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "GetDcName: DsGetDcName failed, err=" + err);
                    throw new PrincipalOperationException(
                              String.Format(
                                  CultureInfo.CurrentCulture,
                                  StringResources.UnableToRetrieveDomainInfo,
                                  err));
                }

                UnsafeNativeMethods.DomainControllerInfo domainControllerInfo =
                    (UnsafeNativeMethods.DomainControllerInfo)Marshal.PtrToStructure(domainControllerInfoPtr, typeof(UnsafeNativeMethods.DomainControllerInfo));

                return(domainControllerInfo);
            }
            finally
            {
                if (domainControllerInfoPtr != IntPtr.Zero)
                {
                    UnsafeNativeMethods.NetApiBufferFree(domainControllerInfoPtr);
                }
            }
        }
예제 #2
0
파일: Utils.cs 프로젝트: modulexcite/pash-1
        internal static UnsafeNativeMethods.DomainControllerInfo GetDcName(string computerName, string domainName, string siteName, int flags)
        {
            UnsafeNativeMethods.DomainControllerInfo domainControllerInfo;
            IntPtr zero = IntPtr.Zero;

            try
            {
                int num = UnsafeNativeMethods.DsGetDcName(computerName, domainName, IntPtr.Zero, siteName, flags, out zero);
                if (num == 0)
                {
                    UnsafeNativeMethods.DomainControllerInfo structure = (UnsafeNativeMethods.DomainControllerInfo)Marshal.PtrToStructure(zero, typeof(UnsafeNativeMethods.DomainControllerInfo));
                    domainControllerInfo = structure;
                }
                else
                {
                    object[] objArray = new object[1];
                    objArray[0] = num;
                    throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.UnableToRetrieveDomainInfo, objArray));
                }
            }
            finally
            {
                if (zero != IntPtr.Zero)
                {
                    UnsafeNativeMethods.NetApiBufferFree(zero);
                }
            }
            return(domainControllerInfo);
        }
예제 #3
0
        public PrincipalContext GetContext(string name, NetCred credentials, ContextOptions contextOptions)
        {
            string contextName   = name;
            string userName      = null;
            bool   explicitCreds = false;

            if (credentials != null && credentials.UserName != null)
            {
                if (credentials.Domain != null)
                {
                    userName = credentials.Domain + "\\" + credentials.UserName;
                }
                else
                {
                    userName = credentials.UserName;
                }

                explicitCreds = true;
            }
            else
            {
                userName = Utils.GetNT4UserName();
            }

            GlobalDebug.WriteLineIf(
                GlobalDebug.Info,
                "SDSCache",
                "GetContext: looking for context for server {0}, user {1}, explicitCreds={2}, options={3}",
                name,
                userName,
                explicitCreds.ToString(),
                contextOptions.ToString());

            if (!_isSAM)
            {
                // Determine the domain DNS name

                // DS_RETURN_DNS_NAME | DS_DIRECTORY_SERVICE_REQUIRED | DS_BACKGROUND_ONLY
                int flags = unchecked ((int)(0x40000000 | 0x00000010 | 0x00000100));
                UnsafeNativeMethods.DomainControllerInfo info = Utils.GetDcName(null, contextName, null, flags);
                contextName = info.DomainName;
            }

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: final contextName is " + contextName);

            ManualResetEvent contextReadyEvent = null;

            while (true)
            {
                Hashtable        credTable = null;
                PrincipalContext ctx       = null;

                // Wait for the PrincipalContext to be ready
                if (contextReadyEvent != null)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: waiting");

                    contextReadyEvent.WaitOne();
                }

                contextReadyEvent = null;

                lock (_tableLock)
                {
                    CredHolder credHolder = (CredHolder)_table[contextName];

                    if (credHolder != null)
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: found a credHolder for " + contextName);

                        credTable = (explicitCreds ? credHolder.explicitCreds : credHolder.defaultCreds);
                        Debug.Assert(credTable != null);

                        object o = credTable[userName];

                        if (o is Placeholder)
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: credHolder for " + contextName + " has a Placeholder");

                            // A PrincipalContext is currently being constructed by another thread.
                            // Wait for it.
                            contextReadyEvent = ((Placeholder)o).contextReadyEvent;
                            continue;
                        }

                        WeakReference refToContext = o as WeakReference;
                        if (refToContext != null)
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: refToContext is non-null");

                            ctx = (PrincipalContext)refToContext.Target;  // null if GC'ed

                            // If the PrincipalContext hasn't been GCed or disposed, use it.
                            // Otherwise, we'll need to create a new one
                            if (ctx != null && ctx.Disposed == false)
                            {
                                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: using found refToContext");
                                return(ctx);
                            }
                            else
                            {
                                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SDSCache", "GetContext: refToContext is GCed/disposed, removing");
                                credTable.Remove(userName);
                            }
                        }
                    }

                    // Either credHolder/credTable are null (no contexts exist for the contextName), or credHolder/credTable
                    // are non-null (contexts exist, but none for the userName).  Either way, we need to create a PrincipalContext.

                    if (credHolder == null)
                    {
                        GlobalDebug.WriteLineIf(
                            GlobalDebug.Info,
                            "SDSCache",
                            "GetContext: null credHolder for " + contextName + ", explicitCreds=" + explicitCreds.ToString());

                        // No contexts exist for the contextName.  Create a CredHolder for the contextName so we have a place
                        // to store the PrincipalContext we'll be creating.
                        credHolder          = new CredHolder();
                        _table[contextName] = credHolder;

                        credTable = (explicitCreds ? credHolder.explicitCreds : credHolder.defaultCreds);
                    }

                    // Put a placeholder on the contextName/userName slot, so that other threads that come along after
                    // we release the tableLock know we're in the process of creating the needed PrincipalContext and will wait for us
                    credTable[userName] = new Placeholder();
                }

                // Now we just need to create a PrincipalContext for the contextName and credentials
                GlobalDebug.WriteLineIf(
                    GlobalDebug.Info,
                    "SDSCache",
                    "GetContext: creating context, contextName=" + contextName + ", options=" + contextOptions.ToString());

                ctx = new PrincipalContext(
                    (_isSAM ? ContextType.Machine : ContextType.Domain),
                    contextName,
                    null,
                    contextOptions,
                    credentials?.UserName,
                    credentials?.Password
                    );

                lock (_tableLock)
                {
                    Placeholder placeHolder = (Placeholder)credTable[userName];

                    // Replace the placeholder with the newly-created PrincipalContext
                    credTable[userName] = new WeakReference(ctx);

                    // Signal waiting threads to continue.  We do this after inserting the PrincipalContext
                    // into the table, so that the PrincipalContext is ready as soon as the other threads wake up.
                    // (Actually, the order probably doesn't matter, since even if we did it in the
                    // opposite order and the other thread woke up before we inserted the PrincipalContext, it would
                    // just block as soon as it tries to acquire the tableLock that we're currently holding.)
                    bool f = placeHolder.contextReadyEvent.Set();
                    Debug.Assert(f);
                }

                return(ctx);
            }
        }
예제 #4
0
        public PrincipalContext GetContext(string name, NetCred credentials, ContextOptions contextOptions)
        {
            string           nT4UserName;
            PrincipalContext target;
            PrincipalContext principalContext;
            ContextType      contextType;
            string           userName;
            string           password;
            Hashtable        hashtables;
            Hashtable        hashtables1;
            string           domainName = name;
            bool             flag       = false;

            if (credentials == null || credentials.UserName == null)
            {
                nT4UserName = Utils.GetNT4UserName();
            }
            else
            {
                if (credentials.Domain == null)
                {
                    nT4UserName = credentials.UserName;
                }
                else
                {
                    nT4UserName = string.Concat(credentials.Domain, "\\", credentials.UserName);
                }
                flag = true;
            }
            if (!this.isSAM)
            {
                int num = 0x40000110;
                UnsafeNativeMethods.DomainControllerInfo dcName = Utils.GetDcName(null, domainName, null, num);
                domainName = dcName.DomainName;
            }
            ManualResetEvent manualResetEvent = null;

            while (true)
            {
                Hashtable hashtables2 = null;
                if (manualResetEvent != null)
                {
                    manualResetEvent.WaitOne();
                }
                manualResetEvent = null;
                lock (this.tableLock)
                {
                    SDSCache.CredHolder item = (SDSCache.CredHolder) this.table[domainName];
                    if (item != null)
                    {
                        if (flag)
                        {
                            hashtables1 = item.explicitCreds;
                        }
                        else
                        {
                            hashtables1 = item.defaultCreds;
                        }
                        hashtables2 = hashtables1;
                        object obj = hashtables2[nT4UserName];
                        if (obj as SDSCache.Placeholder == null)
                        {
                            WeakReference weakReference = obj as WeakReference;
                            if (weakReference != null)
                            {
                                target = (PrincipalContext)weakReference.Target;
                                if (target == null || target.Disposed)
                                {
                                    hashtables2.Remove(nT4UserName);
                                }
                                else
                                {
                                    principalContext = target;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            manualResetEvent = ((SDSCache.Placeholder)obj).contextReadyEvent;
                            continue;
                        }
                    }
                    if (item == null)
                    {
                        item = new SDSCache.CredHolder();
                        this.table[domainName] = item;
                        if (flag)
                        {
                            hashtables = item.explicitCreds;
                        }
                        else
                        {
                            hashtables = item.defaultCreds;
                        }
                        hashtables2 = hashtables;
                    }
                    hashtables2[nT4UserName] = new SDSCache.Placeholder();
                    if (this.isSAM)
                    {
                        contextType = ContextType.Machine;
                    }
                    else
                    {
                        contextType = ContextType.Domain;
                    }
                    string         str           = domainName;
                    object         obj1          = null;
                    ContextOptions contextOption = contextOptions;
                    if (credentials != null)
                    {
                        userName = credentials.UserName;
                    }
                    else
                    {
                        userName = null;
                    }
                    if (credentials != null)
                    {
                        password = credentials.Password;
                    }
                    else
                    {
                        password = null;
                    }
                    target = new PrincipalContext(contextType, str, obj1, contextOption, userName, password);
                    lock (this.tableLock)
                    {
                        SDSCache.Placeholder placeholder = (SDSCache.Placeholder)hashtables2[nT4UserName];
                        hashtables2[nT4UserName] = new WeakReference(target);
                        placeholder.contextReadyEvent.Set();
                    }
                    return(target);
                }
            }
            return(principalContext);
        }