Как создать RUNAS/NETONLY функциональность в (C#/.NET/WinForms) программу?

Во-первых, всегда передавайте массивы, методы обычно не должны выполнять такую ​​проверку ввода в JavaScript. Также не добавляйте calculateStatsForMetric, если у вас есть код для выброса, оберните его в try / catch и верните значение Falsey.

Теперь вы можете использовать методы массива более высокого порядка, такие как flatMap и map :

  • Взять каждую метрику
      [1116 ] Для каждой метрики
    • Возьмите каждую статистику (для этого требуется плоская карта на карте)
    • Вычислите функцию по ней
    • Сохраните истинные значения (это требует фильтра)

Или в коде:

export const refactored = (measure, metrics, stats) => 
  metrics.flatMap(metric => stats.map(stat => ({
    metric,
    stat,
    value: calculateStatsForMetric(stat, metric, measure)
  }))).filter(o => o.value);

21
задан Cade Roux 16 April 2009 в 21:35
поделиться

4 ответа

Я собрал эти полезные ссылки:

http://www.developmentnow.com/g/36_2006_3_0_0_725350/Need -помощь-с-олицетворения-пожалуйста-.htm

http://blrchen.spaces.live.com/blog/cns!572204F8C4F8A77A!251.entry

http://geekswithblogs.net/khanna/archive/ 2005/02/09 / 22430.aspx

http://msmvps.com/blogs/martinzugec/archive/2008/06/03/use-runas-from-non-domain-computer.aspx

Оказывается Я собираюсь использовать LOGON_NETCREDENTIALS_ONLY с CreateProcessWithLogonW . Я собираюсь посмотреть, смогу ли я заставить программу определить, была ли она запущена таким образом, а если нет, собрать учетные данные домена и запустить себя. Таким образом, будет только один самоуправляемый EXE-файл.

3
ответ дан 29 November 2019 в 21:50
поделиться

Я только что сделал нечто подобное, используя ImpersonationContext . Он очень интуитивно понятен и отлично работает для меня.

Чтобы работать от имени другого пользователя, синтаксис:

using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
{
    // code that executes under the new context...
}

Вот класс:

namespace Tools
{
    #region Using directives.
    // ----------------------------------------------------------------------

    using System;
    using System.Security.Principal;
    using System.Runtime.InteropServices;
    using System.ComponentModel;

    // ----------------------------------------------------------------------
    #endregion

    /////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Impersonation of a user. Allows to execute code under another
    /// user context.
    /// Please note that the account that instantiates the Impersonator class
    /// needs to have the 'Act as part of operating system' privilege set.
    /// </summary>
    /// <remarks>   
    /// This class is based on the information in the Microsoft knowledge base
    /// article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158
    /// 
    /// Encapsulate an instance into a using-directive like e.g.:
    /// 
    ///     ...
    ///     using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
    ///     {
    ///         ...
    ///         [code that executes under the new context]
    ///         ...
    ///     }
    ///     ...
    /// 
    /// Please contact the author Uwe Keim (mailto:uwe.keim@zeta-software.de)
    /// for questions regarding this class.
    /// </remarks>
    public class Impersonator :
        IDisposable
    {
        #region Public methods.
        // ------------------------------------------------------------------

        /// <summary>
        /// Constructor. Starts the impersonation with the given credentials.
        /// Please note that the account that instantiates the Impersonator class
        /// needs to have the 'Act as part of operating system' privilege set.
        /// </summary>
        /// <param name="userName">The name of the user to act as.</param>
        /// <param name="domainName">The domain name of the user to act as.</param>
        /// <param name="password">The password of the user to act as.</param>
        public Impersonator(
            string userName,
            string domainName,
            string password)
        {
            ImpersonateValidUser(userName, domainName, password);
        }

        // ------------------------------------------------------------------
        #endregion

        #region IDisposable member.
        // ------------------------------------------------------------------

        public void Dispose()
        {
            UndoImpersonation();
        }

        // ------------------------------------------------------------------
        #endregion

        #region P/Invoke.
        // ------------------------------------------------------------------

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

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int DuplicateToken(
            IntPtr hToken,
            int impersonationLevel,
            ref IntPtr hNewToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool RevertToSelf();

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

        private const int LOGON32_LOGON_INTERACTIVE = 2;
        private const int LOGON32_PROVIDER_DEFAULT = 0;

        // ------------------------------------------------------------------
        #endregion

        #region Private member.
        // ------------------------------------------------------------------

        /// <summary>
        /// Does the actual impersonation.
        /// </summary>
        /// <param name="userName">The name of the user to act as.</param>
        /// <param name="domainName">The domain name of the user to act as.</param>
        /// <param name="password">The password of the user to act as.</param>
        private void ImpersonateValidUser(
            string userName,
            string domain,
            string password)
        {
            WindowsIdentity tempWindowsIdentity = null;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            try
            {
                if (RevertToSelf())
                {
                    if (LogonUser(
                        userName,
                        domain,
                        password,
                        LOGON32_LOGON_INTERACTIVE,
                        LOGON32_PROVIDER_DEFAULT,
                        ref token) != 0)
                    {
                        if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                        {
                            tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                            impersonationContext = tempWindowsIdentity.Impersonate();
                        }
                        else
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }
                    }
                    else
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }
                else
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                if (token != IntPtr.Zero)
                {
                    CloseHandle(token);
                }
                if (tokenDuplicate != IntPtr.Zero)
                {
                    CloseHandle(tokenDuplicate);
                }
            }
        }

        /// <summary>
        /// Reverts the impersonation.
        /// </summary>
        private void UndoImpersonation()
        {
            if (impersonationContext != null)
            {
                impersonationContext.Undo();
            }
        }

        private WindowsImpersonationContext impersonationContext = null;

        // ------------------------------------------------------------------
        #endregion
    }

    /////////////////////////////////////////////////////////////////////////
}
6
ответ дан 29 November 2019 в 21:50
поделиться

Этот код является частью класса RunAs, который мы используем для запуска внешний процесс с повышенными привилегиями. Если для имени пользователя и пароля указано значение NULL, появится стандартное предупреждение UAC. При передаче значения имени пользователя и пароля вы можете запустить приложение с повышенными правами без запроса UAC.

public static Process Elevated( string process, string args, string username, string password, string workingDirectory )
{
    if( process == null || process.Length == 0 ) throw new ArgumentNullException( "process" );

    process = Path.GetFullPath( process );
    string domain = null;
    if( username != null )
        username = GetUsername( username, out domain );
    ProcessStartInfo info = new ProcessStartInfo();
    info.UseShellExecute = false;
    info.Arguments = args;
    info.WorkingDirectory = workingDirectory ?? Path.GetDirectoryName( process );
    info.FileName = process;
    info.Verb = "runas";
    info.UserName = username;
    info.Domain = domain;
    info.LoadUserProfile = true;
    if( password != null )
    {
        SecureString ss = new SecureString();
        foreach( char c in password )
            ss.AppendChar( c );
        info.Password = ss;
    }

    return Process.Start( info );
}

private static string GetUsername( string username, out string domain ) 
{
    SplitUserName( username, out username, out domain );

    if( domain == null && username.IndexOf( '@' ) < 0 )
        domain = Environment.GetEnvironmentVariable( "USERDOMAIN" );
    return username;
}
2
ответ дан 29 November 2019 в 21:50
поделиться

Они предназначены для нетривиальных контейнеров / итераторов. Откорректируйте свои привычки, и вы не потеряете производительность, когда это имеет значение.

Кроме того, есть несколько причин, чтобы предпочесть const_iterator, несмотря ни на что:

  1. Использование const выражает намерение кода (то есть только чтение, без изменения эти объекты).
  2. Использование const (_iterator) предотвращает случайное изменение данных. (см. выше)
  3. В некоторых библиотеках используетсяхватка констант begin () , чтобы пометить данные как грязные (например, OpenSG) и отправить их другим потокам / по сети при синхронизации, так что там имеет реальное влияние на производительность.
  4. Кроме того, предоставление вам доступа к неконстантным функциям-членам может иметь побочные эффекты, которые вы не намереваетесь (во многом так же, как описано выше), например отсоединение контейнеров копирования при записи от общие данные. Qt для одного, detach () создает новую копию данных, если ее используют два или более объектов. Это совершенно бесполезно, если вы просто собираетесь читать данные, которые вы указываете с помощью const_iterator .

    Конечно, есть точки данных в другом направлении:

    1. Для контейнеров STL и и много простых семантических контейнеров копирования, это не будет иметь значения для производительности. Код эквивалентен . Тем не менее, возможность написать чистый код и избежать ошибок побеждает.
    2. Const является вирусным, поэтому, если вы работаете в устаревшей базе кода, где const плохо (или просто не реализован), вам, возможно, придется работать с не -константные итераторы.
    3. По-видимому, в некоторых до C ++ 0x STL есть ошибка, из-за которой const_iterators нельзя было использовать для стирания () элементов из контейнеров.
0
ответ дан 29 November 2019 в 21:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: