示例#1
0
/*
  compare two dns
*/
static int samba_ldb_dn_link_comparison(struct ldb_context *ldb, void *mem_ctx,
					const struct ldb_val *v1, const struct ldb_val *v2)
{
	struct ldb_dn *dn1 = NULL, *dn2 = NULL;
	int ret;

	if (dsdb_dn_is_deleted_val(v1)) {
		/* If the DN is deleted, then we can't search for it */
		return -1;
	}

	if (dsdb_dn_is_deleted_val(v2)) {
		/* If the DN is deleted, then we can't search for it */
		return -1;
	}

	dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1);
	if ( ! ldb_dn_validate(dn1)) return -1;

	dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2);
	if ( ! ldb_dn_validate(dn2)) {
		talloc_free(dn1);
		return -1;
	}

	ret = ldb_dn_compare(dn1, dn2);

	talloc_free(dn1);
	talloc_free(dn2);
	return ret;
}
示例#2
0
/*
  see if two DNs match, comparing first by GUID, then by SID, and
  finally by string components
 */
static int samba_dn_extended_match(struct ldb_context *ldb,
				   const struct ldb_val *v1,
				   const struct ldb_val *v2,
				   bool *matched)
{
	TALLOC_CTX *tmp_ctx;
	struct ldb_dn *dn1, *dn2;
	const struct ldb_val *guid1, *guid2, *sid1, *sid2;
	uint32_t rmd_flags1, rmd_flags2;

	tmp_ctx = talloc_new(ldb);

	dn1 = ldb_dn_from_ldb_val(tmp_ctx, ldb, v1);
	dn2 = ldb_dn_from_ldb_val(tmp_ctx, ldb, v2);
	if (!dn1 || !dn2) {
		/* couldn't parse as DN's */
		talloc_free(tmp_ctx);
		(*matched) = false;
		return LDB_SUCCESS;
	}

	rmd_flags1 = dsdb_dn_rmd_flags(dn1);
	rmd_flags2 = dsdb_dn_rmd_flags(dn2);

	if ((rmd_flags1 & DSDB_RMD_FLAG_DELETED) !=
	    (rmd_flags2 & DSDB_RMD_FLAG_DELETED)) {
		/* only match if they have the same deletion status */
		talloc_free(tmp_ctx);
		(*matched) = false;
		return LDB_SUCCESS;
	}


	guid1 = ldb_dn_get_extended_component(dn1, "GUID");
	guid2 = ldb_dn_get_extended_component(dn2, "GUID");
	if (guid1 && guid2) {
		(*matched) = (data_blob_cmp(guid1, guid2) == 0);
		talloc_free(tmp_ctx);
		return LDB_SUCCESS;
	}

	sid1 = ldb_dn_get_extended_component(dn1, "SID");
	sid2 = ldb_dn_get_extended_component(dn2, "SID");
	if (sid1 && sid2) {
		(*matched) = (data_blob_cmp(sid1, sid2) == 0);
		talloc_free(tmp_ctx);
		return LDB_SUCCESS;
	}

	(*matched) = (ldb_dn_compare(dn1, dn2) == 0);

	talloc_free(tmp_ctx);
	return LDB_SUCCESS;
}
示例#3
0
/* Map a DN contained in an ldb value into the local partition. */
static struct ldb_val ldb_dn_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val)
{
	struct ldb_context *ldb;
	struct ldb_dn *dn, *newdn;
	struct ldb_val newval;

	ldb = ldb_module_get_ctx(module);

	dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val);
	if (! ldb_dn_validate(dn)) {
		newval.length = 0;
		newval.data = NULL;
		talloc_free(dn);
		return newval;
	}
	newdn = ldb_dn_map_remote(module, mem_ctx, dn);
	talloc_free(dn);

	newval.length = 0;
	newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn);
	if (newval.data) {
		newval.length = strlen((char *)newval.data);
	}
	talloc_free(newdn);

	return newval;
}
示例#4
0
/*
  return an array of SIDs from a ldb_message given an attribute name
  assumes the SIDs are in extended DN format
 */
WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx,
				 struct ldb_message *msg,
				 TALLOC_CTX *mem_ctx,
				 const char *attr,
				 const struct dom_sid ***sids)
{
	struct ldb_message_element *el;
	unsigned int i;

	el = ldb_msg_find_element(msg, attr);
	if (!el) {
		*sids = NULL;
		return WERR_OK;
	}

	(*sids) = talloc_array(mem_ctx, const struct dom_sid *, el->num_values + 1);
	W_ERROR_HAVE_NO_MEMORY(*sids);

	for (i=0; i<el->num_values; i++) {
		struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, sam_ctx, &el->values[i]);
		NTSTATUS status;
		struct dom_sid *sid;

		sid = talloc(*sids, struct dom_sid);
		W_ERROR_HAVE_NO_MEMORY(sid);
		status = dsdb_get_extended_dn_sid(dn, sid, "SID");
		if (!NT_STATUS_IS_OK(status)) {
			return WERR_INTERNAL_DB_CORRUPTION;
		}
		(*sids)[i] = sid;
	}
	(*sids)[i] = NULL;

	return WERR_OK;
}
示例#5
0
static int parse_memberofs(struct ldb_context *ldb,
                           struct ldb_message_element *el,
                           struct group_info *gi)
{
    int i;
    struct ldb_dn *dn = NULL;

    gi->memberofs = talloc_array(gi, const char *, el->num_values+1);
    if (gi->memberofs == NULL) {
        return ENOMEM;
    }

    for (i = 0; i< el->num_values; ++i) {
        dn = ldb_dn_from_ldb_val(gi, ldb, &(el->values[i]));
        gi->memberofs[i] = talloc_strdup(gi, rdn_as_string(gi, dn));
        talloc_zfree(dn);
        if (gi->memberofs[i] == NULL) {
            return ENOMEM;
        }
        DEBUG(SSSDBG_TRACE_FUNC, "memberof value: %s\n", gi->memberofs[i]);
    }
    gi->memberofs[el->num_values] = NULL;

