source: trunk/athena/bin/access/access_off.c @ 12125

Revision 12125, 5.0 KB checked in by ghudson, 26 years ago (diff)
Read boot environment from /var/athena/env.boot before starting sshd. For now, specify absolute path to sshd as argv[0]. This should be reverted later when the boot scripts have /etc/athena in the paths they set.
  • Property svn:executable set to *
Line 
1/* Copyright 1996 by the Massachusetts Institute of Technology.
2 *
3 * Permission to use, copy, modify, and distribute this
4 * software and its documentation for any purpose and without
5 * fee is hereby granted, provided that the above copyright
6 * notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting
8 * documentation, and that the name of M.I.T. not be used in
9 * advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission.
11 * M.I.T. makes no representations about the suitability of
12 * this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 */
15
16static const char rcsid[] = "$Id: access_off.c,v 1.11 1998-11-06 18:52:16 ghudson Exp $";
17
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <signal.h>
23#include <errno.h>
24#include <string.h>
25#include <unistd.h>
26#include <fcntl.h>
27
28#define PATH_INETD_PID          "/var/athena/inetd.pid"
29#define PATH_SSHD_PID           "/var/athena/sshd.pid"
30#define PATH_SSHD               "/etc/athena/sshd"
31#define PATH_RC_CONF            "/etc/athena/rc.conf"
32#define PATH_BOOT_ENVIRON       "/var/athena/env.boot"
33#define ENV_FALLBACK            { "PATH=/etc/athena", NULL }
34
35static char **get_boot_environment(void);
36
37int main(int argc, char **argv)
38{
39  FILE *pidfile, *rcfile;
40  int pid, on, running;
41  char *progname, buf[1024], **env, *env_fallback[] = ENV_FALLBACK;
42
43  progname = strrchr(argv[0], '/');
44  progname = (progname) ? progname + 1 : argv[0];
45
46  /* We're turning access off if this program was invoked as access_off;
47   * otherwise we're turning access on. */
48  on = (strcmp(progname, "access_off") != 0);
49
50  /* Send SIGUSR1 or SIGUSR2 to the Athena inetd. */
51  pidfile = fopen(PATH_INETD_PID, "r");
52  if (!pidfile)
53    {
54      fprintf(stderr, "Cannot read %s.  Daemon probably not running\n",
55              PATH_INETD_PID);
56      return 1;
57    }
58  if (fscanf(pidfile, "%d", &pid) != 1)
59    {
60      fprintf(stderr, "Error reading %s.\n", PATH_INETD_PID);
61      return 1;
62    }
63  fclose(pidfile);
64  if (kill(pid, (on) ? SIGUSR1 : SIGUSR2) < 0)
65    {
66      if (errno != ESRCH)
67        perror("Error killing daemon");
68      return 1;
69    }
70
71  /* If SSHD is set to "switched" in /etc/athena/rc.conf, then start or stop
72   * sshd if it's not already in the state we want. */
73  rcfile = fopen(PATH_RC_CONF, "r");
74  if (!rcfile)
75    {
76      fprintf(stderr, "Cannot read %s: %s", PATH_RC_CONF, strerror(errno));
77      return 1;
78    }
79  while (fgets(buf, sizeof(buf), rcfile) != NULL)
80    {
81      /* Ignore lines which aren't setting SSHD. */
82      if (strncmp(buf, "SSHD=", 5) != 0)
83        continue;
84
85      /* If SSHD is not set to "switched" then we do nothing. */
86      if (strncmp(buf + 5, "switched", 8) != 0)
87        break;
88
89      /* Read the sshd pidfile and send a signal 0 to the contained pid
90       * to determine if sshd is running. */
91      pidfile = fopen(PATH_SSHD_PID, "r");
92      if (pidfile && fscanf(pidfile, "%d", &pid) == 1 && kill(pid, 0) == 0)
93        running = 1;
94      else
95        running = 0;
96      if (pidfile)
97        fclose(pidfile);
98
99      if (on && !running)
100        {
101          /* ssh is not running and we'd like it to be running.  Start it. */
102          pid = fork();
103          if (pid == -1)
104            {
105              perror("Error forking to run sshd");
106              return 1;
107            }
108          else if (pid == 0)
109            {
110              fclose(rcfile);
111              /* Make ruid and saved uid equal to effective uid before exec,
112               * or sshd might notice and get confused.  Set the environment
113               * to the boot-time environment.
114               */
115              setuid(geteuid());
116              env = get_boot_environment();
117              if (!env)
118                env = env_fallback;
119              execle(PATH_SSHD, PATH_SSHD, (char *) NULL, env);
120              perror("Error running sshd");
121            }
122        }
123      else if (!on && running)
124        {
125          /* ssh is running and we'd like it not to be running.  Kill it.
126           * We can be sure that we read its pid in this case. */
127          kill(pid, SIGTERM);
128        }
129
130      break;
131    }
132  fclose(rcfile);
133
134  return 0;
135}
136
137static char **get_boot_environment(void)
138{
139  int fd, len, count;
140  struct stat st;
141  char *buf, *p, *q, **env, **ep;
142
143  /* Open and read the stored boot environment. */
144  fd = open(PATH_BOOT_ENVIRON, O_RDONLY);
145  if (fd == -1)
146    return NULL;
147  if (fstat(fd, &st) == -1)
148    {
149      close(fd);
150      return NULL;
151    }
152  buf = malloc(st.st_size);
153  if (!buf)
154    {
155      close(fd);
156      return NULL;
157    }
158  len = 0;
159  while (len < st.st_size)
160    {
161      count = read(fd, buf + len, st.st_size - len);
162      if (count < 0 && errno != EINTR)
163        {
164          close(fd);
165          free(buf);
166          return NULL;
167        }
168      else if (count > 0)
169        len += count;
170    }
171  close(fd);
172
173  /* Allocate space for the environment pointers. */
174  count = 0;
175  for (p = buf; *p; p++)
176    {
177      if (*p == '\n')
178        count++;
179    }
180  env = malloc((count + 1) * sizeof(char *));
181  if (!env)
182    {
183      free(buf);
184      return NULL;
185    }
186
187  /* Set the environment pointers. */
188  ep = env;
189  p = buf;
190  while ((q = strchr(p, '\n')) != NULL)
191    {
192      *ep++ = p;
193      *q = 0;
194      p = q + 1;
195    }
196
197  /* Terminate the environment list and return it. */
198  *ep = NULL;
199  return env;
200}
Note: See TracBrowser for help on using the repository browser.