Professional Web Applications Themes

impersonation works on local xp not on web server - ASP.NET Security

The program I have written to change a password by impersonating an admin has worked successfully on my local XP, but when transferred to the Windows 2000 server the impersonation fails. I have tried everything I can think of even to the extent of making sure the W2k box has the SE_TCB_NAME privilege and installing a server certification and the program is still not functioning properly on the server. I believe that the LogonUser() function is taking in the correct values with the exception that the token has no value...it continually is showing an output of 0 when I debug ...

  1. #1

    Default impersonation works on local xp not on web server

    The program I have written to change a password by impersonating an
    admin has worked successfully on my local XP, but when transferred to
    the Windows 2000 server the impersonation fails. I have tried
    everything I can think of even to the extent of making sure the W2k
    box has the SE_TCB_NAME privilege and installing a server
    certification and the program is still not functioning properly on the
    server. I believe that the LogonUser() function is taking in the
    correct values with the exception that the token has no value...it
    continually is showing an output of 0 when I debug on the server. Any
    suggestions would be greatly appreciated. Here is some code:
    using System;
    using System.DirectoryServices;
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Security.Permissions;
    using System.Security.Principal;
    using System.Configuration;
    using System.Diagnostics;


    namespace BoardShareData
    {
    public class UserSecurity
    {
    public UserSecurity()
    {

    }

    #region Impersonate Info
    private const int LOGON32_LOGON_INTERACTIVE = 2;
    private const int LOGON32_PROVIDER_DEFAULT = 0;

    WindowsImpersonationContext impersonationContext;

    [DllImport("advapi32.dll")]
    private static extern bool LogonUser(
    String lpszUsername,
    String lpszDomain,
    String lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    ref IntPtr phToken );

    [DllImport("advapi32.dll")]
    private static extern bool DuplicateToken(
    IntPtr ExistingTokenHandle,
    int ImpersonationLevel,
    ref IntPtr DuplicateTokenHandle );

    #endregion

    #region Private Methods
    /// <summary>
    /// Sets up the impersonation
    /// </summary>
    /// <returns></returns>
    private bool _impersonateValidUser()
    {
    string adminUser, adminPwd, domain;
    // values come from web.config file
    domain = Environment.MachineName.ToString();
    adminUser = ConfigurationSettings.AppSettings["pwdAdminUser"].ToString();
    adminPwd = ConfigurationSettings.AppSettings["pwdAdminPwd"].ToString();
    #if (DEBUG)
    // debug environment
    adminUser = ConfigurationSettings.AppSettings["pwdAdminUser-debug"].ToString();
    adminPwd = ConfigurationSettings.AppSettings["pwdAdminPwd-debug"].ToString();
    #endif

    WindowsIdentity tempWindowsIdentity;
    IntPtr token = IntPtr.Zero;
    IntPtr tokenDuplicate = IntPtr.Zero;

    // check to make sure user has rights to change the password
    if(LogonUser(adminUser, domain, adminPwd, LOGON32_LOGON_INTERACTIVE,
    LOGON32_PROVIDER_DEFAULT, ref token) != false)
    {
    if(DuplicateToken(token, 2, ref tokenDuplicate) != false)
    {
    tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
    impersonationContext = tempWindowsIdentity.Impersonate();
    if (impersonationContext != null)
    return true;
    else
    return false;
    }
    else
    return false;
    }
    else
    return false;
    }

    /// <summary>
    /// Undoes the impersonation
    /// </summary>
    private void _undoImpersonation()
    {
    impersonationContext.Undo();
    }
    #endregion

    #region Public Methods
    // change password for a given user
    public void ChangePassword(string userName, string userPwd)
    {
    if (this._impersonateValidUser())
    {
    // valid admin user, impersonation is working
    // impersonation set up, change the password
    string adStr = "WinNT://" + Environment.MachineName.ToString();

    DirectoryEntry ad = new DirectoryEntry(adStr);
    DirectoryEntry user;
    // find user and set password
    try
    {
    user = ad.Children.Find(userName, "User");
    user.Invoke("SetPassword", new object[] {userPwd});
    user.CommitChanges();
    // done with impersonation
    this._undoImpersonation();
    }
    catch (Exception exp)
    {
    // error encountered, undo impersonation
    this._undoImpersonation();
    throw exp;
    }
    }
    else
    {
    // impersonation did not work, some type of error handling here to
    let user know what happened
    Console.Write("You are not a valid user");
    }
    }

    #endregion
    }
    }
    smyers@quilogy.com Guest

  2. #2

    Default Re: impersonation works on local xp not on web server

    Are you trying to change passwords against AD? If so, there is a much
    easier way to do this using LDAP that doesn't require impersonation. I can
    help with the AD if that applies.

    If you must impersonate, you should use the canonical example provided by
    Microsoft here:
    [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemSecurityPrincipalWindowsImpersonationCo ntextClassTopic.asp?frame=true[/url]

    HTH,

    Joe K.

    <smyersquilogy.com> wrote in message
    news:5526074.0404291342.4a92a37cposting.google.co m...
    > The program I have written to change a password by impersonating an
    > admin has worked successfully on my local XP, but when transferred to
    > the Windows 2000 server the impersonation fails. I have tried
    > everything I can think of even to the extent of making sure the W2k
    > box has the SE_TCB_NAME privilege and installing a server
    > certification and the program is still not functioning properly on the
    > server. I believe that the LogonUser() function is taking in the
    > correct values with the exception that the token has no value...it
    > continually is showing an output of 0 when I debug on the server. Any
    > suggestions would be greatly appreciated. Here is some code:
    > using System;
    > using System.DirectoryServices;
    > using System.Runtime.InteropServices;
    > using System.Security;
    > using System.Security.Permissions;
    > using System.Security.Principal;
    > using System.Configuration;
    > using System.Diagnostics;
    >
    >
    > namespace BoardShareData
    > {
    > public class UserSecurity
    > {
    > public UserSecurity()
    > {
    >
    > }
    >
    > #region Impersonate Info
    > private const int LOGON32_LOGON_INTERACTIVE = 2;
    > private const int LOGON32_PROVIDER_DEFAULT = 0;
    >
    > WindowsImpersonationContext impersonationContext;
    >
    > [DllImport("advapi32.dll")]
    > private static extern bool LogonUser(
    > String lpszUsername,
    > String lpszDomain,
    > String lpszPassword,
    > int dwLogonType,
    > int dwLogonProvider,
    > ref IntPtr phToken );
    >
    > [DllImport("advapi32.dll")]
    > private static extern bool DuplicateToken(
    > IntPtr ExistingTokenHandle,
    > int ImpersonationLevel,
    > ref IntPtr DuplicateTokenHandle );
    >
    > #endregion
    >
    > #region Private Methods
    > /// <summary>
    > /// Sets up the impersonation
    > /// </summary>
    > /// <returns></returns>
    > private bool _impersonateValidUser()
    > {
    > string adminUser, adminPwd, domain;
    > // values come from web.config file
    > domain = Environment.MachineName.ToString();
    > adminUser = ConfigurationSettings.AppSettings["pwdAdminUser"].ToString();
    > adminPwd = ConfigurationSettings.AppSettings["pwdAdminPwd"].ToString();
    > #if (DEBUG)
    > // debug environment
    > adminUser =
    ConfigurationSettings.AppSettings["pwdAdminUser-debug"].ToString();
    > adminPwd =
    ConfigurationSettings.AppSettings["pwdAdminPwd-debug"].ToString();
    > #endif
    >
    > WindowsIdentity tempWindowsIdentity;
    > IntPtr token = IntPtr.Zero;
    > IntPtr tokenDuplicate = IntPtr.Zero;
    >
    > // check to make sure user has rights to change the password
    > if(LogonUser(adminUser, domain, adminPwd, LOGON32_LOGON_INTERACTIVE,
    > LOGON32_PROVIDER_DEFAULT, ref token) != false)
    > {
    > if(DuplicateToken(token, 2, ref tokenDuplicate) != false)
    > {
    > tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
    > impersonationContext = tempWindowsIdentity.Impersonate();
    > if (impersonationContext != null)
    > return true;
    > else
    > return false;
    > }
    > else
    > return false;
    > }
    > else
    > return false;
    > }
    >
    > /// <summary>
    > /// Undoes the impersonation
    > /// </summary>
    > private void _undoImpersonation()
    > {
    > impersonationContext.Undo();
    > }
    > #endregion
    >
    > #region Public Methods
    > // change password for a given user
    > public void ChangePassword(string userName, string userPwd)
    > {
    > if (this._impersonateValidUser())
    > {
    > // valid admin user, impersonation is working
    > // impersonation set up, change the password
    > string adStr = "WinNT://" + Environment.MachineName.ToString();
    >
    > DirectoryEntry ad = new DirectoryEntry(adStr);
    > DirectoryEntry user;
    > // find user and set password
    > try
    > {
    > user = ad.Children.Find(userName, "User");
    > user.Invoke("SetPassword", new object[] {userPwd});
    > user.CommitChanges();
    > // done with impersonation
    > this._undoImpersonation();
    > }
    > catch (Exception exp)
    > {
    > // error encountered, undo impersonation
    > this._undoImpersonation();
    > throw exp;
    > }
    > }
    > else
    > {
    > // impersonation did not work, some type of error handling here to
    > let user know what happened
    > Console.Write("You are not a valid user");
    > }
    > }
    >
    > #endregion
    > }
    > }

    Joe Kaplan \(MVP - ADSI\) Guest

  3. #3

    Default Re: impersonation works on local xp not on web server

    I am trying to change passwords against AD. Any help would be appreciated.
    Thanks in advance!
    Sam

    "Joe Kaplan \(MVP - ADSI\)" <joseph.e.kaplanremovethis.accenture.com> wrote in message news:<uptPiVjLEHA.3332TK2MSFTNGP10.phx.gbl>...
    > Are you trying to change passwords against AD? If so, there is a much
    > easier way to do this using LDAP that doesn't require impersonation. I can
    > help with the AD if that applies.
    >
    > If you must impersonate, you should use the canonical example provided by
    > Microsoft here:
    > [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemSecurityPrincipalWindowsImpersonationCo ntextClassTopic.asp?frame=true[/url]
    >
    > HTH,
    >
    > Joe K.
    >
    > <smyersquilogy.com> wrote in message
    > news:5526074.0404291342.4a92a37cposting.google.co m...
    > > The program I have written to change a password by impersonating an
    > > admin has worked successfully on my local XP, but when transferred to
    > > the Windows 2000 server the impersonation fails. I have tried
    > > everything I can think of even to the extent of making sure the W2k
    > > box has the SE_TCB_NAME privilege and installing a server
    > > certification and the program is still not functioning properly on the
    > > server. I believe that the LogonUser() function is taking in the
    > > correct values with the exception that the token has no value...it
    > > continually is showing an output of 0 when I debug on the server. Any
    > > suggestions would be greatly appreciated. Here is some code:
    > > using System;
    > > using System.DirectoryServices;
    > > using System.Runtime.InteropServices;
    > > using System.Security;
    > > using System.Security.Permissions;
    > > using System.Security.Principal;
    > > using System.Configuration;
    > > using System.Diagnostics;
    > >
    > >
    > > namespace BoardShareData
    > > {
    > > public class UserSecurity
    > > {
    > > public UserSecurity()
    > > {
    > >
    > > }
    > >
    > > #region Impersonate Info
    > > private const int LOGON32_LOGON_INTERACTIVE = 2;
    > > private const int LOGON32_PROVIDER_DEFAULT = 0;
    > >
    > > WindowsImpersonationContext impersonationContext;
    > >
    > > [DllImport("advapi32.dll")]
    > > private static extern bool LogonUser(
    > > String lpszUsername,
    > > String lpszDomain,
    > > String lpszPassword,
    > > int dwLogonType,
    > > int dwLogonProvider,
    > > ref IntPtr phToken );
    > >
    > > [DllImport("advapi32.dll")]
    > > private static extern bool DuplicateToken(
    > > IntPtr ExistingTokenHandle,
    > > int ImpersonationLevel,
    > > ref IntPtr DuplicateTokenHandle );
    > >
    > > #endregion
    > >
    > > #region Private Methods
    > > /// <summary>
    > > /// Sets up the impersonation
    > > /// </summary>
    > > /// <returns></returns>
    > > private bool _impersonateValidUser()
    > > {
    > > string adminUser, adminPwd, domain;
    > > // values come from web.config file
    > > domain = Environment.MachineName.ToString();
    > > adminUser = ConfigurationSettings.AppSettings["pwdAdminUser"].ToString();
    > > adminPwd = ConfigurationSettings.AppSettings["pwdAdminPwd"].ToString();
    > > #if (DEBUG)
    > > // debug environment
    > > adminUser =
    > ConfigurationSettings.AppSettings["pwdAdminUser-debug"].ToString();
    > > adminPwd =
    > ConfigurationSettings.AppSettings["pwdAdminPwd-debug"].ToString();
    > > #endif
    > >
    > > WindowsIdentity tempWindowsIdentity;
    > > IntPtr token = IntPtr.Zero;
    > > IntPtr tokenDuplicate = IntPtr.Zero;
    > >
    > > // check to make sure user has rights to change the password
    > > if(LogonUser(adminUser, domain, adminPwd, LOGON32_LOGON_INTERACTIVE,
    > > LOGON32_PROVIDER_DEFAULT, ref token) != false)
    > > {
    > > if(DuplicateToken(token, 2, ref tokenDuplicate) != false)
    > > {
    > > tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
    > > impersonationContext = tempWindowsIdentity.Impersonate();
    > > if (impersonationContext != null)
    > > return true;
    > > else
    > > return false;
    > > }
    > > else
    > > return false;
    > > }
    > > else
    > > return false;
    > > }
    > >
    > > /// <summary>
    > > /// Undoes the impersonation
    > > /// </summary>
    > > private void _undoImpersonation()
    > > {
    > > impersonationContext.Undo();
    > > }
    > > #endregion
    > >
    > > #region Public Methods
    > > // change password for a given user
    > > public void ChangePassword(string userName, string userPwd)
    > > {
    > > if (this._impersonateValidUser())
    > > {
    > > // valid admin user, impersonation is working
    > > // impersonation set up, change the password
    > > string adStr = "WinNT://" + Environment.MachineName.ToString();
    > >
    > > DirectoryEntry ad = new DirectoryEntry(adStr);
    > > DirectoryEntry user;
    > > // find user and set password
    > > try
    > > {
    > > user = ad.Children.Find(userName, "User");
    > > user.Invoke("SetPassword", new object[] {userPwd});
    > > user.CommitChanges();
    > > // done with impersonation
    > > this._undoImpersonation();
    > > }
    > > catch (Exception exp)
    > > {
    > > // error encountered, undo impersonation
    > > this._undoImpersonation();
    > > throw exp;
    > > }
    > > }
    > > else
    > > {
    > > // impersonation did not work, some type of error handling here to
    > > let user know what happened
    > > Console.Write("You are not a valid user");
    > > }
    > > }
    > >
    > > #endregion
    > > }
    > > }
    smyers@quilogy.com Guest

  4. #4

    Default Re: impersonation works on local xp not on web server

    Sorry for the delay. Below is a .NET ChangePassword routine I put together
    for someone else. It basically attempts to find the user in AD by their
    username using their old password to authenticate to AD. If it succeeds, it
    tries the ChangePassword function.

    One thing to watch out for is that ChangePassword only wants to work on a
    128 secure SSL connection to the DC. Make sure you have your DC configured
    with a valid certificate and you bind to it with the DNS name that the cert
    is issued to.

    HTH,

    Joe K.

    Private Sub ChangePassword(ByVal username As String, ByVal oldPassword
    As String, ByVal newPassword As String)

    Dim dcDNS As String = "yourdc.com" 'use this if you want to supply a
    server name
    Dim rootDN As String
    Dim rootDSE As DirectoryEntry
    Dim searchRoot As DirectoryEntry
    Dim userEntry As DirectoryEntry
    Dim searcher As DirectorySearcher
    Dim results As SearchResultCollection
    Dim result As SearchResult

    Try
    'note the authenicationtypes here
    'you need to either use SecureSocketsLayer for ChangePasswor
    rootDSE = New DirectoryEntry(String.Format("LDAP://{0}/rootDSE",
    dcDNS), username, oldPassword, AuthenticationTypes.Secure Or
    AuthenticationTypes.SecureSocketsLayer Or AuthenticationTypes.ServerBind)
    rootDN =
    DirectCast(rootDSE.Properties("defaultNamingContex t").Value, String)
    searchRoot = New DirectoryEntry(String.Format("LDAP://{0}/{1}",
    dcDNS, rootDN), username, oldPassword, AuthenticationTypes.Secure Or
    AuthenticationTypes.SecureSocketsLayer Or AuthenticationTypes.ServerBind)
    searcher = New DirectorySearcher(searchRoot)
    searcher.Filter = String.Format("sAMAccountName={0}", username)
    searcher.SearchScope = SearchScope.Subtree
    searcher.CacheResults = False

    'I use FindAll here because FindOne leaks memory if it does not
    find anything
    'in .NET 1.0 and 1.1
    results = searcher.FindAll()
    For Each result In results
    'only use this method on .NET 1.1 or higher
    'otherwise, get the adsPath value and build a new
    DirectoryEntry with the supplied credentials
    userEntry = result.GetDirectoryEntry()
    Exit For 'this is redundant because sAMAccountName is unique
    in the domain, but it is done for clarity
    Next

    If userEntry Is Nothing Then
    Throw New InvalidOperationException("User not found in this
    domain.")
    End If

    userEntry.Invoke("ChangePassword", New Object() {oldPassword,
    newPassword})
    userEntry.CommitChanges()

    Catch ex As System.Reflection.TargetInvocationException
    Throw ex.InnerException

    Finally 'these prevent other memory leaks
    If Not userEntry Is Nothing Then userEntry.Dispose()
    If Not results Is Nothing Then results.Dispose()
    If Not searcher Is Nothing Then searcher.Dispose()
    If Not searchRoot Is Nothing Then searchRoot.Dispose()
    If Not rootDSE Is Nothing Then rootDSE.Dispose()
    End Try
    End Sub


    <smyersquilogy.com> wrote in message
    news:5526074.0404300502.7a384822posting.google.co m...
    > I am trying to change passwords against AD. Any help would be appreciated.
    > Thanks in advance!
    > Sam
    >

    Joe Kaplan \(MVP - ADSI\) Guest

Similar Threads

  1. flash media server only works local on server
    By sven1973 in forum Macromedia Flash Flashcom
    Replies: 0
    Last Post: December 7th, 05:01 PM
  2. flv playback works on local system, not on web server
    By skeeze in forum Adobe Flash, Flex & Director
    Replies: 3
    Last Post: January 8th, 08:23 AM
  3. Web Services Works Local But Not On Server
    By MDKelly in forum Macromedia Flash Data Integration
    Replies: 3
    Last Post: September 26th, 03:30 AM
  4. Replies: 1
    Last Post: September 10th, 05:03 PM
  5. Replies: 1
    Last Post: June 26th, 09:17 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139