HEIMDAL: move code from source4/heimdal* to third_party/heimdal*
[samba.git] / third_party / heimdal / lib / krb5 / test_alname.c
1 /*
2  * Copyright (c) 2003 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of KTH nor the names of its contributors may be
18  *    used to endorse or promote products derived from this software without
19  *    specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
32
33 #include "krb5_locl.h"
34 #include <getarg.h>
35 #include <err.h>
36
37 char localname[1024];
38 static size_t lname_size = sizeof (localname);
39 static int lname_size_arg = 0;
40 static int simple_flag = 0;
41 static int verbose_flag = 0;
42 static int version_flag = 0;
43 static int help_flag    = 0;
44
45 static struct getargs args[] = {
46     {"lname-size",      0,      arg_integer,    &lname_size_arg,
47      "set localname size (0 means use default, must be 0..1023)", "integer" },
48     {"simple",  0,      arg_flag,       &simple_flag, /* Used for scripting */
49      "map the given principal and print the resulting localname", NULL },
50     {"verbose", 0,      arg_flag,       &verbose_flag,
51      "print the actual principal name as well as the localname", NULL },
52     {"version", 0,      arg_flag,       &version_flag,
53      "print version", NULL },
54     {"help",    0,      arg_flag,       &help_flag,
55      NULL, NULL }
56 };
57
58 static void
59 test_alname(krb5_context context, krb5_const_realm realm,
60             const char *user, const char *inst,
61             const char *localuser, int ok)
62 {
63     krb5_principal p;
64     krb5_error_code ret;
65     char *princ;
66
67     ret = krb5_make_principal(context, &p, realm, user, inst, NULL);
68     if (ret)
69         krb5_err(context, 1, ret, "krb5_build_principal");
70
71     ret = krb5_unparse_name(context, p, &princ);
72     if (ret)
73         krb5_err(context, 1, ret, "krb5_unparse_name");
74
75     ret = krb5_aname_to_localname(context, p, lname_size, localname);
76     krb5_free_principal(context, p);
77     if (ret) {
78         if (!ok) {
79             free(princ);
80             return;
81         }
82         krb5_err(context, 1, ret, "krb5_aname_to_localname: %s -> %s",
83                  princ, localuser);
84         free(princ);
85     }
86
87     if (strcmp(localname, localuser) != 0) {
88         if (ok)
89             errx(1, "compared failed %s != %s (should have succeded)",
90                  localname, localuser);
91     } else {
92         if (!ok)
93             errx(1, "compared failed %s == %s (should have failed)",
94                  localname, localuser);
95     }
96
97 }
98
99 static void
100 usage (int ret)
101 {
102     arg_printusage (args,
103                     sizeof(args)/sizeof(*args),
104                     NULL,
105                     "");
106     exit (ret);
107 }
108
109 int
110 main(int argc, char **argv)
111 {
112     krb5_context context;
113     krb5_error_code ret;
114     krb5_realm realm;
115     int optidx = 0;
116     char *user;
117
118     setprogname(argv[0]);
119
120     if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
121         usage(1);
122
123     if (help_flag)
124         usage (0);
125
126     if(version_flag){
127         print_version(NULL);
128         exit(0);
129     }
130
131     argc -= optidx;
132     argv += optidx;
133
134     ret = krb5_init_context(&context);
135     if (ret)
136         errx (1, "krb5_init_context failed: %d", ret);
137
138     if (simple_flag) {
139         krb5_principal princ;
140         char *unparsed;
141         int status = 0;
142
143         /* Map then print the result and exit */
144         if (argc != 1)
145             errx(1, "One argument is required and it must be a principal name");
146
147         ret = krb5_parse_name(context, argv[0], &princ);
148         if (ret)
149             krb5_err(context, 1, ret, "krb5_build_principal");
150
151         ret = krb5_unparse_name(context, princ, &unparsed);
152         if (ret)
153             krb5_err(context, 1, ret, "krb5_unparse_name");
154
155         if (lname_size_arg > 0 && lname_size_arg < 1024)
156             lname_size = lname_size_arg;
157         else if (lname_size_arg != 0)
158             errx(1, "local name size must be between 0 and 1023 (inclusive)");
159
160         ret = krb5_aname_to_localname(context, princ, lname_size, localname);
161         if (ret == KRB5_NO_LOCALNAME) {
162             if (verbose_flag)
163                 fprintf(stderr, "No mapping obtained for %s\n", unparsed);
164             exit(1);
165         }
166         switch (ret) {
167         case KRB5_PLUGIN_NO_HANDLE:
168             fprintf(stderr, "Error: KRB5_PLUGIN_NO_HANDLE leaked!\n");
169             status = 2;
170             break;
171         case KRB5_CONFIG_NOTENUFSPACE:
172             fprintf(stderr, "Error: lname-size (%lu) too small\n",
173                     (long unsigned)lname_size);
174             status = 3;
175             break;
176         case 0:
177             if (verbose_flag)
178                 printf("%s ", unparsed);
179             printf("%s\n", localname);
180             break;
181         default:
182             krb5_err(context, 4, ret, "krb5_aname_to_localname");
183             break;
184         }
185         free(unparsed);
186         krb5_free_principal(context, princ);
187         krb5_free_context(context);
188         exit(status);
189     }
190
191     if (argc != 1)
192         errx(1, "first argument should be a local user that is in root .k5login");
193
194     user = argv[0];
195
196     ret = krb5_get_default_realm(context, &realm);
197     if (ret)
198         krb5_err(context, 1, ret, "krb5_get_default_realm");
199
200     test_alname(context, realm, user, NULL, user, 1);
201     test_alname(context, realm, user, "root", "root", 1);
202
203     test_alname(context, "FOO.BAR.BAZ.KAKA", user, NULL, user, 0);
204     test_alname(context, "FOO.BAR.BAZ.KAKA", user, "root", "root", 0);
205
206     test_alname(context, realm, user, NULL,
207                 "not-same-as-user", 0);
208     test_alname(context, realm, user, "root",
209                 "not-same-as-user", 0);
210
211     test_alname(context, "FOO.BAR.BAZ.KAKA", user, NULL,
212                 "not-same-as-user", 0);
213     test_alname(context, "FOO.BAR.BAZ.KAKA", user, "root",
214                 "not-same-as-user", 0);
215
216     krb5_free_context(context);
217
218     return 0;
219 }