--- xc/programs/xfs/difs/fonts.c.xfsredhat Sun Aug 22 15:29:55 1999 +++ xc/programs/xfs/difs/fonts.c Tue Mar 14 12:10:39 2000 @@ -108,6 +108,113 @@ } /* + * xf86GetPathElem -- + * Extract a single element from the font path string starting at + * pnt. The font path element will be returned, and pnt will be + * updated to point to the start of the next element, or set to + * NULL if there are no more. + */ +char * +xf86GetPathElem(pnt) + char **pnt; +{ + char *p1; + + p1 = *pnt; + *pnt = index(*pnt, ','); + if (*pnt != NULL) { + **pnt = '\0'; + *pnt += 1; + } + return(p1); +} + +/* + * xf86ValidateFontPath -- + * Validates the user-specified font path. Each element that + * begins with a '/' is checked to make sure the directory exists. + * If the directory exists, the existence of a file named 'fonts.dir' + * is checked. If either check fails, an error is printed and the + * element is removed from the font path. + */ +#define DIR_FILE "/fonts.dir" +#define CHECK_TYPE(mode, type) ((S_IFMT & (mode)) == (type)) +static char * +xf86ValidateFontPath(path) + char *path; +{ + char *tmp_path, *out_pnt, *path_elem, *next, *p1, *dir_elem; + struct stat stat_buf; + int flag; + int dirlen; + + tmp_path = (char *)calloc(1,strlen(path)+1); + out_pnt = tmp_path; + path_elem = NULL; + next = path; + while (next != NULL) { + path_elem = xf86GetPathElem(&next); +#ifndef __EMX__ + if (*path_elem == '/') { + dir_elem = (char *)calloc(1, strlen(path_elem) + 1); + if ((p1 = strchr(path_elem, ':')) != 0) +#else + /* OS/2 must prepend X11ROOT */ + if (*path_elem == '/') { + path_elem = (char*)__XOS2RedirRoot(path_elem); + dir_elem = (char*)calloc(1, strlen(path_elem) + 1); + if (p1 = strchr(path_elem+2, ':')) +#endif + dirlen = p1 - path_elem; + else + dirlen = strlen(path_elem); + strncpy(dir_elem, path_elem, dirlen); + dir_elem[dirlen] = '\0'; + flag = stat(dir_elem, &stat_buf); + if (flag == 0) + if (!CHECK_TYPE(stat_buf.st_mode, S_IFDIR)) + flag = -1; + if (flag != 0) { + printf("warning!\n"); + ErrorF("Warning: The directory \"%s\" does not exist.\n", dir_elem); + ErrorF(" Entry deleted from font path.\n"); + continue; + } + else { + p1 = (char *)malloc(strlen(dir_elem)+strlen(DIR_FILE)+1); + strcpy(p1, dir_elem); + strcat(p1, DIR_FILE); + flag = stat(p1, &stat_buf); + if (flag == 0) + if (!CHECK_TYPE(stat_buf.st_mode, S_IFREG)) + flag = -1; +#ifndef __EMX__ + free(p1); +#endif + if (flag != 0) { + ErrorF("Warning: 'fonts.dir' not found (or not valid) in \"%s\".\n", + dir_elem); + ErrorF(" Entry deleted from font path.\n"); + ErrorF(" (Run 'mkfontdir' on \"%s\").\n", dir_elem); + continue; + } + } + free(dir_elem); + } + + /* + * Either an OK directory, or a font server name. So add it to + * the path. + */ + if (out_pnt != tmp_path) + *out_pnt++ = ','; + strcat(out_pnt, path_elem); + out_pnt += strlen(path_elem); + } + return(tmp_path); +} + +/* * note that the font wakeup queue is not refcounted. this is because * an fpe needs to be added when it's inited, and removed when it's finally * freed, in order to handle any data that isn't requested, like FS events. @@ -734,8 +841,12 @@ *end, *p; int err; + char *fixedpath; + + fixedpath = xf86ValidateFontPath(str); - len = strlen(str) + 1; + len = strlen(fixedpath) + 1; + str = fixedpath; paths = p = (char *) ALLOCATE_LOCAL(len); npaths = 0; @@ -755,6 +866,7 @@ err = set_font_path_elements(npaths, paths, badpath); + free(fixedpath); DEALLOCATE_LOCAL(paths); return err; --- xc/programs/xfs/difs/main.c.xfsredhat Sun Mar 7 15:50:25 1999 +++ xc/programs/xfs/difs/main.c Tue Mar 14 12:10:39 2000 @@ -56,12 +56,18 @@ #include "dispatch.h" #include "extentst.h" #include "difs.h" +#include +#include +#include char *ConnectionInfo; int ConnInfoLen; Cache serverCache; +int droppriv; /* whether or not to drop root privileges at startup */ +int becomeDaemon; /* whether or not to become a daemon */ + #ifndef DEFAULT_CONFIG_FILE #define DEFAULT_CONFIG_FILE "/usr/lib/X11/fs/config" #endif @@ -80,15 +86,43 @@ main(int argc, char *argv[]) { int i; + struct passwd *pwent; argcGlobal = argc; argvGlobal = argv; + droppriv = 0; + becomeDaemon = 0; configfilename = DEFAULT_CONFIG_FILE; /* init stuff */ ProcessCmdLine(argc, argv); InitErrors(); + + /* become xfs user, if possible */ + if ((geteuid() == 0) && droppriv) { + pwent = getpwnam("xfs"); + if (pwent) { + if (setgid(pwent->pw_gid)) { + ErrorF("fatal: couldn't set groupid to xfs user's group\n"); + exit(1); + } + + if (setgroups(0, 0)) { + ErrorF("fatal: couldn't drop supplementary groups\n"); + exit(1); + } + + if (setuid(pwent->pw_uid)) { + ErrorF("fatal: couldn't set userid to xfs user\n"); + exit(1); + } + } + } else if (droppriv) { + ErrorF("fatal: droppriv flag specified, but xfs not run as root\n"); + exit(1); + } + /* * do this first thing, to get any options that only take effect at * startup time. it is erad again each time the server resets @@ -97,6 +131,10 @@ ErrorF("fatal: couldn't read config file\n"); exit(1); } + + /* become a daemon if explicitly requested to do so. */ + if (becomeDaemon) + daemon(0, 0); while (1) { serverGeneration++; --- xc/programs/xfs/os/utils.c.xfsredhat Sun Mar 7 15:50:30 1999 +++ xc/programs/xfs/os/utils.c Tue Mar 14 12:10:39 2000 @@ -91,6 +91,8 @@ #endif extern char *configfilename; +extern int droppriv; /* whether or not to drop root privileges */ +extern int becomeDaemon; /* whether to become a daemon or not */ char *progname; Bool CloneSelf; @@ -189,7 +191,7 @@ static void usage(void) { - fprintf(stderr, "usage: %s [-config config_file] [-port tcp_port]\n", + fprintf(stderr, "usage: %s [-config config_file] [-port tcp_port] [-droppriv] [-daemon]\n", progname); exit(1); } @@ -293,6 +295,10 @@ ProcessLSoption (argv[++i]); else usage(); + } else if (!strcmp(argv[i], "-droppriv")) { + droppriv = 1; + } else if (!strcmp(argv[i], "-daemon")) { + becomeDaemon = 1; } else if (!strcmp(argv[i], "-cf") || !strcmp(argv[i], "-config")) { if (argv[i + 1]) configfilename = argv[++i]; --- xc/programs/xfs/os/Imakefile.xfsredhat Sun Feb 13 08:54:42 2000 +++ xc/programs/xfs/os/Imakefile Tue Mar 14 12:10:39 2000 @@ -23,7 +23,7 @@ SOCK_DEFINES = -DBSD44SOCKETS #endif -/* ERROR_DEFINES = -DUSE_SYSLOG */ +ERROR_DEFINES = -DUSE_SYSLOG OS_DEFINES = ServerOSDefines --- xc/programs/xfs/os/error.c.xfsredhat Sun Oct 25 14:59:57 1998 +++ xc/programs/xfs/os/error.c Tue Mar 14 13:29:26 2000 @@ -76,6 +76,7 @@ Bool UseSyslog; char ErrorFile[PATH_MAX]; +int log_open = 0; static void abort_server(void) @@ -142,17 +143,21 @@ #ifdef USE_SYSLOG if (UseSyslog) { - syslog(LOG_NOTICE, f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); + va_list args; + va_start(args, f); + syslog(LOG_NOTICE, f, args); + va_end(args); return; } #endif - + { /* XXX should Notices just be ignored if not using syslog? */ va_list args; va_start(args, f); fprintf(stderr, "%s notice: ", progname); vfprintf(stderr, f, args); va_end(args); + } } /* @@ -164,15 +169,20 @@ { #ifdef USE_SYSLOG if (UseSyslog) { - syslog(LOG_ERR, f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); + va_list args; + va_start(args, f); + syslog(LOG_ERR, f, args); + va_end(args); return; } #endif + { va_list args; va_start(args, f); fprintf(stderr, "%s error: ", progname); vfprintf(stderr, f, args); va_end(args); + } } /* VARARGS1 */