指定用户名,拿最小session,实现和用户ui交互。

这样,搞windows的自动化部署,就可以向前一大步啦。

比以前用psexec要用户名密码,指定session要先进多啦。

安全保密性也提高了。。

#include <windows.h>
#include <stdio.h>
#include <Userenv.h>
#include <Wtsapi32.h>
#pragma comment(lib, "WtsApi32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "userenv.lib")
using namespace std;

HANDLE GetUserToken(DWORD dwSessionId)
{
    HANDLE hImpersonationToken = 0;
    if (!WTSQueryUserToken(dwSessionId, &hImpersonationToken))
    {
        printf(" WTSQueryUserToken ERROR: %d\n", GetLastError());
        return FALSE;
    }
    DWORD dwNeededSize = 0;
    HANDLE *realToken = new HANDLE;
    TOKEN_USER *pTokenUser = NULL;
    PTOKEN_GROUPS pGroups = NULL;
    //twice call function
    if (!GetTokenInformation(hImpersonationToken, TokenUser, NULL, 0, &dwNeededSize))
    {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && dwNeededSize > 0)
        {
            pTokenUser = (TOKEN_USER*)new BYTE[dwNeededSize];
            if (!GetTokenInformation(hImpersonationToken, TokenUser, pTokenUser, dwNeededSize, &dwNeededSize))
            {
                printf("GetTokenInformation ERROR: %d", GetLastError());
            }
        }
        return hImpersonationToken;
    }
    return hImpersonationToken;
}

bool GetSessionUserName(DWORD dwSessionId, char username[256])
{
    LPTSTR pBuffer = NULL;
    DWORD dwBufferLen;
    if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pBuffer, &dwBufferLen))
    {
        printf(" WTSQuerySessionInformation ERROR: %d\n", GetLastError());
        return FALSE;
    }
    lstrcpy(username ,pBuffer);
    WTSFreeMemory(pBuffer);
    return TRUE;
}

void Usage(void)
{
    printf("==============Usage================\n"
            "path:\\callsession.exe 'system-admin' 'path:\\xxx.exe start'\n"
            "==============Usage================\n");
}

int main(int argc, char **argv)
{
    if(argc==1)
    {
        Usage();
        return FALSE;
    }
    else if(argc==3)
    {
        LPSTR lpUsername = argv[1];
        LPSTR lpCmdLine = argv[2];
        DWORD session_id = -1;
        DWORD session_count = 0;
        WTS_SESSION_INFOA *pSession = NULL;
        char username[256];
        BOOL blFound = FALSE;
        //EnumerateSessions
        if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSession, &session_count))
        {
            printf("WTSEnumerateSessions ERROR: %d", GetLastError());
            return FALSE;
        }
        //Get the right user and his session id
        for(DWORD i = 0; i < session_count; ++i)
        {
            GetSessionUserName(pSession[i].SessionId,username);
            //if( (pSession[i].State == WTSActive) && (pSession[i].State != WTSDisconnected) )
            if(!strcmp(lpUsername, username))
            {
                printf("\tSession user's name = %s\n",username);
                session_id = pSession[i].SessionId;
                printf("\tsession_id = %d\n",session_id);
                blFound = TRUE;
                break;
            }
        }
        if (!blFound){
            printf("No login username %s found.", lpUsername);
            return FALSE;
        }
        WTSFreeMemory(pSession); //free meme heap
        //Duplicate User Token
        HANDLE hTokenThis = GetUserToken(session_id);
        HANDLE hTokenDup = NULL;
        if (!DuplicateTokenEx(hTokenThis, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &hTokenDup))
        {
            printf("DuplicateTokenEx ERROR: %d\n", GetLastError());
            return FALSE;
        }
        if (!SetTokenInformation(hTokenDup, TokenSessionId, &session_id, sizeof(DWORD)))
        {
             printf("SetTokenInformation Error === %d\n",GetLastError());
             return FALSE;
        }
        //init this process info
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory(&si, sizeof(STARTUPINFO));
        ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
        si.cb = sizeof(STARTUPINFO);
        si.lpDesktop = "WinSta0\\Default";
        //LPVOID pEnv = NULL;
        DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
        //CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE);
        if (!CreateProcessAsUser(hTokenDup, NULL, lpCmdLine, NULL, NULL, FALSE, dwCreationFlag, NULL, NULL, &si, &pi))
        {
            printf("CreateProcessAsUser Error === %d\n",GetLastError());
            return FALSE;
        }
        printf("OK");
    }

    return 0;
}

  

