auth: local realms configuration
[openafs.git] / tests / auth / realms-t.c
1 /*
2  * Copyright 2010, Sine Nomine Associates and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14
15 #include <rx/rx.h>
16 #include <rx/rxkad.h>
17 #include <afs/cellconfig.h>
18
19 #include <tap/basic.h>
20 #include "common.h"
21
22 extern int _afsconf_Touch(struct afsconf_dir *adir);
23
24 int verbose = 0;
25
26 #define LOCAL 1
27 #define FOREIGN 0
28 struct testcase {
29     char *name;
30     char *inst;
31     char *cell;
32     int expectedLocal;
33 };
34
35 /*
36  * test set 0
37  * cell: example.org
38  */
39 struct testcase testset0[] = {
40     {"jdoe", NULL, NULL, LOCAL},
41     {"jdoe", NULL, "example.org", LOCAL},
42     {"jdoe", NULL, "EXAMPLE.ORG", LOCAL},
43     {"jdoe", NULL, NULL, LOCAL},
44     {"jdoe", NULL, "my.realm.org", FOREIGN},
45     {"jdoe", NULL, "MY.REALM.ORG", FOREIGN},
46     {"jdoe", NULL, "MY.OTHER.REALM.ORG", FOREIGN},
47     {"jdoe", "admin", NULL, LOCAL},
48     {"jdoe", "admin", "my.realm.org", FOREIGN},
49     {"jdoe", "admin", "MY.REALM.ORG", FOREIGN},
50     {"jdoe", "admin", "your.realm.org", FOREIGN},
51     {"jdoe", "admin", "YOUR.REALM.ORG", FOREIGN},
52     {"admin", NULL, "example.org", LOCAL},
53     {"admin", NULL, "my.realm.org", FOREIGN},
54     {"admin", NULL, "MY.REALM.ORG", FOREIGN},
55     {"admin", NULL, "MY.OTHER.REALM.ORG", FOREIGN},
56     {NULL},
57 };
58
59 /*
60  * test set 1
61  * cell: example.org
62  * local realms: MY.REALM.ORG, MY.OTHER.REALM.ORG
63  */
64 struct testcase testset1[] = {
65     {"jdoe", NULL, NULL, LOCAL},
66     {"jdoe", NULL, "example.org", LOCAL},
67     {"jdoe", NULL, "EXAMPLE.ORG", LOCAL},
68     {"jdoe", NULL, NULL, LOCAL},
69     {"jdoe", NULL, "my.realm.org", LOCAL},
70     {"jdoe", NULL, "MY.REALM.ORG", LOCAL},
71     {"jdoe", NULL, "MY.OTHER.REALM.ORG", LOCAL},
72     {"jdoe", NULL, "SOME.REALM.ORG", FOREIGN},
73     {"jdoe", "admin", NULL, LOCAL},
74     {"jdoe", "admin", "my.realm.org", LOCAL},
75     {"jdoe", "admin", "MY.REALM.ORG", LOCAL},
76     {"jdoe", "admin", "MY.OTHER.REALM.ORG", LOCAL},
77     {"jdoe", "admin", "your.realm.org", FOREIGN},
78     {"jdoe", "admin", "YOUR.REALM.ORG", FOREIGN},
79     {"admin", NULL, "example.org", LOCAL},
80     {"admin", NULL, "my.realm.org", LOCAL},
81     {"admin", NULL, "MY.REALM.ORG", LOCAL},
82     {"admin", NULL, "MY.OTHER.REALM.ORG", LOCAL},
83     {NULL},
84 };
85
86 /*
87  * test set 2
88  * cell: example.org
89  * local realms: MY.REALM.ORG, MY.OTHER.REALM.ORG
90  * exclude: admin@MY.REALM.ORG
91  */
92 struct testcase testset2[] = {
93     {"jdoe", NULL, NULL, LOCAL},
94     {"jdoe", NULL, "example.org", LOCAL},
95     {"jdoe", NULL, "EXAMPLE.ORG", LOCAL},
96     {"jdoe", NULL, NULL, LOCAL},
97     {"jdoe", NULL, "my.realm.org", LOCAL},
98     {"jdoe", NULL, "MY.REALM.ORG", LOCAL},
99     {"jdoe", NULL, "MY.OTHER.REALM.ORG", LOCAL},
100     {"jdoe", "admin", NULL, LOCAL},
101     {"jdoe", "admin", "my.realm.org", LOCAL},
102     {"jdoe", "admin", "MY.REALM.ORG", LOCAL},
103     {"jdoe", "admin", "MY.OTHER.REALM.ORG", LOCAL},
104     {"jdoe", "admin", "your.realm.org", FOREIGN},
105     {"jdoe", "admin", "YOUR.REALM.ORG", FOREIGN},
106     {"admin", NULL, "example.org", LOCAL},
107     {"admin", NULL, "my.realm.org", LOCAL},
108     {"admin", NULL, "MY.REALM.ORG", FOREIGN},
109     {"admin", NULL, "MY.OTHER.REALM.ORG", LOCAL},
110     {NULL},
111 };
112
113 struct testcase* testset[] = { testset0, testset1, testset2 };
114
115 char *
116 make_string(int len)
117 {
118     char *s = malloc(len + 1);
119     if (!s) {
120         fprintf(stderr, "Failed to allocate string buffer.\n");
121         exit(1);
122     }
123     memset(s, 'x', len);
124     s[len] = '\0';
125     return s;
126 }
127
128 void
129 run_tests(struct afsconf_dir *dir, int setnum, char *setname)
130 {
131     struct testcase *t;
132     int code;
133
134     for (t = testset[setnum]; t->name; t++) {
135         afs_int32 local = -1;
136
137         code = afsconf_IsLocalRealmMatch(dir, &local, t->name, t->inst, t->cell);
138         ok(code == 0, "%s: test case %s/%s/%s",
139            setname,
140            t->name ? t->name : "(null)",
141            t->inst ? t->inst : "(null)",
142            t->cell ? t->cell : "(null)");
143         if (code==0) {
144            ok(local == t->expectedLocal, "... expected %d, got %d", t->expectedLocal, local);
145         }
146     }
147 }
148
149 void
150 run_edge_tests(struct afsconf_dir *dir)
151 {
152     afs_int32 local = -1;
153     int code = 0;
154     char *name = "jdoe";
155     char *inst = "";
156     char *cell = "";
157
158     /* null argument checks */
159     code = afsconf_IsLocalRealmMatch(dir, &local, NULL, inst, cell);
160     ok(code == EINVAL, "null name: code=%d", code);
161
162     code = afsconf_IsLocalRealmMatch(dir, &local, name, NULL, cell);
163     ok(code == 0, "null inst: code=%d", code);
164
165     code = afsconf_IsLocalRealmMatch(dir, &local, name, inst, NULL);
166     ok(code == 0, "null cell: code=%d", code);
167
168     /* large ticket test */
169     name = make_string(64);
170     inst = make_string(64);
171     cell = make_string(64);
172     code = afsconf_IsLocalRealmMatch(dir, &local, name, inst, cell);
173     ok(code == 0, "name size 64: code=%d", code);
174     free(name);
175     free(inst);
176     free(cell);
177
178     name = make_string(255);
179     inst = NULL;
180     cell = "my.realm.org";
181     code = afsconf_IsLocalRealmMatch(dir, &local, name, inst, cell);
182     ok(code == 0, "name size 255: code=%d", code);
183     free(name);
184 }
185
186 void
187 write_krb_conf(char *dirname, char *data)
188 {
189     char *filename = NULL;
190     FILE *fp;
191
192     asnprintf(&filename, 256, "%s/%s", dirname, "krb.conf");
193     if ((fp = fopen(filename, "w")) == NULL) {
194         fprintf(stderr, "Unable to create test file %s\n", filename);
195         exit(1);
196     }
197     if (verbose) {
198         diag("writing to %s: %s", filename, data);
199     }
200     fprintf(fp, "%s\n", data);
201     fclose(fp);
202     free(filename);
203 }
204
205 void
206 write_krb_excl(char *dirname)
207 {
208     char *filename = NULL;
209     FILE *fp;
210     char *data;
211
212     asnprintf(&filename, 256, "%s/%s", dirname, "krb.excl");
213     if ((fp = fopen(filename, "w")) == NULL) {
214         fprintf(stderr, "Unable to create test file %s\n", filename);
215         exit(1);
216     }
217     data = "admin@MY.REALM.ORG";
218     if (verbose) {
219         diag("writing to %s: %s", filename, data);
220     }
221     fprintf(fp, "%s\n", data);
222     data = "admin@EXAMPLE.ORG";
223     if (verbose) {
224         diag("writing to %s: %s", filename, data);
225     }
226     fprintf(fp, "%s\n", data);
227     fclose(fp);
228     free(filename);
229 }
230
231 void
232 update_csdb(char *dirname)
233 {
234     char *filename = NULL;
235     FILE *fp;
236
237     asnprintf(&filename, 256, "%s/%s", dirname, "CellServDB");
238     if ((fp = fopen(filename, "a")) == NULL) {
239         fprintf(stderr, "Unable to create test file %s\n", filename);
240         exit(1);
241     }
242     fprintf(fp, "10.0.0.1 #bogus.example.org\n");
243     fclose(fp);
244     free(filename);
245 }
246
247 void
248 test_edges(void)
249 {
250     struct afsconf_dir *dir;
251     char *dirname;
252
253     /* run edge case tests */
254     dirname = afstest_BuildTestConfig();
255     dir = afsconf_Open(dirname);
256     if (dir == NULL) {
257         fprintf(stderr, "Unable to configure directory.\n");
258         exit(1);
259     }
260     run_edge_tests(dir);
261     afstest_UnlinkTestConfig(dirname);
262 }
263
264 void
265 test_no_config_files(void)
266 {
267     struct afsconf_dir *dir;
268     char *dirname;
269
270     /* run tests without config files */
271     dirname = afstest_BuildTestConfig();
272     dir = afsconf_Open(dirname);
273     if (dir == NULL) {
274         fprintf(stderr, "Unable to configure directory.\n");
275         exit(1);
276     }
277     run_tests(dir, 0, "no config");
278     afstest_UnlinkTestConfig(dirname);
279 }
280
281 void
282 test_with_config_files(void)
283 {
284     struct afsconf_dir *dir;
285     char *dirname;
286
287     /* run tests with config files */
288     dirname = afstest_BuildTestConfig();
289     write_krb_conf(dirname, "MY.REALM.ORG MY.OTHER.REALM.ORG");
290     write_krb_excl(dirname);
291     dir = afsconf_Open(dirname);
292     if (dir == NULL) {
293         fprintf(stderr, "Unable to configure directory.\n");
294         exit(1);
295     }
296     run_tests(dir, 2, "config");
297     afstest_UnlinkTestConfig(dirname);
298 }
299
300 void
301 test_set_local_realms(void)
302 {
303     struct afsconf_dir *dir;
304     char *dirname;
305
306     /* Simulate command line -realm option; overrides config file, if one.
307      * Multiple realms can be added. */
308     ok(afsconf_SetLocalRealm("MY.REALM.ORG") == 0, "set local realm MY.REALM.ORG");
309     ok(afsconf_SetLocalRealm("MY.OTHER.REALM.ORG") == 0, "set local realm MY.OTHER.REALM.ORG");
310
311     /* run tests without config files */
312     dirname = afstest_BuildTestConfig();
313     dir = afsconf_Open(dirname);
314     if (dir == NULL) {
315         fprintf(stderr, "Unable to configure directory.\n");
316         exit(1);
317     }
318     write_krb_conf(dirname, "SOME.REALM.ORG");
319     run_tests(dir, 1, "set realm test");
320     afstest_UnlinkTestConfig(dirname);
321 }
322
323 void
324 test_update_config_files(void)
325 {
326     int code;
327     struct afsconf_dir *dir;
328     char *dirname;
329     afs_int32 local = -1;
330
331     dirname = afstest_BuildTestConfig();
332     write_krb_conf(dirname, "SOME.REALM.ORG");
333     dir = afsconf_Open(dirname);
334     if (dir == NULL) {
335         fprintf(stderr, "Unable to configure directory.\n");
336         exit(1);
337     }
338
339     code = afsconf_IsLocalRealmMatch(dir, &local, "jdoe", NULL, "SOME.REALM.ORG");
340     ok(code == 0 && local == 1, "before update: jdoe@SOME.REALM.ORG");
341
342     code = afsconf_IsLocalRealmMatch(dir, &local, "jdoe", NULL, "MY.REALM.ORG");
343     ok(code == 0 && local == 0, "before update: admin@MY.REALM.ORG");
344
345     write_krb_conf(dirname, "MY.REALM.ORG MY.OTHER.REALM.ORG");
346     write_krb_excl(dirname);
347     update_csdb(dirname);
348     _afsconf_Touch(dir);        /* forces reopen */
349
350     code = afsconf_IsLocalRealmMatch(dir, &local, "jdoe", NULL, "MY.REALM.ORG");
351     ok(code == 0 && local == 1, "after update: jdoe@MY.REALM.ORG");
352
353     code = afsconf_IsLocalRealmMatch(dir, &local, "admin", NULL, "MY.REALM.ORG");
354     ok(code == 0 && local == 0, "after update: admin@MY.REALM.ORG");
355
356     afstest_UnlinkTestConfig(dirname);
357 }
358
359 int
360 main(int argc, char **argv)
361 {
362     plan(113);
363
364     test_edges();
365     test_no_config_files();
366     test_with_config_files();
367     test_update_config_files();
368     test_set_local_realms(); /* must be the last test */
369
370     return 0;
371 }