Esempio n. 1
0
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;
}