実行中のプロセスで他のユーザでログオン(偽装ログオン)

  • デル株式会社
  • 昔のソース。

    プロセスの実行ユーザの権限不足で、
    コピー等の処理できない場合に、
    権限の有るユーザでログオン(偽装ログオン)し処理を実行するようにする。

    実際、要件によるからあんまり使わないと思うけども。。
    昔のソースだけに実際動くんだろうか?

    void CCpFlDlg::OnBnClickedOk()
    {
        CString strDcn;
        CString strUser;
        CString strPws;
        CString strPath;
        CString strPath2;
        CString strTemp;
    
         HANDLE hToken = NULL;
    
        BOOL bRet = TRUE;
        int  bErr = 0;
    
        m_edtDcn.GetWindowTextA ( strDcn  );
        m_edtUser.GetWindowTextA( strUser );
        m_edtPws.GetWindowTextA ( strPws  );
        m_edtPath.GetWindowTextA( strPath );
        m_edtPath2.GetWindowTextA( strPath2 );
    
        // 別のユーザでログオン
        if( ::LogonUserA( ( LPTSTR )strUser.GetString(),
                          ( LPTSTR )strDcn.GetString(),
                             ( LPTSTR )strPws.GetString(),
                          //LOGON32_LOGON_NETWORK,
                          LOGON32_LOGON_INTERACTIVE,
                          LOGON32_PROVIDER_DEFAULT,
                          &hToken ) == FALSE ) 
        {
            // ログオンに失敗
            bErr = ::GetLastError();
    
            if( bErr ==    ERROR_LOGON_FAILURE )
            {
                MessageBox( "ERROR_LOGON_FAILURE" );
            }
            else if( bErr == ERROR_ACCOUNT_RESTRICTION )
            {
                MessageBox( "ERROR_ACCOUNT_RESTRICTION" );
            }
            else if( bErr == ERROR_LOGON_TYPE_NOT_GRANTED )
            {
                MessageBox( "ERROR_LOGON_TYPE_NOT_GRANTED" );
            }
            else if( bErr == ERROR_ACCOUNT_DISABLED )
            {
                MessageBox( "ERROR_ACCOUNT_DISABLED" );
            }
            else
            {
                strTemp.Format( "その他ログオン失敗 [ %d ]", bErr );
    
                MessageBox( strTemp );
            }
            
            return;
        }
            
        MessageBox( "偽装ログオン成功" );
    
        // 偽装トークンでスレッドの権限をログオンユーザ権限に偽装
        if( ImpersonateLoggedOnUser( hToken ) == FALSE )
        {
            bErr = ::GetLastError();
            
            strTemp.Format( "スレッド偽装に失敗 [ %d ]", bErr );
    
            MessageBox( strTemp );
    
            ::CloseHandle(hToken);
    
            return;
        }    
        
        MessageBox( "スレッド偽装成功" );
        
        // 対象権限でしか動かない処理(例えばコピー)
        if( ::CopyFile( ( LPCSTR )strPath.GetString(), 
                        ( LPCSTR )strPath2.GetString(),
                        FALSE ) == FALSE )
        {
            bErr = ::GetLastError();
            
            strTemp.Format( "コピー失敗 [ %d ]", bErr );
    
            MessageBox( strTemp );
        }
        
    
        // スレッド偽装の終了
        RevertToSelf();
    
        // トークンハンドルクローズ
        ::CloseHandle( hToken );
    }
    

    関連記事

    ページ上部へ戻る