    return EOK;
}
示例#6
0
WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
{
	WERROR status;
	static const char *attrs[] = { "namingContexts", NULL };
	unsigned int i;
	int ret;
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;
	struct ldb_message_element *el;

	tmp_ctx = talloc_new(s);
	W_ERROR_HAVE_NO_MEMORY(tmp_ctx);

	ret = ldb_search(s->samdb, tmp_ctx, &res,
			 ldb_dn_new(tmp_ctx, s->samdb, ""), LDB_SCOPE_BASE, attrs, NULL);
	if (ret != LDB_SUCCESS) {
		DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(s->samdb)));
		talloc_free(tmp_ctx);
		return WERR_DS_DRA_INTERNAL_ERROR;
       }

       el = ldb_msg_find_element(res->msgs[0], "namingContexts");
       if (!el) {
               DEBUG(1,("Finding namingContexts element in root_res failed: %s\n",
			ldb_errstring(s->samdb)));
	       talloc_free(tmp_ctx);
	       return WERR_DS_DRA_INTERNAL_ERROR;
       }

       for (i=0; i<el->num_values; i++) {
	       struct ldb_dn *pdn;
	       struct dreplsrv_partition *p;

	       pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
	       if (pdn == NULL) {
		       talloc_free(tmp_ctx);
		       return WERR_DS_DRA_INTERNAL_ERROR;
	       }
	       if (!ldb_dn_validate(pdn)) {
		       return WERR_DS_DRA_INTERNAL_ERROR;
	       }

	       p = talloc_zero(s, struct dreplsrv_partition);
	       W_ERROR_HAVE_NO_MEMORY(p);

	       p->dn = talloc_steal(p, pdn);

	       DLIST_ADD(s->partitions, p);

	       DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn)));
	}

	talloc_free(tmp_ctx);

	status = dreplsrv_refresh_partitions(s);
	W_ERROR_NOT_OK_RETURN(status);

	return WERR_OK;
}
示例#7
0
/*
  match a simple leaf node
*/
static int ldb_match_equality(struct ldb_context *ldb, 
			      const struct ldb_message *msg,
			      const struct ldb_parse_tree *tree,
			      enum ldb_scope scope,
			      bool *matched)
{
	unsigned int i;
	struct ldb_message_element *el;
	const struct ldb_schema_attribute *a;
	struct ldb_dn *valuedn;
	int ret;

	if (ldb_attr_dn(tree->u.equality.attr) == 0) {
		valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value);
		if (valuedn == NULL) {
			return LDB_ERR_INVALID_DN_SYNTAX;
		}

		ret = ldb_dn_compare(msg->dn, valuedn);

		talloc_free(valuedn);

		*matched = (ret == 0);
		return LDB_SUCCESS;
	}

	/* TODO: handle the "*" case derived from an extended search
	   operation without the attibute type defined */
	el = ldb_msg_find_element(msg, tree->u.equality.attr);
	if (el == NULL) {
		*matched = false;
		return LDB_SUCCESS;
	}

	a = ldb_schema_attribute_by_name(ldb, el->name);
	if (a == NULL) {
		return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
	}

	for (i=0;i<el->num_values;i++) {
		if (a->syntax->operator_fn) {
			ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
						     &tree->u.equality.value, &el->values[i], matched);
			if (ret != LDB_SUCCESS) return ret;
			if (*matched) return LDB_SUCCESS;
		} else {
			if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value,
						     &el->values[i]) == 0) {
				*matched = true;
				return LDB_SUCCESS;
			}
		}
	}

	*matched = false;
	return LDB_SUCCESS;
}
示例#8
0
static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_ctx,
					    const struct ldb_val *in, struct ldb_val *out)
{
	struct ldb_dn *dn1 = NULL;
	const struct dsdb_schema *schema = dsdb_get_schema(ldb, NULL);
	const struct dsdb_class *sclass;
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	if (!tmp_ctx) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	if (!schema) {
		talloc_free(tmp_ctx);
		*out = data_blob_talloc(mem_ctx, in->data, in->length);
		if (in->data && !out->data) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
		return LDB_SUCCESS;
	}
	dn1 = ldb_dn_from_ldb_val(tmp_ctx, ldb, in);
	if ( ! ldb_dn_validate(dn1)) {
		const char *lDAPDisplayName = talloc_strndup(tmp_ctx, (char *)in->data, in->length);
		sclass = dsdb_class_by_lDAPDisplayName(schema, lDAPDisplayName);
		if (sclass) {
			struct ldb_dn *dn = ldb_dn_new(tmp_ctx, ldb,
						       sclass->defaultObjectCategory);
			if (dn == NULL) {
				talloc_free(tmp_ctx);
				return LDB_ERR_OPERATIONS_ERROR;
			}

			*out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn));
			talloc_free(tmp_ctx);

			if (!out->data) {
				return LDB_ERR_OPERATIONS_ERROR;
			}
			return LDB_SUCCESS;
		} else {
			*out = data_blob_talloc(mem_ctx, in->data, in->length);
			talloc_free(tmp_ctx);

			if (in->data && !out->data) {
				return LDB_ERR_OPERATIONS_ERROR;
			}
			return LDB_SUCCESS;
		}
	}
	*out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn1));
	talloc_free(tmp_ctx);

	if (!out->data) {
		return LDB_ERR_OPERATIONS_ERROR;
	}
	return LDB_SUCCESS;
}
示例#9
0
/*
  make sure we only add repsFrom entries for DCs who are masters for
  the partition
 */
static bool check_MasterNC(struct kccsrv_partition *p, struct repsFromToBlob *r,
			   struct ldb_result *res)
{
	struct repsFromTo1 *r1 = &r->ctr.ctr1;
	struct GUID invocation_id = r1->source_dsa_invocation_id;
	unsigned int i, j;

	/* we are expecting only version 1 */
	SMB_ASSERT(r->version == 1);

	for (i=0; i<res->count; i++) {
		struct ldb_message *msg = res->msgs[i];
		struct ldb_message_element *el;
		struct ldb_dn *dn;

		struct GUID id2 = samdb_result_guid(msg, "invocationID");
		if (GUID_all_zero(&id2) ||
		    !GUID_equal(&invocation_id, &id2)) {
			continue;
		}

		el = ldb_msg_find_element(msg, "msDS-hasMasterNCs");
		if (!el || el->num_values == 0) {
			el = ldb_msg_find_element(msg, "hasMasterNCs");
			if (!el || el->num_values == 0) {
				continue;
			}
		}
		for (j=0; j<el->num_values; j++) {
			dn = ldb_dn_from_ldb_val(p, p->service->samdb, &el->values[j]);
			if (!ldb_dn_validate(dn)) {
				talloc_free(dn);
				continue;
			}
			if (ldb_dn_compare(dn, p->dn) == 0) {
				talloc_free(dn);
				DEBUG(5,("%s %s match on %s in %s\n",
					 r1->other_info->dns_name,
					 el->name,
					 ldb_dn_get_linearized(dn),
					 ldb_dn_get_linearized(msg->dn)));
				return true;
			}
			talloc_free(dn);
		}
	}
	return false;
}
示例#10
0
struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb,
				       TALLOC_CTX *mem_ctx,
				       const struct ldb_message *msg,
				       const char *attr_name)
{
	struct ldb_dn *res_dn;
	const struct ldb_val *v;

	v = ldb_msg_find_ldb_val(msg, attr_name);
	if (!v || !v->data) {
		return NULL;
	}
	res_dn = ldb_dn_from_ldb_val(mem_ctx, ldb, v);
	if ( ! ldb_dn_validate(res_dn)) {
		talloc_free(res_dn);
		return NULL;
	}
	return res_dn;
}
示例#11
0
static int samba_ldb_dn_link_canonicalise(struct ldb_context *ldb, void *mem_ctx,
					  const struct ldb_val *in, struct ldb_val *out)
{
	struct ldb_dn *dn;
	int ret = -1;

	out->length = 0;
	out->data = NULL;

	dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in);
	if ( ! ldb_dn_validate(dn)) {
		return LDB_ERR_INVALID_DN_SYNTAX;
	}

	/* By including the RMD_FLAGS of a deleted DN, we ensure it
	 * does not casually match a not deleted DN */
	if (dsdb_dn_is_deleted_val(in)) {
		out->data = (uint8_t *)talloc_asprintf(mem_ctx,
						       "<RMD_FLAGS=%u>%s",
						       dsdb_dn_val_rmd_flags(in),
						       ldb_dn_get_casefold(dn));
	} else {
		out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn);
	}

	if (out->data == NULL) {
		goto done;
	}
	out->length = strlen((char *)out->data);

	ret = 0;

