1 /*
2 * lib/krb5/krb/bld_princ.c
3 *
4 * Copyright 1991 by the Massachusetts Institute of Technology.
5 * All Rights Reserved.
6 *
7 * Copyright 2020 Nexenta by DDN, Inc. All rights reserved.
8 *
9 * Export of this software from the United States of America may
10 * require a specific license from the United States Government.
11 * It is the responsibility of any person or organization contemplating
12 * export to obtain such a license before exporting.
13 *
14 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
15 * distribute this software and its documentation for any purpose and
16 * without fee is hereby granted, provided that the above copyright
17 * notice appear in all copies and that both that copyright notice and
18 * this permission notice appear in supporting documentation, and that
19 * the name of M.I.T. not be used in advertising or publicity pertaining
20 * to distribution of the software without specific, written prior
21 * permission. Furthermore if you modify this software you must label
22 * your software as modified software and not distribute it in such a
23 * fashion that it might be confused with the original M.I.T. software.
24 * M.I.T. makes no representations about the suitability of
25 * this software for any purpose. It is provided "as is" without express
26 * or implied warranty.
27 *
28 *
29 * Build a principal from a list of strings
30 */
31
32 #include <stdarg.h>
33 #include "k5-int.h"
34
35 /*ARGSUSED*/
36 krb5_error_code
37 KRB5_CALLCONV
krb5_build_principal_va(krb5_context context,krb5_principal princ,unsigned int rlen,const char * realm,va_list ap)38 krb5_build_principal_va(krb5_context context, krb5_principal princ, unsigned int rlen, const char *realm, va_list ap)
39 {
40 register int i, count = 0;
41 register char *next;
42 char *tmpdata;
43 krb5_data *data;
44
45 /* guess at an initial sufficent count of 2 pieces */
46 count = 2;
47
48 /* get space for array and realm, and insert realm */
49 data = (krb5_data *) malloc(sizeof(krb5_data) * count);
50 if (data == 0)
51 return ENOMEM;
52 krb5_princ_set_realm_length(context, princ, rlen);
53 tmpdata = malloc(rlen + 1);
54 if (!tmpdata) {
55 free (data);
56 return ENOMEM;
57 }
58 krb5_princ_set_realm_data(context, princ, tmpdata);
59 memcpy(tmpdata, realm, rlen);
60 tmpdata[rlen] = '\0';
61
62 /* process rest of components */
63
64 for (i = 0, next = va_arg(ap, char *);
65 next;
66 next = va_arg(ap, char *), i++) {
67 if (i == count) {
68 /* not big enough. realloc the array */
69 krb5_data *p_tmp;
70 p_tmp = (krb5_data *) realloc((char *)data,
71 sizeof(krb5_data)*(count*2));
72 if (!p_tmp) {
73 free_out:
74 while (--i >= 0)
75 krb5_xfree(data[i].data);
76 krb5_xfree(data);
77 krb5_xfree(tmpdata);
78 return (ENOMEM);
79 }
80 count *= 2;
81 data = p_tmp;
82 }
83
84 data[i].length = strlen(next);
85 data[i].data = strdup(next);
86 if (!data[i].data)
87 goto free_out;
88 }
89 princ->data = data;
90 princ->length = i;
91 princ->type = KRB5_NT_UNKNOWN;
92 princ->magic = KV5M_PRINCIPAL;
93 return 0;
94 }
95
96 krb5_error_code KRB5_CALLCONV_C
krb5_build_principal(krb5_context context,krb5_principal * princ,unsigned int rlen,const char * realm,...)97 krb5_build_principal(krb5_context context, krb5_principal * princ,
98 unsigned int rlen,
99 const char * realm, ...)
100 {
101 va_list ap;
102 krb5_error_code retval;
103 krb5_principal pr_ret = (krb5_principal)malloc(sizeof(krb5_principal_data));
104
105 if (!pr_ret)
106 return ENOMEM;
107
108 va_start(ap, realm);
109 retval = krb5_build_principal_va(context, pr_ret, rlen, realm, ap);
110 va_end(ap);
111 if (retval == 0)
112 *princ = pr_ret;
113 return retval;
114 }
115