Exemple #1
0
/* called with the main thread */
static int APP_CC
session_start_fork(int width, int height, int bpp, char *username,
                   char *password, tbus data, tui8 type, char *domain,
                   char *program, char *directory, char *client_ip)
{
    int display = 0;
    int pid = 0;
    int wmpid = 0;
    int xpid = 0;
    int i = 0;
    char geometry[32];
    char depth[32];
    char screen[32];
    char text[256];
    char passwd_file[256];
    char **pp1 = (char **)NULL;
    struct session_chain *temp = (struct session_chain *)NULL;
    struct list *xserver_params = (struct list *)NULL;
    time_t ltime;
    struct tm stime;
    char execvpparams[2048];

    /* initialize (zero out) local variables: */
    g_memset(&ltime, 0, sizeof(time_t));
    g_memset(&stime, 0, sizeof(struct tm));
    g_memset(geometry, 0, sizeof(char) * 32);
    g_memset(depth, 0, sizeof(char) * 32);
    g_memset(screen, 0, sizeof(char) * 32);
    g_memset(text, 0, sizeof(char) * 256);
    g_memset(passwd_file, 0, sizeof(char) * 256);

    /* check to limit concurrent sessions */
    if (g_session_count >= g_cfg->sess.max_sessions)
    {
        log_message(LOG_LEVEL_INFO, "max concurrent session limit "
                    "exceeded. login for user %s denied", username);
        return 0;
    }

    temp = (struct session_chain *)g_malloc(sizeof(struct session_chain), 0);

    if (temp == 0)
    {
        log_message(LOG_LEVEL_ERROR, "cannot create new chain "
                    "element - user %s", username);
        return 0;
    }

    temp->item = (struct session_item *)g_malloc(sizeof(struct session_item), 0);

    if (temp->item == 0)
    {
        g_free(temp);
        log_message(LOG_LEVEL_ERROR, "cannot create new session "
                    "item - user %s", username);
        return 0;
    }

    display = session_get_aval_display_from_chain();

    if (display == 0)
    {
        g_free(temp->item);
        g_free(temp);
        return 0;
    }

    pid = g_fork();

    if (pid == -1)
    {
    }
    else if (pid == 0) /* child sesman */
    {
        g_tcp_close(g_sck);
        g_tcp_close(g_thread_sck);
        auth_start_session(data, display);
        g_sprintf(geometry, "%dx%d", width, height);
        g_sprintf(depth, "%d", bpp);
        g_sprintf(screen, ":%d", display);
        wmpid = g_fork();

        if (wmpid == -1)
        {
        }
        else if (wmpid == 0) /* child (child sesman) xserver */
        {
            wait_for_xserver(display);
            env_set_user(username, 0, display);

            if (x_server_running(display))
            {
                auth_set_env(data);

                if (directory != 0)
                {
                    if (directory[0] != 0)
                    {
                        g_set_current_dir(directory);
                    }
                }

                if (program != 0)
                {
                    if (program[0] != 0)
                    {
                        g_execlp3(program, program, 0);
                        log_message(LOG_LEVEL_ALWAYS,
                                    "error starting program %s for user %s - pid %d",
                                    program, username, g_getpid());
                    }
                }

                /* try to execute user window manager if enabled */
                if (g_cfg->enable_user_wm)
                {
                    g_sprintf(text, "%s/%s", g_getenv("HOME"), g_cfg->user_wm);

                    if (g_file_exist(text))
                    {
                        g_execlp3(text, g_cfg->user_wm, 0);
                        log_message(LOG_LEVEL_ALWAYS, "error starting user "
                                    "wm for user %s - pid %d", username, g_getpid());
                        /* logging parameters */
                        log_message(LOG_LEVEL_DEBUG, "errno: %d, "
                                    "description: %s", errno, g_get_strerror());
                        log_message(LOG_LEVEL_DEBUG, "execlp3 parameter "
                                    "list:");
                        log_message(LOG_LEVEL_DEBUG, "        argv[0] = %s",
                                    text);
                        log_message(LOG_LEVEL_DEBUG, "        argv[1] = %s",
                                    g_cfg->user_wm);
                    }
                }

                /* if we're here something happened to g_execlp3
                   so we try running the default window manager */
                g_sprintf(text, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm);
                g_execlp3(text, g_cfg->default_wm, 0);

                log_message( LOG_LEVEL_ALWAYS, "error starting default "
                             "wm for user %s - pid %d", username, g_getpid());
                /* logging parameters */
                log_message( LOG_LEVEL_DEBUG, "errno: %d, description: "
                             "%s", errno, g_get_strerror());
                log_message(LOG_LEVEL_DEBUG, "execlp3 parameter list:");
                log_message(LOG_LEVEL_DEBUG, "        argv[0] = %s",
                            text);
                log_message(LOG_LEVEL_DEBUG, "        argv[1] = %s",
                            g_cfg->default_wm);

                /* still a problem starting window manager just start xterm */
                g_execlp3("xterm", "xterm", 0);

                /* should not get here */
                log_message(LOG_LEVEL_ALWAYS, "error starting xterm "
                            "for user %s - pid %d", username, g_getpid());
                /* logging parameters */
                log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
                            "%s", errno, g_get_strerror());
            }
            else
            {
                log_message(LOG_LEVEL_ERROR, "another Xserver might "
                            "already be active on display %d - see log", display);
            }

            log_message(LOG_LEVEL_DEBUG, "aborting connection...");
            g_exit(0);
        }
        else /* parent (child sesman) */
        {
            xpid = g_fork();

            if (xpid == -1)
            {
            }
            else if (xpid == 0) /* child */
            {
                env_set_user(username, passwd_file, display);
                env_check_password_file(passwd_file, password);

                if (type == SESMAN_SESSION_TYPE_XVNC)
                {
                    xserver_params = list_create();
                    xserver_params->auto_free = 1;
                    /* these are the must have parameters */
                    list_add_item(xserver_params, (long)g_strdup("Xvnc"));
                    list_add_item(xserver_params, (long)g_strdup(screen));
                    list_add_item(xserver_params, (long)g_strdup("-geometry"));
                    list_add_item(xserver_params, (long)g_strdup(geometry));
                    list_add_item(xserver_params, (long)g_strdup("-depth"));
                    list_add_item(xserver_params, (long)g_strdup(depth));
                    list_add_item(xserver_params, (long)g_strdup("-rfbauth"));
                    list_add_item(xserver_params, (long)g_strdup(passwd_file));

                    /* additional parameters from sesman.ini file */
                    //config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC,
                    //                           xserver_params);
                    list_append_list_strdup(g_cfg->vnc_params, xserver_params, 0);

                    /* make sure it ends with a zero */
                    list_add_item(xserver_params, 0);
                    pp1 = (char **)xserver_params->items;
                    log_message(LOG_LEVEL_INFO, "Xvnc start:%s", dumpItemsToString(xserver_params, execvpparams, 2048));
                    g_execvp("Xvnc", pp1);
                }
                else if (type == SESMAN_SESSION_TYPE_XRDP)
                {
                    xserver_params = list_create();
                    xserver_params->auto_free = 1;
                    /* these are the must have parameters */
                    list_add_item(xserver_params, (long)g_strdup("X11rdp"));
                    list_add_item(xserver_params, (long)g_strdup(screen));
                    list_add_item(xserver_params, (long)g_strdup("-geometry"));
                    list_add_item(xserver_params, (long)g_strdup(geometry));
                    list_add_item(xserver_params, (long)g_strdup("-depth"));
                    list_add_item(xserver_params, (long)g_strdup(depth));

                    /* additional parameters from sesman.ini file */
                    //config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP,
                    //                           xserver_params);
                    list_append_list_strdup(g_cfg->rdp_params, xserver_params, 0);

                    /* make sure it ends with a zero */
                    list_add_item(xserver_params, 0);
                    pp1 = (char **)xserver_params->items;
                    log_message(LOG_LEVEL_INFO, "X11rdp start:%s", dumpItemsToString(xserver_params, execvpparams, 2048));
                    g_execvp("X11rdp", pp1);
                }
                else
                {
                    log_message(LOG_LEVEL_ALWAYS, "bad session type - "
                                "user %s - pid %d", username, g_getpid());
                    g_exit(1);
                }

                /* should not get here */
                log_message(LOG_LEVEL_ALWAYS, "error starting X server "
                            "- user %s - pid %d", username, g_getpid());

                /* logging parameters */
                log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
                            "%s", errno, g_get_strerror());
                log_message(LOG_LEVEL_DEBUG, "execve parameter list size: "
                            "%d", (xserver_params)->count);

                for (i = 0; i < (xserver_params->count); i++)
                {
                    log_message(LOG_LEVEL_DEBUG, "        argv[%d] = %s",
                                i, (char *)list_get_item(xserver_params, i));
                }

                list_delete(xserver_params);
                g_exit(1);
            }
            else /* parent (child sesman)*/
            {
                wait_for_xserver(display);
                g_snprintf(text, 255, "%d", display);
                g_setenv("XRDP_SESSVC_DISPLAY", text, 1);
                g_snprintf(text, 255, ":%d.0", display);
                g_setenv("DISPLAY", text, 1);
                /* new style waiting for clients */
                session_start_sessvc(xpid, wmpid, data, username, display);
            }
        }
    }
    else /* parent sesman process */
    {
        temp->item->pid = pid;
        temp->item->display = display;
        temp->item->width = width;
        temp->item->height = height;
        temp->item->bpp = bpp;
        temp->item->data = data;
        g_strncpy(temp->item->client_ip, client_ip, 255);   /* store client ip data */
        g_strncpy(temp->item->name, username, 255);

        ltime = g_time1();
        localtime_r(&ltime, &stime);
        temp->item->connect_time.year = (tui16)(stime.tm_year + 1900);
        temp->item->connect_time.month = (tui8)stime.tm_mon;
        temp->item->connect_time.day = (tui8)stime.tm_mday;
        temp->item->connect_time.hour = (tui8)stime.tm_hour;
        temp->item->connect_time.minute = (tui8)stime.tm_min;
        zero_time(&(temp->item->disconnect_time));
        zero_time(&(temp->item->idle_time));

        temp->item->type = type;
        temp->item->status = SESMAN_SESSION_STATUS_ACTIVE;

        temp->next = g_sessions;
        g_sessions = temp;
        g_session_count++;
    }

    return display;
}
Exemple #2
0
/*  its the responsibility of the caller to free passwd_file                  */
int
env_set_user(const char *username, char **passwd_file, int display,
             const struct list *env_names, const struct list *env_values)
{
    int error;
    int pw_uid;
    int pw_gid;
    int uid;
    int index;
    int len;
    char *name;
    char *value;
    char *pw_shell;
    char *pw_dir;
    char text[256];
    char hostname[256];

    pw_shell = 0;
    pw_dir = 0;

    error = g_getuser_info(username, &pw_gid, &pw_uid, &pw_shell, &pw_dir, 0);

    if (error == 0)
    {
        g_rm_temp_dir();
        error = g_setgid(pw_gid);

        if (error == 0)
        {
            error = g_initgroups(username, pw_gid);
        }

        if (error == 0)
        {
            uid = pw_uid;
            error = g_setuid(uid);
        }

        g_mk_socket_path(0);

        if (error == 0)
        {
            g_clearenv();
            g_setenv("SHELL", pw_shell, 1);
            g_setenv("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin", 1);
            g_setenv("USER", username, 1);
            g_setenv("LOGNAME", username, 1);
            g_sprintf(text, "%d", uid);
            g_setenv("UID", text, 1);
            g_setenv("HOME", pw_dir, 1);
            g_set_current_dir(pw_dir);
            g_sprintf(text, ":%d.0", display);
            g_setenv("DISPLAY", text, 1);
            g_setenv("XRDP_SESSION", "1", 1);
            /* XRDP_SOCKET_PATH should be set even here, chansrv uses this */
            g_setenv("XRDP_SOCKET_PATH", XRDP_SOCKET_PATH, 1);
            /* pulse sink socket */
            g_snprintf(text, sizeof(text) - 1, CHANSRV_PORT_OUT_BASE_STR, display);
            g_setenv("XRDP_PULSE_SINK_SOCKET", text, 1);
            /* pulse source socket */
            g_snprintf(text, sizeof(text) - 1, CHANSRV_PORT_IN_BASE_STR, display);
            g_setenv("XRDP_PULSE_SOURCE_SOCKET", text, 1);
            if ((env_names != 0) && (env_values != 0) &&
                (env_names->count == env_values->count))
            {
                for (index = 0; index < env_names->count; index++)
                {
                    name = (char *) list_get_item(env_names, index),
                    value = (char *) list_get_item(env_values, index),
                    g_setenv(name, value, 1);
                }
            }
            g_gethostname(hostname, 255);
            hostname[255] = 0;
            if (passwd_file != 0)
            {
                if (0 == g_cfg->auth_file_path)
                {
                    /* if no auth_file_path is set, then we go for
                     $HOME/.vnc/sesman_passwd-USERNAME@HOSTNAME:DISPLAY */
                    if (!g_directory_exist(".vnc"))
                    {
                        if (g_mkdir(".vnc") < 0)
                        {
                            log_message(LOG_LEVEL_ERROR,
                                        "Error creating .vnc directory: %s",
                                        g_get_strerror());
                        }
                    }

                    len = g_snprintf(NULL, 0, "%s/.vnc/sesman_passwd-%s@%s:%d",
                                     pw_dir, username, hostname, display);

                    *passwd_file = (char *) g_malloc(len + 1, 1);
                    if (*passwd_file != NULL)
                    {
                        /* Try legacy names first, remove if found */
                        g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd:%d",
                                  pw_dir, username, display);
                        if (g_file_exist(*passwd_file))
                        {
                            log_message(LOG_LEVEL_WARNING, "Removing old "
                                        "password file %s", *passwd_file);
                            g_file_delete(*passwd_file);
                        }
                        g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd",
                                  pw_dir, username);
                        if (g_file_exist(*passwd_file))
                        {
                            log_message(LOG_LEVEL_WARNING, "Removing insecure "
                                        "password file %s", *passwd_file);
                            g_file_delete(*passwd_file);
                        }
                        g_sprintf(*passwd_file, "%s/.vnc/sesman_passwd-%s@%s:%d",
                                  pw_dir, username, hostname, display);
                    }
                }
                else
                {
                    /* we use auth_file_path as requested */
                    len = g_snprintf(NULL, 0, g_cfg->auth_file_path, username);

                    *passwd_file = (char *) g_malloc(len + 1, 1);
                    if (*passwd_file != NULL)
                    {
                        g_sprintf(*passwd_file, g_cfg->auth_file_path, username);
                    }
                }

                if (*passwd_file != NULL)
                {
                    LOG_DBG("pass file: %s", *passwd_file);
                }
            }

            g_free(pw_dir);
            g_free(pw_shell);
        }
    }
    else
    {
        log_message(LOG_LEVEL_ERROR,
                    "error getting user info for user %s",
                    username);
    }

    return error;
}
Exemple #3
0
/*  its the responsibility of the caller to free passwd_file                  */
int DEFAULT_CC
env_set_user(const char *username, char **passwd_file, int display,
             const struct list *env_names, const struct list *env_values)
{
    int error;
    int pw_uid;
    int pw_gid;
    int uid;
    int index;
    int len;
    char *name;
    char *value;
    char *pw_shell;
    char *pw_dir;
    char text[256];

    pw_shell = 0;
    pw_dir = 0;

    error = g_getuser_info(username, &pw_gid, &pw_uid, &pw_shell, &pw_dir, 0);

    if (error == 0)
    {
        g_rm_temp_dir();
        error = g_setgid(pw_gid);

        if (error == 0)
        {
            error = g_initgroups(username, pw_gid);
        }

        if (error == 0)
        {
            uid = pw_uid;
            error = g_setuid(uid);
        }

        g_mk_temp_dir(0);

        if (error == 0)
        {
            g_clearenv();
            g_setenv("SHELL", pw_shell, 1);
            g_setenv("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin", 1);
            g_setenv("USER", username, 1);
            g_sprintf(text, "%d", uid);
            g_setenv("UID", text, 1);
            g_setenv("HOME", pw_dir, 1);
            g_set_current_dir(pw_dir);
            g_sprintf(text, ":%d.0", display);
            g_setenv("DISPLAY", text, 1);
            g_setenv("XRDP_SESSION", "1", 1);
            if ((env_names != 0) && (env_values != 0) &&
                    (env_names->count == env_values->count))
            {
                for (index = 0; index < env_names->count; index++)
                {
                    name = (char *) list_get_item(env_names, index),
                    value = (char *) list_get_item(env_values, index),
                    g_setenv(name, value, 1);
                }
            }

            if (passwd_file != 0)
            {
                if (0 == g_cfg->auth_file_path)
                {
                    /* if no auth_file_path is set, then we go for
                     $HOME/.vnc/sesman_username_passwd:DISPLAY */
                    if (!g_directory_exist(".vnc"))
                    {
                        if (g_mkdir(".vnc") < 0)
                        {
                            log_message(LOG_LEVEL_ERROR,
                                        "Error creating .vnc directory: %s",
                                        g_get_strerror());
                        }
                    }

                    len = g_snprintf(NULL, 0, "%s/.vnc/sesman_%s_passwd:%d",
                                     pw_dir, username, display);

                    *passwd_file = (char *) g_malloc(len + 1, 1);
                    if (*passwd_file != NULL)
                    {
                        /* Try legacy name first, remove if found */
                        g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd",
                                  pw_dir, username);
                        if (g_file_exist(*passwd_file))
                        {
                            log_message(LOG_LEVEL_WARNING, "Removing insecure "
                                        "password file %s", *passwd_file);
                            g_file_delete(*passwd_file);
                        }

                        g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd:%d",
                                  pw_dir, username, display);
                    }
                }
                else
                {
                    /* we use auth_file_path as requested */
                    len = g_snprintf(NULL, 0, g_cfg->auth_file_path, username);

                    *passwd_file = (char *) g_malloc(len + 1, 1);
                    if (*passwd_file != NULL)
                    {
                        g_sprintf(*passwd_file, g_cfg->auth_file_path, username);
                    }
                }

                if (*passwd_file != NULL)
                {
                    LOG_DBG("pass file: %s", *passwd_file);
                }
            }

            g_free(pw_dir);
            g_free(pw_shell);
        }
    }
    else
    {
        log_message(LOG_LEVEL_ERROR,
                    "error getting user info for user %s",
                    username);
    }

    return error;
}
Exemple #4
0
VOID WINAPI
MyServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
    WSADATA w;
    char text[256];
    int pid;
    //HANDLE event_han;
    //  int fd;
    //  char text[256];

    //  fd = g_file_open("c:\\temp\\xrdp\\log.txt");
    //  g_file_write(fd, "hi\r\n", 4);
    //event_han = RegisterEventSource(0, "xrdp");
    //log_event(event_han, "hi xrdp log");
    g_threadid = tc_get_threadid();
    g_set_current_dir("c:\\temp\\xrdp");
    g_listen = 0;
    WSAStartup(2, &w);
    g_sync_mutex = tc_mutex_create();
    g_sync1_mutex = tc_mutex_create();
    pid = g_getpid();
    g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid);
    g_term_event = g_create_wait_obj(text);
    g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid);
    g_sync_event = g_create_wait_obj(text);
    g_memset(&g_service_status, 0, sizeof(SERVICE_STATUS));
    g_service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    g_service_status.dwCurrentState = SERVICE_RUNNING;
    g_service_status.dwControlsAccepted = SERVICE_CONTROL_INTERROGATE |
                                          SERVICE_ACCEPT_STOP |
                                          SERVICE_ACCEPT_SHUTDOWN;
    g_service_status.dwWin32ExitCode = NO_ERROR;
    g_service_status.dwServiceSpecificExitCode = 0;
    g_service_status.dwCheckPoint = 0;
    g_service_status.dwWaitHint = 0;
    //  g_sprintf(text, "calling RegisterServiceCtrlHandler\r\n");
    //  g_file_write(fd, text, g_strlen(text));
    g_ssh = RegisterServiceCtrlHandler("xrdp", MyHandler);

    if (g_ssh != 0)
    {
        //    g_sprintf(text, "ok\r\n");
        //    g_file_write(fd, text, g_strlen(text));
        SetServiceStatus(g_ssh, &g_service_status);
        g_listen = xrdp_listen_create();
        xrdp_listen_main_loop(g_listen);
        g_sleep(100);
        g_service_status.dwCurrentState = SERVICE_STOPPED;
        SetServiceStatus(g_ssh, &g_service_status);
    }
    else
    {
        //g_sprintf(text, "RegisterServiceCtrlHandler failed\r\n");
        //g_file_write(fd, text, g_strlen(text));
    }

    xrdp_listen_delete(g_listen);
    tc_mutex_delete(g_sync_mutex);
    tc_mutex_delete(g_sync1_mutex);
    g_destroy_wait_obj(g_term_event);
    g_destroy_wait_obj(g_sync_event);
    WSACleanup();
    //CloseHandle(event_han);
}
Exemple #5
0
int DEFAULT_CC
env_set_user(char *username, char *passwd_file, int display)
{
    int error;
    int pw_uid;
    int pw_gid;
    int uid;
    char pw_shell[256];
    char pw_dir[256];
    char pw_gecos[256];
    char text[256];

    error = g_getuser_info(username, &pw_gid, &pw_uid, pw_shell, pw_dir,
                           pw_gecos);

    if (error == 0)
    {
        g_rm_temp_dir();
        error = g_setgid(pw_gid);

        if (error == 0)
        {
            error = g_initgroups(username, pw_gid);
        }

        if (error == 0)
        {
            uid = pw_uid;
            error = g_setuid(uid);
        }

        g_mk_temp_dir(0);

        if (error == 0)
        {
            g_clearenv();
            g_setenv("SHELL", pw_shell, 1);
            g_setenv("PATH", "/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin", 1);
            g_setenv("USER", username, 1);
            g_sprintf(text, "%d", uid);
            g_setenv("UID", text, 1);
            g_setenv("HOME", pw_dir, 1);
            g_set_current_dir(pw_dir);
            g_sprintf(text, ":%d.0", display);
            g_setenv("DISPLAY", text, 1);
            g_setenv("LANG", "en_US.UTF-8", 1);

            if (passwd_file != 0)
            {
                if (0 == g_cfg->auth_file_path)
                {
                    /* if no auth_file_path is set, then we go for
                       $HOME/.vnc/sesman_username_passwd */
                    g_mkdir(".vnc");
                    g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username);
                }
                else
                {
                    /* we use auth_file_path as requested */
                    g_sprintf(passwd_file, g_cfg->auth_file_path, username);
                }

                LOG_DBG("pass file: %s", passwd_file);
            }
        }
    }
    else
    {
        log_message(LOG_LEVEL_ERROR,
                    "error getting user info for user %s", username);
    }

    return error;
}