done:
	talloc_free(dn);

	return ret;
}
示例#12
0
WERROR dsdb_origin_objects_commit(struct ldb_context *ldb,
				  TALLOC_CTX *mem_ctx,
				  const struct drsuapi_DsReplicaObjectListItem *first_object,
				  uint32_t *_num,
				  uint32_t dsdb_repl_flags,
				  struct drsuapi_DsReplicaObjectIdentifier2 **_ids)
{
	WERROR status;
	const struct dsdb_schema *schema;
	const struct drsuapi_DsReplicaObjectListItem *cur;
	struct ldb_message **objects;
	struct drsuapi_DsReplicaObjectIdentifier2 *ids;
	uint32_t i;
	uint32_t num_objects = 0;
	const char * const attrs[] = {
		"objectGUID",
		"objectSid",
		NULL
	};
	struct ldb_result *res;
	int ret;

	for (cur = first_object; cur; cur = cur->next_object) {
		num_objects++;
	}

	if (num_objects == 0) {
		return WERR_OK;
	}

	ret = ldb_transaction_start(ldb);
	if (ret != LDB_SUCCESS) {
		return WERR_DS_INTERNAL_FAILURE;
	}

	objects	= talloc_array(mem_ctx, struct ldb_message *,
			       num_objects);
	if (objects == NULL) {
		status = WERR_NOMEM;
		goto cancel;
	}

	schema = dsdb_get_schema(ldb, objects);
	if (!schema) {
		return WERR_DS_SCHEMA_NOT_LOADED;
	}

	for (i=0, cur = first_object; cur; cur = cur->next_object, i++) {
		status = dsdb_origin_object_convert(ldb, schema, cur,
						    objects, &objects[i]);
		if (!W_ERROR_IS_OK(status)) {
			goto cancel;
		}
	}

	ids = talloc_array(mem_ctx,
			   struct drsuapi_DsReplicaObjectIdentifier2,
			   num_objects);
	if (ids == NULL) {
		status = WERR_NOMEM;
		goto cancel;
	}

	if (dsdb_repl_flags & DSDB_REPL_FLAG_ADD_NCNAME) {
		/* check for possible NC creation */
		for (i=0; i < num_objects; i++) {
			struct ldb_message *msg = objects[i];
			struct ldb_message_element *el;
			struct ldb_dn *nc_dn;

			if (ldb_msg_check_string_attribute(msg, "objectClass", "crossRef") == 0) {
				continue;
			}
			el = ldb_msg_find_element(msg, "nCName");
			if (el == NULL || el->num_values != 1) {
				continue;
			}
			nc_dn = ldb_dn_from_ldb_val(objects, ldb, &el->values[0]);
			if (!ldb_dn_validate(nc_dn)) {
				continue;
			}
			ret = dsdb_create_partial_replica_NC(ldb, nc_dn);
			if (ret != LDB_SUCCESS) {
				status = WERR_DS_INTERNAL_FAILURE;
				goto cancel;
			}
		}
	}

	for (i=0; i < num_objects; i++) {
		struct dom_sid *sid = NULL;
		struct ldb_request *add_req;

		DEBUG(6,(__location__ ": adding %s\n", 
			 ldb_dn_get_linearized(objects[i]->dn)));

		ret = ldb_build_add_req(&add_req,
					ldb,
					objects,
					objects[i],
					NULL,
					NULL,
					ldb_op_default_callback,
					NULL);
		if (ret != LDB_SUCCESS) {
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}

		ret = ldb_request_add_control(add_req, LDB_CONTROL_RELAX_OID, true, NULL);
		if (ret != LDB_SUCCESS) {
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}
		
		ret = ldb_request(ldb, add_req);
		if (ret == LDB_SUCCESS) {
			ret = ldb_wait(add_req->handle, LDB_WAIT_ALL);
		}
		if (ret != LDB_SUCCESS) {
			DEBUG(0,(__location__ ": Failed add of %s - %s\n",
				 ldb_dn_get_linearized(objects[i]->dn), ldb_errstring(ldb)));
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}

		talloc_free(add_req);

		ret = ldb_search(ldb, objects, &res, objects[i]->dn,
				 LDB_SCOPE_BASE, attrs,
				 "(objectClass=*)");
		if (ret != LDB_SUCCESS) {
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}
		ids[i].guid = samdb_result_guid(res->msgs[0], "objectGUID");
		sid = samdb_result_dom_sid(objects, res->msgs[0], "objectSid");
		if (sid) {
			ids[i].sid = *sid;
		} else {
			ZERO_STRUCT(ids[i].sid);
		}
	}

	ret = ldb_transaction_commit(ldb);
	if (ret != LDB_SUCCESS) {
		return WERR_DS_INTERNAL_FAILURE;
	}

	talloc_free(objects);

