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.)
master
Ben Cohen 8 years ago committed by Idan Freiberg
parent 9f80fcd74e
commit 3b5b7a5935

@ -142,6 +142,24 @@ trans_delete(struct trans *self)
g_free(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 int
trans_get_wait_objs(struct trans *self, tbus *objs, int *count) trans_get_wait_objs(struct trans *self, tbus *objs, int *count)

@ -93,6 +93,8 @@ struct trans*
trans_create(int mode, int in_size, int out_size); trans_create(int mode, int in_size, int out_size);
void void
trans_delete(struct trans* self); trans_delete(struct trans* self);
void
trans_delete_from_child(struct trans* self);
int int
trans_get_wait_objs(struct trans* self, tbus* objs, int* count); trans_get_wait_objs(struct trans* self, tbus* objs, int* count);
int int

@ -288,7 +288,7 @@ xrdp_listen_fork(struct xrdp_listen *self, struct trans *server_trans)
g_close_wait_obj(self->pro_done_event); g_close_wait_obj(self->pro_done_event);
xrdp_listen_create_pro_done(self); xrdp_listen_create_pro_done(self);
/* delete listener, child need not listen */ /* delete listener, child need not listen */
trans_delete(self->listen_trans); trans_delete_from_child(self->listen_trans);
self->listen_trans = 0; self->listen_trans = 0;
/* new connect instance */ /* new connect instance */
process = xrdp_process_create(self, 0); process = xrdp_process_create(self, 0);

Loading…
Cancel
Save