- principals = talloc_array(tmp_ctx, struct principal_container *, spn_el ? (spn_el->num_values + 2) : 2);
-
- spn_el = ldb_msg_find_element(msg, "servicePrincipalName");
- for (i=0; spn_el && i < spn_el->num_values; i++) {
- principals[i] = talloc(principals, struct principal_container);
- if (!principals[i]) {
- talloc_free(tmp_ctx);
- *error_string = "Cannot allocate mem_ctx";
- return ENOMEM;
- }
-
- principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context);
- principals[i]->string_form = talloc_asprintf(principals[i], "%*.*s@%s",
- (int)spn_el->values[i].length,
- (int)spn_el->values[i].length,
- (const char *)spn_el->values[i].data, upper_realm);
- if (!principals[i]->string_form) {
- talloc_free(tmp_ctx);
- *error_string = "Cannot allocate full samAccountName";
- return ENOMEM;
- }
-
- ret = krb5_parse_name(smb_krb5_context->krb5_context,
- principals[i]->string_form, &principals[i]->principal);
-
- if (ret) {
- talloc_free(tmp_ctx);
- (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
- return ret;
- }
-
- /* This song-and-dance effectivly puts the principal
- * into talloc, so we can't loose it. */
- talloc_set_destructor(principals[i], free_principal);
- }
-
- if (samAccountName) {
- principals[i] = talloc(principals, struct principal_container);
- if (!principals[i]) {
- talloc_free(tmp_ctx);
- *error_string = "Cannot allocate mem_ctx";
- return ENOMEM;
- }
-
- principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context);
- principals[i]->string_form = talloc_asprintf(parent_ctx, "%s@%s", samAccountName, upper_realm);
- if (!principals[i]->string_form) {
- talloc_free(tmp_ctx);
- *error_string = "Cannot allocate full samAccountName";
- return ENOMEM;
- }
-
- ret = krb5_make_principal(smb_krb5_context->krb5_context, &principals[i]->principal, upper_realm, samAccountName,
- NULL);
- if (ret) {
- talloc_free(tmp_ctx);
- (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
- return ret;
- }
-
- /* This song-and-dance effectivly puts the principal
- * into talloc, so we can't loose it. */
- talloc_set_destructor(principals[i], free_principal);
- i++;
- }
-
- principals[i] = NULL;
- *principals_out = talloc_steal(parent_ctx, principals);
-
- talloc_free(tmp_ctx);
- return ret;
-}
-
-static krb5_error_code salt_principal_from_msg(TALLOC_CTX *parent_ctx,
- struct ldb_message *msg,
- struct smb_krb5_context *smb_krb5_context,
- krb5_principal *salt_princ,
- const char **error_string)
-{
- const char *salt_principal = ldb_msg_find_attr_as_string(msg, "saltPrincipal", NULL);
- const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
- const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);
- if (salt_principal) {
- return parse_principal(parent_ctx, salt_principal, smb_krb5_context, salt_princ, error_string);
- } else if (samAccountName) {
- krb5_error_code ret;
- char *machine_username;
- char *salt_body;
- char *lower_realm;
- char *upper_realm;
-
- TALLOC_CTX *tmp_ctx;
- struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container);
- if (!mem_ctx) {
- *error_string = "Cannot allocate mem_ctx";
- return ENOMEM;
- }
-
- tmp_ctx = talloc_new(mem_ctx);
- if (!tmp_ctx) {
- talloc_free(mem_ctx);
- *error_string = "Cannot allocate tmp_ctx";
- return ENOMEM;
- }
-
- if (!realm) {
- *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm";
- return EINVAL;
- }
-
- machine_username = talloc_strdup(tmp_ctx, samAccountName);
- if (!machine_username) {
- talloc_free(mem_ctx);
- *error_string = "Cannot duplicate samAccountName";
- return ENOMEM;
- }
-
- if (machine_username[strlen(machine_username)-1] == '$') {
- machine_username[strlen(machine_username)-1] = '\0';
- }