	*_num = num_objects;
	*_ids = ids;
	return WERR_OK;

cancel:
	talloc_free(objects);
	ldb_transaction_cancel(ldb);
	return status;
}
示例#13
0
static int parse_members(TALLOC_CTX *mem_ctx,
                         struct ldb_context *ldb,
                         struct sss_domain_info *domain,
                         struct ldb_message_element *el,
                         const  char *parent_name,
                         const  char ***user_members,
                         const  char ***group_members,
                         int    *num_group_members)
{
    struct ldb_dn *user_basedn = NULL, *group_basedn = NULL;
    struct ldb_dn *parent_dn = NULL;
    struct ldb_dn *dn = NULL;
    const char **um = NULL, **gm = NULL;
    unsigned int um_index = 0, gm_index = 0;
    TALLOC_CTX *tmp_ctx = NULL;
    int ret;
    int i;

    tmp_ctx = talloc_new(mem_ctx);
    if (!tmp_ctx) {
        ret = ENOMEM;
        goto fail;
    }

    user_basedn = sysdb_user_base_dn(tmp_ctx, domain);
    group_basedn = sysdb_group_base_dn(tmp_ctx, domain);
    if (!user_basedn || !group_basedn) {
        ret = ENOMEM;
        goto fail;
    }

    um = talloc_array(mem_ctx, const char *, el->num_values+1);
    gm = talloc_array(mem_ctx, const char *, el->num_values+1);
    if (!um || !gm) {
        ret = ENOMEM;
        goto fail;
    }

    for (i = 0; i< el->num_values; ++i) {
        dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &(el->values[i]));

        /* user member or group member? */
        parent_dn = ldb_dn_get_parent(tmp_ctx, dn);
        if (ldb_dn_compare_base(parent_dn, user_basedn) == 0) {
            um[um_index] = rdn_as_string(mem_ctx, dn);
            if (um[um_index] == NULL) {
                ret = ENOMEM;
                goto fail;
            }
            DEBUG(SSSDBG_TRACE_FUNC, "User member %s\n", um[um_index]);
            um_index++;
        } else if (ldb_dn_compare_base(parent_dn, group_basedn) == 0) {
            gm[gm_index] = rdn_as_string(mem_ctx, dn);
            if (gm[gm_index] == NULL) {
                ret = ENOMEM;
                goto fail;
            }
            if (parent_name && strcmp(gm[gm_index], parent_name) == 0) {
                DEBUG(SSSDBG_TRACE_FUNC,
                      "Skipping circular nesting for group %s\n",
                          gm[gm_index]);
                continue;
            }
            DEBUG(SSSDBG_TRACE_FUNC, "Group member %s\n", gm[gm_index]);
            gm_index++;
        } else {
            DEBUG(SSSDBG_OP_FAILURE, "Group member not a user nor group: %s\n",
                        ldb_dn_get_linearized(dn));
            ret = EIO;
            goto fail;
        }

        talloc_zfree(dn);
        talloc_zfree(parent_dn);
    }
    um[um_index] = NULL;
    gm[gm_index] = NULL;

    if (um_index > 0) {
        um = talloc_realloc(mem_ctx, um, const char *, um_index+1);
        if (!um) {
            ret = ENOMEM;
            goto fail;
        }
    } else {
示例#14
0
static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb, 
					    const struct dsdb_schema *schema,
					    const struct dsdb_attribute *attr,
					    const struct ldb_message_element *in,
					    TALLOC_CTX *mem_ctx,
					    struct drsuapi_DsReplicaAttribute *out)
{
	uint32_t i;
	DATA_BLOB *blobs;

	if (attr->attributeID_id == 0xFFFFFFFF) {
		return WERR_FOOBAR;
	}

	out->attid			= attr->attributeID_id;
	out->value_ctr.num_values	= in->num_values;
	out->value_ctr.values		= talloc_array(mem_ctx,
						       struct drsuapi_DsAttributeValue,
						       in->num_values);
	W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);

	blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
	W_ERROR_HAVE_NO_MEMORY(blobs);

	for (i=0; i < in->num_values; i++) {
		struct drsuapi_DsReplicaObjectIdentifier3 id3;
		enum ndr_err_code ndr_err;
		const DATA_BLOB *guid_blob, *sid_blob;
		struct ldb_dn *dn;
		TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
		W_ERROR_HAVE_NO_MEMORY(tmp_ctx);

		out->value_ctr.values[i].blob	= &blobs[i];

		dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);

		W_ERROR_HAVE_NO_MEMORY(dn);

		guid_blob = ldb_dn_get_extended_component(dn, "GUID");

		ZERO_STRUCT(id3);

		if (guid_blob) {
			ndr_err = ndr_pull_struct_blob_all(guid_blob, 
							   tmp_ctx, schema->iconv_convenience, &id3.guid,
							   (ndr_pull_flags_fn_t)ndr_pull_GUID);
			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
				NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
				talloc_free(tmp_ctx);
				return ntstatus_to_werror(status);
			}
		}

		sid_blob = ldb_dn_get_extended_component(dn, "SID");
		if (sid_blob) {
			
			ndr_err = ndr_pull_struct_blob_all(sid_blob, 
							   tmp_ctx, schema->iconv_convenience, &id3.sid,
							   (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
				NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
				talloc_free(tmp_ctx);
				return ntstatus_to_werror(status);
			}
		}

		id3.dn = ldb_dn_get_linearized(dn);

		ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
			talloc_free(tmp_ctx);
			return ntstatus_to_werror(status);
		}
		talloc_free(tmp_ctx);
	}

	return WERR_OK;
}
示例#15
0
WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
{
	WERROR status;
	static const char *attrs[] = { "hasMasterNCs", "hasPartialReplicaNCs", NULL };
	unsigned int i;
	int ret;
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;
	struct ldb_message_element *el;
	struct ldb_dn *ntds_dn;

	tmp_ctx = talloc_new(s);
	W_ERROR_HAVE_NO_MEMORY(tmp_ctx);

	ntds_dn = samdb_ntds_settings_dn(s->samdb);
	if (!ntds_dn) {
		DEBUG(1,(__location__ ": Unable to find ntds_dn: %s\n", ldb_errstring(s->samdb)));
		talloc_free(tmp_ctx);
		return WERR_DS_DRA_INTERNAL_ERROR;
	}

	ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, ntds_dn, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN);
	if (ret != LDB_SUCCESS) {
		DEBUG(1,("Searching for hasMasterNCs in NTDS DN failed: %s\n", ldb_errstring(s->samdb)));
		talloc_free(tmp_ctx);
		return WERR_DS_DRA_INTERNAL_ERROR;
	}

	el = ldb_msg_find_element(res->msgs[0], "hasMasterNCs");
	if (!el) {
		DEBUG(1,("Finding hasMasterNCs element in root_res failed: %s\n",
			 ldb_errstring(s->samdb)));
		talloc_free(tmp_ctx);
		return WERR_DS_DRA_INTERNAL_ERROR;
	}

	for (i=0; i<el->num_values; i++) {
		struct ldb_dn *pdn;
		struct dreplsrv_partition *p;

		pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
		if (pdn == NULL) {
			talloc_free(tmp_ctx);
			return WERR_DS_DRA_INTERNAL_ERROR;
		}
		if (!ldb_dn_validate(pdn)) {
			return WERR_DS_DRA_INTERNAL_ERROR;
		}

		p = talloc_zero(s, struct dreplsrv_partition);
		W_ERROR_HAVE_NO_MEMORY(p);

		p->dn = talloc_steal(p, pdn);
		p->service = s;

		DLIST_ADD(s->partitions, p);

		DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn)));
	}

	el = ldb_msg_find_element(res->msgs[0], "hasPartialReplicaNCs");

	for (i=0; el && i<el->num_values; i++) {
		struct ldb_dn *pdn;
		struct dreplsrv_partition *p;

		pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
		if (pdn == NULL) {
			talloc_free(tmp_ctx);
			return WERR_DS_DRA_INTERNAL_ERROR;
		}
		if (!ldb_dn_validate(pdn)) {
			return WERR_DS_DRA_INTERNAL_ERROR;
		}

		p = talloc_zero(s, struct dreplsrv_partition);
		W_ERROR_HAVE_NO_MEMORY(p);

		p->dn = talloc_steal(p, pdn);
		p->partial_replica = true;
		p->service = s;

		DLIST_ADD(s->partitions, p);

		DEBUG(2, ("dreplsrv_partition[%s] loaded (partial replica)\n", ldb_dn_get_linearized(p->dn)));
	}

	talloc_free(tmp_ctx);

	status = dreplsrv_refresh_partitions(s);
	W_ERROR_NOT_OK_RETURN(status);

	return WERR_OK;
}
示例#16
0
/*
 * This function generates the transitive closure of a given SAM object "dn_val"
 * (it basically expands nested memberships).
 * If the object isn't located in the "res_sids" structure yet and the
 * "only_childs" flag is false, we add it to "res_sids".
 * Then we've always to consider the "memberOf" attributes. We invoke the
 * function recursively on each of it with the "only_childs" flag set to
 * "false".
 * The "only_childs" flag is particularly useful if you have a user object and
 * want to include all it's groups (referenced with "memberOf") but not itself
 * or considering if that object matches the filter.
 *
 * At the beginning "res_sids" should reference to a NULL pointer.
 */
