From 7d2643ba917f8848874039634f7388a49f74467e Mon Sep 17 00:00:00 2001 From: mstone2001 <80594939+mstone2001@users.noreply.github.com> Date: Fri, 22 Sep 2023 11:09:57 -0400 Subject: [PATCH 01/10] Support Additional OS. Update xrdp to support netbsd, openindiana, macos, gentoo linux. --- common/os_calls.c | 105 +++++++++++++++++++++++++++-- configure.ac | 27 ++++++++ instfiles/Makefile.am | 29 ++++++++ instfiles/manifest/Makefile.am | 3 + instfiles/manifest/xrdp-sesman.xml | 60 +++++++++++++++++ instfiles/manifest/xrdp.xml | 59 ++++++++++++++++ instfiles/method/Makefile.am | 3 + instfiles/method/xrdp | 85 +++++++++++++++++++++++ instfiles/method/xrdp-sesman | 85 +++++++++++++++++++++++ instfiles/openrc/Makefile.am | 3 + instfiles/openrc/xrdp | 4 ++ instfiles/openrc/xrdp-sesman | 4 ++ instfiles/pam.d/xrdp-sesman.macos | 2 +- sesman/Makefile.am | 10 ++- sesman/libsesman/verify_user_pam.c | 10 ++- sesman/tools/Makefile.am | 8 +++ tools/devel/tcp_proxy/Makefile.am | 4 ++ xrdp/xrdp_mm.c | 37 +++++++--- 18 files changed, 520 insertions(+), 18 deletions(-) create mode 100644 instfiles/manifest/Makefile.am create mode 100644 instfiles/manifest/xrdp-sesman.xml create mode 100644 instfiles/manifest/xrdp.xml create mode 100644 instfiles/method/Makefile.am create mode 100755 instfiles/method/xrdp create mode 100755 instfiles/method/xrdp-sesman create mode 100644 instfiles/openrc/Makefile.am create mode 100755 instfiles/openrc/xrdp create mode 100755 instfiles/openrc/xrdp-sesman diff --git a/common/os_calls.c b/common/os_calls.c index 68687f95ae..d6bf9cc036 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -100,8 +100,11 @@ extern char **environ; /* sys/ucred.h needs to be included to use struct xucred * in FreeBSD and OS X. No need for other BSDs except GNU/kFreeBSD */ +/* Solaris uses __sun and needs .h */ #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) #include +#elif defined(__sun) +#include #endif /* for solaris */ @@ -149,11 +152,14 @@ g_mk_socket_path(void) LOG(LOG_LEVEL_ERROR, "g_mk_socket_path: g_create_path(%s) failed", XRDP_SOCKET_PATH); + + LOG(LOG_LEVEL_TRACE, "g_mk_socket_path() returned 1"); return 1; } } g_chmod_hex(XRDP_SOCKET_PATH, 0x1777); } + return 0; } @@ -591,6 +597,7 @@ g_sck_vsock_socket(void) int g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid) { + LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred(%d)", sck); #if defined(SO_PEERCRED) socklen_t ucred_length; struct myucred @@ -603,6 +610,7 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid) ucred_length = sizeof(credentials); if (getsockopt(sck, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length)) { + LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 1"); return 1; } if (pid != 0) @@ -626,6 +634,8 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid) if (getsockopt(sck, SOL_LOCAL, LOCAL_PEERCRED, &xucred, &xucred_length)) { + LOG(LOG_LEVEL_ERROR, "getsockopt() failed: %s", strerror(errno)); + LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 1"); return 1; } if (pid != 0) @@ -640,8 +650,69 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid) { *gid = xucred.cr_gid; } + + LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 0"); + return 0; +#elif defined(LOCAL_PEEREID) + /* Net BSD */ + #ifndef SOL_LOCAL + #define SOL_LOCAL 0 + #endif + struct unpcbid xucred; + unsigned int xucred_length; + xucred_length = sizeof(xucred); + if (getsockopt(sck, SOL_LOCAL, LOCAL_PEEREID, &xucred, &xucred_length)) + { + LOG(LOG_LEVEL_ERROR, "getsockopt() failed: %s", strerror(errno)); + LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 1"); + return 1; + } + + if (pid != 0) + { + *pid = xucred.unp_pid; + } + if (uid != 0) + { + *uid = xucred.unp_euid; + } + if (gid != 0) + { + *gid = xucred.unp_egid; + } + + LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 0"); + return 0; +#elif defined(__sun) + /* Solaris, OpenIndiana */ + ucred_t* xucred = NULL; + + if(getpeerucred(sck, &xucred)) + { + LOG(LOG_LEVEL_ERROR, "getsockopt() failed: %s", strerror(errno)); + LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 1"); + return 1; + } + + if (pid != 0) + { + *pid = ucred_getpid(xucred); + } + if (uid != 0) + { + *uid = ucred_geteuid(xucred); + } + if (gid != 0) + { + *gid = ucred_getegid(xucred); + } + + ucred_free(xucred); + LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 0"); return 0; #else + LOG(LOG_LEVEL_ERROR, "g_sck_get_peer_cred() has no implementation."); + LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 1"); return 1; #endif } @@ -3017,6 +3088,7 @@ g_fork(void) #if defined(_WIN32) return 0; #else + LOG_DEVEL(LOG_LEVEL_TRACE, "g_fork()"); int rv; rv = fork(); @@ -3028,6 +3100,7 @@ g_fork(void) g_get_errno(), g_get_strerror()); } + LOG_DEVEL(LOG_LEVEL_TRACE, "g_fork() returned %d", rv); return rv; #endif } @@ -3040,7 +3113,10 @@ g_setgid(int pid) #if defined(_WIN32) return 0; #else - return setgid(pid); + LOG_DEVEL(LOG_LEVEL_TRACE, "g_setgid(%d)", pid); + int retval = setgid(pid); + LOG_DEVEL(LOG_LEVEL_TRACE, "--g_setgid()"); + return retval; #endif } @@ -3053,12 +3129,15 @@ g_initgroups(const char *username) #if defined(_WIN32) return 0; #else + LOG_DEVEL(LOG_LEVEL_TRACE, "g_initgroups(%s)", username); int gid; int error = g_getuser_info_by_name(username, NULL, &gid, NULL, NULL, NULL); if (error == 0) { error = initgroups(username, gid); } + + LOG_DEVEL(LOG_LEVEL_TRACE, "g_initgroups() returned %d", error); return error; #endif } @@ -3302,14 +3381,16 @@ g_setpgid(int pid, int pgid) void g_clearenv(void) { + LOG_DEVEL(LOG_LEVEL_TRACE, "g_clearenv()"); #if defined(_WIN32) #else -#if defined(BSD) +#if defined(BSD) || defined(__sun) || defined(__APPLE__) environ[0] = 0; #else environ = 0; #endif #endif + LOG_DEVEL(LOG_LEVEL_TRACE, "--g_clearenv()"); } /*****************************************************************************/ @@ -3320,7 +3401,10 @@ g_setenv(const char *name, const char *value, int rewrite) #if defined(_WIN32) return 0; #else - return setenv(name, value, rewrite); + LOG_DEVEL(LOG_LEVEL_TRACE, "g_setenv(%s, %s, %d)", name, value, rewrite); + int retval = setenv(name, value, rewrite); + LOG_DEVEL(LOG_LEVEL_TRACE, "g_setenv() returned %d", retval); + return retval; #endif } @@ -3424,7 +3508,10 @@ g_getuser_info_by_name(const char *username, int *uid, int *gid, if (gecos != 0) { - *gecos = g_strdup(pwd_1->pw_gecos); + if( pwd_1->pw_gecos == NULL ) + *gecos = g_strdup(""); + else + *gecos = g_strdup(pwd_1->pw_gecos); } } } @@ -3472,7 +3559,10 @@ g_getuser_info_by_uid(int uid, char **username, int *gid, if (gecos != 0) { - *gecos = g_strdup(pwd_1->pw_gecos); + if( pwd_1->pw_gecos == NULL ) + *gecos = g_strdup(""); + else + *gecos = g_strdup(pwd_1->pw_gecos); } return 0; @@ -3780,7 +3870,10 @@ g_shmdt(const void *shmaddr) int g_gethostname(char *name, int len) { - return gethostname(name, len); + LOG_DEVEL(LOG_LEVEL_TRACE, "g_gethostname(name, %d)", len); + int retval = gethostname(name, len); + LOG_DEVEL(LOG_LEVEL_TRACE, "g_gethostname(%s, %d) returned %d", name, len, retval); + return retval; } static unsigned char g_reverse_byte[0x100] = diff --git a/configure.ac b/configure.ac index 3e3557dbb4..3dc475cbbf 100644 --- a/configure.ac +++ b/configure.ac @@ -20,6 +20,7 @@ AC_CONFIG_SUBDIRS([libpainter librfxcodec]) # Use silent rules by default if supported by Automake m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +SDK_FLAGS= case $host_os in *linux*) linux=yes @@ -38,6 +39,10 @@ case $host_os in ;; *darwin*) macos=yes + SDK_FLAGS="--sysroot $(xcrun --show-sdk-path)" + ;; + *solaris*) + solaris=yes ;; esac @@ -46,6 +51,8 @@ AM_CONDITIONAL(FREEBSD, [test "x$freebsd" = xyes]) AM_CONDITIONAL(OPENBSD, [test "x$openbsd" = xyes]) AM_CONDITIONAL(NETBSD, [test "x$netbsd" = xyes]) AM_CONDITIONAL(MACOS, [test "x$macos" = xyes]) +AM_CONDITIONAL(SOLARIS, [test "x$solaris" = xyes]) +AC_SUBST(SDK_FLAGS) AC_CHECK_SIZEOF([int]) AC_CHECK_SIZEOF([long]) @@ -110,6 +117,10 @@ AC_ARG_ENABLE(pamuserpass, AS_HELP_STRING([--enable-pamuserpass], [Build PAM userpass support (default: no)]), [], [enable_pamuserpass=no]) AM_CONDITIONAL(SESMAN_PAMUSERPASS, [test x$enable_pamuserpass = xyes]) +AC_ARG_ENABLE(userpass, AS_HELP_STRING([--enable-userpass], + [Build userpass support (no pam) (default: no)]), + [], [enable_userpass=no]) +AM_CONDITIONAL(SESMAN_USERPASS, [test x$enable_userpass = xyes]) AC_ARG_ENABLE(pam-config, AS_HELP_STRING([--enable-pam-config=CONF], [Select PAM config to install: arch, debian, redhat, suse, freebsd, macos, unix (default: autodetect)])) @@ -188,6 +199,11 @@ AC_ARG_ENABLE(rdpsndaudin, AS_HELP_STRING([--enable-rdpsndaudin], [], [enable_rdpsndaudin=no]) AM_CONDITIONAL(XRDP_RDPSNDAUDIN, [test x$enable_rdpsndaudin = xyes]) +AC_ARG_ENABLE(openrc, AS_HELP_STRING([--enable-openrc], + [Use openrc in (default: no)]), + [], [enable_openrc=no]) +AM_CONDITIONAL(XRDP_OPENRC, [test x$enable_openrc = xyes]) + AC_ARG_WITH(imlib2, AS_HELP_STRING([--with-imlib2=ARG], [imlib2 library to use for non-BMP backgrounds (ARG=yes/no/)]),,) AC_ARG_WITH(freetype2, AS_HELP_STRING([--with-freetype2=ARG], [freetype2 library to use for rendering fonts (ARG=yes/no/)]),,) @@ -361,6 +377,13 @@ then AUTHMOD_OBJ=verify_user_pam_userpass.lo AUTHMOD_LIB="-lpam -lpam_userpass" fi +if test x$enable_userpass = xyes +then + auth_cnt=`expr $auth_cnt + 1` + auth_mech="Builtin" + AUTHMOD_OBJ=verify_user.lo + AUTHMOD_LIB=-lcrypt +fi if test $auth_cnt -gt 1 then @@ -574,6 +597,9 @@ AC_CONFIG_FILES([ instfiles/pam.d/Makefile instfiles/pulse/Makefile instfiles/rc.d/Makefile + instfiles/openrc/Makefile + instfiles/method/Makefile + instfiles/manifest/Makefile keygen/Makefile waitforx/Makefile libipm/Makefile @@ -628,6 +654,7 @@ echo " ipv6only $enable_ipv6only" echo " vsock $enable_vsock" echo " auth mechanism $auth_mech" echo " rdpsndaudin $enable_rdpsndaudin" +echo " openrc $enable_openrc" echo echo " with imlib2 $use_imlib2" echo " with freetype2 $use_freetype2" diff --git a/instfiles/Makefile.am b/instfiles/Makefile.am index a318ed8f92..959a8ff320 100644 --- a/instfiles/Makefile.am +++ b/instfiles/Makefile.am @@ -66,9 +66,15 @@ systemdsystemunit_DATA = \ xrdp-sesman.service \ xrdp.service else +if XRDP_OPENRC + SUBDIRS += \ + default \ + openrc +else SUBDIRS += \ default \ init.d +endif # XRDP_OPENRC endif # HAVE_SYSTEMD endif # LINUX @@ -79,6 +85,19 @@ SUBDIRS += \ pulse endif +if NETBSD +SUBDIRS += \ + pam.d \ + rc.d \ + pulse +endif + +if SOLARIS +SUBDIRS += \ + manifest \ + method +endif + if MACOS SUBDIRS += pam.d endif @@ -101,3 +120,13 @@ install-data-hook: sed -i '' 's|%%PREFIX%%|$(prefix)|g' $(DESTDIR)$(sysconfdir)/rc.d/xrdp \ $(DESTDIR)$(sysconfdir)/rc.d/xrdp-sesman endif + + +if NETBSD +# must be tab below +install-data-hook: + sed -i 's|%%PREFIX%%/sbin|$(prefix)/sbin|g' $(DESTDIR)$(sysconfdir)/rc.d/xrdp \ + $(DESTDIR)$(sysconfdir)/rc.d/xrdp-sesman + sed -i 's|%%PREFIX%%||g' $(DESTDIR)$(sysconfdir)/rc.d/xrdp \ + $(DESTDIR)$(sysconfdir)/rc.d/xrdp-sesman +endif diff --git a/instfiles/manifest/Makefile.am b/instfiles/manifest/Makefile.am new file mode 100644 index 0000000000..e702630df4 --- /dev/null +++ b/instfiles/manifest/Makefile.am @@ -0,0 +1,3 @@ +startscriptdir = /lib/svc/manifest/site + +dist_startscript_SCRIPTS = xrdp.xml xrdp-sesman.xml diff --git a/instfiles/manifest/xrdp-sesman.xml b/instfiles/manifest/xrdp-sesman.xml new file mode 100644 index 0000000000..6800ad34e6 --- /dev/null +++ b/instfiles/manifest/xrdp-sesman.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/instfiles/manifest/xrdp.xml b/instfiles/manifest/xrdp.xml new file mode 100644 index 0000000000..f9a6eac7d9 --- /dev/null +++ b/instfiles/manifest/xrdp.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/instfiles/method/Makefile.am b/instfiles/method/Makefile.am new file mode 100644 index 0000000000..89c9d98f7a --- /dev/null +++ b/instfiles/method/Makefile.am @@ -0,0 +1,3 @@ +startscriptdir = /lib/svc/method + +dist_startscript_SCRIPTS = xrdp xrdp-sesman diff --git a/instfiles/method/xrdp b/instfiles/method/xrdp new file mode 100755 index 0000000000..4b4d0e9cba --- /dev/null +++ b/instfiles/method/xrdp @@ -0,0 +1,85 @@ +#!/bin/bash +. /lib/svc/share/smf_include.sh + +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib +export PATH=$PATH:$ORACLE_HOME/bin + +VERBOSE= +NAME=xrdp +FULLNAME=/usr/local/sbin/$NAME +TIMEOUT=15 + +log_if_verbose() +{ + if [ -n "$VERBOSE" ]; then + echo $@ + fi +} + +waitFor() { + name=$1 + timeout=$2 + + let i=0 + + # Loop until we are certain that the process has been stopped + while [ $i -lt $timeout ]; do + pgrep -xf $name > /dev/null + if [ $? -ne 0 ]; then + break; + fi + + let i=i+1 + sleep 1 + log_if_verbose "$i seconds" + done + + pgrep -xf $name > /dev/null + return $? +} + +function start +{ + $FULLNAME +} + +function stop +{ + log_if_verbose "Sending TERM to $NAME" + pkill -TERM -xf $FULLNAME + + waitFor $FULLNAME $TIMEOUT + + if [ $? -eq 0 ]; then + log_if_verbose "Sending KILL to $NAME" + pkill -KILL -xf $FULLNAME + waitFor $FULLNAME 1 + rm -f /var/run/$NAME.pid + fi + + return $? +} + +function refresh +{ + log_if_verbose "Refresh not implemented." + return 1; +} + +case $1 in + start) start ;; + stop) stop ;; + refresh) refresh;; + + *) echo "Usage: $0 { start | stop | refresh }" >&2 + exit $SMF_EXIT_ERR_FATAL + ;; +esac + +retval=$? + +if [ $? -eq 0 ]; then + retval=$SMF_EXIT_OK +fi; + +exit $SMF_EXIT_OK diff --git a/instfiles/method/xrdp-sesman b/instfiles/method/xrdp-sesman new file mode 100755 index 0000000000..7a86e61c33 --- /dev/null +++ b/instfiles/method/xrdp-sesman @@ -0,0 +1,85 @@ +#!/bin/bash +. /lib/svc/share/smf_include.sh + +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib +export PATH=$PATH:$ORACLE_HOME/bin + +VERBOSE=true +NAME=xrdp-sesman +FULLNAME=/usr/local/sbin/$NAME +TIMEOUT=5 + +log_if_verbose() +{ + if [ -n "$VERBOSE" ]; then + echo $@ + fi +} + +waitFor() { + name=$1 + timeout=$2 + + let i=0 + + # Loop until we are certain that the process has been stopped + while [ $i -lt $timeout ]; do + pgrep -xf $name > /dev/null + if [ $? -eq 0 ]; then + break; + fi + + let i=i+1 + sleep 1 + log_if_verbose "$i seconds" + done + + pgrep -xf $name > /dev/null + return $? +} + +function start +{ + $FULLNAME +} + +function stop +{ + log_if_verbose "Sending TERM to $NAME" + pkill -TERM -xf $FULLNAME + + waitFor $FULLNAME $TIMEOUT + + if [ $? -ne 0 ]; then + log_if_verbose "Sending KILL to $NAME" + pkill -KILL -xf $FULLNAME + waitFor $FULLNAME 1 + rm -f /var/run/$NAME.pid + fi + + return $? +} + +function refresh +{ + log_if_verbose "Refresh not implemented." + return 1; +} + +case $1 in + start) start ;; + stop) stop ;; + refresh) refresh;; + + *) echo "Usage: $0 { start | stop | refresh }" >&2 + exit $SMF_EXIT_ERR_FATAL + ;; +esac + +retval=$? + +if [ $? -eq 0 ]; then + retval=$SMF_EXIT_OK +fi; + +exit $SMF_EXIT_OK diff --git a/instfiles/openrc/Makefile.am b/instfiles/openrc/Makefile.am new file mode 100644 index 0000000000..576a9a70c1 --- /dev/null +++ b/instfiles/openrc/Makefile.am @@ -0,0 +1,3 @@ +startscriptdir = $(sysconfdir)/init.d + +dist_startscript_SCRIPTS = xrdp xrdp-sesman diff --git a/instfiles/openrc/xrdp b/instfiles/openrc/xrdp new file mode 100755 index 0000000000..6e59f651b5 --- /dev/null +++ b/instfiles/openrc/xrdp @@ -0,0 +1,4 @@ +#!/sbin/openrc-run + +command="/usr/local/sbin/xrdp" +pidfile="/run/${RC_SVCNAME}.pid" diff --git a/instfiles/openrc/xrdp-sesman b/instfiles/openrc/xrdp-sesman new file mode 100755 index 0000000000..c5a8827983 --- /dev/null +++ b/instfiles/openrc/xrdp-sesman @@ -0,0 +1,4 @@ +#!/sbin/openrc-run + +command="/usr/local/sbin/xrdp-sesman" +pidfile="/run/${RC_SVCNAME}.pid" diff --git a/instfiles/pam.d/xrdp-sesman.macos b/instfiles/pam.d/xrdp-sesman.macos index 9eb7920e77..1891cc885f 100644 --- a/instfiles/pam.d/xrdp-sesman.macos +++ b/instfiles/pam.d/xrdp-sesman.macos @@ -5,7 +5,7 @@ auth optional pam_ntlm.so try_first_pass auth optional pam_mount.so try_first_pass auth required pam_opendirectory.so try_first_pass account required pam_nologin.so -account required pam_sacl.so sacl_service=ssh +account required pam_sacl.so sacl_service=xrdp-sesman account required pam_opendirectory.so password required pam_opendirectory.so session required pam_launchd.so diff --git a/sesman/Makefile.am b/sesman/Makefile.am index 542186d87d..f35b545050 100644 --- a/sesman/Makefile.am +++ b/sesman/Makefile.am @@ -10,7 +10,8 @@ AM_CPPFLAGS = \ -DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \ -I$(top_srcdir)/sesman/libsesman \ -I$(top_srcdir)/common \ - -I$(top_srcdir)/libipm + -I$(top_srcdir)/libipm \ + $(SDK_FLAGS) sbin_PROGRAMS = \ xrdp-sesman @@ -65,3 +66,10 @@ SUBDIRS = \ sesexec \ tools \ chansrv + +if SOLARIS +# must be tab below. SOLARIS Xorg does not allow logfile parameter. +install-data-hook: + sed -i 's|param=-logfile|;param=-logfile|g' $(DESTDIR)$(sysconfdir)/xrdp/sesman.ini + sed -i 's|param=.xorgxrdp.%s.log|;param=.xorgxrdp.%s.log|g' $(DESTDIR)$(sysconfdir)/xrdp/sesman.ini +endif diff --git a/sesman/libsesman/verify_user_pam.c b/sesman/libsesman/verify_user_pam.c index ca5136688d..84f1ed775c 100644 --- a/sesman/libsesman/verify_user_pam.c +++ b/sesman/libsesman/verify_user_pam.c @@ -117,6 +117,7 @@ static int verify_pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { + LOG(LOG_LEVEL_TRACE, "verify_pam_conv(%d, msg, resp, appdata_ptr)", num_msg); int i; struct pam_response *reply = NULL; struct conv_func_data *conv_func_data; @@ -194,6 +195,7 @@ verify_pam_conv(int num_msg, const struct pam_message **msg, g_free(reply); } + LOG(LOG_LEVEL_TRACE, "verify_pam_conv() returned %d", rv); return rv; } @@ -402,6 +404,7 @@ auth_start_session_private(struct auth_info *auth_info, int display_num) { int error; char display[256]; + LOG(LOG_LEVEL_TRACE, "auth_start_session_private(auth_info, %d)", display_num); g_sprintf(display, ":%d", display_num); error = pam_set_item(auth_info->ph, PAM_TTY, display); @@ -410,6 +413,7 @@ auth_start_session_private(struct auth_info *auth_info, int display_num) { LOG(LOG_LEVEL_ERROR, "pam_set_item failed: %s", pam_strerror(auth_info->ph, error)); + LOG(LOG_LEVEL_TRACE, "auth_start_session_private() returned 1"); return 1; } @@ -419,6 +423,7 @@ auth_start_session_private(struct auth_info *auth_info, int display_num) { LOG(LOG_LEVEL_ERROR, "pam_setcred failed: %s", pam_strerror(auth_info->ph, error)); + LOG(LOG_LEVEL_TRACE, "auth_start_session_private() returned 1"); return 1; } @@ -429,10 +434,12 @@ auth_start_session_private(struct auth_info *auth_info, int display_num) { LOG(LOG_LEVEL_ERROR, "pam_open_session failed: %s", pam_strerror(auth_info->ph, error)); + LOG(LOG_LEVEL_TRACE, "auth_start_session_private() returned 1"); return 1; } auth_info->session_opened = 1; + LOG(LOG_LEVEL_TRACE, "auth_start_session_private() returned 0"); return 0; } @@ -503,9 +510,10 @@ auth_end(struct auth_info *auth_info) pam_end(auth_info->ph, PAM_SUCCESS); auth_info->ph = 0; } + + g_free(auth_info); } - g_free(auth_info); return 0; } diff --git a/sesman/tools/Makefile.am b/sesman/tools/Makefile.am index a6803bb3f1..ce19b63067 100644 --- a/sesman/tools/Makefile.am +++ b/sesman/tools/Makefile.am @@ -32,6 +32,10 @@ xrdp_dis_SOURCES = \ xrdp_dis_LDADD = \ $(top_builddir)/common/libcommon.la +if SOLARIS + xrdp_dis_LDADD += -lsocket +endif + xrdp_xcon_SOURCES = \ xcon.c @@ -43,6 +47,10 @@ xrdp_sesrun_LDADD = \ $(top_builddir)/common/libcommon.la \ $(top_builddir)/libipm/libipm.la +if SOLARIS + xrdp_sesrun_LDADD += -lsocket +endif + xrdp_sesadmin_LDADD = \ $(top_builddir)/sesman/libsesman/libsesman.la \ $(top_builddir)/common/libcommon.la \ diff --git a/tools/devel/tcp_proxy/Makefile.am b/tools/devel/tcp_proxy/Makefile.am index 6c1e534336..85ab24e0c0 100644 --- a/tools/devel/tcp_proxy/Makefile.am +++ b/tools/devel/tcp_proxy/Makefile.am @@ -11,3 +11,7 @@ tcp_proxy_SOURCES = \ tcp_proxy_LDADD = \ $(top_builddir)/common/libcommon.la \ $(DLOPEN_LIBS) + +if SOLARIS + tcp_proxy_LDADD += -lsocket +endif diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 04e646a807..bd6c6c8535 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -2605,16 +2605,35 @@ xrdp_mm_connect_sm(struct xrdp_mm *self) gw_username = xrdp_mm_get_value(self, "pamusername"); gw_password = xrdp_mm_get_value(self, "pampassword"); - if (!g_strcmp(gw_username, "same")) - { - gw_username = xrdp_mm_get_value(self, "username"); - } - - if (gw_password == NULL || - !g_strcmp(gw_password, "same")) - { + if( gw_username != NULL ) + { + if (!g_strcmp(gw_username, "same")) + { + gw_username = xrdp_mm_get_value(self, "username"); + } + + if( !g_strncmp("ask", gw_username, 3)) + { + gw_username = self->wm->session->client_info->username; + } + } + + if (gw_password != NULL ) + { + if( !g_strcmp(gw_password, "same")) + { + gw_password = xrdp_mm_get_value(self, "password"); + } + + if( !g_strncmp("ask", gw_password, 3)) + { + gw_password = self->wm->session->client_info->password; + } + } + else + { gw_password = xrdp_mm_get_value(self, "password"); - } + } if (gw_username == NULL || gw_password == NULL) { From 08c049d60f01db83b4a66617087ae6353a5eb670 Mon Sep 17 00:00:00 2001 From: Michael Stone Date: Sat, 23 Sep 2023 11:07:22 -0400 Subject: [PATCH 02/10] Update flags for Solaris. --- common/Makefile.am | 3 ++- common/os_calls.c | 5 +---- configure.ac | 23 ++++++----------------- sesman/Makefile.am | 3 +-- 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/common/Makefile.am b/common/Makefile.am index c929baab19..6b8ccda90c 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -28,7 +28,8 @@ AM_CPPFLAGS = \ -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \ -DXRDP_PID_PATH=\"${localstatedir}/run\" \ -DXRDP_LOG_PATH=\"${localstatedir}/log\" \ - -DXRDP_SOCKET_PATH=\"${socketdir}\" + -DXRDP_SOCKET_PATH=\"${socketdir}\" \ + $(XOPEN_FLAGS) # -no-suppress is an automake-specific flag which is needed # to prevent us missing compiler errors in some circumstances diff --git a/common/os_calls.c b/common/os_calls.c index d6bf9cc036..94d530287c 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -32,10 +32,6 @@ #include #include #else -/* fix for solaris 10 with gcc 3.3.2 problem */ -#if defined(sun) || defined(__sun) -#define ctid_t id_t -#endif #include #include #include @@ -44,6 +40,7 @@ #if defined(XRDP_ENABLE_VSOCK) #include #endif +#include #include #include #include diff --git a/configure.ac b/configure.ac index 3dc475cbbf..ff4f1bc684 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_CONFIG_SUBDIRS([libpainter librfxcodec]) # Use silent rules by default if supported by Automake m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -SDK_FLAGS= +XOPEN_FLAGS= case $host_os in *linux*) linux=yes @@ -39,10 +39,10 @@ case $host_os in ;; *darwin*) macos=yes - SDK_FLAGS="--sysroot $(xcrun --show-sdk-path)" ;; - *solaris*) + *solaris*) solaris=yes + XOPEN_FLAGS="-D_XOPEN_SOURCE=600" ;; esac @@ -52,7 +52,7 @@ AM_CONDITIONAL(OPENBSD, [test "x$openbsd" = xyes]) AM_CONDITIONAL(NETBSD, [test "x$netbsd" = xyes]) AM_CONDITIONAL(MACOS, [test "x$macos" = xyes]) AM_CONDITIONAL(SOLARIS, [test "x$solaris" = xyes]) -AC_SUBST(SDK_FLAGS) +AC_SUBST(XOPEN_FLAGS) AC_CHECK_SIZEOF([int]) AC_CHECK_SIZEOF([long]) @@ -93,8 +93,8 @@ AC_ARG_ENABLE(tests, [Ensure dependencies for the tests are installed]), [ensure_tests_deps=yes], []) AC_ARG_ENABLE(pam, AS_HELP_STRING([--enable-pam], - [Build PAM support (default: yes)]), - [], [enable_pam=yes]) + [Build PAM support (default: no)]), + [], [enable_pam=no]) AM_CONDITIONAL(SESMAN_NOPAM, [test x$enable_pam != xyes]) AC_ARG_ENABLE(vsock, AS_HELP_STRING([--enable-vsock], [Build AF_VSOCK support (default: no)]), @@ -117,10 +117,6 @@ AC_ARG_ENABLE(pamuserpass, AS_HELP_STRING([--enable-pamuserpass], [Build PAM userpass support (default: no)]), [], [enable_pamuserpass=no]) AM_CONDITIONAL(SESMAN_PAMUSERPASS, [test x$enable_pamuserpass = xyes]) -AC_ARG_ENABLE(userpass, AS_HELP_STRING([--enable-userpass], - [Build userpass support (no pam) (default: no)]), - [], [enable_userpass=no]) -AM_CONDITIONAL(SESMAN_USERPASS, [test x$enable_userpass = xyes]) AC_ARG_ENABLE(pam-config, AS_HELP_STRING([--enable-pam-config=CONF], [Select PAM config to install: arch, debian, redhat, suse, freebsd, macos, unix (default: autodetect)])) @@ -377,13 +373,6 @@ then AUTHMOD_OBJ=verify_user_pam_userpass.lo AUTHMOD_LIB="-lpam -lpam_userpass" fi -if test x$enable_userpass = xyes -then - auth_cnt=`expr $auth_cnt + 1` - auth_mech="Builtin" - AUTHMOD_OBJ=verify_user.lo - AUTHMOD_LIB=-lcrypt -fi if test $auth_cnt -gt 1 then diff --git a/sesman/Makefile.am b/sesman/Makefile.am index f35b545050..63a4bb1908 100644 --- a/sesman/Makefile.am +++ b/sesman/Makefile.am @@ -10,8 +10,7 @@ AM_CPPFLAGS = \ -DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \ -I$(top_srcdir)/sesman/libsesman \ -I$(top_srcdir)/common \ - -I$(top_srcdir)/libipm \ - $(SDK_FLAGS) + -I$(top_srcdir)/libipm sbin_PROGRAMS = \ xrdp-sesman From 7f62ea02d677ca94b81c41540e9f055cf3559555 Mon Sep 17 00:00:00 2001 From: Michael Stone Date: Sat, 23 Sep 2023 12:31:45 -0400 Subject: [PATCH 03/10] Add -w option to waitforx to configure wait time. Fix call to usleep for NetBSD, where value must be < 1000000 --- common/os_calls.c | 11 ++++++++++- sesman/sesexec/xwait.c | 10 ++++++---- waitforx/waitforx.c | 18 ++++++++++-------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/common/os_calls.c b/common/os_calls.c index 94d530287c..9fcafb054b 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -1409,7 +1409,16 @@ g_sleep(int msecs) #if defined(_WIN32) Sleep(msecs); #else - usleep(msecs * 1000); + //On NetBSD usleep can not be > 1000000, so use sleep instead. + if( msecs >= 1000 ) + { + int remainder = msecs % 1000; + sleep(msecs / 1000); + if( remainder != 0 ) + { + usleep(remainder * 1000); + } + } #endif } diff --git a/sesman/sesexec/xwait.c b/sesman/sesexec/xwait.c index 9a7bd376f6..9732f40618 100644 --- a/sesman/sesexec/xwait.c +++ b/sesman/sesexec/xwait.c @@ -56,18 +56,20 @@ log_waitforx_messages(FILE *dp) * Contruct the command to run to check the X server */ static struct list * -make_xwait_command(int display) +make_xwait_command(int display, int wait) { const char exe[] = XRDP_LIBEXEC_PATH "/waitforx"; char displaystr[64]; + char waitstr[64]; struct list *cmd = list_create(); if (cmd != NULL) { cmd->auto_free = 1; g_snprintf(displaystr, sizeof(displaystr), ":%d", display); - - if (!list_add_strdup_multi(cmd, exe, "-d", displaystr, NULL)) + g_snprintf(waitstr, sizeof(waitstr), "%d", wait); + + if (!list_add_strdup_multi(cmd, exe, "-d", displaystr, "-w", waitstr, NULL)) { list_delete(cmd); cmd = NULL; @@ -86,7 +88,7 @@ wait_for_xserver(uid_t uid, { enum xwait_status rv = XW_STATUS_MISC_ERROR; int fd[2] = {-1, -1}; - struct list *cmd = make_xwait_command(display); + struct list *cmd = make_xwait_command(display, 10); // Construct the command to execute to check the display diff --git a/waitforx/waitforx.c b/waitforx/waitforx.c index b9dabedfe2..d7c8a35284 100644 --- a/waitforx/waitforx.c +++ b/waitforx/waitforx.c @@ -28,13 +28,12 @@ alarm_handler(int signal_num) /*****************************************************************************/ static Display * -open_display(const char *display) +open_display(const char *display, const int wait) { Display *dpy = NULL; - unsigned int wait = ATTEMPTS; unsigned int n; - for (n = 1; n <= ATTEMPTS; ++n) + for (n = 1; n <= wait; ++n) { printf("Opening display %s. Attempt %u of %u\n", display, n, wait); dpy = XOpenDisplay(display); @@ -57,12 +56,11 @@ open_display(const char *display) * @return 0 if/when outputs are available, 1 otherwise */ static int -wait_for_r_and_r(Display *dpy) +wait_for_r_and_r(Display *dpy, int wait) { int error_base = 0; int event_base = 0; unsigned int outputs = 0; - unsigned int wait = ATTEMPTS; unsigned int n; XRRScreenResources *res = NULL; @@ -115,19 +113,23 @@ main(int argc, char **argv) const char *display_name = NULL; int opt; int status = XW_STATUS_MISC_ERROR; + unsigned int wait = ATTEMPTS; Display *dpy = NULL; /* Disable stdout buffering so any messages are passed immediately * to sesman */ setvbuf(stdout, NULL, _IONBF, 0); - while ((opt = getopt(argc, argv, "d:")) != -1) + while ((opt = getopt(argc, argv, "d:w:")) != -1) { switch (opt) { case 'd': display_name = optarg; break; + case 'w': + wait = atoi(optarg); + break; default: /* '?' */ usage(argv[0], status); } @@ -140,7 +142,7 @@ main(int argc, char **argv) g_set_alarm(alarm_handler, ALARM_WAIT); - dpy = open_display(display_name); + dpy = open_display(display_name, wait); if (!dpy) { printf("Unable to open display %s\n", display_name); @@ -148,7 +150,7 @@ main(int argc, char **argv) } else { - if (wait_for_r_and_r(dpy) == 0) + if (wait_for_r_and_r(dpy, wait) == 0) { status = XW_STATUS_OK; } From e33d6268d0b3c1b1f1370bbf507bf965775213ac Mon Sep 17 00:00:00 2001 From: Michael Stone Date: Sat, 23 Sep 2023 18:55:18 -0400 Subject: [PATCH 04/10] Fix issues with SIGINT on solaris. --- common/Makefile.am | 3 +-- common/os_calls.c | 7 ++++++- configure.ac | 9 ++++++--- instfiles/manifest/xrdp-sesman.xml | 5 ----- instfiles/manifest/xrdp.xml | 4 ---- instfiles/method/xrdp-sesman | 4 +++- waitforx/waitforx.c | 6 +++++- 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/common/Makefile.am b/common/Makefile.am index 6b8ccda90c..23d1997f7b 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -28,8 +28,7 @@ AM_CPPFLAGS = \ -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \ -DXRDP_PID_PATH=\"${localstatedir}/run\" \ -DXRDP_LOG_PATH=\"${localstatedir}/log\" \ - -DXRDP_SOCKET_PATH=\"${socketdir}\" \ - $(XOPEN_FLAGS) + -DXRDP_SOCKET_PATH=\"${socketdir}\" # -no-suppress is an automake-specific flag which is needed # to prevent us missing compiler errors in some circumstances diff --git a/common/os_calls.c b/common/os_calls.c index 9fcafb054b..06e643f4bd 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -3004,6 +3004,7 @@ g_set_alarm(void (*func)(int), unsigned int secs) /* Cancel any previous alarm to prevent a race */ unsigned int rv = alarm(0); signal(SIGALRM, func); + signal(SIGINT, func); (void)alarm(secs); return rv; #endif @@ -3356,7 +3357,11 @@ g_waitpid_status(int pid) } else { - LOG(LOG_LEVEL_WARNING, "wait for pid %d returned unknown result", pid); + LOG(LOG_LEVEL_WARNING, "wait for pid %d returned unknown result %s", pid, g_get_strerror()); + if( errno == EINTR ) + { + return g_waitpid_status(pid); + } } } diff --git a/configure.ac b/configure.ac index ff4f1bc684..a2a445a3a1 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,6 @@ AC_CONFIG_SUBDIRS([libpainter librfxcodec]) # Use silent rules by default if supported by Automake m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -XOPEN_FLAGS= case $host_os in *linux*) linux=yes @@ -42,7 +41,6 @@ case $host_os in ;; *solaris*) solaris=yes - XOPEN_FLAGS="-D_XOPEN_SOURCE=600" ;; esac @@ -52,7 +50,6 @@ AM_CONDITIONAL(OPENBSD, [test "x$openbsd" = xyes]) AM_CONDITIONAL(NETBSD, [test "x$netbsd" = xyes]) AM_CONDITIONAL(MACOS, [test "x$macos" = xyes]) AM_CONDITIONAL(SOLARIS, [test "x$solaris" = xyes]) -AC_SUBST(XOPEN_FLAGS) AC_CHECK_SIZEOF([int]) AC_CHECK_SIZEOF([long]) @@ -298,6 +295,11 @@ if test x$use_imlib2 = xyes; then AC_DEFINE([USE_IMLIB2],1, [Compile with imlib2 support]) fi +if test x$solaris = xyes; then + CFLAGS="${CFLAGS} -D_XOPEN_SOURCE=600" + AC_SUBST(CFLAGS) +fi + # Find freetype2 # # The modversion used by pkgcheck does not correspond to the @@ -668,6 +670,7 @@ echo " unit tests performable $perform_unit_tests" echo "" echo " CFLAGS = $CFLAGS" echo " LDFLAGS = $LDFLAGS" +echo " CPPFLAGS = $CPPFLAGS" # xrdp_configure_options.h will be written to the build directory, not the source directory echo '#define XRDP_CONFIGURE_OPTIONS \' > ./xrdp_configure_options.h diff --git a/instfiles/manifest/xrdp-sesman.xml b/instfiles/manifest/xrdp-sesman.xml index 6800ad34e6..b8f0ae6ad5 100644 --- a/instfiles/manifest/xrdp-sesman.xml +++ b/instfiles/manifest/xrdp-sesman.xml @@ -40,11 +40,6 @@ exec="/lib/svc/method/xrdp-sesman stop" timeout_seconds="120" /> - -