static krb5_error_code principals_from_list(TALLOC_CTX *parent_ctx, const char *samAccountName, const char *realm, const char **SPNs, int num_SPNs, krb5_context context, krb5_principal **principals_out, const char **error_string) { unsigned int i; krb5_error_code ret; char *upper_realm; TALLOC_CTX *tmp_ctx; krb5_principal *principals = NULL; tmp_ctx = talloc_new(parent_ctx); if (!tmp_ctx) { *error_string = "Cannot allocate tmp_ctx"; return ENOMEM; } if (!realm) { *error_string = "Cannot make principal without a realm"; ret = EINVAL; goto done; } upper_realm = strupper_talloc(tmp_ctx, realm); if (!upper_realm) { *error_string = "Cannot allocate full upper case realm"; ret = ENOMEM; goto done; } principals = talloc_zero_array(tmp_ctx, krb5_principal, num_SPNs ? (num_SPNs + 2) : 2); for (i = 0; num_SPNs && i < num_SPNs; i++) { ret = krb5_parse_name(context, SPNs[i], &principals[i]); if (ret) { *error_string = smb_get_krb5_error_message(context, ret, parent_ctx); goto done; } } if (samAccountName) { ret = smb_krb5_make_principal(context, &principals[i], upper_realm, samAccountName, NULL); if (ret) { *error_string = smb_get_krb5_error_message(context, ret, parent_ctx); goto done; } } done: if (ret) { keytab_principals_free(context, principals); } else { *principals_out = talloc_steal(parent_ctx, principals); } talloc_free(tmp_ctx); return ret; }
krb5_error_code smb_krb5_create_principals_array(TALLOC_CTX *mem_ctx, krb5_context context, const char *account_name, const char *realm, uint32_t num_spns, const char *spns[], uint32_t *pnum_principals, krb5_principal **pprincipals, const char **error_string) { krb5_error_code code; TALLOC_CTX *tmp_ctx; uint32_t num_principals = 0; krb5_principal *principals; uint32_t i; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { *error_string = "Cannot allocate tmp_ctx"; return ENOMEM; } if (realm == NULL) { *error_string = "Cannot create principal without a realm"; code = EINVAL; goto done; } if (account_name == NULL && (num_spns == 0 || spns == NULL)) { *error_string = "Cannot create principal without an account or SPN"; code = EINVAL; goto done; } if (account_name != NULL && account_name[0] != '\0') { num_principals++; } num_principals += num_spns; principals = talloc_zero_array(tmp_ctx, krb5_principal, num_principals); if (principals == NULL) { *error_string = "Cannot allocate principals"; code = ENOMEM; goto done; } for (i = 0; i < num_spns; i++) { code = krb5_parse_name(context, spns[i], &(principals[i])); if (code != 0) { *error_string = smb_get_krb5_error_message(context, code, mem_ctx); goto done; } } if (account_name != NULL && account_name[0] != '\0') { code = smb_krb5_make_principal(context, &(principals[i]), realm, account_name, NULL); if (code != 0) { *error_string = smb_get_krb5_error_message(context, code, mem_ctx); goto done; } } if (pnum_principals != NULL) { *pnum_principals = num_principals; if (pprincipals != NULL) { *pprincipals = talloc_steal(mem_ctx, principals); } } code = 0; done: talloc_free(tmp_ctx); return code; }
static krb5_error_code salt_principal(TALLOC_CTX *parent_ctx, const char *samAccountName, const char *realm, const char *saltPrincipal, krb5_context context, krb5_principal *salt_princ, const char **error_string) { krb5_error_code ret; char *machine_username; char *salt_body; char *lower_realm; char *upper_realm; TALLOC_CTX *tmp_ctx; if (saltPrincipal) { ret = krb5_parse_name(context, saltPrincipal, salt_princ); if (ret) { *error_string = smb_get_krb5_error_message( context, ret, parent_ctx); } return ret; } if (!samAccountName) { (*error_string) = "Cannot determine salt principal, no " "saltPrincipal or samAccountName specified"; return EINVAL; } if (!realm) { *error_string = "Cannot make principal without a realm"; return EINVAL; } tmp_ctx = talloc_new(parent_ctx); if (!tmp_ctx) { *error_string = "Cannot allocate tmp_ctx"; return ENOMEM; } machine_username = talloc_strdup(tmp_ctx, samAccountName); if (!machine_username) { *error_string = "Cannot duplicate samAccountName"; talloc_free(tmp_ctx); return ENOMEM; } if (machine_username[strlen(machine_username)-1] == '$') { machine_username[strlen(machine_username)-1] = '\0'; } lower_realm = strlower_talloc(tmp_ctx, realm); if (!lower_realm) { *error_string = "Cannot allocate to lower case realm"; talloc_free(tmp_ctx); return ENOMEM; } upper_realm = strupper_talloc(tmp_ctx, realm); if (!upper_realm) { *error_string = "Cannot allocate to upper case realm"; talloc_free(tmp_ctx); return ENOMEM; } salt_body = talloc_asprintf(tmp_ctx, "%s.%s", machine_username, lower_realm); if (!salt_body) { *error_string = "Cannot form salt principal body"; talloc_free(tmp_ctx); return ENOMEM; } ret = smb_krb5_make_principal(context, salt_princ, upper_realm, "host", salt_body, NULL); if (ret) { *error_string = smb_get_krb5_error_message(context, ret, parent_ctx); } talloc_free(tmp_ctx); return ret; }