[PATCH 1/3] dix: Add facilities for client ID tracking.
Mark Kettenis
mark.kettenis at xs4all.nl
Mon Aug 30 11:44:57 PDT 2010
> From: =?utf-8?q?Rami=20Ylim=C3=A4ki?= <rami.ylimaki at vincit.fi>
> Date: Mon, 30 Aug 2010 16:29:31 +0300
>
> An interface is provided for figuring out the PID and process name of
> a client. Make some existing functionality from SELinux and IA
> extensions available for general use.
The problem is that the guts that implement this are rather
Linux-specific. For example:
> +/* Try to determine a command line string for a client based on its
> + * PID. This should be called only once when a new client has
> + * connected, use GetClientCmd to determine the string at other
> + * times. Error (NULL) is returned if command line string can't be
> + * determined for the client. You must release the returned string by
> + * calling free when it's not used anymore. */
> +static const char *DetermineClientCmd(ClientPtr client, pid_t pid)
> +{
> + char path[PATH_MAX + 1];
> + char *cmd = NULL;
> + int fd = 0;
> + int bytes = 0;
> +
> + if (client == NullClient)
> + return NULL;
> +
> + if (snprintf(path, sizeof(path), "/proc/%d/cmdline", pid) < 0)
> + return NULL;
> +
> + fd = open(path, O_RDONLY);
> + if (fd < 0)
> + return NULL;
> + bytes = read(fd, path, sizeof(path));
> + if (bytes <= 0)
> + return NULL;
> + if (close(fd) < 0)
> + return NULL;
> +
> + /* We are only interested in the process name. We don't care about
> + * its arguments. Allocate space only for the process name. */
> + path[bytes - 1] = '\0';
> + bytes = strlen(path) + 1;
> + cmd = malloc(bytes);
> + if (cmd == NULL)
> + return NULL;
> + strncpy(cmd, path, bytes);
> + cmd[bytes - 1] = '\0';
> +
> + return cmd;
> +}
This relies on the OS having a /proc filesystem. Not all OSes
implement such a thing, some don't have it enabled by default
(OpenBSD, where it's only used for Linux emulation) or have a very
different layout (Solaris). OS-specific code should be cleary marked
as such and probably be moved to ../os
> +/* Try to determine a PID for a client from its connection
> + * information. This should be called only once when new client has
> + * connected, use GetClientPid to determine the PID at other
> + * times. Error (0) is returned if PID can't be determined for the
> + * client. */
Returning 0 in the error case is probably a bad idea, since I do
believe that on some systems, 0 is a valid process ID. A better
choice would be (pid_t)-1, which is used for this purpose by setsid().
> +static pid_t DetermineClientPid(ClientPtr client)
> +{
> + LocalClientCredRec *lcc = NULL;
> + pid_t pid = 0;
> +
> + if (client == NullClient)
> + return 0;
> +
> + if (client == serverClient)
> + return getpid();
> +
> + if (GetLocalClientCreds(client, &lcc) != -1)
> + {
> + if (lcc->fieldsSet & LCC_PID_SET)
> + pid = lcc->pid;
> + FreeLocalClientCreds(lcc);
> + }
> +
> + return pid;
> +}
> +
More information about the xorg-devel
mailing list