struct session_data
{
pid_t x_server; ///< PID of X server
pid_t win_mgr; ///< PID of window manager
pid_t chansrv; //< PID of chansrv
time_t start_time; struct session_parameters params; // Flexible array member used to store strings in params and ip_addr; #ifdef __cplusplus char strings[1]; #else char strings[]; #endif
};
if (s->directory[0] != '\0')
{ if (g_cfg->sec.allow_alternate_shell)
{
g_set_current_dir(s->directory);
} else
{
LOG(LOG_LEVEL_WARNING, "Directory change to %s requested, but not " "allowed by AllowAlternateShell config value.",
s->directory);
}
}
if (s->shell[0] != '\0')
{ if (g_cfg->sec.allow_alternate_shell)
{ if (g_cfg->sec.pass_shell_as_env != NULL &&
g_cfg->sec.pass_shell_as_env[0] != '\0')
{ // Pass the shell in to the standard startwm scripts // in an environment variable
LOG(LOG_LEVEL_INFO, "Setting variable '%s' to the specified shell of '%s'",
g_cfg->sec.pass_shell_as_env,
s->shell);
g_setenv_log(g_cfg->sec.pass_shell_as_env, s->shell, 1);
} else
{ // Try to execute the shell directly (if permitted) if (g_strchr(s->shell, ' ') != 0 || g_strchr(s->shell, '\t') != 0)
{
LOG(LOG_LEVEL_INFO, "Using user requested window manager on " "display %u with embedded arguments using a shell: %s",
s->display, s->shell); constchar *argv[] = {"sh", "-c", s->shell, NULL};
g_execvp("/bin/sh", (char **)argv);
} else
{
LOG(LOG_LEVEL_INFO, "Using user requested window manager on " "display %d: %s", s->display, s->shell);
g_execlp3(s->shell, s->shell, 0);
}
}
} else
{
LOG(LOG_LEVEL_WARNING, "Shell %s requested by user, but not allowed by " "AllowAlternateShell config value.",
s->shell);
}
} else
{
LOG(LOG_LEVEL_DEBUG, "The user session on display %u did " "not request a specific window manager", s->display);
}
/* try to execute user window manager if enabled */ if (g_cfg->enable_user_wm)
{
g_snprintf(text, sizeof(text), "%s/%s",
g_getenv("HOME"), g_cfg->user_wm); if (g_file_exist(text))
{
LOG(LOG_LEVEL_INFO, "Using window manager on display %u" " from user home directory: %s", s->display, text);
g_execlp3(text, g_cfg->user_wm, 0);
} else
{
LOG(LOG_LEVEL_DEBUG, "The user home directory window manager configuration " "is enabled but window manager program does not exist: %s",
text);
}
}
LOG(LOG_LEVEL_INFO, "Using the default window manager on display %u: %s",
s->display, g_cfg->default_wm);
g_execlp3(g_cfg->default_wm, g_cfg->default_wm, 0);
/* still a problem starting window manager just start xterm */
LOG(LOG_LEVEL_WARNING, "No window manager on display %u started, " "so falling back to starting xterm for user debugging",
s->display);
g_execlp3("xterm", "xterm", 0);
/* should not get here */
LOG(LOG_LEVEL_ERROR, "A fatal error has occurred attempting to start " "the window manager on display %u, aborting connection",
s->display);
}
/******************************************************************************/ staticstruct list *
prepare_xorg_xserver_params(conststruct session_parameters *s, constchar *authfile)
{
char screen[32]; /* display number */ char text[128]; constchar *xserver;
struct list *params = list_create(); if (params != NULL)
{
params->auto_free = 1;
/* *MakesureXorgdoesn'trunsetuidroot.Rootaccessisnot *needed.Xorgcanfailwhenrunasrootandtheuserhasno *consolepermissions.
*/ if (g_cfg->sec.xorg_no_new_privileges && g_no_new_privs() != 0)
{
LOG(LOG_LEVEL_WARNING, "[session start] (display %u): Failed to disable " "setuid on X server: %s",
s->display, g_get_strerror());
}
/* get path of Xvnc from config */
xserver = (constchar *)list_get_item(g_cfg->vnc_params, 0);
/* these are the must have parameters */
list_add_strdup_multi(params,
xserver, screen, "-auth", authfile, "-geometry", geometry, "-depth", depth,
NULL);
if (passwd_file != NULL)
{ /* RFB authorization */
env_check_password_file(passwd_file, guid_str);
list_add_strdup_multi(params, "-rfbauth", passwd_file,
NULL);
} elseif (port != NULL)
{ /* UDS connection. Authorization is handled by standard socket *permissions,sowedonotneedtoauthorizewithinthe
* VNC protocol exchange as well */ char sock_mode[16];
/* Convert a standard permissions mask into decimal *forthe-rfbunixmodeswitchargument
*/
g_snprintf(sock_mode, sizeof(sock_mode), "%d", 0660); /* rw-rw---- */
/******************************************************************************/ /* Either execs the X server, or returns */ staticvoid
start_x_server(struct login_info *login_info, conststruct session_parameters *s)
{ char authfile[256]; /* The filename for storing xauth information */ char execvpparams[2048]; char *passwd_file = NULL; struct list *xserver_params = NULL; int unknown_session_type = 0;
/* Add the entry in XAUTHORITY file or exit if error */ if (add_xauth_cookie(s->display, authfile) != 0)
{
LOG(LOG_LEVEL_ERROR, "Error setting the xauth cookie for display %u in file %s",
s->display, authfile);
} else
{ switch (s->type)
{ char port[256];
case SCP_SESSION_TYPE_XORG:
xserver_params = prepare_xorg_xserver_params(s, authfile); break;
case SCP_SESSION_TYPE_XVNC:
xserver_params = prepare_xvnc_xserver_params(s, authfile,
passwd_file, NULL); break;
if (xserver_params == NULL)
{
LOG(LOG_LEVEL_ERROR, "Out of memory allocating X server params");
} elseif (unknown_session_type)
{
LOG(LOG_LEVEL_ERROR, "Unknown session type: %d",
s->type);
} else
{ /* fire up X server */
LOG(LOG_LEVEL_INFO, "Starting X server on display %u: %s",
s->display,
dumpItemsToString(xserver_params, execvpparams, 2048));
LOG_DEVEL_LEAKING_FDS("X server", 3, -1);
g_execvp_list((constchar *)xserver_params->items[0],
xserver_params);
}
}
/* should not get here */
g_free(passwd_file);
list_delete(xserver_params);
LOG(LOG_LEVEL_ERROR, "A fatal error has occurred attempting " "to start the X server on display %u, aborting connection",
s->display);
}
/******************************************************************************/ /*
* Simple helper process to fork a child and log errors */ staticint
fork_child( void (*runproc)(struct login_info *, conststruct session_parameters *), struct login_info *login_info, conststruct session_parameters *s,
pid_t group_pid)
{ int pid = g_fork(); if (pid == 0)
{ /* Child process */ if (group_pid >= 0)
{
(void)g_setpgid(0, group_pid);
}
runproc(login_info, s);
g_exit(0);
}
/******************************************************************************/ enum scp_screate_status
session_start_wrapped(struct login_info *login_info, conststruct session_parameters *s, struct session_data *sd)
{ int chansrv_pid; int display_pid; int window_manager_pid; enum scp_screate_status status = E_SCP_SCREATE_GENERAL_ERROR;
/* Set the secondary groups before starting the session to prevent *problemsonPAM-basedsystems(seeLinuxpam_setcred(3)).
* If we have *BSD setusercontext() this is not done here */ #ifndef HAVE_SETUSERCONTEXT if (g_initgroups(login_info->username) != 0)
{
LOG(LOG_LEVEL_ERROR, "Failed to initialise secondary groups for %s: %s",
login_info->username, g_get_strerror()); return E_SCP_SCREATE_GENERAL_ERROR;
} #endif
if (auth_start_session(login_info->auth_info, s->display) != 0)
{ // Errors are logged by the auth module, as they are // specific to that module return E_SCP_SCREATE_GENERAL_ERROR;
} #ifdef USE_BSD_SETLOGIN /** *Createanewsessionandprocessgroupsincethe4.4BSD *setlogin()affectstheentireprocessgroup
*/ if (g_setsid() < 0)
{
LOG(LOG_LEVEL_WARNING, "[session start] (display %d): setsid failed - pid %d",
s->display, g_getpid());
}
if (g_setlogin(login_info->username) < 0)
{
LOG(LOG_LEVEL_WARNING, "[session start] (display %d): setlogin failed for user %s - pid %d",
s->display, login_info->username, g_getpid());
} #endif
/* start the X server in a new process group. * *WegrouptheXserver,windowmanagerandchansrvinasingle *processgroup,asitallowssignalstobesenttotheusersession *withoutaffectingsesexec(andvice-versa).Thisisparticularly *importantwhendebuggingsesexecaswedon'twantaSIGINTin
* the debugger to be passed to the children */
display_pid = fork_child(start_x_server, login_info, s, 0); if (display_pid > 0)
{ enum xwait_status xws;
xws = wait_for_xserver(login_info->uid,
g_cfg->env_names,
g_cfg->env_values,
s->display);
if (xws != XW_STATUS_OK)
{ switch (xws)
{ case XW_STATUS_TIMED_OUT:
LOG(LOG_LEVEL_ERROR, "Timed out waiting for X server"); break; case XW_STATUS_FAILED_TO_START:
LOG(LOG_LEVEL_ERROR, "X server failed to start"); break; default:
LOG(LOG_LEVEL_ERROR, "An error occurred waiting for the X server");
}
status = E_SCP_SCREATE_X_SERVER_FAIL; /* Kill it anyway in case it did start and we just failed to
* pick up on it */
g_sigterm(display_pid);
g_waitpid(display_pid);
} else
{
LOG(LOG_LEVEL_INFO, "X server :%d is working", s->display);
LOG(LOG_LEVEL_INFO, "Starting window manager for display :%d",
s->display);
window_manager_pid = fork_child(start_window_manager,
login_info, s, display_pid); if (window_manager_pid < 0)
{
g_sigterm(display_pid);
g_waitpid(display_pid);
} else
{
utmp_login(window_manager_pid, s->display, login_info);
LOG(LOG_LEVEL_INFO, "Starting the xrdp channel server for display :%d",
s->display);
// Tell the caller we've started
LOG(LOG_LEVEL_INFO, "Session in progress on display :%d. Waiting until the " "window manager (pid %d) exits to end the session",
s->display, window_manager_pid);
if (sd->x_server > 0)
{
LOG(LOG_LEVEL_INFO, "Terminating X server (pid %d) on display :%d",
sd->x_server, sd->params.display);
g_sigterm(sd->x_server);
}
if (sd->chansrv > 0)
{
LOG(LOG_LEVEL_INFO, "Terminating the xrdp channel server (pid %d) " "on display :%d", sd->chansrv, sd->params.display);
g_sigterm(sd->chansrv);
}
}
if (!session_active(sd))
{
cleanup_sockets(g_login_info->uid, sd->params.display);
}
}
/* should not get here */
LOG(LOG_LEVEL_ERROR, "Error starting session reconnection script on display %d: %s",
s->display, g_cfg->reconnect_sh);
} else
{
LOG(LOG_LEVEL_WARNING, "Session reconnection script file does not exist: %s",
g_cfg->reconnect_sh);
}
}
/******************************************************************************/ void
session_reconnect(struct login_info *login_info, struct session_data *sd)
{ if (fork_child(start_reconnect_script,
login_info, &sd->params, sd->x_server) < 0)
{
LOG(LOG_LEVEL_ERROR, "Failed to fork for session reconnection script");
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet am 2026-07-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.