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);
        }
Exemple #2
0
        public void Save(PrincipalContext context)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "Principal", "Entering Save(Context)");

            // Make sure we're not disposed or deleted.
            CheckDisposedOrDeleted();

            // Make sure we're not a fake principal
            CheckFakePrincipal();

            if (context.ContextType == ContextType.Machine || _ctx.ContextType == ContextType.Machine)
            {
                throw new InvalidOperationException(SR.SaveToNotSupportedAgainstMachineStore);
            }
            // We must have a PrincipalContext to save into.  This should always be the case, unless we're unpersisted
            // and they never set a PrincipalContext.
            if (context == null)
            {
                Debug.Assert(this.unpersisted == true);
                throw new InvalidOperationException(SR.NullArguments);
            }

            // If the user is trying to save to the same context we are already set to then just save the changes
            if (context == _ctx)
            {
                Save();
                return;
            }

            // If we already have a context set on this object then make sure the new
            // context is of the same type.
            if (context.ContextType != _ctx.ContextType)
            {
                Debug.Assert(this.unpersisted == true);
                throw new InvalidOperationException(SR.SaveToMustHaveSamecontextType);
            }

            StoreCtx originalStoreCtx = GetStoreCtxToUse();

            _ctx = context;

            // Call the appropriate operation depending on whether this is an insert or update
            StoreCtx newStoreCtx = GetStoreCtxToUse();

            Debug.Assert(newStoreCtx != null);      // since we know this.ctx isn't null
            Debug.Assert(originalStoreCtx != null); // since we know this.ctx isn't null

            if (this.unpersisted)
            {
                // We have an unpersisted principal so we just want to create a principal in the new store.
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "Principal", "Save(context): inserting new principal of type {0} using {1}", this.GetType(), newStoreCtx.GetType());
                Debug.Assert(newStoreCtx == _ctx.ContextForType(this.GetType()));
                newStoreCtx.Insert(this);
                this.unpersisted = false;  // once we persist, we're no longer in the unpersisted state
            }
            else
            {
                // We have a principal that already exists.  We need to move it to the new store.
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "Principal", "Save(context): Moving principal of type {0} using {1}", this.GetType(), newStoreCtx.GetType());

                // we are now saving to a new store so this principal is unpersisted.
                this.unpersisted = true;

                // If the user has modified the name save away the current name so
                // if the move succeeds and the update fails we will move the item back to the original
                // store with the original name.
                bool   nameModified = _nameChanged == LoadState.Changed;
                string previousName = null;

                if (nameModified)
                {
                    string newName = _name;
                    _ctx.QueryCtx.Load(this, PropertyNames.PrincipalName);
                    previousName = _name;
                    this.Name    = newName;
                }

                newStoreCtx.Move(originalStoreCtx, this);

                try
                {
                    this.unpersisted = false;  // once we persist, we're no longer in the unpersisted state

                    newStoreCtx.Update(this);
                }
                catch (System.SystemException e)
                {
                    try
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Error, "Principal", "Save(context):,  Update Failed (attempting to move back) Exception {0} ", e.Message);

                        if (nameModified)
                        {
                            this.Name = previousName;
                        }

                        originalStoreCtx.Move(newStoreCtx, this);

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "Principal", "Move back succeeded");
                    }
                    catch (System.SystemException deleteFail)
                    {
                        // The move back failed.  Just continue we will throw the original exception below.
                        GlobalDebug.WriteLineIf(GlobalDebug.Error, "Principal", "Save(context):,  Move back Failed {0} ", deleteFail.Message);
                    }

                    if (e is System.Runtime.InteropServices.COMException)
                    {
                        throw ExceptionHelper.GetExceptionFromCOMException((System.Runtime.InteropServices.COMException)e);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            _ctx.QueryCtx = newStoreCtx;  // so Updates go to the right StoreCtx
        }
        private void DoLDAPDirectoryInit()
        {
            // use the servername if they gave us one, else let ADSI figure it out
            string serverName = "";

            if (_name != null)
            {
                if (_contextType == ContextType.ApplicationDirectory)
                {
                    serverName = _serverProperties.dnsHostName + ":" +
                                 ((ContextOptions.SecureSocketLayer & _options) > 0 ? _serverProperties.portSSL : _serverProperties.portLDAP);
                }
                else
                {
                    serverName = _name;
                }

                serverName += "/";
            }

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalContext", "DoLDAPDirectoryInit: serverName is " + serverName);

            // use the options they specified
            AuthenticationTypes authTypes = SDSUtils.MapOptionsToAuthTypes(_options);

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalContext", "DoLDAPDirectoryInit: authTypes is " + authTypes.ToString());

            DirectoryEntry de = new DirectoryEntry("LDAP://" + serverName + _container, _username, _password, authTypes);

            try
            {
                // Set the password port to the ssl port read off of the rootDSE.  Without this
                // password change/set won't work when we connect without SSL and ADAM is running
                // on non-standard port numbers.  We have already verified directory connectivity at this point
                // so this should always succeed.
                if (_serverProperties.portSSL > 0)
                {
                    de.Options.PasswordPort = _serverProperties.portSSL;
                }

                StoreCtx storeCtx = CreateContextFromDirectoryEntry(de);

                _queryCtx    = storeCtx;
                _userCtx     = storeCtx;
                _groupCtx    = storeCtx;
                _computerCtx = storeCtx;

                _connectedServer = ADUtils.GetServerName(de);
                de = null;
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                throw ExceptionHelper.GetExceptionFromCOMException(e);
            }
            catch (Exception e)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "PrincipalContext",
                                        "DoLDAPDirectoryInit: caught exception of type "
                                        + e.GetType().ToString() +
                                        " and message " + e.Message);

                throw;
            }
            finally
            {
                // Cleanup the DE on failure
                if (de != null)
                {
                    de.Dispose();
                }
            }
        }