static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, const char *name, struct drsuapi_DsNameInfo1 *info1) { WERROR wret; krb5_error_code ret; krb5_principal principal; const char *service, *dns_name; char *new_service; char *new_princ; enum drsuapi_DsNameStatus namestatus; /* parse principal */ ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name, KRB5_PRINCIPAL_PARSE_NO_REALM, &principal); if (ret) { DEBUG(2, ("Could not parse principal: %s: %s", name, smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx))); return WERR_NOMEM; } /* grab cifs/, http/ etc */ /* This is checked for in callers, but be safe */ if (principal->name.name_string.len < 2) { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; return WERR_OK; } service = principal->name.name_string.val[0]; dns_name = principal->name.name_string.val[1]; /* MAP it */ namestatus = LDB_lookup_spn_alias(smb_krb5_context->krb5_context, sam_ctx, mem_ctx, service, &new_service); if (namestatus == DRSUAPI_DS_NAME_STATUS_NOT_FOUND) { info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY; info1->dns_domain_name = talloc_strdup(mem_ctx, dns_name); if (!info1->dns_domain_name) { krb5_free_principal(smb_krb5_context->krb5_context, principal); return WERR_NOMEM; } return WERR_OK; } else if (namestatus != DRSUAPI_DS_NAME_STATUS_OK) { info1->status = namestatus; krb5_free_principal(smb_krb5_context->krb5_context, principal); return WERR_OK; } /* ooh, very nasty playing around in the Principal... */ free(principal->name.name_string.val[0]); principal->name.name_string.val[0] = strdup(new_service); if (!principal->name.name_string.val[0]) { krb5_free_principal(smb_krb5_context->krb5_context, principal); return WERR_NOMEM; } /* reform principal */ ret = krb5_unparse_name_flags(smb_krb5_context->krb5_context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &new_princ); if (ret) { krb5_free_principal(smb_krb5_context->krb5_context, principal); return WERR_NOMEM; } wret = DsCrackNameOneName(sam_ctx, mem_ctx, format_flags, format_offered, format_desired, new_princ, info1); free(new_princ); if (W_ERROR_IS_OK(wret) && (info1->status == DRSUAPI_DS_NAME_STATUS_NOT_FOUND)) { info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY; info1->dns_domain_name = talloc_strdup(mem_ctx, dns_name); if (!info1->dns_domain_name) { wret = WERR_NOMEM; } } krb5_free_principal(smb_krb5_context->krb5_context, principal); return wret; }
static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, uint32_t format_flags, enum drsuapi_DsNameFormat format_offered, enum drsuapi_DsNameFormat format_desired, const char *name, struct drsuapi_DsNameInfo1 *info1) { WERROR wret; krb5_error_code ret; krb5_principal principal; const krb5_data *component; const char *service, *dns_name; char *new_service; char *new_princ; enum drsuapi_DsNameStatus namestatus; /* parse principal */ ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name, KRB5_PRINCIPAL_PARSE_NO_REALM, &principal); if (ret) { DEBUG(2, ("Could not parse principal: %s: %s\n", name, smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx))); return WERR_NOMEM; } /* grab cifs/, http/ etc */ /* This is checked for in callers, but be safe */ if (krb5_princ_size(smb_krb5_context->krb5_context, principal) < 2) { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; krb5_free_principal(smb_krb5_context->krb5_context, principal); return WERR_OK; } component = krb5_princ_component(smb_krb5_context->krb5_context, principal, 0); service = (const char *)component->data; component = krb5_princ_component(smb_krb5_context->krb5_context, principal, 1); dns_name = (const char *)component->data; /* MAP it */ namestatus = LDB_lookup_spn_alias(smb_krb5_context->krb5_context, sam_ctx, mem_ctx, service, &new_service); if (namestatus == DRSUAPI_DS_NAME_STATUS_NOT_FOUND) { wret = WERR_OK; info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY; info1->dns_domain_name = talloc_strdup(mem_ctx, dns_name); if (!info1->dns_domain_name) { wret = WERR_NOMEM; } krb5_free_principal(smb_krb5_context->krb5_context, principal); return wret; } else if (namestatus != DRSUAPI_DS_NAME_STATUS_OK) { info1->status = namestatus; krb5_free_principal(smb_krb5_context->krb5_context, principal); return WERR_OK; } /* reform principal */ new_princ = talloc_asprintf(mem_ctx, "%s/%s", new_service, dns_name); if (!new_princ) { krb5_free_principal(smb_krb5_context->krb5_context, principal); return WERR_NOMEM; } wret = DsCrackNameOneName(sam_ctx, mem_ctx, format_flags, format_offered, format_desired, new_princ, info1); talloc_free(new_princ); if (W_ERROR_IS_OK(wret) && (info1->status == DRSUAPI_DS_NAME_STATUS_NOT_FOUND)) { info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY; info1->dns_domain_name = talloc_strdup(mem_ctx, dns_name); if (!info1->dns_domain_name) { wret = WERR_NOMEM; } } krb5_free_principal(smb_krb5_context->krb5_context, principal); return wret; }