updated as of latest changes
[freeradius.git] / todo / realm.c
1 /*
2  * realm.c      Read and process realm file.
3  *
4  *
5  * Version:     @(#)  realm.c  16-Jul-1998  miquels@cistron.nl
6  *
7  */
8
9 char util_sccsid[] =
10 "@(#)realm.c    1.0 Copyright 1998 Cistron Internet Services B.V.";
11
12 #include        <sys/types.h>
13 #include        <sys/socket.h>
14 #include        <sys/time.h>
15 #include        <netinet/in.h>
16
17 #include        <stdio.h>
18 #include        <stdlib.h>
19 #include        <netdb.h>
20 #include        <pwd.h>
21 #include        <time.h>
22 #include        <ctype.h>
23
24 #include        "radiusd.h"
25
26 CONF *conf;
27
28 struct tpl {
29         char    *name;
30         int     offset;
31 };
32
33 static struct tpl tpl[] = {
34   {  "realm",           offsetof(CONF, realm)           },
35   {  "radwtmp",         offsetof(CONF, radwtmp)         },
36   {  "radutmp",         offsetof(CONF, radutmp)         },
37   {  "acctdir",         offsetof(CONF, acctdir)         },
38   {  "acctdir2",        offsetof(CONF, acctdir2)        },
39   {  "authproxy",       offsetof(CONF, authproxy)       },
40   {  "acctproxy",       offsetof(CONF, acctproxy)       },
41   {  "striprealm",      offsetof(CONF, striprealm)      },
42   {  NULL,              -1                              },
43 };
44
45 /*
46  *      Initialize the config file structs.
47  */
48 static CONF *initconf(void)
49 {
50         conf = (CONF *)malloc(sizeof(CONF));
51         memset(conf, 0, sizeof(CONF));
52
53         strcpy(conf->radutmp, RADUTMP);
54         strcpy(conf->radutmp, RADWTMP);
55         strcpy(conf->confdir, RADIUS_DIR);
56         strcpy(conf->acctdir, RADACCT_DIR);
57         strcpy(conf->logdir, RADLOG_DIR);
58         strcpy(conf->pidfile, RADIUS_PID);
59         strcpy(conf->checkrad,  CHECKRAD1);
60         strcpy(conf->checkrad2, CHECKRAD2);
61         strcpy(conf->striprealm, "yes");
62
63         return conf;
64 }
65
66 /*
67  *      Read the config file.
68  */
69 int readconf(char *conffile)
70 {
71         FILE    *fp;
72         char    buf[128];
73         char    *key, *val;
74         char    lineno = 0;
75         CONF    *cf, *cf2;
76         int     first = 1;
77
78         /*
79          *      Initialize.
80          */
81         if ((fp = fopen(conffile, "r")) == NULL) {
82                 log(L_ERR, "%s: %s", conffile, strerror(errno));
83                 return -1;
84         }
85         cf = initconf();
86
87         /*
88          *      Read config file line by line.
89          */
90         while(fgets(buf, sizeof(buf), fp)) {
91                 lineno++;
92                 /*
93                  *      Skip comments and empty lines, and split
94                  *      the rest up in key/value pairs.
95                  */
96                 if (buf[0] == '#' || buf[0] == '\n' || buf[0] == 0)
97                         continue;
98                 key = strtok(buf, " \t");
99                 val = strtok(NULL, "\n");
100                 if (key == NULL || key[0] == 0 ||
101                     val == NULL || val[0] == 0) {
102                         log(L_ERR, "%s[%d]: syntax error", conffile, lineno);
103                         return -1;
104                 }
105
106                 /*
107                  *      The "realm" key is special, we allocate a new
108                  *      CONF now _unless_ the "realm" keyword is the
109                  *      first keyword in the file.
110                  */
111                 if (strcmp(key, "realm") == 0 && !first) {
112                         cf2 = (CONF *)malloc(sizeof(CONF));
113                         memcpy(cf2, cf, sizeof(CONF));
114                         strcpy(cf2->striprealm, "no");
115                         cf->next = cf2;
116                         cf = cf2;
117                 }
118                 first = 0;
119
120                 /*
121                  *      Find the key in our keyword list and
122                  *      calculate the offset into the CONF struct
123                  *      for the value.
124                  */
125                 for(i = 0; tpl[i].name; i++) {
126                         if (strcmp(tpl[i].name, key) == 0)
127                                 break;
128                 }
129                 if (tpl[i].name == NULL) {
130                         log(L_ERR, "%s[%d]: unknown keyword %s",
131                                 conffile, lineno, key);
132                         return -1;
133                 }
134                 strcpy((char *)cf + tpl[i].offset, val);
135         }
136         fclose (fp);
137
138         return 0;
139 }
140
141 /*
142  *      Find the configuration for a certain realm.
143  *      We modify the username in-place, so this function should
144  *      only be called once.
145  */
146 CONF *getconf(char *username)
147 {
148         char    buf[128];
149         char    *realm, *user;
150         CONF    *cf;
151
152         strncpy(buf, username, 128);
153         buf[128] = 0;
154
155         /*
156          *      Split username and realm. We support both
157          *      realm\username and username@realm.
158          */
159         if ((realm = strchr(buf, '@')) != NULL) {
160                 *realm++ = 0;
161                 user = buf;
162         } else if ((user = strchr(buf, '\\')) != NULL) {
163                 *user++ = 0;
164                 realm = buf;
165         } else
166                 return conf;
167
168         /*
169          *      Find this realm in the conffile, if not found use
170          *      the default (local) realm and do not strip the realm,
171          *      If found strip realm from username if needed.
172          */
173         for (cf = conf; cf; cf = cf->next)
174                 if (strcasecmp(realm, cf->realm) == 0)
175                         break;
176         if (cf == NULL) {
177                 cf = conf;
178         } else {
179                 if (strcmp(cf->striprealm, "yes") == 0)
180                         strcpy(username, user);
181         }
182
183         return conf;
184 }
185