NTSTATUS dsdb_expand_nested_groups(struct ldb_context *sam_ctx,
				   struct ldb_val *dn_val, const bool only_childs, const char *filter,
				   TALLOC_CTX *res_sids_ctx, struct dom_sid **res_sids,
				   unsigned int *num_res_sids)
{
	const char * const attrs[] = { "memberOf", NULL };
	unsigned int i;
	int ret;
	bool already_there;
	struct ldb_dn *dn;
	struct dom_sid sid;
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;
	NTSTATUS status;
	const struct ldb_message_element *el;

	if (*res_sids == NULL) {
		*num_res_sids = 0;
	}

	if (!sam_ctx) {
		DEBUG(0, ("No SAM available, cannot determine local groups\n"));
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}

	tmp_ctx = talloc_new(res_sids_ctx);

	dn = ldb_dn_from_ldb_val(tmp_ctx, sam_ctx, dn_val);
	if (dn == NULL) {
		talloc_free(tmp_ctx);
		DEBUG(0, (__location__ ": we failed parsing DN %.*s, so we cannot calculate the group token\n",
			  (int)dn_val->length, dn_val->data));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	status = dsdb_get_extended_dn_sid(dn, &sid, "SID");
	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
		/* If we fail finding a SID then this is no error since it could
		 * be a non SAM object - e.g. a group with object class
		 * "groupOfNames" */
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	} else if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, (__location__ ": when parsing DN '%s' we failed to parse it's SID component, so we cannot calculate the group token: %s\n",
			  ldb_dn_get_extended_linearized(tmp_ctx, dn, 1),
			  nt_errstr(status)));
		talloc_free(tmp_ctx);
		return status;
	}

	if (!ldb_dn_minimise(dn)) {
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	if (only_childs) {
		ret = dsdb_search_dn(sam_ctx, tmp_ctx, &res, dn, attrs,
				     DSDB_SEARCH_SHOW_EXTENDED_DN);
	} else {
		/* This is an O(n^2) linear search */
		already_there = sids_contains_sid(*res_sids,
						  *num_res_sids, &sid);
		if (already_there) {
			talloc_free(tmp_ctx);
			return NT_STATUS_OK;
		}

		ret = dsdb_search(sam_ctx, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
				  attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "%s",
				  filter);
	}

	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	if (ret != LDB_SUCCESS) {
		DEBUG(1, (__location__ ": dsdb_search for %s failed: %s\n",
			  ldb_dn_get_extended_linearized(tmp_ctx, dn, 1),
			  ldb_errstring(sam_ctx)));
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	/* We may get back 0 results, if the SID didn't match the filter - such as it wasn't a domain group, for example */
	if (res->count != 1) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	/* We only apply this test once we know the SID matches the filter */
	if (!only_childs) {
		*res_sids = talloc_realloc(res_sids_ctx, *res_sids,
			struct dom_sid, *num_res_sids + 1);
		NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*res_sids, tmp_ctx);
		(*res_sids)[*num_res_sids] = sid;
		++(*num_res_sids);
	}
示例#17
0
/*
  load the partitions list based on replicated NC attributes in our
  NTDSDSA object
 */
WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
{
	WERROR status;
	static const char *attrs[] = { "hasMasterNCs", "msDs-hasMasterNCs", "hasPartialReplicaNCs", "msDS-HasFullReplicaNCs", NULL };
	unsigned int a;
	int ret;
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;
	struct ldb_message_element *el;
	struct ldb_dn *ntds_dn;

	tmp_ctx = talloc_new(s);
	W_ERROR_HAVE_NO_MEMORY(tmp_ctx);

	ntds_dn = samdb_ntds_settings_dn(s->samdb);
	if (!ntds_dn) {
		DEBUG(1,(__location__ ": Unable to find ntds_dn: %s\n", ldb_errstring(s->samdb)));
		talloc_free(tmp_ctx);
		return WERR_DS_DRA_INTERNAL_ERROR;
	}

	ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, ntds_dn, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN);
	if (ret != LDB_SUCCESS) {
		DEBUG(1,("Searching for hasMasterNCs in NTDS DN failed: %s\n", ldb_errstring(s->samdb)));
		talloc_free(tmp_ctx);
		return WERR_DS_DRA_INTERNAL_ERROR;
	}

	for (a=0; attrs[a]; a++) {
		int i;

		el = ldb_msg_find_element(res->msgs[0], attrs[a]);
		if (el == NULL) {
			continue;
		}
		for (i=0; i<el->num_values; i++) {
			struct ldb_dn *pdn;
			struct dreplsrv_partition *p, *tp;
			bool found;

			pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
			if (pdn == NULL) {
				talloc_free(tmp_ctx);
				return WERR_DS_DRA_INTERNAL_ERROR;
			}
			if (!ldb_dn_validate(pdn)) {
				return WERR_DS_DRA_INTERNAL_ERROR;
			}

			p = talloc_zero(s, struct dreplsrv_partition);
			W_ERROR_HAVE_NO_MEMORY(p);

			p->dn = talloc_steal(p, pdn);
			p->service = s;

			if (strcasecmp(attrs[a], "hasPartialReplicaNCs") == 0) {
				p->partial_replica = true;
			} else if (strcasecmp(attrs[a], "msDS-HasFullReplicaNCs") == 0) {
				p->rodc_replica = true;
			}

			/* Do not add partitions more than once */
			found = false;
			for (tp = s->partitions; tp; tp = tp->next) {
				if (ldb_dn_compare(tp->dn, p->dn) == 0) {
					found = true;
					break;
				}
			}
			if (found) {
				talloc_free(p);
				continue;
			}

			DLIST_ADD(s->partitions, p);
			DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn)));
		}
	}

	talloc_free(tmp_ctx);

	status = dreplsrv_refresh_partitions(s);
	W_ERROR_NOT_OK_RETURN(status);

	return WERR_OK;
}
示例#18
0
/*
  work out the principal to use for DRS replication connections
 */
NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
				       TALLOC_CTX *mem_ctx,
				       const struct repsFromTo1 *rft,
				       const char **target_principal)
{
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;
	const char *attrs_server[] = { "dNSHostName", NULL };
	const char *attrs_ntds[] = { "msDS-HasDomainNCs", "hasMasterNCs", NULL };
	int ret;
	const char *hostname, *dnsdomain=NULL;
	struct ldb_dn *ntds_dn, *server_dn;
	struct ldb_dn *forest_dn, *nc_dn;

	*target_principal = NULL;

	tmp_ctx = talloc_new(mem_ctx);

	/* we need to find their hostname */
	ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &rft->source_dsa_obj_guid, &ntds_dn);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		/* its OK for their NTDSDSA DN not to be in our database */
		return NT_STATUS_OK;
	}

	server_dn = ldb_dn_copy(tmp_ctx, ntds_dn);
	if (server_dn == NULL) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	/* strip off the NTDS Settings */
	if (!ldb_dn_remove_child_components(server_dn, 1)) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, server_dn, attrs_server, 0);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		/* its OK for their server DN not to be in our database */
		return NT_STATUS_OK;
	}

	forest_dn = ldb_get_root_basedn(s->samdb);
	if (forest_dn == NULL) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	hostname = ldb_msg_find_attr_as_string(res->msgs[0], "dNSHostName", NULL);
	if (hostname != NULL) {
		char *local_principal;

		/*
		  if we have the dNSHostName attribute then we can use
		  the GC/hostname/realm SPN. All DCs should have this SPN

		  Windows DC may set up it's dNSHostName before setting up
		  GC/xx/xx SPN. So make sure it exists, before using it.
		 */
		local_principal = talloc_asprintf(mem_ctx, "GC/%s/%s",
						    hostname,
						    samdb_dn_to_dns_domain(tmp_ctx, forest_dn));
		if (dreplsrv_spn_exists(s->samdb, ntds_dn, local_principal)) {
			*target_principal = local_principal;
			talloc_free(tmp_ctx);
			return NT_STATUS_OK;
		}

		talloc_free(local_principal);
	}

	/*
	   if we can't find the dNSHostName then we will try for the
	   E3514235-4B06-11D1-AB04-00C04FC2DCD2/${NTDSGUID}/${DNSDOMAIN}
	   SPN. To use that we need the DNS domain name of the target
	   DC. We find that by first looking for the msDS-HasDomainNCs
	   in the NTDSDSA object of the DC, and if we don't find that,
	   then we look for the hasMasterNCs attribute, and eliminate
	   the known schema and configuruation DNs. Despite how
	   bizarre this seems, Hongwei tells us that this is in fact
	   what windows does to find the SPN!!
	*/
	ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, ntds_dn, attrs_ntds, 0);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	nc_dn = ldb_msg_find_attr_as_dn(s->samdb, tmp_ctx, res->msgs[0], "msDS-HasDomainNCs");
	if (nc_dn != NULL) {
		dnsdomain = samdb_dn_to_dns_domain(tmp_ctx, nc_dn);
	}

	if (dnsdomain == NULL) {
		struct ldb_message_element *el;
		int i;
		el = ldb_msg_find_element(res->msgs[0], "hasMasterNCs");
		for (i=0; el && i<el->num_values; i++) {
			nc_dn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
			if (nc_dn == NULL ||
			    ldb_dn_compare(ldb_get_config_basedn(s->samdb), nc_dn) == 0 ||
			    ldb_dn_compare(ldb_get_schema_basedn(s->samdb), nc_dn) == 0) {
				continue;
			}
			/* it must be a domain DN, get the equivalent
			   DNS domain name */
			dnsdomain = samdb_dn_to_dns_domain(tmp_ctx, nc_dn);
			break;
		}
	}

	if (dnsdomain != NULL) {
		*target_principal = talloc_asprintf(mem_ctx,
						    "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s",
						    GUID_string(tmp_ctx, &rft->source_dsa_obj_guid),
						    dnsdomain);
	}

	talloc_free(tmp_ctx);
	return NT_STATUS_OK;
}
示例#19
0
int sysdb_upgrade_10(struct sysdb_ctx *sysdb, const char **ver)
{

    TALLOC_CTX *tmp_ctx;
    int ret;
    struct ldb_result *res;
    struct ldb_message *msg;
    struct ldb_message *user;
    struct ldb_message_element *memberof_el;
    const char *name;
    struct ldb_dn *basedn;
    const char *filter = "(&(objectClass=user)(!(uidNumber=*))(memberOf=*))";
    const char *attrs[] = { "name", "memberof", NULL };
    int i, j;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        return ENOMEM;
    }

    basedn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_USER_BASE,
                            sysdb->domain->name);
    if (basedn == NULL) {
        ret = EIO;
        goto done;
    }

    DEBUG(SSSDBG_CRIT_FAILURE, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_11));

    ret = ldb_transaction_start(sysdb->ldb);
    if (ret != LDB_SUCCESS) {
        ret = EIO;
        goto done;
    }

    ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE,
                     attrs, "%s", filter);
    if (ret != LDB_SUCCESS) {
        ret = EIO;
        goto done;
    }

    for (i = 0; i < res->count; i++) {
        user = res->msgs[i];
        memberof_el = ldb_msg_find_element(user, "memberof");
        name = ldb_msg_find_attr_as_string(user, "name", NULL);
        if (name == NULL) {
            ret = EIO;
            goto done;
        }

        for (j = 0; j < memberof_el->num_values; j++) {
            msg = ldb_msg_new(tmp_ctx);
            if (msg == NULL) {
                ret = ENOMEM;
                goto done;
            }

            msg->dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &memberof_el->values[j]);
            if (msg->dn == NULL) {
                ret = ENOMEM;
                goto done;
            }

            if (!ldb_dn_validate(msg->dn)) {
                DEBUG(SSSDBG_MINOR_FAILURE, ("DN validation failed during "
                                             "upgrade: [%s]\n",
                                             memberof_el->values[j].data));
                talloc_zfree(msg);
                continue;
            }

            ret = ldb_msg_add_empty(msg, "ghost", LDB_FLAG_MOD_ADD, NULL);
            if (ret != LDB_SUCCESS) {
                ret = ENOMEM;
                goto done;
            }
            ret = ldb_msg_add_string(msg, "ghost", name);
            if (ret != LDB_SUCCESS) {
                ret = ENOMEM;
                goto done;
            }

            ret = ldb_msg_add_empty(msg, "member", LDB_FLAG_MOD_DELETE, NULL);
            if (ret != LDB_SUCCESS) {
                ret = ENOMEM;
                goto done;
            }
            ret = ldb_msg_add_string(msg, "member", ldb_dn_get_linearized(user->dn));
            if (ret != LDB_SUCCESS) {
                ret = ENOMEM;
                goto done;
            }

            ret = ldb_modify(sysdb->ldb, msg);
            talloc_zfree(msg);
            if (ret != LDB_SUCCESS) {
                ret = sysdb_error_to_errno(ret);
                goto done;
            }
        }

        ret = ldb_delete(sysdb->ldb, user->dn);
        if (ret != LDB_SUCCESS) {
            ret = sysdb_error_to_errno(ret);
            goto done;
        }
    }

    /* conversion done, upgrade version number */
    msg = ldb_msg_new(tmp_ctx);
    if (!msg) {
        ret = ENOMEM;
        goto done;
    }
    msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE);
    if (!msg->dn) {
        ret = ENOMEM;
        goto done;
    }

    ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL);
    if (ret != LDB_SUCCESS) {
        ret = ENOMEM;
        goto done;
    }

    ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_11);
    if (ret != LDB_SUCCESS) {
        ret = ENOMEM;
        goto done;
    }

    ret = ldb_modify(sysdb->ldb, msg);
    if (ret != LDB_SUCCESS) {
        ret = sysdb_error_to_errno(ret);
        goto done;
    }

    ret = EOK;

