source: trunk/athena/bin/lert/lertsrv.c @ 14069

Revision 14069, 5.9 KB checked in by danw, 25 years ago (diff)
indent and comment style fixes (mostly)
Line 
1/* Copyright 1994, 1999 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
16/* This is the server for the lert system. */
17
18static const char rcsid[] = "$Id: lertsrv.c,v 1.5 1999-12-09 22:24:24 danw Exp $";
19
20#include <stdio.h>
21#include <krb.h>
22#include <des.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <sys/socket.h>
27#include <sys/uio.h>
28#include <netinet/in.h>
29#include <netdb.h>
30#include <sys/time.h>
31#include <hesiod.h>
32#include <string.h>
33#include <pwd.h>
34#include <sys/utsname.h>
35#include <errno.h>
36#include "lert.h"
37
38int main(int argc, char **argv)
39{
40  int s;                        /* The Socket */
41  register int i;               /* Iterator variable */
42  struct sockaddr_in sin;
43  struct sockaddr *burp_me;
44  struct sockaddr_in from;
45  char packet[2048];
46  int plen;
47  char opacket[2048];
48  int oplen;
49  int fromlen;
50  int status;
51  int len;
52  AUTH_DAT ad;
53  KTEXT_ST authent;
54  KTEXT_ST ktxt;
55  int atime;
56  char *tb, *cp;
57  FILE *logf;
58  /* for krb_mk_priv */
59  des_key_schedule sched;               /* session key schedule */
60  struct hostent *hp;
61  struct utsname thishost;
62
63#ifdef LOGGING
64  setbuf(stdout, NULL);
65#endif
66
67  s = socket(AF_INET, SOCK_DGRAM, 0);
68
69  /* Clear the socket structure. */
70  memset(&sin, 0, sizeof(sin));
71  sin.sin_family = AF_INET;
72  sin.sin_port = htons(LERT_PORT);
73  burp_me = (struct sockaddr *)&sin;
74
75  if (bind(s, burp_me, sizeof(sin)) < 0)
76    {
77      fprintf(stderr, "%s: Unable to bind socket: %s\n",
78              argv[0], strerror(errno));
79      exit(1);
80  }
81
82  fromlen = sizeof(from);
83
84  /* Get hostname for krb_mk_priv. */
85  if (uname(&thishost) == -1)
86    {
87      fprintf(stderr, "%s: Unable to get system information: %s\n",
88              argv[0], strerror(errno));
89      exit(1);
90  }
91  hp = gethostbyname(thishost.nodename);
92  if (hp == NULL) {
93    fprintf(stderr, "%s: Unable to get host name information: %s\n",
94            argv[0], strerror(errno));
95    exit(1);
96  }
97
98  memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
99
100  for (;;)
101    {
102      plen = recvfrom(s, packet, sizeof(packet), 0,
103                      (struct sockaddr *)&from, &fromlen);
104      if (plen < 0)
105        {
106          fprintf(stderr, "lertsrv: Error during recv: %s\n",
107                  strerror(errno));
108          sleep(1);             /* Prevent infinite cpu hog loop */
109          continue;
110        }
111
112#ifdef DEBUG
113      fprintf(stderr, "lertsrv: Received packet of length %d\n", plen);
114#endif
115
116      if (packet[0] != LERT_VERSION)
117        {
118          fprintf(stderr, "lertsrv: Received packet with bad version: %d\n",
119                  packet[0]);
120          continue;
121        }
122
123      /* Copy authenticator into aligned region. */
124      memcpy(&authent, &packet[LERT_LENGTH], sizeof(authent));
125
126      status = krb_rd_req(&authent, LERT_SERVICE, LERT_HOME, 0, &ad,
127                          LERTS_SRVTAB);
128
129      if (status != KSUCCESS)
130        {
131          fprintf(stderr, "lertsrv: Kerberos failure: %s\n",
132                  krb_err_txt[status]);
133          continue;
134        }
135
136      opacket[0] = LERT_VERSION;
137      if ((strlen(ad.pinst) != 0) || (strcmp(ad.prealm, "ATHENA.MIT.EDU")))
138        {
139          fprintf(stderr, "lertsrv: %s.%s@%s -- Not null instance ATHENA "
140                  "realm.\n", ad.pname, ad.pinst, ad.prealm);
141          opacket[1] = LERT_NOT_IN_DB;
142          opacket[2] = '\0';
143        }
144      else
145        get_user(ad.pname, &(opacket[1]), ad.checksum);
146
147      /* Prepare krb_mk_priv message */
148      des_key_sched(ad.session, sched);
149
150      /* Make the encrypted message:
151       * version, code, data, plus terminating '\0'
152       */
153      len = krb_mk_priv(opacket, ktxt.dat,
154                        LERT_CHECK + strlen(opacket + LERT_CHECK) + 1,
155                        sched, ad.session, &sin, &from);
156
157      /* Send it. */
158      if (sendto(s, ktxt.dat, len, 0,
159                 (struct sockaddr *) &from, sizeof(from)) < 0)
160        fprintf(stderr, "lertsrv: sendto failed: %s\n", strerror(errno));
161
162      memset(&from, 0, sizeof(from));   /* Avoid confusion, zeroize now */
163    }
164
165  return 0;
166}
167
168int get_user(char *pname, char *result, int onetime)
169{
170  DBM *db;
171  DBM *db2;
172  datum data;
173  datum key;
174  datum data2;
175  datum key2;
176  char result2[128];
177
178  /* Prepare nil return. */
179  result[0] = LERT_FREE;
180  result[1] = '\0';
181
182  /* Open the database. */
183  db = dbm_open(LERTS_DATA, O_RDWR, 0600);
184  if (db == NULL)
185    {
186      fprintf(stderr, "Unable to open lert's database file %s: %s.\n",
187              LERTS_DATA, strerror(errno));
188      return LERT_NO_DB;
189    }
190
191  key.dptr = pname;
192  key.dsize = strlen(pname) + 1;
193
194  /* Get the user. */
195  data = dbm_fetch(db, key);
196  if (data.dptr == NULL)
197    {
198      /* Not in db. */
199      dbm_close(db);
200#ifdef LOGGING
201      fprintf(stdout, "lertsrv: user %s not in db\n", pname);
202#endif
203      return LERT_NOT_IN_DB;
204    }
205  else
206    {
207      strncpy(&(result[1]), data.dptr, data.dsize);
208      result[data.dsize + 1] = '\0';
209
210      if (onetime)
211        {
212          /* Add them to the log. */
213          db2 = dbm_open(LERTS_LOG, O_RDWR | O_CREAT, 0600);
214          if (db2 == NULL)
215            {
216              fprintf(stderr, "Unable to open lert's log database %s: %s.\n",
217                      LERTS_LOG, strerror(errno));
218            }
219          else
220            {
221              data2 = dbm_fetch(db2, key);
222              if (data2.dptr == NULL)
223                dbm_store(db2, key, data, DBM_INSERT);
224              else
225                {
226                  strncpy(result2, data2.dptr, data2.dsize);
227                  strncpy(&(result2[data2.dsize]), data.dptr, data.dsize);
228                  data2.dptr = result2;
229                  data2.dsize += data.dsize;
230                  dbm_store(db2, key, data2, DBM_REPLACE);
231                }
232              dbm_close(db2);
233            }
234          dbm_delete(db, key);
235        }
236      dbm_close(db);
237    }
238
239  result[0] = LERT_MSG;
240#ifdef LOGGING
241  fprintf(stdout, "lertsrv: user %s in db with groups :%s:\n", pname, result);
242#endif
243  return LERT_GOTCHA;
244}
245
246
Note: See TracBrowser for help on using the repository browser.