Skip to content

Commit

Permalink
Support for NetBSD and OpenIndiana.
Browse files Browse the repository at this point in the history
Log an info message instead of error if waitpid returns ECHILD.

Need to re-register for SIGCHLD on Solaris.

Retry on EINTR.

Retry SIGINT in waitpid.

Fix issues with SIGINT on solaris.

Add -w option to waitforx to configure wait time. Fix call to usleep for NetBSD, where value must be < 1000000

Update flags for Solaris.

Support Additional OS.

Update xrdp to support netbsd, openindiana.

Support Additional OS.

Update xrdp to support netbsd.
  • Loading branch information
mstone2001 committed Oct 10, 2023
1 parent 89ceaf0 commit 08a5dc5
Show file tree
Hide file tree
Showing 18 changed files with 514 additions and 38 deletions.
2 changes: 1 addition & 1 deletion common/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ 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}\"

# -no-suppress is an automake-specific flag which is needed
# to prevent us missing compiler errors in some circumstances
Expand Down
158 changes: 139 additions & 19 deletions common/os_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@
#include <windows.h>
#include <winsock.h>
#else
/* fix for solaris 10 with gcc 3.3.2 problem */
#if defined(sun) || defined(__sun)
#define ctid_t id_t
#endif
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
Expand All @@ -55,6 +51,7 @@ struct sockaddr_hvs
};
#endif
#endif
#include <limits.h>
#include <poll.h>
#include <sys/un.h>
#include <sys/time.h>
Expand Down Expand Up @@ -111,8 +108,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 <sys/ucred.h>
#elif defined(__sun)
#include <ucred.h>
#endif

/* for solaris */
Expand Down Expand Up @@ -164,11 +164,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;
}

Expand Down Expand Up @@ -616,6 +619,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
Expand All @@ -628,6 +632,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)
Expand All @@ -651,6 +656,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)
Expand All @@ -665,8 +672,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
}
Expand Down Expand Up @@ -1403,8 +1471,25 @@ g_sleep(int msecs)
{
#if defined(_WIN32)
Sleep(msecs);
//On NetBSD usleep can not be > 1000000, so use sleep instead.
#elif defined(__NetBSD__)
if( msecs >= 1000 )
{
int secs = msecs / 1000;
int remainder = msecs % 1000;

if( secs != 0 )
{
sleep(msecs / 1000);
}

if( remainder != 0 )
{
usleep(remainder * 1000);
}
}
#else
usleep(msecs * 1000);
usleep(msecs * 1000);
#endif
}

Expand Down Expand Up @@ -2990,6 +3075,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
Expand All @@ -3001,6 +3087,7 @@ void
g_signal_child_stop(void (*func)(int))
{
#if defined(_WIN32)
return;
#else
signal(SIGCHLD, func);
#endif
Expand Down Expand Up @@ -3080,6 +3167,7 @@ g_fork(void)
#if defined(_WIN32)
return 0;
#else
LOG_DEVEL(LOG_LEVEL_TRACE, "g_fork()");
int rv;

rv = fork();
Expand All @@ -3091,6 +3179,7 @@ g_fork(void)
g_get_errno(), g_get_strerror());
}

LOG_DEVEL(LOG_LEVEL_TRACE, "g_fork() returned %d", rv);
return rv;
#endif
}
Expand All @@ -3103,7 +3192,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
}

Expand All @@ -3116,12 +3208,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
}
Expand Down Expand Up @@ -3247,7 +3342,7 @@ g_waitchild(struct exit_status *e)
e->reason = E_XR_UNEXPECTED;
e->val = 0;

rv = waitpid(-1, &wstat, WNOHANG);
rv = g_waitpid(-1, &wstat, WNOHANG);

if (rv == -1)
{
Expand Down Expand Up @@ -3279,20 +3374,31 @@ g_waitchild(struct exit_status *e)
Note that signal handlers are established with BSD-style semantics,
so this call is NOT interrupted by a signal */
int
g_waitpid(int pid)
g_waitpid(int pid, int *stat_loc, int options)
{
#if defined(_WIN32)
return 0;
#else
int rv = 0;

if (pid < 0)
again:
rv = waitpid(pid, stat_loc, options);
//retry EINTR.
if( rv == -1 && errno == EINTR )
{
rv = -1;
goto again;
}
else

if( rv == -1 )
{
rv = waitpid(pid, 0, 0);
if( errno == ECHILD )
{
LOG(LOG_LEVEL_INFO, "waitpid returned %s", g_get_strerror());
}
else
{
LOG(LOG_LEVEL_ERROR, "waitpid returned %s", g_get_strerror());
}
}

return rv;
Expand All @@ -3317,7 +3423,7 @@ g_waitpid_status(int pid)
int status;

LOG(LOG_LEVEL_DEBUG, "waiting for pid %d to exit", pid);
rv = waitpid(pid, &status, 0);
rv = g_waitpid(pid, &status, 0);

if (rv != -1)
{
Expand All @@ -3334,7 +3440,7 @@ 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());
}
}

Expand Down Expand Up @@ -3365,14 +3471,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()");
}

/*****************************************************************************/
Expand All @@ -3383,7 +3491,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
}

Expand Down Expand Up @@ -3487,7 +3598,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);
}
}
}
Expand Down Expand Up @@ -3535,7 +3649,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;
Expand Down Expand Up @@ -3843,7 +3960,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] =
Expand Down
2 changes: 1 addition & 1 deletion common/os_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ int g_setlogin(const char *name);
int g_set_allusercontext(int uid);
#endif
int g_waitchild(struct exit_status *e);
int g_waitpid(int pid);
int g_waitpid(int pid, int *stat_loc, int options);
struct exit_status g_waitpid_status(int pid);
/*
* Sets the process group ID of the indicated process to the specified value.
Expand Down
Loading

0 comments on commit 08a5dc5

Please sign in to comment.