Home | History | Annotate | Line # | Download | only in xdm
      1 /*
      2 
      3 Copyright 1988, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included
     12 in all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 OTHER DEALINGS IN THE SOFTWARE.
     21 
     22 Except as contained in this notice, the name of The Open Group shall
     23 not be used in advertising or otherwise to promote the sale, use or
     24 other dealings in this Software without prior written authorization
     25 from The Open Group.
     26 
     27 */
     28 
     29 /*
     30  * xdm - display manager daemon
     31  * Author:  Keith Packard, MIT X Consortium
     32  *
     33  * resource.c
     34  */
     35 
     36 #include "dm.h"
     37 #include "dm_error.h"
     38 
     39 #include <X11/Intrinsic.h>
     40 #include <X11/Xmu/CharSet.h>
     41 
     42 char	*config;
     43 
     44 char	*servers;
     45 int	request_port;
     46 int	debugLevel;
     47 char	*errorLogFile;
     48 int	daemonMode;
     49 char	*pidFile;
     50 int	lockPidFile;
     51 int	sourceAddress;
     52 char	*authDir;
     53 int	autoRescan;
     54 int	removeDomainname;
     55 char	*keyFile;
     56 char	*accessFile;
     57 char	**exportList;
     58 #if !defined(HAVE_ARC4RANDOM)
     59 char	*randomFile;
     60 #endif
     61 #ifdef DEV_RANDOM
     62 char	*randomDevice;
     63 #endif
     64 #if !defined(HAVE_ARC4RANDOM)
     65 char	*prngdSocket;
     66 int	prngdPort;
     67 #endif
     68 
     69 char	*greeterLib;
     70 char	*willing;
     71 int	choiceTimeout;	/* chooser choice timeout */
     72 
     73 #define DM_STRING	0
     74 #define DM_INT		1
     75 #define DM_BOOL	2
     76 #define DM_ARGV	3
     77 
     78 /*
     79  * The following constants are supposed to be set in Makefile or config.h
     80  * from parameters set in configure.  DO NOT CHANGE THESE DEFINITIONS!
     81  */
     82 #ifndef DEF_SERVER_LINE
     83 # define DEF_SERVER_LINE ":0 local /usr/bin/X11/X :0"
     84 #endif
     85 #ifndef XRDB_PROGRAM
     86 # define XRDB_PROGRAM "/usr/bin/X11/xrdb"
     87 #endif
     88 #ifndef DEF_SESSION
     89 # define DEF_SESSION "/usr/bin/X11/xterm -ls"
     90 #endif
     91 #ifndef DEF_USER_PATH
     92 # define DEF_USER_PATH ":/bin:/usr/bin:/usr/bin/X11:/usr/ucb"
     93 #endif
     94 #ifndef DEF_SYSTEM_PATH
     95 # define DEF_SYSTEM_PATH "/etc:/bin:/usr/bin:/usr/bin/X11:/usr/ucb"
     96 #endif
     97 #ifndef DEF_SYSTEM_SHELL
     98 # define DEF_SYSTEM_SHELL "/bin/sh"
     99 #endif
    100 #ifndef DEF_FAILSAFE_CLIENT
    101 # define DEF_FAILSAFE_CLIENT "/usr/bin/X11/xterm"
    102 #endif
    103 #ifndef DEF_XDM_CONFIG
    104 # define DEF_XDM_CONFIG "/usr/lib/X11/xdm/xdm-config"
    105 #endif
    106 #ifndef DEF_CHOOSER
    107 # define DEF_CHOOSER "/usr/lib/X11/xdm/chooser"
    108 #endif
    109 #ifndef DEF_AUTH_NAME
    110 # ifdef HASXDMAUTH
    111 #  define DEF_AUTH_NAME	"XDM-AUTHORIZATION-1 MIT-MAGIC-COOKIE-1"
    112 # else
    113 #  define DEF_AUTH_NAME	"MIT-MAGIC-COOKIE-1"
    114 # endif
    115 #endif
    116 #ifndef DEF_AUTH_DIR
    117 # define DEF_AUTH_DIR "/usr/lib/X11/xdm"
    118 #endif
    119 #ifndef DEF_USER_AUTH_DIR
    120 # define DEF_USER_AUTH_DIR	"/tmp"
    121 #endif
    122 #ifndef DEF_KEY_FILE
    123 # define DEF_KEY_FILE	""
    124 #endif
    125 #ifndef DEF_ACCESS_FILE
    126 # define DEF_ACCESS_FILE	""
    127 #endif
    128 #ifndef DEF_RANDOM_FILE
    129 # define DEF_RANDOM_FILE "/dev/mem"
    130 #endif
    131 #ifndef DEF_PRNGD_SOCKET
    132 # define DEF_PRNGD_SOCKET "/tmp/entropy"
    133 #endif
    134 #ifndef DEF_PRNGD_PORT
    135 # define DEF_PRNGD_PORT "0"
    136 #endif
    137 #ifndef DEF_GREETER_LIB
    138 # define DEF_GREETER_LIB "/usr/lib/X11/xdm/libXdmGreet.so"
    139 #endif
    140 
    141 #define DEF_UDP_PORT	"177"	    /* registered XDMCP port, don't change */
    142 
    143 struct dmResources {
    144 	const char	*name, *class;
    145 	int		type;
    146 	char		**dm_value;
    147 	const char	*default_value;
    148 } DmResources[] = {
    149 { "servers",	"Servers", 	DM_STRING,	&servers,
    150 				DEF_SERVER_LINE} ,
    151 { "requestPort","RequestPort",	DM_INT,		(char **) &request_port,
    152 				DEF_UDP_PORT} ,
    153 { "debugLevel",	"DebugLevel",	DM_INT,		(char **) &debugLevel,
    154 				"0"} ,
    155 { "errorLogFile","ErrorLogFile",	DM_STRING,	&errorLogFile,
    156 				""} ,
    157 { "daemonMode",	"DaemonMode",	DM_BOOL,	(char **) &daemonMode,
    158 				"true"} ,
    159 { "pidFile",	"PidFile",	DM_STRING,	&pidFile,
    160 				""} ,
    161 { "lockPidFile","LockPidFile",	DM_BOOL,	(char **) &lockPidFile,
    162 				"true"} ,
    163 { "authDir",	"authDir",	DM_STRING,	&authDir,
    164 				DEF_AUTH_DIR} ,
    165 { "autoRescan",	"AutoRescan",	DM_BOOL,	(char **) &autoRescan,
    166 				"true"} ,
    167 { "removeDomainname","RemoveDomainname",DM_BOOL,(char **) &removeDomainname,
    168 				"true"} ,
    169 { "keyFile",	"KeyFile",	DM_STRING,	&keyFile,
    170 				DEF_KEY_FILE} ,
    171 { "accessFile",	"AccessFile",	DM_STRING,	&accessFile,
    172 				DEF_ACCESS_FILE} ,
    173 { "exportList",	"ExportList",	DM_ARGV,	(char **) &exportList,
    174 				""} ,
    175 #if !defined(HAVE_ARC4RANDOM)
    176 { "randomFile",	"RandomFile",	DM_STRING,	&randomFile,
    177 				DEF_RANDOM_FILE} ,
    178 { "prngdSocket", "PrngdSocket", DM_STRING,	&prngdSocket,
    179 				DEF_PRNGD_SOCKET},
    180 { "prngdPort", "PrngdPort",	DM_INT,		(char **) &prngdPort,
    181 				DEF_PRNGD_PORT},
    182 #endif
    183 #ifdef DEV_RANDOM
    184 { "randomDevice", "RandomDevice", DM_STRING,	&randomDevice,
    185 				DEV_RANDOM} ,
    186 #endif
    187 { "greeterLib",	"GreeterLib",	DM_STRING,	&greeterLib,
    188 				DEF_GREETER_LIB} ,
    189 { "choiceTimeout","ChoiceTimeout",DM_INT,	(char **) &choiceTimeout,
    190 				"15"} ,
    191 { "sourceAddress","SourceAddress",DM_BOOL,	(char **) &sourceAddress,
    192 				"false"} ,
    193 { "willing",	"Willing",	DM_STRING,	&willing,
    194 				""} ,
    195 };
    196 
    197 #define NUM_DM_RESOURCES	(sizeof DmResources / sizeof DmResources[0])
    198 
    199 #define boffset(f)	XtOffsetOf(struct display, f)
    200 
    201 struct displayResource {
    202 	const char	*name, *class;
    203 	int		type;
    204 	int		offset;
    205 	const char	*default_value;
    206 };
    207 
    208 /* resources for managing the server */
    209 
    210 struct displayResource serverResources[] = {
    211 { "serverAttempts","ServerAttempts",DM_INT,	boffset(serverAttempts),
    212 				"1" },
    213 { "openDelay",	"OpenDelay",	DM_INT,		boffset(openDelay),
    214 				"15" },
    215 { "openRepeat",	"OpenRepeat",	DM_INT,		boffset(openRepeat),
    216 				"5" },
    217 { "openTimeout","OpenTimeout",	DM_INT,		boffset(openTimeout),
    218 				"120" },
    219 { "startAttempts","StartAttempts",DM_INT,	boffset(startAttempts),
    220 				"4" },
    221 { "reservAttempts","ReservAttempts",DM_INT,	boffset(reservAttempts),
    222 				"2" },
    223 { "pingInterval","PingInterval",DM_INT,		boffset(pingInterval),
    224 				"5" },
    225 { "pingTimeout","PingTimeout",	DM_INT,		boffset(pingTimeout),
    226 				"5" },
    227 { "terminateServer","TerminateServer",DM_BOOL,	boffset(terminateServer),
    228 				"false" },
    229 { "grabServer",	"GrabServer",	DM_BOOL,	boffset(grabServer),
    230 				"false" },
    231 { "grabTimeout","GrabTimeout",	DM_INT,		boffset(grabTimeout),
    232 				"3" },
    233 { "resetSignal","Signal",	DM_INT,		boffset(resetSignal),
    234 				"1" },	/* SIGHUP */
    235 { "termSignal",	"Signal",	DM_INT,		boffset(termSignal),
    236 				"15" },	/* SIGTERM */
    237 { "resetForAuth","ResetForAuth",DM_BOOL,	boffset(resetForAuth),
    238 				"false" },
    239 { "authorize",	"Authorize",	DM_BOOL,	boffset(authorize),
    240 				"true" },
    241 { "authComplain","AuthComplain",DM_BOOL,	boffset(authComplain),
    242 				"true" },
    243 { "authName",	"AuthName",	DM_ARGV,	boffset(authNames),
    244 				DEF_AUTH_NAME },
    245 { "authFile",	"AuthFile",	DM_STRING,	boffset(clientAuthFile),
    246 				"" },
    247 };
    248 
    249 #define NUM_SERVER_RESOURCES	(sizeof serverResources/\
    250 				 sizeof serverResources[0])
    251 
    252 /* resources which control the session behaviour */
    253 
    254 struct displayResource sessionResources[] = {
    255 { "resources",	"Resources",	DM_STRING,	boffset(resources),
    256 				"" },
    257 { "xrdb",	"Xrdb",		DM_STRING,	boffset(xrdb),
    258 				XRDB_PROGRAM },
    259 { "setup",	"Setup",	DM_STRING,	boffset(setup),
    260 				"" },
    261 { "startup",	"Startup",	DM_STRING,	boffset(startup),
    262 				"" },
    263 { "reset",	"Reset",	DM_STRING,	boffset(reset),
    264 				"" },
    265 { "session",	"Session",	DM_STRING,	boffset(session),
    266 				DEF_SESSION },
    267 { "userPath",	"Path",		DM_STRING,	boffset(userPath),
    268 				DEF_USER_PATH },
    269 { "systemPath",	"Path",		DM_STRING,	boffset(systemPath),
    270 				DEF_SYSTEM_PATH },
    271 { "systemShell","Shell",	DM_STRING,	boffset(systemShell),
    272 				DEF_SYSTEM_SHELL },
    273 { "failsafeClient","FailsafeClient",	DM_STRING,	boffset(failsafeClient),
    274 				DEF_FAILSAFE_CLIENT },
    275 { "userAuthDir","UserAuthDir",	DM_STRING,	boffset(userAuthDir),
    276 				DEF_USER_AUTH_DIR },
    277 { "chooser",	"Chooser",	DM_STRING,	boffset(chooser),
    278 				DEF_CHOOSER },
    279 };
    280 
    281 #define NUM_SESSION_RESOURCES	(sizeof sessionResources/\
    282 				 sizeof sessionResources[0])
    283 
    284 XrmDatabase	DmResourceDB;
    285 
    286 static void
    287 GetResource (
    288     const char    *name,
    289     const char    *class,
    290     int            valueType,
    291     char         **valuep,
    292     const char    *default_value)
    293 {
    294     char	*type;
    295     XrmValue	value;
    296     const char	*string;
    297     char	*new_string;
    298     char	str_buf[50];
    299     int	len;
    300 
    301     if (DmResourceDB && XrmGetResource (DmResourceDB,
    302 	name, class,
    303 	&type, &value))
    304     {
    305 	string = value.addr;
    306 	len = value.size;
    307     }
    308     else
    309     {
    310 	string = default_value;
    311 	len = strlen (string);
    312     }
    313 
    314     Debug ("%s/%s value %*.*s\n", name, class, len, len, string);
    315 
    316     if (valueType == DM_STRING && *valuep)
    317     {
    318 	if (strlen (*valuep) == len && !strncmp (*valuep, string, len))
    319 	    return;
    320 	else
    321 	    free (*valuep);
    322     }
    323 
    324     switch (valueType) {
    325     case DM_STRING:
    326 	new_string = malloc ((unsigned) (len+1));
    327 	if (!new_string) {
    328 		LogOutOfMem ("GetResource");
    329 		return;
    330 	}
    331 	strncpy (new_string, string, len);
    332 	new_string[len] = '\0';
    333 	*(valuep) = new_string;
    334 	break;
    335     case DM_INT:
    336 	strncpy (str_buf, string, sizeof (str_buf));
    337 	str_buf[sizeof (str_buf)-1] = '\0';
    338 	*((int *) valuep) = atoi (str_buf);
    339 	break;
    340     case DM_BOOL:
    341 	strncpy (str_buf, string, sizeof (str_buf));
    342 	str_buf[sizeof (str_buf)-1] = '\0';
    343 	XmuCopyISOLatin1Lowered (str_buf, str_buf);
    344 	if (!strcmp (str_buf, "true") ||
    345 	    !strcmp (str_buf, "on") ||
    346 	    !strcmp (str_buf, "yes"))
    347 		*((int *) valuep) = 1;
    348 	else if (!strcmp (str_buf, "false") ||
    349 		 !strcmp (str_buf, "off") ||
    350 		 !strcmp (str_buf, "no"))
    351 		*((int *) valuep) = 0;
    352 	break;
    353     case DM_ARGV:
    354 	freeArgs (*(char ***) valuep);
    355 	*((char ***) valuep) = parseArgs ((char **) 0, string);
    356 	break;
    357     }
    358 }
    359 
    360 XrmOptionDescRec configTable [] = {
    361 {"-server",	NULL,			XrmoptionSkipArg,	(caddr_t) NULL },
    362 {"-udpPort",	NULL,			XrmoptionSkipArg,	(caddr_t) NULL },
    363 {"-error",	NULL,			XrmoptionSkipArg,	(caddr_t) NULL },
    364 {"-resources",	NULL,			XrmoptionSkipArg,	(caddr_t) NULL },
    365 {"-session",	NULL,			XrmoptionSkipArg,	(caddr_t) NULL },
    366 {"-debug",	NULL,			XrmoptionSkipArg,	(caddr_t) NULL },
    367 {"-xrm",	NULL,			XrmoptionSkipArg,	(caddr_t) NULL },
    368 {"-config",	".configFile",		XrmoptionSepArg,	(caddr_t) NULL }
    369 };
    370 
    371 XrmOptionDescRec optionTable [] = {
    372 {"-server",	".servers",		XrmoptionSepArg,	(caddr_t) NULL },
    373 {"-udpPort",	".requestPort",		XrmoptionSepArg,	(caddr_t) NULL },
    374 {"-error",	".errorLogFile",	XrmoptionSepArg,	(caddr_t) NULL },
    375 {"-resources",	"*resources",		XrmoptionSepArg,	(caddr_t) NULL },
    376 {"-session",	"*session",		XrmoptionSepArg,	(caddr_t) NULL },
    377 {"-debug",	"*debugLevel",		XrmoptionSepArg,	(caddr_t) NULL },
    378 {"-xrm",	NULL,			XrmoptionResArg,	(caddr_t) NULL },
    379 {"-daemon",	".daemonMode",		XrmoptionNoArg,		"true"         },
    380 {"-nodaemon",	".daemonMode",		XrmoptionNoArg,		"false"        }
    381 };
    382 
    383 static int	originalArgc;
    384 static char	**originalArgv;
    385 
    386 void
    387 InitResources (int argc, char **argv)
    388 {
    389 	XrmInitialize ();
    390 	originalArgc = argc;
    391 	originalArgv = argv;
    392 	ReinitResources ();
    393 }
    394 
    395 void
    396 ReinitResources (void)
    397 {
    398     int	argc;
    399     char	**a;
    400     char	**argv;
    401     XrmDatabase newDB;
    402 
    403     argv = malloc ((originalArgc + 1) * sizeof (char *));
    404     if (!argv)
    405 	LogPanic ("no space for argument realloc\n");
    406     for (argc = 0; argc < originalArgc; argc++)
    407 	argv[argc] = originalArgv[argc];
    408     argv[argc] = NULL;
    409     if (DmResourceDB)
    410 	XrmDestroyDatabase (DmResourceDB);
    411     DmResourceDB = XrmGetStringDatabase ("");
    412     /* pre-parse the command line to get the -config option, if any */
    413     XrmParseCommand (&DmResourceDB, configTable,
    414 		     sizeof (configTable) / sizeof (configTable[0]),
    415 		     "DisplayManager", &argc, argv);
    416     GetResource ("DisplayManager.configFile", "DisplayManager.ConfigFile",
    417 		 DM_STRING, &config, DEF_XDM_CONFIG);
    418     newDB = XrmGetFileDatabase ( config );
    419     if (newDB)
    420     {
    421 	if (DmResourceDB)
    422 	    XrmDestroyDatabase (DmResourceDB);
    423 	DmResourceDB = newDB;
    424     }
    425     else if (argc != originalArgc)
    426 	LogError ("Can't open configuration file %s\n", config );
    427     XrmParseCommand (&DmResourceDB, optionTable,
    428 		     sizeof (optionTable) / sizeof (optionTable[0]),
    429 		     "DisplayManager", &argc, argv);
    430     if (argc > 1)
    431     {
    432 	LogError ("extra arguments on command line:");
    433 	for (a = argv + 1; *a; a++)
    434 		LogAppend (" \"%s\"", *a);
    435 	LogAppend ("\n");
    436     }
    437     free (argv);
    438 }
    439 
    440 void
    441 LoadDMResources (void)
    442 {
    443 	int	i;
    444 	char	name[1024], class[1024];
    445 
    446 	for (i = 0; i < NUM_DM_RESOURCES; i++) {
    447 		snprintf (name, sizeof(name), "DisplayManager.%s", DmResources[i].name);
    448 		snprintf (class, sizeof(class), "DisplayManager.%s", DmResources[i].class);
    449 		GetResource (name, class, DmResources[i].type,
    450 			      (char **) DmResources[i].dm_value,
    451 			      DmResources[i].default_value);
    452 	}
    453 }
    454 
    455 static void
    456 CleanUpName (char *src, char *dst, int len)
    457 {
    458     while (*src) {
    459 	if (--len <= 0)
    460 		break;
    461 	switch (*src)
    462 	{
    463 	case ':':
    464 	case '.':
    465 	    *dst++ = '_';
    466 	    break;
    467 	default:
    468 	    *dst++ = *src;
    469 	}
    470 	++src;
    471     }
    472     *dst = '\0';
    473 }
    474 
    475 static void
    476 LoadDisplayResources (
    477     struct display	    *d,
    478     struct displayResource  *resources,
    479     int			    numResources)
    480 {
    481     int	i;
    482     char	name[1024], class[1024];
    483     char	dpyName[512], dpyClass[512];
    484 
    485     CleanUpName (d->name, dpyName, sizeof (dpyName));
    486     CleanUpName (d->class ? d->class : d->name, dpyClass, sizeof (dpyClass));
    487     for (i = 0; i < numResources; i++) {
    488 	    snprintf (name, sizeof(name), "DisplayManager.%s.%s",
    489 		    dpyName, resources[i].name);
    490 	    snprintf (class, sizeof(class), "DisplayManager.%s.%s",
    491 		    dpyClass, resources[i].class);
    492 	    GetResource (name, class, resources[i].type,
    493 			  (char **) (((char *) d) + resources[i].offset),
    494 			  resources[i].default_value);
    495     }
    496 }
    497 
    498 void
    499 LoadServerResources (struct display *d)
    500 {
    501     LoadDisplayResources (d, serverResources, NUM_SERVER_RESOURCES);
    502 }
    503 
    504 void
    505 LoadSessionResources (struct display *d)
    506 {
    507     LoadDisplayResources (d, sessionResources, NUM_SESSION_RESOURCES);
    508 }
    509