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 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 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