Answered ITaskScheduler access denied error

  • Saturday, December 31, 2011 12:59 AM
     
     

    I've developed a COM+ server component (dll) that uses the ITaskScheduler and ITask interfaces to create and edit tasks for a specific .exe also created by the company I work for. The component is called from a classic ASP page (VBScript) and is part of an office package we are developing. The whole system uses a web interface. When run under IIS on Windows Server 2003/2008 I get 0x80070005 access denied errors when attempting to call, for instance, ITaskScheduler->Enum. This makes perfect sense, the IUsr_... account shouldn't have access to the task scheduler. I added fields for the user to enter their credentials on the webpage, and then made calls to LogonUser and then ImpersonateLoggedOnUser in the COM object. However I still get access denied errors. Subsequent calls to IServerSecurity->QueryBlanket show that the COM object is still being run under the IUsr_... account. My logon logic is as follows:

     

    bool SystemUser::LogonUser(const wchar_t* userName, const wchar_t* domain, const wchar_t* password)

    {

    if(::LogonUser(userName, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &_token))

    {

    return true;

    }

    System::LogSystemError(__W_FILE__, __W_FUNCTION__, __LINE__, L"Unable to logon user: %s domain: %s", userName, domain);

    return false;

    }

     

    bool SystemUser::Impersonate()

    {

    if(::ImpersonateLoggedOnUser(_token))

    {

    return true;

    }

    System::LogSystemError(__W_FILE__, __W_FUNCTION__, __LINE__, L"Unable to impersonate user");

    return false;

    }

     

    SuccessCode::Enum SystemUser::Logon(const wchar_t* userName, const wchar_t* domain, const wchar_t* password)

    {

    if(!_token)

    {

    if(!LogonUser(userName, domain, password) || !Impersonate())

    {

    return SuccessCode::ImpersonateError;

    }

    else

    {

    Global::systemLog.Write(LogLevel::Information, L"Successfully logged on as user: '%s' domain: '%s'", userName, domain);

    }

    }

    return SuccessCode::Success;

    }

     

    Using LOGON32_LOGON_INTERACTIVE as the logon type makes no difference. Neither does setting up specific roles in the COM+ MMC. Any help or suggestions hugely appreciated.

All Replies

  • Monday, January 02, 2012 6:45 AM
    Moderator
     
     Answered Has Code

    Hi andrewdk,

    Happy new year!

    There is one thing you should read first, the Impersonation Levels in COM: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686632(v=vs.85).aspx

    In IIS 6, you could use some registry settings in HKLM\System\CurrentControlSet\Services\w3svc\Parameters.  Create four named values of type DWORD. The first should be CoInitializeSecurityParam, and its value should be 1. This tells the worker process to pay attention to the next three settings: AuthenticationLevel, ImpersonationLevel, and AuthenticationCapabilities. If specified, the IIS 6 worker process will use these values when it calls CoInitializeSecurity. [quoted from the book The .NET Developer's Guide to Windows Security]

     // Authentication Levels
     #define RPC_C_AUTHN_LEVEL_DEFAULT 0
     #define RPC_C_AUTHN_LEVEL_NONE 1
     #define RPC_C_AUTHN_LEVEL_CONNECT 2
     #define RPC_C_AUTHN_LEVEL_CALL 3
     #define RPC_C_AUTHN_LEVEL_PKT 4
     #define RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 5
     #define RPC_C_AUTHN_LEVEL_PKT_PRIVACY 6
    
     // Impersonation Levels
     #define RPC_C_IMP_LEVEL_DEFAULT 0
     #define RPC_C_IMP_LEVEL_ANONYMOUS 1
     #define RPC_C_IMP_LEVEL_IDENTIFY 2
     #define RPC_C_IMP_LEVEL_IMPERSONATE 3
     #define RPC_C_IMP_LEVEL_DELEGATE 4
    
     typedef enum tagEOLE_AUTHENTICATION_CAPABILITIES {
       EOAC_NONE = 0x0,
       EOAC_MUTUAL_AUTH = 0x1,
       EOAC_SECURE_REFS = 0x2,
       EOAC_ACCESS_CONTROL = 0x4,
       EOAC_APPID = 0x8,
       EOAC_DYNAMIC = 0x10,
       EOAC_STATIC_CLOAKING = 0x20,
       EOAC_DYNAMIC_CLOAKING = 0x40,
       EOAC_ANY_AUTHORITY = 0x80,
       EOAC_MAKE_FULLSIC = 0x100,
       EOAC_REQUIRE_FULLSIC = 0x200,
       EOAC_AUTO_IMPERSONATE = 0x400,
       EOAC_DEFAULT = 0x800,
       EOAC_DISABLE_AAA = 0x1000,
       EOAC_NO_CUSTOM_MARSHAL = 0x2000
     } EOLE_AUTHENTICATION_CAPABILITIES;
    

    More about Authentication Levels: http://msdn.microsoft.com/en-us/library/windows/desktop/ms678509(v=vs.85).aspx

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
  • Wednesday, January 11, 2012 11:53 PM
     
     
    Thanks Bob, happy New Year to you too! My apologies for the late reply, I'm snowed under with multiple projects at the moment. I tried your suggestion, but to no avail. I'm still getting access denied errors when attempting to use any ITaskScheduler functionality. Back to the drawing board I guess.