A short time ago, there was some talk about various wrappers around the X server, and I pointed out that Debian already has one better than the example posted. Since then, I have received requests to post Debian's wrapper source. This comes from Debian's xfree86 source package. I do not know who the original author was (I did not write this code), but a good guess would be Mark W. Eichin <eichinat_private>, Debian's X maintainer. I will include the code at the bottom of the message. First let me include a sample of the config file that it looks for: /etc/X11/Xserver: -- cut -- /usr/X11R6/bin/XF86_S3V Console The first line in this file is the full pathname of the default X server. The second line shows who is allowed to run the X server: RootOnly Console (anyone whose controlling tty is on the console) Anybody -- cut -- OK, here is the source to the wrapper itself. Just compile with gcc -O2 or some such. xserver-wrapper.c: -- cut -- /* X.c - a simple wrapper for X servers that decides whether to let them be * run. * * This program may be distributed under the terms of the GNU public license */ #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/stat.h> #define VT_MAJOR_DEV 4 #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif typedef enum { RootOnly, Console, Anybody } SecurityLevel; static SecurityLevel getSecLevel(char *security) { char *c; for (c=security; *c; c++) *c=toupper(*c); if (strncmp(security,"ROOTONLY",8)==0) return RootOnly; if (strncmp(security,"CONSOLE",7)==0) return Console; if (strncmp(security,"ANYBODY",7)==0) return Anybody; return RootOnly; } static int checkSecLevel(SecurityLevel level) { struct stat s; switch (level) { case RootOnly: return FALSE; break; case Console: if (fstat(0,&s)!=0) { fprintf(stderr,"X: cannot stat stdin\n"); return FALSE; } if (S_ISCHR(s.st_mode) && ((s.st_rdev>>8)&0xff)==VT_MAJOR_DEV && (s.st_rdev&0xff)<128) { return TRUE; } break; case Anybody: return TRUE; } return FALSE; } int main(int argc, char **argv) { FILE *cf; char xserver[1024]; char security[80]; char *c; if (!(cf=fopen("/etc/X11/Xserver","r"))) { fprintf(stderr,"X: cannot find configuration file /etc/X11/Xserver\n" "\nIf you want to run X clients locally you must install an\n" "X server package (eg. xsvga, xs3, xp9000, etc.)\n" "Installation of one of these packages should modify the\n" "configuration file appropriately.\n"); exit(1); } if (!fgets(xserver,1024,cf)) { fprintf(stderr,"X: cannot read name of X server from /etc/X11/Xserver\n"); exit(1); } /* Strip trailing newline from server name */ for (c=xserver; *c!=0; c++) if (*c=='\n') *c=0; if (!fgets(security,80,cf)) { fprintf(stderr,"X: cannot read security setting from /etc/X11/Xserver\n"); exit(1); } if (getuid()==0 || checkSecLevel(getSecLevel(security))) { /* Run the X server */ int i; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-config")) { if (setuid(getuid())) { perror("X couldn't drop setuid privileges for alternate config"); exit(1); } break; } } execv(xserver,argv); fprintf(stderr,"X: exec of %s failed\n",xserver); exit(1); } else { if (argc == 2 && !strcmp(argv[1], "-showconfig")) { if (setuid(getuid())) { perror("X couldn't drop setuid privileges"); exit(1); } execv(xserver,argv); fprintf(stderr,"X: unprivileged exec of %s failed\n",xserver); exit(1); } else { fprintf(stderr,"X: you are not authorised to run the X server\n"); exit(1); } } exit(1); /* We should never reach this */ } -- cut -- -- John Goerzen Southwind Internet Access, Inc, Business e-mail: jgoerzenat_private Personal e-mail: jgoerzenat_private Wichita State University e-mail: jgoerzenat_private Developer, Debian GNU/Linux <http://www.debian.org>
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:40:53 PDT