Access Denied executing Batch File from CreateProcessAsUser

Discussion in 'ASP .Net Security' started by S Hayes, Apr 26, 2005.

  1. S Hayes

    S Hayes Guest

    I am trying to run a batch file from within an Asp.net webservice and am
    receiving an Access Denied error. I have verified that the impersonated user
    has proper rights to the directory that the batch file is in by executing a
    program from the same directory. It seems that everything works fine for non
    batch file execution, but batch files return an error.

    I'm currently running under IIS 5.

    --
    STH
    S Hayes, Apr 26, 2005
    #1
    1. Advertising

  2. The batch file executed under IIS user account. You should define rights for
    it. Impersonation doesn't work for your scenario


    "S Hayes" <> wrote in message
    news:...
    >I am trying to run a batch file from within an Asp.net webservice and am
    > receiving an Access Denied error. I have verified that the impersonated
    > user
    > has proper rights to the directory that the batch file is in by executing
    > a
    > program from the same directory. It seems that everything works fine for
    > non
    > batch file execution, but batch files return an error.
    >
    > I'm currently running under IIS 5.
    >
    > --
    > STH
    Yunus Emre ALPÖZEN [MCP], Apr 26, 2005
    #2
    1. Advertising

  3. S Hayes

    S Hayes Guest

    I don't understand what you mean by "The batch file executed under IIS user
    account". I am using the CreateProcessAsUser which will create the process
    using the credentials of the passed in Token which I am getting from the
    Impersonated user. Again, I have verified this works when executing a
    program file, but fails when executing a batch file.

    "Yunus Emre ALPÖZEN [MCP]" wrote:

    > The batch file executed under IIS user account. You should define rights for
    > it. Impersonation doesn't work for your scenario
    >
    >
    > "S Hayes" <> wrote in message
    > news:...
    > >I am trying to run a batch file from within an Asp.net webservice and am
    > > receiving an Access Denied error. I have verified that the impersonated
    > > user
    > > has proper rights to the directory that the batch file is in by executing
    > > a
    > > program from the same directory. It seems that everything works fine for
    > > non
    > > batch file execution, but batch files return an error.
    > >
    > > I'm currently running under IIS 5.
    > >
    > > --
    > > STH

    >
    >
    >
    S Hayes, Apr 26, 2005
    #3
  4. do u develop an ASP.NET web service ???

    "CreateProcessAsUser property specifies whether a CGI process is created in
    the system context or in the context of the requesting user"
    not a batch application.

    My advice u to use System.Diagnostics.Process...

    Do u have any sample code to cause error again??

    "S Hayes" <> wrote in message
    news:...
    >I don't understand what you mean by "The batch file executed under IIS user
    > account". I am using the CreateProcessAsUser which will create the
    > process
    > using the credentials of the passed in Token which I am getting from the
    > Impersonated user. Again, I have verified this works when executing a
    > program file, but fails when executing a batch file.
    >
    > "Yunus Emre ALPÖZEN [MCP]" wrote:
    >
    >> The batch file executed under IIS user account. You should define rights
    >> for
    >> it. Impersonation doesn't work for your scenario
    >>
    >>
    >> "S Hayes" <> wrote in message
    >> news:...
    >> >I am trying to run a batch file from within an Asp.net webservice and am
    >> > receiving an Access Denied error. I have verified that the
    >> > impersonated
    >> > user
    >> > has proper rights to the directory that the batch file is in by
    >> > executing
    >> > a
    >> > program from the same directory. It seems that everything works fine
    >> > for
    >> > non
    >> > batch file execution, but batch files return an error.
    >> >
    >> > I'm currently running under IIS 5.
    >> >
    >> > --
    >> > STH

    >>
    >>
    >>
    Yunus Emre ALPÖZEN [MCP], Apr 26, 2005
    #4
  5. S Hayes

    S Hayes Guest

    I can't use System.Diagnostics.Process in my case since this class ALWAYS
    creates the process with the underlying process security context, not the
    impersonated users security context.

    This code is being executed within a ASP.NET web services.

    The following is the function that is being called. When the executable
    parameter passed in is a batch file, I get the 'Access Denied' error on the
    CreateProcessAsUser call. If the executable parameter is a program, then
    everything works nicely. As stated in earlier Threads, both the batch file
    and the program file are in the same directory and the impersonated user has
    Full rights.

    <<**********************************
    #region Win32 declarations

    [StructLayout(LayoutKind.Sequential)]
    private struct STARTUPINFO
    {
    public int cb;
    public String lpReserved;
    public String lpDesktop;
    public String lpTitle;
    public uint dwX;
    public uint dwY;
    public uint dwXSize;
    public uint dwYSize;
    public uint dwXCountChars;
    public uint dwYCountChars;
    public uint dwFillAttribute;
    public uint dwFlags;
    public short wShowWindow;
    public short cbReserved2;
    public IntPtr lpReserved2;
    public IntPtr hStdInput;
    public IntPtr hStdOutput;
    public IntPtr hStdError;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct PROCESS_INFORMATION
    {
    public IntPtr hProcess;
    public IntPtr hThread;
    public uint dwProcessId;
    public uint dwThreadId;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct SECURITY_ATTRIBUTES
    {
    public int Length;
    public IntPtr lpSecurityDescriptor;
    public bool bInheritHandle;
    }

    [DllImport("kernel32.dll")]
    private static extern bool GetExitCodeProcess(IntPtr hProcess, out uint
    lpExitCode);

    [DllImport("kernel32", SetLastError=true, ExactSpelling=true)]
    private static extern Int32 WaitForSingleObject(IntPtr handle, Int32
    milliseconds);

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

    [DllImport("advapi32.dll", EntryPoint="CreateProcessAsUser",
    SetLastError=true, CharSet=CharSet.Ansi,
    CallingConvention=CallingConvention.StdCall)]
    private extern static bool CreateProcessAsUser(IntPtr hToken, String
    lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES
    lpProcessAttributes,
    ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int
    dwCreationFlags, IntPtr lpEnvironment,
    String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out
    PROCESS_INFORMATION lpProcessInformation);

    [DllImport("advapi32.dll", EntryPoint="DuplicateTokenEx",
    SetLastError=true)]
    private extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle,
    uint dwDesiredAccess,
    ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType,
    int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);

    #endregion

    public static int RunProcessAsUser(string executable,string cmdLine,int
    timeOut)
    {
    int errorCode = 0;
    bool ret;
    IntPtr token = new IntPtr(0);
    IntPtr dupedToken = new IntPtr(0);

    SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
    sa.bInheritHandle = false;
    sa.Length = Marshal.SizeOf(sa);
    sa.lpSecurityDescriptor = (IntPtr)0;

    token = WindowsIdentity.GetCurrent().Token;
    const uint GENERIC_ALL = 0x10000000;

    const int SecurityImpersonation = 2;
    const int TokenType = 1;

    ret = DuplicateTokenEx(token, GENERIC_ALL, ref sa, SecurityImpersonation,
    TokenType, ref dupedToken);

    if (ret == false)
    {
    errorCode = Marshal.GetLastWin32Error();
    throw new Exceptions.SecurityException("Unable to duplicate User
    Security Token",new Win32Exception(errorCode));
    }

    STARTUPINFO si = new STARTUPINFO();
    si.cb = Marshal.SizeOf(si);
    si.lpDesktop = "";

    PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
    ret = CreateProcessAsUser(dupedToken, executable, cmdLine, ref sa, ref
    sa, false, 0, (IntPtr)0, null, ref si, out pi);

    if (ret == false)
    {
    errorCode = Marshal.GetLastWin32Error();
    throw new Exceptions.SecurityException("Unable to Create Process for
    User",new Win32Exception(errorCode));
    }

    if(WaitForSingleObject( pi.hProcess, timeOut ) != 0)
    throw new Exceptions.WarningException("Timeout running User Process");

    uint ec;
    GetExitCodeProcess(pi.hProcess,out ec);
    errorCode = (int)ec;

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    CloseHandle(dupedToken);

    return errorCode;
    }

    **********************************>>

    "Yunus Emre ALPÖZEN [MCP]" wrote:

    > do u develop an ASP.NET web service ???
    >
    > "CreateProcessAsUser property specifies whether a CGI process is created in
    > the system context or in the context of the requesting user"
    > not a batch application.
    >
    > My advice u to use System.Diagnostics.Process...
    >
    > Do u have any sample code to cause error again??
    >
    > "S Hayes" <> wrote in message
    > news:...
    > >I don't understand what you mean by "The batch file executed under IIS user
    > > account". I am using the CreateProcessAsUser which will create the
    > > process
    > > using the credentials of the passed in Token which I am getting from the
    > > Impersonated user. Again, I have verified this works when executing a
    > > program file, but fails when executing a batch file.
    > >
    > > "Yunus Emre ALPÖZEN [MCP]" wrote:
    > >
    > >> The batch file executed under IIS user account. You should define rights
    > >> for
    > >> it. Impersonation doesn't work for your scenario
    > >>
    > >>
    > >> "S Hayes" <> wrote in message
    > >> news:...
    > >> >I am trying to run a batch file from within an Asp.net webservice and am
    > >> > receiving an Access Denied error. I have verified that the
    > >> > impersonated
    > >> > user
    > >> > has proper rights to the directory that the batch file is in by
    > >> > executing
    > >> > a
    > >> > program from the same directory. It seems that everything works fine
    > >> > for
    > >> > non
    > >> > batch file execution, but batch files return an error.
    > >> >
    > >> > I'm currently running under IIS 5.
    > >> >
    > >> > --
    > >> > STH
    > >>
    > >>
    > >>

    >
    >
    >
    S Hayes, Apr 27, 2005
    #5
  6. Did you see some of the references to previous threads that suggested using
    WMI to accomplish this? Apparently that solution works well. I can't
    remember what the problem is with CreateProcessAsUser, but you seem to have
    the same symptoms that others have complained of in the past.

    Just a thought...

    Joe K.

    "S Hayes" <> wrote in message
    news:...
    >I can't use System.Diagnostics.Process in my case since this class ALWAYS
    > creates the process with the underlying process security context, not the
    > impersonated users security context.
    >
    > This code is being executed within a ASP.NET web services.
    >
    > The following is the function that is being called. When the executable
    > parameter passed in is a batch file, I get the 'Access Denied' error on
    > the
    > CreateProcessAsUser call. If the executable parameter is a program, then
    > everything works nicely. As stated in earlier Threads, both the batch
    > file
    > and the program file are in the same directory and the impersonated user
    > has
    > Full rights.
    >
    > <<**********************************
    > #region Win32 declarations
    >
    > [StructLayout(LayoutKind.Sequential)]
    > private struct STARTUPINFO
    > {
    > public int cb;
    > public String lpReserved;
    > public String lpDesktop;
    > public String lpTitle;
    > public uint dwX;
    > public uint dwY;
    > public uint dwXSize;
    > public uint dwYSize;
    > public uint dwXCountChars;
    > public uint dwYCountChars;
    > public uint dwFillAttribute;
    > public uint dwFlags;
    > public short wShowWindow;
    > public short cbReserved2;
    > public IntPtr lpReserved2;
    > public IntPtr hStdInput;
    > public IntPtr hStdOutput;
    > public IntPtr hStdError;
    > }
    >
    > [StructLayout(LayoutKind.Sequential)]
    > private struct PROCESS_INFORMATION
    > {
    > public IntPtr hProcess;
    > public IntPtr hThread;
    > public uint dwProcessId;
    > public uint dwThreadId;
    > }
    >
    > [StructLayout(LayoutKind.Sequential)]
    > private struct SECURITY_ATTRIBUTES
    > {
    > public int Length;
    > public IntPtr lpSecurityDescriptor;
    > public bool bInheritHandle;
    > }
    >
    > [DllImport("kernel32.dll")]
    > private static extern bool GetExitCodeProcess(IntPtr hProcess, out uint
    > lpExitCode);
    >
    > [DllImport("kernel32", SetLastError=true, ExactSpelling=true)]
    > private static extern Int32 WaitForSingleObject(IntPtr handle, Int32
    > milliseconds);
    >
    > [DllImport("kernel32.dll", EntryPoint="CloseHandle", SetLastError=true,
    > CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
    > private extern static bool CloseHandle(IntPtr handle);
    >
    > [DllImport("advapi32.dll", EntryPoint="CreateProcessAsUser",
    > SetLastError=true, CharSet=CharSet.Ansi,
    > CallingConvention=CallingConvention.StdCall)]
    > private extern static bool CreateProcessAsUser(IntPtr hToken, String
    > lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES
    > lpProcessAttributes,
    > ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int
    > dwCreationFlags, IntPtr lpEnvironment,
    > String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out
    > PROCESS_INFORMATION lpProcessInformation);
    >
    > [DllImport("advapi32.dll", EntryPoint="DuplicateTokenEx",
    > SetLastError=true)]
    > private extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle,
    > uint dwDesiredAccess,
    > ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType,
    > int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);
    >
    > #endregion
    >
    > public static int RunProcessAsUser(string executable,string cmdLine,int
    > timeOut)
    > {
    > int errorCode = 0;
    > bool ret;
    > IntPtr token = new IntPtr(0);
    > IntPtr dupedToken = new IntPtr(0);
    >
    > SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
    > sa.bInheritHandle = false;
    > sa.Length = Marshal.SizeOf(sa);
    > sa.lpSecurityDescriptor = (IntPtr)0;
    >
    > token = WindowsIdentity.GetCurrent().Token;
    > const uint GENERIC_ALL = 0x10000000;
    >
    > const int SecurityImpersonation = 2;
    > const int TokenType = 1;
    >
    > ret = DuplicateTokenEx(token, GENERIC_ALL, ref sa,
    > SecurityImpersonation,
    > TokenType, ref dupedToken);
    >
    > if (ret == false)
    > {
    > errorCode = Marshal.GetLastWin32Error();
    > throw new Exceptions.SecurityException("Unable to duplicate User
    > Security Token",new Win32Exception(errorCode));
    > }
    >
    > STARTUPINFO si = new STARTUPINFO();
    > si.cb = Marshal.SizeOf(si);
    > si.lpDesktop = "";
    >
    > PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
    > ret = CreateProcessAsUser(dupedToken, executable, cmdLine, ref sa, ref
    > sa, false, 0, (IntPtr)0, null, ref si, out pi);
    >
    > if (ret == false)
    > {
    > errorCode = Marshal.GetLastWin32Error();
    > throw new Exceptions.SecurityException("Unable to Create Process for
    > User",new Win32Exception(errorCode));
    > }
    >
    > if(WaitForSingleObject( pi.hProcess, timeOut ) != 0)
    > throw new Exceptions.WarningException("Timeout running User
    > Process");
    >
    > uint ec;
    > GetExitCodeProcess(pi.hProcess,out ec);
    > errorCode = (int)ec;
    >
    > CloseHandle(pi.hProcess);
    > CloseHandle(pi.hThread);
    >
    > CloseHandle(dupedToken);
    >
    > return errorCode;
    > }
    >
    > **********************************>>
    >
    > "Yunus Emre ALPÖZEN [MCP]" wrote:
    >
    >> do u develop an ASP.NET web service ???
    >>
    >> "CreateProcessAsUser property specifies whether a CGI process is created
    >> in
    >> the system context or in the context of the requesting user"
    >> not a batch application.
    >>
    >> My advice u to use System.Diagnostics.Process...
    >>
    >> Do u have any sample code to cause error again??
    >>
    >> "S Hayes" <> wrote in message
    >> news:...
    >> >I don't understand what you mean by "The batch file executed under IIS
    >> >user
    >> > account". I am using the CreateProcessAsUser which will create the
    >> > process
    >> > using the credentials of the passed in Token which I am getting from
    >> > the
    >> > Impersonated user. Again, I have verified this works when executing a
    >> > program file, but fails when executing a batch file.
    >> >
    >> > "Yunus Emre ALPÖZEN [MCP]" wrote:
    >> >
    >> >> The batch file executed under IIS user account. You should define
    >> >> rights
    >> >> for
    >> >> it. Impersonation doesn't work for your scenario
    >> >>
    >> >>
    >> >> "S Hayes" <> wrote in message
    >> >> news:...
    >> >> >I am trying to run a batch file from within an Asp.net webservice and
    >> >> >am
    >> >> > receiving an Access Denied error. I have verified that the
    >> >> > impersonated
    >> >> > user
    >> >> > has proper rights to the directory that the batch file is in by
    >> >> > executing
    >> >> > a
    >> >> > program from the same directory. It seems that everything works
    >> >> > fine
    >> >> > for
    >> >> > non
    >> >> > batch file execution, but batch files return an error.
    >> >> >
    >> >> > I'm currently running under IIS 5.
    >> >> >
    >> >> > --
    >> >> > STH
    >> >>
    >> >>
    >> >>

    >>
    >>
    >>
    Joe Kaplan \(MVP - ADSI\), Apr 28, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Maya
    Replies:
    1
    Views:
    5,871
    Victor Bazarov
    Dec 20, 2004
  2. Replies:
    0
    Views:
    2,209
  3. Pete Fong

    Createprocessasuser

    Pete Fong, May 7, 2004, in forum: Python
    Replies:
    0
    Views:
    344
    Pete Fong
    May 7, 2004
  4. Pete Fong
    Replies:
    4
    Views:
    3,105
    Roger Upole
    Jun 15, 2004
  5. Maya
    Replies:
    1
    Views:
    659
    Joona I Palaste
    Dec 20, 2004
Loading...

Share This Page