alpha版出炉,实现win2008 service的session 0穿透的更多相关文章

  1. Redis 3.0.0 正式版出炉,高性能 K/V 服务

    Redis 3.0.0 正式版最终到来了,与 RC6 版本号比較.该版本号改进包含: * 修复了无磁盘的复制问题 (Oran Agra) * 在角色变化后对 BLPOP 复制进行測试 (Salvato ...

  2. Alpha版总结会议

    昨天上课的时候,我们学习了项目总结这一部分的内容,并根据老师提供的项目Postmortem模板对我们的项目进行了总结. 项目Postmortem模板主要分为设想和目标.计划.资源.变更管理.设计和实现 ...

  3. 导师互选系统 Alpha版冲刺总结

    导师互选系统 Alpha版冲刺总结 一.设想和目标 我们的软件什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件主要是要实现导师和学生双向互选的功能.功能定义清晰明确,在软 ...

  4. “来用”alpha版使用说明书

    1引言 1 .1编写目的 针对我们发布的alpha版本做出安装和使用说明,使参与内测的人员及用户了解软件的使用方法和相关内容. 1 .2参考资料 <c#程序设计基础>,赵敏主编,2011, ...

  5. [转帖]2018年JVM生态系统报告出炉

    很多未解之谜终于有答案了——2018年JVM生态系统报告出炉 https://blog.csdn.net/hollis_chuang/article/details/84134298   2018年1 ...

  6. 【Sprint3冲刺之前】TD学生助手——alpha版发布

    TD学生助手——alpha版发布 1.设想和目标  1.我们的软件要解决的问题 TD学生助手的主要核心思想就是帮助学生安排他们忙碌的学校生活.主要是通过以下几个方面 1.通过学生的需要进行分类(考试, ...

  7. 【转帖】2018全球公有云IaaS榜单出炉:阿里、腾讯、中国电信、金山云列前十

    2018全球公有云IaaS榜单出炉:阿里.腾讯.中国电信.金山云列前十 https://news.cnblogs.com/n/628391/ 中国电信貌似就是用的华为的技术 阿里 腾讯 华为 金山 百 ...

  8. 2019年6月份Github上最热门的开源项目排行出炉,一起来看看本月上榜的开源项目

    6月份Github上最热门的开源项目排行出炉,一起来看看本月上榜的开源项目有哪些: 1. the-art-of-command-line https://github.com/jlevy/the-ar ...

  9. 怒肝俩月,新鲜出炉史上最有趣的Java小白手册,第一版,每个 Java 初学者都应该收藏

    这么说吧,在我眼里,Java 就是最流行的编程语言,没有之一(PHP 往一边站).不仅岗位多,容易找到工作,关键是薪资水平也到位,不学 Java 亏得慌,对吧? 那可能零基础学编程的小伙伴就会头疼了, ...

随机推荐

  1. Springboot 相关注解大全

    1.Spring注解 1.@Autowired 标注在方法,Spring容器创建当前对象,就会调用方法,完成赋值:方法使用的参数,自定义类型的值从ioc容器中获取自动装配; Spring利用依赖注入( ...

  2. SQL 事务篇和约束

    数据库事务: 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行 事务是恢复和并发控制的基本单位.事务应该具有4个属性 ...

  3. Node“getTextContent() is undefined for the type Node”处理办法

    最近一个项目在MyEclipse导入后总是报getTextContent() is undefined for the type Node错误. 经过查找原来是因为Node类为JDK中自带的(org. ...

  4. 网页添加qq咨询

    <style>.box{ width:130px; height:150px; position:fixed; right:0px; top:30%; z-index:999; borde ...

  5. Listview多种布局的使用

    ListView中有两个可以用来让ListView可以在视图中显示多种布局的方法,分别是getItemType和getViewTypeCount 其中 getItemViewType返回的是有参数po ...

  6. leetcode523 Continuous Subarray Sum

    思路: 令sum[p]表示p位置的前缀和.如果sum[i] % k == sum[j] % k (j - i > 1),则存在子段(i, j]的和能够整除k. 实现: class Solutio ...

  7. javascript异步下载 Promise实现

    一般下载都是直接打开一个链接就行.var URL = 'XXXX';window.open(URL)其实这样会有些问题:1. 浏览器禁止打开新窗口,导致无法下载 那么怎么解决呢?这样: <a h ...

  8. Activity随笔

    Activity的生命周期 1.正常情况下的生命周期 onCreate:  Activity正在被创建,生命周期中的第一个方法,常在此方法中做一些初始化工作,比如调用setContentView方法, ...

  9. NodeJS、NPM安装配置步骤

    安装NodeJS和NPM 1.Node JS 官网下载地址 https://nodejs.org/en/download/ 2.安装完后,使用cmd 命令输入两个命令,查看安装状态 node -v n ...

  10. jQuery.fn.extend和jQuery.extend

    <script src="http://www.cssrain.cn/demo/JQuery+API/jquery-1[1].2.1.pack.js" type=" ...