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