Imported Upstream version 1.10.2
[platform/upstream/krb5.git] / src / lib / krb5 / krb / bld_princ.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/bld_princ.c - Build a principal from a list of strings */
3 /*
4  * Copyright 1991 by the Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  *
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  Furthermore if you modify this software you must label
20  * your software as modified software and not distribute it in such a
21  * fashion that it might be confused with the original M.I.T. software.
22  * M.I.T. makes no representations about the suitability of
23  * this software for any purpose.  It is provided "as is" without express
24  * or implied warranty.
25  */
26
27 #include <stdarg.h>
28 #include "k5-int.h"
29
30 /* Takes first component as argument for KIM API,
31  * which does not allow realms with zero components */
32 static krb5_error_code
33 krb5int_build_principal_va(krb5_context context,
34                            krb5_principal princ,
35                            unsigned int rlen,
36                            const char *realm,
37                            const char *first,
38                            va_list ap)
39 {
40     krb5_error_code retval = 0;
41     char *r = NULL;
42     krb5_data *data = NULL;
43     krb5_int32 count = 0;
44     krb5_int32 size = 2;  /* initial guess at needed space */
45     char *component = NULL;
46
47     data = malloc(size * sizeof(krb5_data));
48     if (!data) { retval = ENOMEM; }
49
50     if (!retval) {
51         r = strdup(realm);
52         if (!r) { retval = ENOMEM; }
53     }
54
55     if (!retval && first) {
56         data[0].length = strlen(first);
57         data[0].data = strdup(first);
58         if (!data[0].data) { retval = ENOMEM; }
59         count++;
60
61         /* ap is only valid if first is non-NULL */
62         while (!retval && (component = va_arg(ap, char *))) {
63             if (count == size) {
64                 krb5_data *new_data = NULL;
65
66                 size *= 2;
67                 new_data = realloc ((char *) data, sizeof(krb5_data) * size);
68                 if (new_data) {
69                     data = new_data;
70                 } else {
71                     retval = ENOMEM;
72                 }
73             }
74
75             if (!retval) {
76                 data[count].length = strlen(component);
77                 data[count].data = strdup(component);
78                 if (!data[count].data) { retval = ENOMEM; }
79                 count++;
80             }
81         }
82     }
83
84     if (!retval) {
85         princ->type = KRB5_NT_UNKNOWN;
86         princ->magic = KV5M_PRINCIPAL;
87         krb5_princ_set_realm_data(context, princ, r);
88         krb5_princ_set_realm_length(context, princ, rlen);
89         princ->data = data;
90         princ->length = count;
91         r = NULL;    /* take ownership */
92         data = NULL; /* take ownership */
93     }
94
95     if (data) {
96         while (--count >= 0) {
97             free(data[count].data);
98         }
99         free(data);
100     }
101     free(r);
102
103     return retval;
104 }
105
106 krb5_error_code KRB5_CALLCONV
107 krb5_build_principal_va(krb5_context context,
108                         krb5_principal princ,
109                         unsigned int rlen,
110                         const char *realm,
111                         va_list ap)
112 {
113     char *first = va_arg(ap, char *);
114
115     return krb5int_build_principal_va(context, princ, rlen, realm, first, ap);
116 }
117
118 /* Takes first component as argument for KIM API,
119  * which does not allow realms with zero components */
120 krb5_error_code KRB5_CALLCONV
121 krb5int_build_principal_alloc_va(krb5_context context,
122                                  krb5_principal *princ,
123                                  unsigned int rlen,
124                                  const char *realm,
125                                  const char *first,
126                                  va_list ap)
127 {
128     krb5_error_code retval = 0;
129
130     krb5_principal p = malloc(sizeof(krb5_principal_data));
131     if (!p) { retval = ENOMEM; }
132
133     if (!retval) {
134         retval = krb5int_build_principal_va(context, p, rlen, realm, first, ap);
135     }
136
137     if (!retval) {
138         *princ = p;
139     } else {
140         free(p);
141     }
142
143     return retval;
144 }
145
146 krb5_error_code KRB5_CALLCONV
147 krb5_build_principal_alloc_va(krb5_context context,
148                               krb5_principal *princ,
149                               unsigned int rlen,
150                               const char *realm,
151                               va_list ap)
152 {
153     krb5_error_code retval = 0;
154     krb5_principal p;
155     char *first;
156
157     p = malloc(sizeof(krb5_principal_data));
158     if (p == NULL)
159         return ENOMEM;
160
161     first = va_arg(ap, char *);
162     retval = krb5int_build_principal_va(context, p, rlen, realm, first, ap);
163     if (retval) {
164         free(p);
165         return retval;
166     }
167
168     *princ = p;
169     return 0;
170 }
171
172 krb5_error_code KRB5_CALLCONV_C
173 krb5_build_principal(krb5_context context,
174                      krb5_principal * princ,
175                      unsigned int rlen,
176                      const char * realm, ...)
177 {
178     krb5_error_code retval = 0;
179     va_list ap;
180
181     va_start(ap, realm);
182     retval = krb5_build_principal_alloc_va(context, princ, rlen, realm, ap);
183     va_end(ap);
184
185     return retval;
186 }
187
188 /*Anonymous and well known principals*/
189 static const char anon_realm_str[] = KRB5_ANONYMOUS_REALMSTR;
190 static const krb5_data anon_realm_data = {
191     KV5M_DATA, sizeof(anon_realm_str) - 1, (char *) anon_realm_str
192 };
193 static const char wellknown_str[] = KRB5_WELLKNOWN_NAMESTR;
194 static const char anon_str[] = KRB5_ANONYMOUS_PRINCSTR;
195 static const krb5_data anon_princ_data[] = {
196     { KV5M_DATA, sizeof(wellknown_str) - 1, (char *) wellknown_str },
197     { KV5M_DATA, sizeof(anon_str) - 1, (char *) anon_str }
198 };
199
200 const krb5_principal_data anon_princ = {
201     KV5M_PRINCIPAL,
202     { KV5M_DATA, sizeof(anon_realm_str) - 1, (char *) anon_realm_str },
203     (krb5_data *) anon_princ_data, 2, KRB5_NT_WELLKNOWN
204 };
205
206 const krb5_data * KRB5_CALLCONV
207 krb5_anonymous_realm()
208 {
209     return &anon_realm_data;
210 }
211
212 krb5_const_principal KRB5_CALLCONV
213 krb5_anonymous_principal()
214 {
215     return &anon_princ;
216 }