Странное поведени LogonUser - Access denied
От: senglory  
Дата: 04.12.13 07:57
Оценка:
using System;
using System.Data;
using System.Data.SqlClient ;
using System.Threading;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
using System.ComponentModel;
using System.IO;
using System.Xml;
using System.Collections;
using System.Diagnostics;
using System.Web;
using System.Security.Policy;


namespace Z
{
    public class SimulateUser2 : IDisposable
    {
        const int LOGON32_PROVIDER_DEFAULT = 0;
        const int LOGON32_LOGON_INTERACTIVE = 2;
        const int LOGON32_LOGON_NETWORK = 3;

        WindowsImpersonationContext _wic = null;

        public string _loginID = "";
        public string _domain = "";
        public string _password = "";

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool LogonUser(string lpszloginID,
            string lpszDomain, string lpszPassword, int dwLogonType,
            int dwLogonProvider, ref IntPtr phToken);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern bool CloseHandle(IntPtr handle);

        public SimulateUser2(string loginID, string domain, string password)
        {
            this._loginID = loginID;
            this._domain = domain;
            this._password = password;
        }

        public void Impersonate()
        {
            _wic = this.Logon().Impersonate();
        }

        public void Revert()
        {
            if (_wic != null)
                _wic.Undo();
            _wic = null;
        }

        public WindowsIdentity Logon()
        {
            // Initialize pointer.
            IntPtr windowsIdentityHandle = new IntPtr(0);
            windowsIdentityHandle = IntPtr.Zero;

            bool success = LogonUser(this._loginID, this._domain,
                this._password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                ref windowsIdentityHandle);

            // Throw an exception if the logon fails.
            if (success == false)
            {
                int error = Marshal.GetLastWin32Error();
                throw new Exception("LogonUser failed. Error: " + error);
            }

            WindowsIdentity windowsIdentity =
                new WindowsIdentity(windowsIdentityHandle, "NTLM", System.Security.Principal.WindowsAccountType.Normal, true);
            CloseHandle(windowsIdentityHandle);
            return (windowsIdentity);
        }

        void IDisposable.Dispose()
        {
            Revert();
        }
    }


    class Z
    {
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
            WindowsIdentity id = WindowsIdentity.GetCurrent();
            WindowsPrincipal wPrincipal = new WindowsPrincipal(id);
            bool st = wPrincipal.IsInRole(@"TEST\YYY Setup Group");
            bool sta = wPrincipal.IsInRole(@"BUILTIN\Administrators");
            bool staa = wPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
            var un2 = WindowsIdentity.GetCurrent().Name;
            var s2 = Path.GetTempPath();
            string _filename2 = Path.Combine(Path.GetTempPath(), "YYYInstall.log");
            File.AppendAllText(_filename2, "Impersonating user - BEFORE " + un2);

            var username = @"YYYSetup";
            var domain = @"test";
            var pwd = "1";
            using (var su = new SimulateUser2(username, domain, pwd))
            {
                su.Impersonate();

                var un = WindowsIdentity.GetCurrent().Name;

                var s = Path.GetTempPath();
                string _filename = Path.Combine(Path.GetTempPath(), "YYYInstall.log");
                File.AppendAllText(_filename, "Impersonating user - IN " + un);
            }

.NET 4.5 Юзер YYYSetup входит в TEST\YYY Setup Group и в локальные админы (я его туда поместил через Local Users and Groups MMC). Однако, в sta и staa я получаю FALSE. Но это полбеды. Беда — на втором вызове File.AppendAllText я получаю Access Denied. Вопрос — что сделать чтобы не было этого исключения? Напрямую под локальным админом заходить не буду.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.