コード例 #1
0
ファイル: pydsdb.c プロジェクト: 285858315/samba
static PyObject *py_dsdb_get_partitions_dn(PyObject *self, PyObject *args)
{
	struct ldb_context *ldb;
	struct ldb_dn *dn;
	PyObject *py_ldb, *ret;

	if (!PyArg_ParseTuple(args, "O", &py_ldb))
		return NULL;

	PyErr_LDB_OR_RAISE(py_ldb, ldb);

	dn = samdb_partitions_dn(ldb, NULL);
	if (dn == NULL) {
		PyErr_NoMemory();
		return NULL;
	}
	ret = pyldb_Dn_FromDn(dn);
	talloc_free(dn);
	return ret;
}
コード例 #2
0
ファイル: netlogon.c プロジェクト: Marvin-Lee/libwmiclient
/*
  fill in the cldap netlogon union for a given version
*/
static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd,
				     TALLOC_CTX *mem_ctx,
				     const char *domain,
				     const char *domain_guid,
				     const char *user,
				     const char *src_address,
				     uint32_t version,
				     union nbt_cldap_netlogon *netlogon)
{
	const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL};
	const char *dom_attrs[] = {"objectGUID", NULL};
	struct ldb_message **ref_res, **dom_res;
	int ret, count = 0;
	const char **services = lp_server_services();
	uint32_t server_type;
	const char *pdc_name;
	struct GUID domain_uuid;
	const char *realm;
	const char *dns_domain;
	const char *pdc_dns_name;
	const char *flatname;
	const char *server_site;
	const char *client_site;
	const char *pdc_ip;
	struct ldb_dn *partitions_basedn;

	partitions_basedn = samdb_partitions_dn(cldapd->samctx, mem_ctx);

	/* the domain has an optional trailing . */
	if (domain && domain[strlen(domain)-1] == '.') {
		domain = talloc_strndup(mem_ctx, domain, strlen(domain)-1);
	}

	if (domain) {
		struct ldb_result *dom_ldb_result;
		struct ldb_dn *dom_dn;
		/* try and find the domain */
		count = gendb_search(cldapd->samctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs, 
				   "(&(&(objectClass=crossRef)(dnsRoot=%s))(nETBIOSName=*))", 
				   domain);
		if (count == 1) {
			dom_dn = samdb_result_dn(cldapd->samctx, mem_ctx, ref_res[0], "ncName", NULL);
			if (!dom_dn) {
				return NT_STATUS_NO_SUCH_DOMAIN;
			}
			ret = ldb_search(cldapd->samctx, dom_dn,
					 LDB_SCOPE_BASE, "objectClass=domain", 
					 dom_attrs, &dom_ldb_result);
			if (ret != LDB_SUCCESS) {
				DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(dom_dn), ldb_errstring(cldapd->samctx)));
				return NT_STATUS_NO_SUCH_DOMAIN;
			}
			talloc_steal(mem_ctx, dom_ldb_result);
			if (dom_ldb_result->count != 1) {
				DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(dom_dn)));
				return NT_STATUS_NO_SUCH_DOMAIN;
			}
			dom_res = dom_ldb_result->msgs;
		}
	}

	if (count == 0 && domain_guid) {
		/* OK, so no dice with the name, try and find the domain with the GUID */
		count = gendb_search(cldapd->samctx, mem_ctx, NULL, &dom_res, dom_attrs, 
				   "(&(objectClass=domainDNS)(objectGUID=%s))", 
				   domain_guid);
		if (count == 1) {
			/* try and find the domain */
			ret = gendb_search(cldapd->samctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs, 
					   "(&(objectClass=crossRef)(ncName=%s))", 
					   ldb_dn_get_linearized(dom_res[0]->dn));
			if (ret != 1) {
				DEBUG(2,("Unable to find referece to '%s' in sam\n",
					 ldb_dn_get_linearized(dom_res[0]->dn)));
				return NT_STATUS_NO_SUCH_DOMAIN;
			}
		}
	}

	if (count == 0) {
		DEBUG(2,("Unable to find domain with name %s or GUID {%s}\n", domain, domain_guid));
		return NT_STATUS_NO_SUCH_DOMAIN;
	}

	server_type      = 
		NBT_SERVER_PDC | NBT_SERVER_GC | 
		NBT_SERVER_DS | NBT_SERVER_TIMESERV |
		NBT_SERVER_CLOSEST | NBT_SERVER_WRITABLE | 
		NBT_SERVER_GOOD_TIMESERV;

	if (str_list_check(services, "ldap")) {
		server_type |= NBT_SERVER_LDAP;
	}

	if (str_list_check(services, "kdc")) {
		server_type |= NBT_SERVER_KDC;
	}

	pdc_name         = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
	domain_uuid      = samdb_result_guid(dom_res[0], "objectGUID");
	realm            = samdb_result_string(ref_res[0], "dnsRoot", lp_realm());
	dns_domain       = samdb_result_string(ref_res[0], "dnsRoot", lp_realm());
	pdc_dns_name     = talloc_asprintf(mem_ctx, "%s.%s", 
					   strlower_talloc(mem_ctx, lp_netbios_name()), 
					   dns_domain);

	flatname         = samdb_result_string(ref_res[0], "nETBIOSName", lp_workgroup());
	server_site      = "Default-First-Site-Name";
	client_site      = "Default-First-Site-Name";
	pdc_ip           = iface_best_ip(src_address);

	ZERO_STRUCTP(netlogon);

	switch (version & 0xF) {
	case 0:
	case 1:
		netlogon->logon1.type        = (user?19+2:19);
		netlogon->logon1.pdc_name    = pdc_name;
		netlogon->logon1.user_name   = user;
		netlogon->logon1.domain_name = flatname;
		netlogon->logon1.nt_version  = 1;
		netlogon->logon1.lmnt_token  = 0xFFFF;
		netlogon->logon1.lm20_token  = 0xFFFF;
		break;
	case 2:
	case 3:
		netlogon->logon3.type         = (user?19+2:19);
		netlogon->logon3.pdc_name     = pdc_name;
		netlogon->logon3.user_name    = user;
		netlogon->logon3.domain_name  = flatname;
		netlogon->logon3.domain_uuid  = domain_uuid;
		netlogon->logon3.forest       = realm;
		netlogon->logon3.dns_domain   = dns_domain;
		netlogon->logon3.pdc_dns_name = pdc_dns_name;
		netlogon->logon3.pdc_ip       = pdc_ip;
		netlogon->logon3.server_type  = server_type;
		netlogon->logon3.lmnt_token   = 0xFFFF;
		netlogon->logon3.lm20_token   = 0xFFFF;
		break;
	case 4:
	case 5:
	case 6:
	case 7:
		netlogon->logon5.type         = (user?23+2:23);
		netlogon->logon5.server_type  = server_type;
		netlogon->logon5.domain_uuid  = domain_uuid;
		netlogon->logon5.forest       = realm;
		netlogon->logon5.dns_domain   = dns_domain;
		netlogon->logon5.pdc_dns_name = pdc_dns_name;
		netlogon->logon5.domain       = flatname;
		netlogon->logon5.pdc_name     = lp_netbios_name();
		netlogon->logon5.user_name    = user;
		netlogon->logon5.server_site  = server_site;
		netlogon->logon5.client_site  = client_site;
		netlogon->logon5.lmnt_token   = 0xFFFF;
		netlogon->logon5.lm20_token   = 0xFFFF;
		break;
	default:
		netlogon->logon13.type         = (user?23+2:23);
		netlogon->logon13.server_type  = server_type;
		netlogon->logon13.domain_uuid  = domain_uuid;
		netlogon->logon13.forest       = realm;
		netlogon->logon13.dns_domain   = dns_domain;
		netlogon->logon13.pdc_dns_name = pdc_dns_name;
		netlogon->logon13.domain       = flatname;
		netlogon->logon13.pdc_name     = lp_netbios_name();
		netlogon->logon13.user_name    = user;
		netlogon->logon13.server_site  = server_site;
		netlogon->logon13.client_site  = client_site;
		netlogon->logon13.unknown      = 10;
		netlogon->logon13.unknown2     = 2;
		netlogon->logon13.pdc_ip       = pdc_ip;
		netlogon->logon13.lmnt_token   = 0xFFFF;
		netlogon->logon13.lm20_token   = 0xFFFF;
		break;
	}

	return NT_STATUS_OK;
}
コード例 #3
0
ファイル: cracknames.c プロジェクト: endisd/samba
static WERROR DsCrackNameOneFilter(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,
                                   struct ldb_dn *name_dn, const char *name,
                                   const char *domain_filter, const char *result_filter,
                                   struct drsuapi_DsNameInfo1 *info1)
{
    int ldb_ret;
    struct ldb_result *domain_res = NULL;
    const char * const *domain_attrs;
    const char * const *result_attrs;
    struct ldb_message **result_res = NULL;
    struct ldb_message *result = NULL;
    struct ldb_dn *result_basedn = NULL;
    int i;
    char *p;
    struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);

    const char * const _domain_attrs_1779[] = { "ncName", "dnsRoot", NULL};
    const char * const _result_attrs_null[] = { NULL };

    const char * const _domain_attrs_canonical[] = { "ncName", "dnsRoot", NULL};
    const char * const _result_attrs_canonical[] = { "canonicalName", NULL };

    const char * const _domain_attrs_nt4[] = { "ncName", "dnsRoot", "nETBIOSName", NULL};
    const char * const _result_attrs_nt4[] = { "sAMAccountName", "objectSid", "objectClass", NULL};

    const char * const _domain_attrs_guid[] = { "ncName", "dnsRoot", NULL};
    const char * const _result_attrs_guid[] = { "objectGUID", NULL};

    const char * const _domain_attrs_display[] = { "ncName", "dnsRoot", NULL};
    const char * const _result_attrs_display[] = { "displayName", "samAccountName", NULL};

    const char * const _domain_attrs_none[] = { "ncName", "dnsRoot" , NULL};
    const char * const _result_attrs_none[] = { NULL};

    /* here we need to set the attrs lists for domain and result lookups */
    switch (format_desired) {
    case DRSUAPI_DS_NAME_FORMAT_FQDN_1779:
    case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX:
        domain_attrs = _domain_attrs_1779;
        result_attrs = _result_attrs_null;
        break;
    case DRSUAPI_DS_NAME_FORMAT_CANONICAL:
        domain_attrs = _domain_attrs_canonical;
        result_attrs = _result_attrs_canonical;
        break;
    case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT:
        domain_attrs = _domain_attrs_nt4;
        result_attrs = _result_attrs_nt4;
        break;
    case DRSUAPI_DS_NAME_FORMAT_GUID:
        domain_attrs = _domain_attrs_guid;
        result_attrs = _result_attrs_guid;
        break;
    case DRSUAPI_DS_NAME_FORMAT_DISPLAY:
        domain_attrs = _domain_attrs_display;
        result_attrs = _result_attrs_display;
        break;
    default:
        domain_attrs = _domain_attrs_none;
        result_attrs = _result_attrs_none;
        break;
    }

    if (domain_filter) {
        /* if we have a domain_filter look it up and set the result_basedn and the dns_domain_name */
        ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
                             partitions_basedn,
                             LDB_SCOPE_ONELEVEL,
                             domain_attrs,
                             "%s", domain_filter);

        if (ldb_ret != LDB_SUCCESS) {
            DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s", ldb_errstring(sam_ctx)));
            info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
            return WERR_OK;
        }

        switch (domain_res->count) {
        case 1:
            break;
        case 0:
            info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
            return WERR_OK;
        default:
            info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
            return WERR_OK;
        }

        info1->dns_domain_name	= samdb_result_string(domain_res->msgs[0], "dnsRoot", NULL);
        W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name);
        info1->status		= DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY;
    } else {
        info1->dns_domain_name	= NULL;
        info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
    }

    if (result_filter) {
        int ret;
        struct ldb_result *res;
        if (domain_res) {
            result_basedn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);

            ret = ldb_search(sam_ctx, mem_ctx, &res,
                             result_basedn, LDB_SCOPE_SUBTREE,
                             result_attrs, "%s", result_filter);
            if (ret != LDB_SUCCESS) {
                talloc_free(result_res);
                info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
                return WERR_OK;
            }
            ldb_ret = res->count;
            result_res = res->msgs;
        } else {
            /* search with the 'phantom root' flag */
            struct ldb_request *req;

            res = talloc_zero(mem_ctx, struct ldb_result);
            W_ERROR_HAVE_NO_MEMORY(res);

            ret = ldb_build_search_req(&req, sam_ctx, mem_ctx,
                                       ldb_get_root_basedn(sam_ctx),
                                       LDB_SCOPE_SUBTREE,
                                       result_filter,
                                       result_attrs,
                                       NULL,
                                       res,
                                       ldb_search_default_callback,
                                       NULL);
            if (ret == LDB_SUCCESS) {
                struct ldb_search_options_control *search_options;
                search_options = talloc(req, struct ldb_search_options_control);
                W_ERROR_HAVE_NO_MEMORY(search_options);
                search_options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT;

                ret = ldb_request_add_control(req, LDB_CONTROL_SEARCH_OPTIONS_OID, false, search_options);
            }
            if (ret != LDB_SUCCESS) {
                talloc_free(res);
                info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
                return WERR_OK;
            }

            ret = ldb_request(sam_ctx, req);

            if (ret == LDB_SUCCESS) {
                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
            }

            talloc_free(req);

            if (ret != LDB_SUCCESS) {
                DEBUG(2, ("DsCrackNameOneFilter phantom root search failed: %s",
                          ldb_errstring(sam_ctx)));
                info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
                return WERR_OK;
            }
            ldb_ret = res->count;
            result_res = res->msgs;
        }
    } else if (format_offered == DRSUAPI_DS_NAME_FORMAT_FQDN_1779) {
コード例 #4
0
ファイル: cracknames.c プロジェクト: endisd/samba
static WERROR DsCrackNameUPN(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)
{
    int ldb_ret;
    WERROR status;
    const char *domain_filter = NULL;
    const char *result_filter = NULL;
    krb5_error_code ret;
    krb5_principal principal;
    const char *realm;
    char *unparsed_name_short;
    const char *domain_attrs[] = { NULL };
    struct ldb_result *domain_res = NULL;

    /* Prevent recursion */
    if (!name) {
        info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
        return WERR_OK;
    }

    ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name,
                                KRB5_PRINCIPAL_PARSE_REQUIRE_REALM, &principal);
    if (ret) {
        info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
        return WERR_OK;
    }

    realm = krb5_principal_get_realm(smb_krb5_context->krb5_context, principal);

    ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
                         samdb_partitions_dn(sam_ctx, mem_ctx),
                         LDB_SCOPE_ONELEVEL,
                         domain_attrs,
                         "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
                         ldb_binary_encode_string(mem_ctx, realm),
                         ldb_binary_encode_string(mem_ctx, realm));

    if (ldb_ret != LDB_SUCCESS) {
        DEBUG(2, ("DsCrackNameUPN domain ref search failed: %s", ldb_errstring(sam_ctx)));
        info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
        return WERR_OK;
    }

    switch (domain_res->count) {
    case 1:
        break;
    case 0:
        return dns_domain_from_principal(mem_ctx, smb_krb5_context,
                                         name, info1);
    default:
        info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
        return WERR_OK;
    }

    ret = krb5_unparse_name_flags(smb_krb5_context->krb5_context, principal,
                                  KRB5_PRINCIPAL_UNPARSE_NO_REALM, &unparsed_name_short);
    krb5_free_principal(smb_krb5_context->krb5_context, principal);

    if (ret) {
        free(unparsed_name_short);
        return WERR_NOMEM;
    }

    /* This may need to be extended for more userPrincipalName variations */
    result_filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))",
                                    ldb_binary_encode_string(mem_ctx, unparsed_name_short));

    domain_filter = talloc_asprintf(mem_ctx, "(distinguishedName=%s)", ldb_dn_get_linearized(domain_res->msgs[0]->dn));

    if (!result_filter || !domain_filter) {
        free(unparsed_name_short);
        return WERR_NOMEM;
    }
    status = DsCrackNameOneFilter(sam_ctx, mem_ctx,
                                  smb_krb5_context,
                                  format_flags, format_offered, format_desired,
                                  NULL, unparsed_name_short, domain_filter, result_filter,
                                  info1);
    free(unparsed_name_short);

    return status;
}
コード例 #5
0
static WERROR DsCrackNameOneFilter(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,
				   struct ldb_dn *name_dn, const char *name, 
				   const char *domain_filter, const char *result_filter, 
				   struct drsuapi_DsNameInfo1 *info1,
				   int scope, struct ldb_dn *search_dn)
{
	int ldb_ret;
	struct ldb_result *domain_res = NULL;
	const char * const *domain_attrs;
	const char * const *result_attrs;
	struct ldb_message **result_res = NULL;
	struct ldb_message *result = NULL;
	int i;
	char *p;
	struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);

	const char * const _domain_attrs_1779[] = { "ncName", "dnsRoot", NULL};
	const char * const _result_attrs_null[] = { NULL };

	const char * const _domain_attrs_canonical[] = { "ncName", "dnsRoot", NULL};
	const char * const _result_attrs_canonical[] = { "canonicalName", NULL };

	const char * const _domain_attrs_nt4[] = { "ncName", "dnsRoot", "nETBIOSName", NULL};
	const char * const _result_attrs_nt4[] = { "sAMAccountName", "objectSid", "objectClass", NULL};

	const char * const _domain_attrs_guid[] = { "ncName", "dnsRoot", NULL};
	const char * const _result_attrs_guid[] = { "objectGUID", NULL};

	const char * const _domain_attrs_display[] = { "ncName", "dnsRoot", NULL};
	const char * const _result_attrs_display[] = { "displayName", "samAccountName", NULL};

	const char * const _domain_attrs_none[] = { "ncName", "dnsRoot" , NULL};
	const char * const _result_attrs_none[] = { NULL};

	/* here we need to set the attrs lists for domain and result lookups */
	switch (format_desired) {
	case DRSUAPI_DS_NAME_FORMAT_FQDN_1779:
	case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX:
		domain_attrs = _domain_attrs_1779;
		result_attrs = _result_attrs_null;
		break;
	case DRSUAPI_DS_NAME_FORMAT_CANONICAL:
		domain_attrs = _domain_attrs_canonical;
		result_attrs = _result_attrs_canonical;
		break;
	case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT:
		domain_attrs = _domain_attrs_nt4;
		result_attrs = _result_attrs_nt4;
		break;
	case DRSUAPI_DS_NAME_FORMAT_GUID:		
		domain_attrs = _domain_attrs_guid;
		result_attrs = _result_attrs_guid;
		break;
	case DRSUAPI_DS_NAME_FORMAT_DISPLAY:		
		domain_attrs = _domain_attrs_display;
		result_attrs = _result_attrs_display;
		break;
	default:
		domain_attrs = _domain_attrs_none;
		result_attrs = _result_attrs_none;
		break;
	}

	if (domain_filter) {
		/* if we have a domain_filter look it up and set the result_basedn and the dns_domain_name */
		ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
					     partitions_basedn,
					     LDB_SCOPE_ONELEVEL,
					     domain_attrs,
					     "%s", domain_filter);

		if (ldb_ret != LDB_SUCCESS) {
			DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s\n", ldb_errstring(sam_ctx)));
			info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
			return WERR_OK;
		}

		switch (domain_res->count) {
		case 1:
			break;
		case 0:
			info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
			return WERR_OK;
		default:
			info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
			return WERR_OK;
		}

		info1->dns_domain_name	= ldb_msg_find_attr_as_string(domain_res->msgs[0], "dnsRoot", NULL);
		W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name);
		info1->status		= DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY;
	} else {
		info1->dns_domain_name	= NULL;
		info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
	}

	if (result_filter) {
		int ret;
		struct ldb_result *res;
		uint32_t dsdb_flags = 0;
		struct ldb_dn *real_search_dn = NULL;
		info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;

		/*
		 * From 4.1.4.2.11 of MS-DRSR
		 * if DS_NAME_FLAG_GCVERIFY in flags then
		 * rt := select all O from all
		 * where attrValue in GetAttrVals(O, att, false)
		 * else
		 * rt := select all O from subtree DefaultNC()
		 * where attrValue in GetAttrVals(O, att, false)
		 * endif
		 * return rt
		 */
		if (format_flags & DRSUAPI_DS_NAME_FLAG_GCVERIFY ||
		    format_offered == DRSUAPI_DS_NAME_FORMAT_GUID)
		{
			dsdb_flags = DSDB_SEARCH_SEARCH_ALL_PARTITIONS;
		} else if (domain_res) {
			if (!search_dn) {
				struct ldb_dn *tmp_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);
				real_search_dn = tmp_dn;
			} else {
				real_search_dn = search_dn;
			}
		} else {
			real_search_dn = ldb_get_default_basedn(sam_ctx);
		}
		if (format_desired == DRSUAPI_DS_NAME_FORMAT_GUID){
			 dsdb_flags |= DSDB_SEARCH_SHOW_RECYCLED;
		}
		/* search with the 'phantom root' flag */
		ret = dsdb_search(sam_ctx, mem_ctx, &res,
				  real_search_dn,
				  scope,
				  result_attrs,
				  dsdb_flags,
				  "%s", result_filter);
		if (ret != LDB_SUCCESS) {
			DEBUG(2, ("DsCrackNameOneFilter search from '%s' with flags 0x%08x failed: %s\n",
				  ldb_dn_get_linearized(real_search_dn),
				  dsdb_flags,
				  ldb_errstring(sam_ctx)));
			info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
			return WERR_OK;
		}

		ldb_ret = res->count;
		result_res = res->msgs;
	} else if (format_offered == DRSUAPI_DS_NAME_FORMAT_FQDN_1779) {
		ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res,
					  result_attrs);
	} else if (domain_res) {
		name_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);
		ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res,
					  result_attrs);
	} else {
		/* Can't happen */
		DEBUG(0, ("LOGIC ERROR: DsCrackNameOneFilter domain ref search not available: This can't happen...\n"));
		info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
		return WERR_OK;
	}

	switch (ldb_ret) {
	case 1:
		result = result_res[0];
		break;
	case 0:
		switch (format_offered) {
		case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL: 
			return DsCrackNameSPNAlias(sam_ctx, mem_ctx, 
						   smb_krb5_context, 
						   format_flags, format_offered, format_desired,
						   name, info1);

		case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
			return DsCrackNameUPN(sam_ctx, mem_ctx, smb_krb5_context, 
					      format_flags, format_offered, format_desired,
					      name, info1);
		default:
			break;
		}
		info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
		return WERR_OK;
	case -1:
		DEBUG(2, ("DsCrackNameOneFilter result search failed: %s\n", ldb_errstring(sam_ctx)));
		info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
		return WERR_OK;
	default:
		switch (format_offered) {
		case DRSUAPI_DS_NAME_FORMAT_CANONICAL:
		case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX:
		{
			const char *canonical_name = NULL; /* Not required, but we get warnings... */
			/* We may need to manually filter further */
			for (i = 0; i < ldb_ret; i++) {
				switch (format_offered) {
				case DRSUAPI_DS_NAME_FORMAT_CANONICAL:
					canonical_name = ldb_dn_canonical_string(mem_ctx, result_res[i]->dn);
					break;
				case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX:
					canonical_name = ldb_dn_canonical_ex_string(mem_ctx, result_res[i]->dn);
					break;
				default:
					break;
				}
				if (strcasecmp_m(canonical_name, name) == 0) {
					result = result_res[i];
					break;
				}
			}
			if (!result) {
				info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
				return WERR_OK;
			}
		}
		/* FALL TROUGH */
		default:
			info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
			return WERR_OK;
		}
	}

	info1->dns_domain_name = ldb_dn_canonical_string(mem_ctx, result->dn);
	W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name);
	p = strchr(info1->dns_domain_name, '/');
	if (p) {
		p[0] = '\0';
	}

	/* here we can use result and domain_res[0] */
	switch (format_desired) {
	case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: {
		info1->result_name	= ldb_dn_alloc_linearized(mem_ctx, result->dn);
		W_ERROR_HAVE_NO_MEMORY(info1->result_name);

		info1->status		= DRSUAPI_DS_NAME_STATUS_OK;
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_CANONICAL: {
		info1->result_name	= ldb_msg_find_attr_as_string(result, "canonicalName", NULL);
		info1->status		= DRSUAPI_DS_NAME_STATUS_OK;
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: {
		/* Not in the virtual ldb attribute */
		return DsCrackNameOneSyntactical(mem_ctx, 
						 DRSUAPI_DS_NAME_FORMAT_FQDN_1779, 
						 DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
						 result->dn, name, info1);
	}
	case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: {

		const struct dom_sid *sid = samdb_result_dom_sid(mem_ctx, result, "objectSid");
		const char *_acc = "", *_dom = "";
		if (sid == NULL) {
			info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING;
			return WERR_OK;
		}

		if (samdb_find_attribute(sam_ctx, result, "objectClass",
					 "domain")) {
			/* This can also find a DomainDNSZones entry,
			 * but it won't have the SID we just
			 * checked.  */
			ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
						     partitions_basedn,
						     LDB_SCOPE_ONELEVEL,
						     domain_attrs,
						     "(ncName=%s)", ldb_dn_get_linearized(result->dn));

			if (ldb_ret != LDB_SUCCESS) {
				DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s\n", ldb_errstring(sam_ctx)));
				info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
				return WERR_OK;
			}

			switch (domain_res->count) {
			case 1:
				break;
			case 0:
				info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
				return WERR_OK;
			default:
				info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
				return WERR_OK;
			}
			_dom = ldb_msg_find_attr_as_string(domain_res->msgs[0], "nETBIOSName", NULL);
			W_ERROR_HAVE_NO_MEMORY(_dom);
		} else {
			_acc = ldb_msg_find_attr_as_string(result, "sAMAccountName", NULL);
			if (!_acc) {
				info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING;
				return WERR_OK;
			}
			if (dom_sid_in_domain(dom_sid_parse_talloc(mem_ctx, SID_BUILTIN), sid)) {
				_dom = "BUILTIN";
			} else {
				const char *attrs[] = { NULL };
				struct ldb_result *domain_res2;
				struct dom_sid *dom_sid = dom_sid_dup(mem_ctx, sid);
				if (!dom_sid) {
					return WERR_OK;
				}
				dom_sid->num_auths--;
				ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
							     NULL,
							     LDB_SCOPE_BASE,
							     attrs,
							     "(&(objectSid=%s)(objectClass=domain))", 
							     ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));

				if (ldb_ret != LDB_SUCCESS) {
					DEBUG(2, ("DsCrackNameOneFilter domain search failed: %s\n", ldb_errstring(sam_ctx)));
					info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
					return WERR_OK;
				}

				switch (domain_res->count) {
				case 1:
					break;
				case 0:
					info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
					return WERR_OK;
				default:
					info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
					return WERR_OK;
				}

				ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res2,
							     partitions_basedn,
							     LDB_SCOPE_ONELEVEL,
							     domain_attrs,
							     "(ncName=%s)", ldb_dn_get_linearized(domain_res->msgs[0]->dn));

				if (ldb_ret != LDB_SUCCESS) {
					DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s\n", ldb_errstring(sam_ctx)));
					info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
					return WERR_OK;
				}

				switch (domain_res2->count) {
				case 1:
					break;
				case 0:
					info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
					return WERR_OK;
				default:
					info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
					return WERR_OK;
				}
				_dom = ldb_msg_find_attr_as_string(domain_res2->msgs[0], "nETBIOSName", NULL);
				W_ERROR_HAVE_NO_MEMORY(_dom);
			}
		}

		info1->result_name	= talloc_asprintf(mem_ctx, "%s\\%s", _dom, _acc);
		W_ERROR_HAVE_NO_MEMORY(info1->result_name);

		info1->status		= DRSUAPI_DS_NAME_STATUS_OK;
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_GUID: {
		struct GUID guid;

		guid = samdb_result_guid(result, "objectGUID");

		info1->result_name	= GUID_string2(mem_ctx, &guid);
		W_ERROR_HAVE_NO_MEMORY(info1->result_name);

		info1->status		= DRSUAPI_DS_NAME_STATUS_OK;
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_DISPLAY: {
		info1->result_name	= ldb_msg_find_attr_as_string(result, "displayName", NULL);
		if (!info1->result_name) {
			info1->result_name	= ldb_msg_find_attr_as_string(result, "sAMAccountName", NULL);
		} 
		if (!info1->result_name) {
			info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
		} else {
			info1->status = DRSUAPI_DS_NAME_STATUS_OK;
		}
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL: {
		info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:	
	case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: {
		info1->dns_domain_name = NULL;
		info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
		return WERR_OK;
	}
	default:
		info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING;
		return WERR_OK;
	}
}
コード例 #6
0
/*
 * This function will workout the filtering parameter in order to be able to do
 * the adapted search when the incomming format is format_functional.
 * This boils down to defining the search_dn (passed as pointer to ldb_dn *) and the
 * ldap filter request.
 * Main input parameters are:
 * * name, which is the portion of the functional name after the
 * first '/'.
 * * domain_filter, which is a ldap search filter used to find the NC DN given the
 * function name to crack.
 */
static WERROR get_format_functional_filtering_param(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
			char *name, struct drsuapi_DsNameInfo1 *info1,
			struct ldb_dn **psearch_dn, const char *domain_filter, const char **presult_filter)
{
	struct ldb_result *domain_res = NULL;
	const char * const domain_attrs[] = {"ncName", NULL};
	struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
	int ldb_ret;
	char *account,  *s, *result_filter = NULL;
	struct ldb_dn *search_dn = NULL;

	*psearch_dn = NULL;
	*presult_filter = NULL;

	ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
				partitions_basedn,
				LDB_SCOPE_ONELEVEL,
				domain_attrs,
				"%s", domain_filter);

	if (ldb_ret != LDB_SUCCESS) {
		DEBUG(2, ("DsCrackNameOne domain ref search failed: %s\n", ldb_errstring(sam_ctx)));
		info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
		return WERR_FOOBAR;
	}

	if (domain_res->count == 1) {
		struct ldb_dn *tmp_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);
		const char * const name_attrs[] = {"name", NULL};

		account = name;
		s = strchr(account, '/');
		talloc_free(domain_res);
		while(s) {
			s[0] = '\0';
			s++;

			ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
						tmp_dn,
						LDB_SCOPE_ONELEVEL,
						name_attrs,
						"name=%s", account);

			if (ldb_ret != LDB_SUCCESS) {
				DEBUG(2, ("DsCrackNameOne domain ref search failed: %s\n", ldb_errstring(sam_ctx)));
				info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
				return WERR_OK;
			}
			talloc_free(tmp_dn);
			switch (domain_res->count) {
			case 1:
				break;
			case 0:
				talloc_free(domain_res);
				info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
				return WERR_OK;
			default:
				talloc_free(domain_res);
				info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
				return WERR_OK;
			}

			tmp_dn = talloc_steal(mem_ctx, domain_res->msgs[0]->dn);
			talloc_free(domain_res);
			search_dn = tmp_dn;
			account = s;
			s = strchr(account, '/');
		}
		account = ldb_binary_encode_string(mem_ctx, account);
		W_ERROR_HAVE_NO_MEMORY(account);
		result_filter = talloc_asprintf(mem_ctx, "(name=%s)",
						account);
		W_ERROR_HAVE_NO_MEMORY(result_filter);
	}
	*psearch_dn = search_dn;
	*presult_filter = result_filter;
	return WERR_OK;
}