1 /*
2  * xdmshell - simple program for running xdm from login
3  *
4  *
5 Copyright 1988, 1998  The Open Group
6 
7 Permission to use, copy, modify, distribute, and sell this software and its
8 documentation for any purpose is hereby granted without fee, provided that
9 the above copyright notice appear in all copies and that both that
10 copyright notice and this permission notice appear in supporting
11 documentation.
12 
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 
23 Except as contained in this notice, the name of The Open Group shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from The Open Group.
26  * *
27  * Author:  Jim Fulton, MIT X Consortium
28  *
29  * This program should probably be setuid to root.
30  *
31  * WARNING:  Make sure that you tailor your Xresources file to have a
32  * way of invoking the abort-display() action.  Otherwise, you won't be able
33  * bring down X when you are finished.
34  */
35 
36 
37 #include <stdio.h>
38 #include "dm.h"
39 #include <errno.h>
40 #include <unistd.h>
41 
42 #ifndef BINDIR
43 # define BINDIR "/usr/bin/X11"
44 #endif
45 
46 /*
47  * HP-UX does have vfork, but A/UX doesn't
48  */
49 #ifdef HAVE_WORKING_VFORK /* autoconf's preferred name */
50 # define HAS_VFORK
51 #endif
52 
53 #ifndef HAS_VFORK
54 # define vfork() fork()
55 #endif
56 
57 static char *ProgramName;
58 
exec_args(char * filename,char ** args)59 static int exec_args (
60     char *filename,
61     char **args)
62 {
63     pid_t pid;
64     waitType status;
65 
66     if (!filename) return -1;
67 
68     if (filename[0] != '/') {
69 	fprintf (stderr,
70 	       "%s:  attempt to execute program with relative pathname:  %s\n",
71 		 ProgramName, filename);
72 	return -1;
73     }
74 
75     if (access (filename, X_OK) != 0) return -1;
76 
77     switch (pid = vfork ()) {
78       case -1:						/* error */
79 	return -1;
80       case 0:    					/* child */
81 	execv (filename, args);
82 	_exit (1);
83 	/* NOTREACHED */
84       default:						/* parent */
85 	while (wait (&status) != pid) ;
86     }
87     return waitCode (status);
88 }
89 
90 #if defined(sun)
exec_one_arg(char * filename,char * arg)91 static int exec_one_arg (
92     char    *filename,
93     char    *arg)
94 {
95     char    *argv[3];
96 
97     argv[0] = filename;
98     argv[1] = arg;
99     argv[2] = NULL;
100     return exec_args (filename, argv);
101 }
102 #endif
103 
104 int
main(int argc,char * argv[])105 main (
106     int argc,
107     char *argv[])
108 {
109     int ttyfd;
110     char cmdbuf[256];
111     char *args[10];
112 
113     ProgramName = argv[0];
114 
115     if (argc > 1) {
116 	fprintf (stderr, "usage:  %s\r\n", ProgramName);
117 	exit (1);
118     }
119 
120     ttyfd = open ("/dev/tty", O_RDWR, 0);
121     if (ttyfd < 3) {			/* stdin = 0, stdout = 1, stderr = 2 */
122 	fprintf (stderr,
123 		 "%s:  must be run directly from the console.\r\n",
124 		 ProgramName);
125 	exit (1);
126     }
127     (void) close (ttyfd);
128 
129     /* make xdm run in a non-setuid environment */
130     if (setuid (geteuid()) == -1) {
131 	fprintf(stderr, "%s: cannot setuid (error %d, %s)\r\n",
132 		ProgramName, errno, strerror(errno));
133 	exit(1);
134     }
135 
136     /*
137      * exec /usr/bin/X11/xdm -nodaemon -udpPort 0
138      */
139     strcpy (cmdbuf, BINDIR);
140     strcat (cmdbuf, "/xdm");
141     args[0] = cmdbuf;
142     args[1] = "-nodaemon";
143     args[2] = "-udpPort";
144     args[3] = "0";
145     args[4] = NULL;
146     if (exec_args (cmdbuf, args) == -1) {
147 	fprintf (stderr, "%s:  unable to execute %s (error %d, %s)\r\n",
148 		 ProgramName, cmdbuf, errno, strerror(errno));
149 	exit (1);
150     }
151 
152 #ifdef sun
153     strcpy (cmdbuf, BINDIR);
154     strcat (cmdbuf, "/kbd_mode");
155     (void) exec_one_arg (cmdbuf, "-a");
156 #endif
157 
158     exit (0);
159     /*NOTREACHED*/
160 }
161