done:
    ret = finish_upgrade(ret, sysdb->ldb, SYSDB_VERSION_0_11, ver);
    talloc_free(tmp_ctx);
    return ret;
}
示例#20
0
文件: util_samr.c 项目: Arkhont/samba
/* Return the members of this group (which may be a domain group or an alias) */
NTSTATUS dsdb_enum_group_mem(struct ldb_context *ldb,
			     TALLOC_CTX *mem_ctx,
			     struct ldb_dn *dn,
			     struct dom_sid **members_out,
			     unsigned int *pnum_members)
{
	struct ldb_message *msg;
	unsigned int i, j;
	int ret;
	struct dom_sid *members;
	struct ldb_message_element *member_el;
	const char *attrs[] = { "member", NULL };
	NTSTATUS status;
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	ret = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs,
			      DSDB_SEARCH_SHOW_EXTENDED_DN, NULL);
	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
	}
	if (ret != LDB_SUCCESS) {
		DEBUG(1, ("dsdb_enum_group_mem: dsdb_search for %s failed: %s\n",
			  ldb_dn_get_linearized(dn), ldb_errstring(ldb)));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	member_el = ldb_msg_find_element(msg, "member");
	if (!member_el) {
		*members_out = NULL;
		*pnum_members = 0;
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	members = talloc_array(mem_ctx, struct dom_sid, member_el->num_values);
	if (members == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	j = 0;
	for (i=0; i <member_el->num_values; i++) {
		struct ldb_dn *member_dn = ldb_dn_from_ldb_val(tmp_ctx, ldb,
							       &member_el->values[i]);
		if (!member_dn || !ldb_dn_validate(member_dn)) {
			DEBUG(1, ("Could not parse %*.*s as a DN\n",
				  (int)member_el->values[i].length,
				  (int)member_el->values[i].length,
				  (const char *)member_el->values[i].data));
			talloc_free(tmp_ctx);
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}

		status = dsdb_get_extended_dn_sid(member_dn, &members[j],
						  "SID");
		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
			/* If we fail finding a SID then this is no error since
			 * it could be a non SAM object - e.g. a contact */
			continue;
		} else if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("When parsing DN '%s' we failed to parse it's SID component, so we cannot fetch the membership: %s\n",
				  ldb_dn_get_extended_linearized(tmp_ctx, member_dn, 1),
				  nt_errstr(status)));
			talloc_free(tmp_ctx);
			return status;
		}

		++j;
	}

	*members_out = talloc_steal(mem_ctx, members);
	*pnum_members = j;
	talloc_free(tmp_ctx);
	return NT_STATUS_OK;
}
示例#21
0
文件: ldb.c 项目: 0x24bin/winexe-1
static bool torture_ldb_dn(struct torture_context *torture)
{
	TALLOC_CTX *mem_ctx = talloc_new(torture);
	struct ldb_context *ldb;
	struct ldb_dn *dn;
	struct ldb_dn *child_dn;
	struct ldb_dn *typo_dn;
	struct ldb_val val;

	torture_assert(torture, 
		       ldb = ldb_init(mem_ctx, torture->ev),
		       "Failed to init ldb");

	torture_assert_int_equal(torture, 
				 ldb_register_samba_handlers(ldb), 0, 
				 "Failed to register Samba handlers");

	ldb_set_utf8_fns(ldb, NULL, wrap_casefold);

	/* Check behaviour of a normal DN */
	torture_assert(torture, 
		       dn = ldb_dn_new(mem_ctx, ldb, NULL), 
		       "Failed to create a NULL DN");

	torture_assert(torture, 
		       ldb_dn_validate(dn),
		       "Failed to validate NULL DN");

	torture_assert(torture, 
		       ldb_dn_add_base_fmt(dn, "dc=org"), 
		       "Failed to add base DN");

	torture_assert(torture, 
		       ldb_dn_add_child_fmt(dn, "dc=samba"), 
		       "Failed to add base DN");

	torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "dc=samba,dc=org", 
				 "linearized DN incorrect");

	torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0), "dc=samba,dc=org", 
				 "extended linearized DN incorrect");

	/* Check child DN comparisons */
	torture_assert(torture, 
		       child_dn = ldb_dn_new(mem_ctx, ldb, "CN=users,DC=SAMBA,DC=org"), 
		       "Failed to create child DN");

	torture_assert(torture, 
		       ldb_dn_compare(dn, child_dn) != 0,
		       "Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should != 0");

	torture_assert(torture, 
		       ldb_dn_compare_base(child_dn, dn) != 0,
		       "Base Comparison of CN=users,DC=SAMBA,DC=org and dc=samba,dc=org should != 0");

	torture_assert(torture, 
		       ldb_dn_compare_base(dn, child_dn) == 0,
		       "Base Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should == 0");

	/* Check comparisons with a truncated DN */
	torture_assert(torture, 
		       typo_dn = ldb_dn_new(mem_ctx, ldb, "c=samba,dc=org"), 
		       "Failed to create 'typo' DN");

	torture_assert(torture, 
		       ldb_dn_compare(dn, typo_dn) != 0,
		       "Comparison on dc=samba,dc=org and c=samba,dc=org should != 0");

	torture_assert(torture, 
		       ldb_dn_compare_base(typo_dn, dn) != 0,
		       "Base Comparison of c=samba,dc=org and dc=samba,dc=org should != 0");

	torture_assert(torture, 
		       ldb_dn_compare_base(dn, typo_dn) != 0,
		       "Base Comparison on dc=samba,dc=org and c=samba,dc=org should != 0");

	/* Check DN based on MS-ADTS:3.1.1.5.1.2 Naming Constraints*/
	torture_assert(torture,
		       dn = ldb_dn_new(mem_ctx, ldb, "CN=New\nLine,DC=SAMBA,DC=org"),
		       "Failed to create a DN with 0xA in it");

	/* this is a warning until we work out how the DEL: CNs work */
	if (ldb_dn_validate(dn) != false) {
		torture_warning(torture,
				"should have failed to validate a DN with 0xA in it");
	}

	val = data_blob_const("CN=Zer\0,DC=SAMBA,DC=org", 23);
	torture_assert(torture,
		       NULL == ldb_dn_from_ldb_val(mem_ctx, ldb, &val),
		       "should fail to create a DN with 0x0 in it");

	talloc_free(mem_ctx);
	return true;
}
示例#22
0
文件: dsdb_dn.c 项目: endisd/samba
struct dsdb_dn *dsdb_dn_parse(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 
			      const struct ldb_val *dn_blob, const char *dn_oid)
{
	struct dsdb_dn *dsdb_dn;
	struct ldb_dn *dn;
	const char *data;
	size_t len;
	TALLOC_CTX *tmp_ctx;
	char *p1;
	char *p2;
	uint32_t blen;
	struct ldb_val bval;
	struct ldb_val dval;
	char *dn_str;

	enum dsdb_dn_format dn_format = dsdb_dn_oid_to_format(dn_oid);
	switch (dn_format) {
	case DSDB_INVALID_DN:
		return NULL;
	case DSDB_NORMAL_DN:
	{
		dn = ldb_dn_from_ldb_val(mem_ctx, ldb, dn_blob);
		if (!dn || !ldb_dn_validate(dn)) {
			talloc_free(dn);
			return NULL;
		}
		return dsdb_dn_construct_internal(mem_ctx, dn, data_blob_null, dn_format, dn_oid);
	}
	case DSDB_BINARY_DN:
		if (dn_blob->length < 2 || dn_blob->data[0] != 'B' || dn_blob->data[1] != ':') {
			return NULL;
		}
		break;
	case DSDB_STRING_DN:
		if (dn_blob->length < 2 || dn_blob->data[0] != 'S' || dn_blob->data[1] != ':') {
			return NULL;
		}
		break;
	default:
		return NULL;
	}

	if (dn_blob && dn_blob->data
	    && (strlen((const char*)dn_blob->data) != dn_blob->length)) {
		/* The RDN must not contain a character with value 0x0 */
		return NULL;
	}
		
	if (!dn_blob->data || dn_blob->length == 0) {
		return NULL;
	}
		
	tmp_ctx = talloc_new(mem_ctx);
	if (tmp_ctx == NULL) {
		return NULL;
	}
		
	data = (const char *)dn_blob->data;

	len = dn_blob->length - 2;
	p1 = talloc_strndup(tmp_ctx, (const char *)dn_blob->data + 2, len);
	if (!p1) {
		goto failed;
	}

	errno = 0;
	blen = strtoul(p1, &p2, 10);
	if (errno != 0) {
		DEBUG(10, (__location__ ": failed\n"));
		goto failed;
	}
	if (p2 == NULL) {
		DEBUG(10, (__location__ ": failed\n"));
		goto failed;
	}
	if (p2[0] != ':') {
		DEBUG(10, (__location__ ": failed\n"));
		goto failed;
	}
	len -= PTR_DIFF(p2,p1);//???
	p1 = p2+1;
	len--;
		
	if (blen >= len) {
		DEBUG(10, (__location__ ": blen=%u len=%u\n", (unsigned)blen, (unsigned)len));
		goto failed;
	}
		
	p2 = p1 + blen;
	if (p2[0] != ':') {
		DEBUG(10, (__location__ ": %s", p2));
		goto failed;
	}
	dn_str = p2+1;
		
		
	switch (dn_format) {
	case DSDB_BINARY_DN:
		if ((blen % 2 != 0)) {
			DEBUG(10, (__location__ ": blen=%u - not an even number\n", (unsigned)blen));
			goto failed;
		}
		
		if (blen >= 2) {
			bval.length = (blen/2)+1;
			bval.data = talloc_size(tmp_ctx, bval.length);
			if (bval.data == NULL) {
				DEBUG(10, (__location__ ": err\n"));
				goto failed;
			}
			bval.data[bval.length-1] = 0;
		
			bval.length = strhex_to_str((char *)bval.data, bval.length,
						    p1, blen);
			if (bval.length != (blen / 2)) {
				DEBUG(10, (__location__ ": non hexidecimal characters found in binary prefix\n"));
				goto failed;
			}
		} else {
			bval = data_blob_null;
		}

		break;
	case DSDB_STRING_DN:
		bval = data_blob(p1, blen);
		break;
	default:
		/* never reached */
		return NULL;
	}
	

	dval.data = (uint8_t *)dn_str;
	dval.length = strlen(dn_str);
		
	dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &dval);
	if (!dn || !ldb_dn_validate(dn)) {
		DEBUG(10, (__location__ ": err\n"));
		goto failed;
	}
		
	dsdb_dn = dsdb_dn_construct(mem_ctx, dn, bval, dn_oid);
		
	return dsdb_dn;

failed:
	talloc_free(tmp_ctx);
	return NULL;
}