From 3b5b7a59351757e3983d54faf754328b44d55990 Mon Sep 17 00:00:00 2001 From: Ben Cohen Date: Thu, 22 Jun 2017 19:38:37 +0100 Subject: [PATCH] UDS file deleted after first connection If you run xrdp with a Unix Domain Socket (UDS) for the port specified in /etc/xrdp/xrdp.ini then the first connection succeeds but subsequent connections fail. In fact the UDS is deleted from the filesystem as soon as the first connection is established. Test case: 1. Edit /etc/xrdp/xrdp.ini to set "port=/var/run/xrdp-local.socket". 2. Restart xrdp. 3. Run the following. When rdesktop starts up and the logon dialog is displayed, press "Cancel". sudo socat TCP-LISTEN:12345 UNIX-CONNECT:/var/run/xrdp-local.socket & rdesktop localhost:12345 4. Run the following: sudo socat TCP-LISTEN:12346 UNIX-CONNECT:/var/run/xrdp-local.socket & rdesktop localhost:12346 Expected behaviour: rdesktop starts up and displays the logon dialog. Observed behaviour: rdesktop exits with "ERROR: Connection closed" and socat exits with "No such file or directory. This is because in the child process after forking, xrdp_listen_fork() calls trans_delete() which deletes the UDS. Simply commenting out the g_file_delete() and g_free() fixes this, but that isn't a proper solution because trans_delete() is called from elsewhere where the UDS might no longer be wanted. Fix by adding a function trans_delete_from_child() that frees and clears listen_filename before calling trans_delete(), and call the new function from xrdp_listen_fork(). (Workaround: set "fork=false" in /etc/xrdp/xrdp.ini, because trans_delete() is then not called.) --- common/trans.c | 18 ++++++++++++++++++ common/trans.h | 2 ++ xrdp/xrdp_listen.c | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/common/trans.c b/common/trans.c index 9448760c..5909e4eb 100644 --- a/common/trans.c +++ b/common/trans.c @@ -142,6 +142,24 @@ trans_delete(struct trans *self) g_free(self); } +/*****************************************************************************/ +void +trans_delete_from_child(struct trans *self) +{ + if (self == 0) + { + return; + } + + if (self->listen_filename != 0) + { + g_free(self->listen_filename); + self->listen_filename = 0; + } + + trans_delete(self); +} + /*****************************************************************************/ int trans_get_wait_objs(struct trans *self, tbus *objs, int *count) diff --git a/common/trans.h b/common/trans.h index 57a0fd6a..30559347 100644 --- a/common/trans.h +++ b/common/trans.h @@ -93,6 +93,8 @@ struct trans* trans_create(int mode, int in_size, int out_size); void trans_delete(struct trans* self); +void +trans_delete_from_child(struct trans* self); int trans_get_wait_objs(struct trans* self, tbus* objs, int* count); int diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index a04768b1..192b0786 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -288,7 +288,7 @@ xrdp_listen_fork(struct xrdp_listen *self, struct trans *server_trans) g_close_wait_obj(self->pro_done_event); xrdp_listen_create_pro_done(self); /* delete listener, child need not listen */ - trans_delete(self->listen_trans); + trans_delete_from_child(self->listen_trans); self->listen_trans = 0; /* new connect instance */ process = xrdp_process_create(self, 0);