none
Impersonate no Windows Vista/7 (Problemas com UAC) RRS feed

  • Pergunta

  • Oi, Pessoal...

    Estou tendo problemas para usar o Impersonate na minha aplicacao.
    Meu problema é o seguinte:
    Tenho uma aplicacao que é instalada no servidor. Ao rodar o executavel, ele deve verificar e instalar (se não estiver) um componente de autenticação (DLL). Esta instalação deve ser feita na pasta %ProgramFiles%\MeuDir (que no Windows em PT_BR seria C:\Arquivos de Programas\MeuDir) da minha maquina LOCAL.
    Meu usuario (padrao) não tem direitos de Administrador, mas a configuração da aplicação contem nome_usuário/senha de um administrador do dominio da rede.
    Estou tentando o impersonate conforme codigo abaixo:

    //////////////////////////////// Inicio das Defs  //////////////////////////
    szModuleName = "CopiaArqs.exe" // Executavel a rodar...
    szCommandLine = "\"C:\\Tempo\"" \"C:\\Arquivos de Programas\\Grebs\"" // "DirOrigem DirDestino"
    //////////////////////////////// Inicio do Codigo //////////////////////////
        HANDLE  m_hUserToken;
        HANDLE  m_hNewHandle;
        DWORD   m_dwErrorCode;
        
        // Domain name was specified
        if(domain.length() > 0) {
            bLoggedOn = LogonUser(userName.c_str(), domain.c_str(), password.c_str(),
                                  LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &m_hUserToken);
        } else {
            bLoggedOn = LogonUser(userName.c_str(), domain.c_str(), password.c_str(),
                                  LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, &m_hUserToken);
        }
        
        if(!bLoggedOn) {
            m_dwErrorCode = GetLastError();
            return false;
        }
        
        // Now impersonate them
        if(!ImpersonateLoggedOnUser(m_hUserToken)) {
            m_dwErrorCode = GetLastError();
            ExpandErrorMessage(m_dwErrorCode);
            return false;
        }

        PROCESS_INFORMATION     Pi;
        STARTUPINFO             Si;
        char*                   pCmdLine;
        BOOL                    bRetorno;
        int                     inTamanho;

        memset(&Si, 0, sizeof(STARTUPINFO));
        Si.cb= sizeof(STARTUPINFO);
        GetStartupInfo(&Si);
        inTamanho = szCommandLine.length() + 1;
        pCmdLine = new char[inTamanho];
        if(!pCmdLine) {
            return FALSE;
        }
        memset(pCmdLine, 0, inTamanho);
        strcpy(pCmdLine, szCommandLine.c_str());

        DuplicateTokenEx(m_hUserToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation , &m_hNewHandle);
        bRetorno = CreateProcessAsUser(m_hNewHandle, szModuleName.c_str(), pCmdLine, NULL, NULL, FALSE,
            NORMAL_PRIORITY_CLASS, NULL, NULL, &Si, &Pi);

        if (!bRetorno) {
            m_dwErrorCode = GetLastError();
            ExpandErrorMessage(m_dwErrorCode);
        }
        CloseHandle(m_hNewHandle);
        m_hNewHandle = NULL;
        delete [] pCmdLine;

    //////////////////////////////// Fim do Codigo //////////////////////////

    Antes, obtinha erro 1314 ("Usuario nao tem direitos") ao tentar criar o novo Processo (copiar os arquivos).
    Apos duplicar o Token (linha DuplicateTokenEx()... ) o erro passou a ser 1349 (Uso incorreto do Token/Token incompativel).

    O codigo acima é uma copia/adaptação, pois está dividido em varias funções/métodos de uma classe (CImpersonate).

    Por isso coloquei os valores de alguns membros (szModuleName, etc...)

    Particularmente, dividi em funcoes para Logon/Logoff e CreateNewProcess.

    Teoricamente o impersonate funciona (LogonUser com sucesso), falhando somente no CreateNewProcess.

    Os exemplos (abundantes) na net nao demonstram como resolver o problema, sendo comum a sugestao de rodar o aplicativo como ADMIN (via RUNAS ou manifest). Esta opção não é viável, pois seria uma quebra de segurança maior que a falta do componente... :-)

    Vale salientar que somente neste momento (copia da DLL no primeiro acesso) é que necessito de direitos de administrador.

    Desde já agradeco a toda e qualquer ajuda.

    Sem mais para o momento,

        Fernando / Tercete


    C/C++ Developer


    • Tipo Alterado Tercete terça-feira, 29 de março de 2011 18:21
    • Editado Tercete terça-feira, 29 de março de 2011 18:53
    terça-feira, 22 de março de 2011 20:20

Todas as Respostas