Пример #1
0
} END_TEST

// ^ Unit test ----------------------------------------------------------------

// v Suite definition ---------------------------------------------------------

static void create_ldb_from_ldif(const char *ldb_path, const char *ldif_path,
				 const char *default_context, const char *root_context)
{
	FILE *f;
	struct ldb_ldif *ldif;
	struct ldb_context *ldb_ctx = NULL;
	TALLOC_CTX *local_mem_ctx = talloc_new(NULL);
	struct ldb_message *msg;

	ldb_ctx = ldb_init(local_mem_ctx, NULL);
	ldb_connect(ldb_ctx, ldb_path, 0, 0);
	f = fopen(ldif_path, "r");

	msg = ldb_msg_new(local_mem_ctx);
	msg->dn = ldb_dn_new(msg, ldb_ctx, "@INDEXLIST");
	ldb_msg_add_string(msg, "@IDXATTR", "cn");
	ldb_msg_add_string(msg, "@IDXATTR", "oleguid");
	ldb_msg_add_string(msg, "@IDXATTR", "mappedId");
	msg->elements[0].flags = LDB_FLAG_MOD_ADD;
	ldb_add(ldb_ctx, msg);

	while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) {
		struct ldb_message *normalized_msg;
		ldb_msg_normalize(ldb_ctx, local_mem_ctx, ldif->msg,
				  &normalized_msg);
		ldb_add(ldb_ctx, normalized_msg);
		talloc_free(normalized_msg);
		ldb_ldif_read_free(ldb_ctx, ldif);
	}

	if (default_context && root_context) {
		msg = ldb_msg_new(local_mem_ctx);
		msg->dn = ldb_dn_new(msg, ldb_ctx, "@ROOTDSE");
		ldb_msg_add_string(msg, "defaultNamingContext", default_context);
		ldb_msg_add_string(msg, "rootDomainNamingContext", root_context);
		msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
		ldb_add(ldb_ctx, msg);
	}

	fclose(f);
	talloc_free(local_mem_ctx);
}
Пример #2
0
/**
   \details Save (commit) message in openchangedb database

   \param msg the message object
   \param SaveFlags flags associated to the save operation

   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
_PUBLIC_ enum MAPISTATUS openchangedb_message_save(void *_msg, uint8_t SaveFlags)
{
	struct openchangedb_message *msg = (struct openchangedb_message *)_msg;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!msg, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!msg->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);

	switch (msg->status) {
	case OPENCHANGEDB_MESSAGE_CREATE:
		OPENCHANGE_RETVAL_IF(!msg->msg, MAPI_E_NOT_INITIALIZED, NULL);
		if (ldb_add(msg->ldb_ctx, msg->msg) != LDB_SUCCESS) {
			return MAPI_E_CALL_FAILED;
		}
		break;
	case OPENCHANGEDB_MESSAGE_OPEN:
		if (ldb_modify(msg->ldb_ctx, msg->res->msgs[0]) != LDB_SUCCESS) {
			return MAPI_E_CALL_FAILED;
		}
		break;
	}

	/* FIXME: Deal with SaveFlags */

	return MAPI_E_SUCCESS;
}
Пример #3
0
/*
  add records from an opened file
*/
static int process_file(struct ldb_context *ldb, FILE *f, int *count,
                        int *failures)
{
    struct ldb_ldif *ldif;
    int ret = LDB_SUCCESS;

    while ((ldif = ldb_ldif_read_file(ldb, f))) {
        if (ldif->changetype != LDB_CHANGETYPE_ADD &&
                ldif->changetype != LDB_CHANGETYPE_NONE) {
            fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n");
            break;
        }

        ldif->msg = ldb_msg_canonicalize(ldb, ldif->msg);

        ret = ldb_add(ldb, ldif->msg);
        if (ret != LDB_SUCCESS) {
            fprintf(stderr, "ERR: \"%s\" on DN %s\n",
                    ldb_errstring(ldb), ldb_dn_linearize(ldb, ldif->msg->dn));
            (*failures)++;
        } else {
            (*count)++;
        }
        ldb_ldif_read_free(ldb, ldif);
    }

    return ret;
}
Пример #4
0
/*
  add a new record
 */
static isc_result_t b9_add_record(struct dlz_bind9_data *state, const char *name,
				  struct ldb_dn *dn,
				  struct dnsp_DnssrvRpcRecord *rec)
{
	struct ldb_message *msg;
	enum ndr_err_code ndr_err;
	struct ldb_val v;
	int ret;

	msg = ldb_msg_new(rec);
	if (msg == NULL) {
		return ISC_R_NOMEMORY;
	}
	msg->dn = dn;
	ret = ldb_msg_add_string(msg, "objectClass", "dnsNode");
	if (ret != LDB_SUCCESS) {
		return ISC_R_FAILURE;
	}

	ndr_err = ndr_push_struct_blob(&v, rec, rec, (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		return ISC_R_FAILURE;
	}
	ret = ldb_msg_add_value(msg, "dnsRecord", &v, NULL);
	if (ret != LDB_SUCCESS) {
		return ISC_R_FAILURE;
	}

	ret = ldb_add(state->samdb, msg);
	if (ret != LDB_SUCCESS) {
		return ISC_R_FAILURE;
	}

	return ISC_R_SUCCESS;
}
Пример #5
0
/*
  process modifies for one file
*/
static int process_file(struct ldb_context *ldb, FILE *f, int *count)
{
	struct ldb_ldif *ldif;
	int ret = LDB_SUCCESS;
	
	while ((ldif = ldb_ldif_read_file(ldb, f))) {
		switch (ldif->changetype) {
		case LDB_CHANGETYPE_NONE:
		case LDB_CHANGETYPE_ADD:
			ret = ldb_add(ldb, ldif->msg);
			break;
		case LDB_CHANGETYPE_DELETE:
			ret = ldb_delete(ldb, ldif->msg->dn);
			break;
		case LDB_CHANGETYPE_MODIFY:
			ret = ldb_modify(ldb, ldif->msg);
			break;
		}
		if (ret != LDB_SUCCESS) {
			fprintf(stderr, "ERR: \"%s\" on DN %s\n", 
				ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn));
			failures++;
		} else {
			(*count)++;
		}
		ldb_ldif_read_free(ldb, ldif);
	}

	return ret;
}
Пример #6
0
static bool ldb_add_record(struct ldb_context *ldb, unsigned rid)
{
	struct ldb_message *msg;	
	int ret;

	msg = ldb_msg_new(ldb);
	if (msg == NULL) {
		return false;
	}

	msg->dn = ldb_dn_new_fmt(msg, ldb, "SID=S-1-5-21-53173311-3623041448-2049097239-%u", rid);
	if (msg->dn == NULL) {
		return false;
	}

	if (ldb_msg_add_fmt(msg, "UID", "%u", rid) != 0) {
		return false;
	}

	ret = ldb_add(ldb, msg);

	talloc_free(msg);

	return ret == LDB_SUCCESS;
}
Пример #7
0
/*
  setup some initial ldif in a ldb
*/
int gendb_add_ldif(struct ldb_context *ldb, const char *ldif_string)
{
	struct ldb_ldif *ldif;
	int ret;
	ldif = ldb_ldif_read_string(ldb, &ldif_string);
	if (ldif == NULL) return -1;
	ret = ldb_add(ldb, ldif->msg);
	talloc_free(ldif);
	return ret;
}
Пример #8
0
static int confdb_write_ldif(struct confdb_ctx *cdb,
                             const char *config_ldif,
                             bool replace_whole_db)
{
    int ret;
    struct ldb_ldif *ldif;

    while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) {
        if (ldif->changetype == LDB_CHANGETYPE_DELETE) {
            /* We should remove this section */
            ret = ldb_delete(cdb->ldb, ldif->msg->dn);
            if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                /* Removing a non-existing section is not an error */
                ret = LDB_SUCCESS;
            }
        } else {
            ret = ldb_add(cdb->ldb, ldif->msg);
            if (ret != LDB_SUCCESS && replace_whole_db == false) {
                /* This section already existed, remove and re-add it. We
                * really want to replace the whole thing instead of messing
                * around with changetypes and flags on individual elements
                */
                ret = ldb_delete(cdb->ldb, ldif->msg->dn);
                if (ret == LDB_SUCCESS) {
                    ret = ldb_add(cdb->ldb, ldif->msg);
                }
            }
        }

        if (ret != LDB_SUCCESS) {
            DEBUG(SSSDBG_FATAL_FAILURE,
                "Failed to initialize DB (%d,[%s]), aborting!\n",
                ret, ldb_errstring(cdb->ldb));
            return EIO;
        }
        ldb_ldif_read_free(cdb->ldb, ldif);
    }

    return EOK;
}
/**
   \details return the mapped property ID matching the nameid
   structure passed in parameter.

   \param ldb_ctx pointer to the namedprops ldb context
   \param nameid the MAPINAMEID structure to lookup
   \param propID pointer to the property ID the function returns

   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
 */
_PUBLIC_ enum mapistore_error mapistore_namedprops_create_id(struct ldb_context *ldb_ctx, struct MAPINAMEID nameid, uint16_t mapped_id)
{
	int ret;
	TALLOC_CTX *mem_ctx;
	char *ldif_record;
	struct ldb_ldif *ldif;
	char *hex_id, *dec_id, *dec_mappedid, *guid;
	struct ldb_message *normalized_msg;
	const char *ldif_records[] = { NULL, NULL };

	mem_ctx = talloc_zero(NULL, TALLOC_CTX);

	dec_mappedid = talloc_asprintf(mem_ctx, "%u", mapped_id);
	guid = GUID_string(mem_ctx, &nameid.lpguid);
	switch (nameid.ulKind) {
	case MNID_ID:
		hex_id = talloc_asprintf(mem_ctx, "%.4x", nameid.kind.lid);
		dec_id = talloc_asprintf(mem_ctx, "%u", nameid.kind.lid);
		ldif_record = talloc_asprintf(mem_ctx, "dn: CN=0x%s,CN=%s,CN=default\nobjectClass: MNID_ID\ncn: 0x%s\npropType: PT_NULL\noleguid: %s\nmappedId: %s\npropId: %s\n",
					      hex_id, guid, hex_id, guid, dec_mappedid, dec_id);
		break;
	case MNID_STRING:
		ldif_record = talloc_asprintf(mem_ctx, "dn: CN=%s,CN=%s,CN=default\nobjectClass: MNID_STRING\ncn: %s\npropType: PT_NULL\noleguid: %s\nmappedId: %s\npropName: %s\n",
					      nameid.kind.lpwstr.Name, guid, nameid.kind.lpwstr.Name, guid, dec_mappedid, nameid.kind.lpwstr.Name);
		break;
	default:
		abort();
	}

	DEBUG(5, ("inserting record:\n%s\n", ldif_record));
	ldif_records[0] = ldif_record;
	ldif = ldb_ldif_read_string(ldb_ctx, ldif_records);
	ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg);
	MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL);
	ret = ldb_add(ldb_ctx, normalized_msg);
	talloc_free(normalized_msg);
	if (ret != LDB_SUCCESS) {
		MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL);
	}

	/* we invalidate the cache, if present */
	if (nameids_cache) {
		talloc_free(nameids_cache);
		nameids_cache = NULL;
	}

	return ret;
}
Пример #10
0
/*
  add a group mapping entry
 */
static bool add_mapping_entry(GROUP_MAP *map, int flag)
{
	struct ldb_message *msg;	
	int ret, i;
	fstring string_sid;

	msg = ldb_msg_new(ldb);
	if (msg == NULL) {
		return False;
	}

	msg->dn = mapping_dn(msg, &map->sid);
	if (msg->dn == NULL) {
		goto failed;
	}

	if (ldb_msg_add_string(msg, "objectClass", "groupMap") != LDB_SUCCESS ||
	    ldb_msg_add_string(msg, "sid", 
			       sid_to_fstring(string_sid, &map->sid)) != LDB_SUCCESS ||
	    ldb_msg_add_fmt(msg, "gidNumber", "%u", (unsigned)map->gid) != LDB_SUCCESS ||
	    ldb_msg_add_fmt(msg, "sidNameUse", "%u", (unsigned)map->sid_name_use) != LDB_SUCCESS ||
	    ldb_msg_add_string(msg, "comment", map->comment) != LDB_SUCCESS ||
	    ldb_msg_add_string(msg, "ntName", map->nt_name) != LDB_SUCCESS) {
		goto failed;
	}

	ret = ldb_add(ldb, msg);

	/* if it exists we update it. This is a hangover from the semantics the
	   tdb backend had */
	if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
		for (i=0;i<msg->num_elements;i++) {
			msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
		}
		ret = ldb_modify(ldb, msg);
	}

	talloc_free(msg);

	return ret == LDB_SUCCESS;

failed:
	talloc_free(msg);
	return False;
}
Пример #11
0
int confdb_create_base(struct confdb_ctx *cdb)
{
    int ret;
    struct ldb_ldif *ldif;

    const char *base_ldif = CONFDB_BASE_LDIF;

    while ((ldif = ldb_ldif_read_string(cdb->ldb, &base_ldif))) {
        ret = ldb_add(cdb->ldb, ldif->msg);
        if (ret != LDB_SUCCESS) {
            DEBUG(0, ("Failed to initialize DB (%d,[%s]), aborting!\n",
                      ret, ldb_errstring(cdb->ldb)));
            return EIO;
        }
        ldb_ldif_read_free(cdb->ldb, ldif);
    }

    return EOK;
}
Пример #12
0
/*
  test ldb speed
*/
static bool test_ldb_speed(struct torture_context *torture, const void *_data)
{
	struct timeval tv;
	struct ldb_context *ldb;
	int timelimit = torture_setting_int(torture, "timelimit", 10);
	int i, count;
	TALLOC_CTX *tmp_ctx = talloc_new(torture);
	struct ldb_ldif *ldif;
	const char *init_ldif = "dn: @INDEXLIST\n" \
		"@IDXATTR: UID\n";
	float ldb_speed;

	unlink("./test.ldb");

	torture_comment(torture, "Testing ldb speed for sidmap\n");

	ldb = ldb_wrap_connect(tmp_ctx, torture->ev, torture->lp_ctx, "tdb://test.ldb", 
				NULL, NULL, LDB_FLG_NOSYNC, NULL);
	if (!ldb) {
		unlink("./test.ldb");
		talloc_free(tmp_ctx);
		torture_fail(torture, "Failed to open test.ldb");
	}

	/* add an index */
	ldif = ldb_ldif_read_string(ldb, &init_ldif);
	if (ldif == NULL) goto failed;
	if (ldb_add(ldb, ldif->msg) != LDB_SUCCESS) goto failed;
	talloc_free(ldif);

	torture_comment(torture, "Adding %d SID records\n", torture_entries);

	for (i=0;i<torture_entries;i++) {
		if (!ldb_add_record(ldb, i)) {
			torture_result(torture, TORTURE_FAIL, "Failed to add SID %d\n", i);
			goto failed;
		}
	}

	if (talloc_total_blocks(torture) > 100) {
		torture_result(torture, TORTURE_FAIL, "memory leak in ldb add\n");
		goto failed;
	}

	torture_comment(torture, "Testing for %d seconds\n", timelimit);

	tv = timeval_current();

	for (count=0;timeval_elapsed(&tv) < timelimit;count++) {
		struct ldb_dn *dn;
		struct ldb_result *res;

		i = random() % torture_entries;
		dn = ldb_dn_new_fmt(tmp_ctx, ldb, "SID=S-1-5-21-53173311-3623041448-2049097239-%u", i);
		if (ldb_search(ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL) != LDB_SUCCESS || res->count != 1) {
			torture_fail(torture, talloc_asprintf(torture, "Failed to find SID %d", i));
		}
		talloc_free(res);
		talloc_free(dn);
		if (ldb_search(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE, NULL, "(UID=%u)", i) != LDB_SUCCESS || res->count != 1) {
			torture_fail(torture, talloc_asprintf(torture, "Failed to find UID %d", i));
		}
		talloc_free(res);
	}

	if (talloc_total_blocks(torture) > 100) {
		unlink("./test.ldb");
		talloc_free(tmp_ctx);
		torture_fail(torture, "memory leak in ldb search");
	}

	ldb_speed = count/timeval_elapsed(&tv);
	torture_comment(torture, "ldb speed %.2f ops/sec\n", ldb_speed);

	torture_comment(torture, "ldb/tdb speed ratio is %.2f%%\n", (100*ldb_speed/tdb_speed));
	

	unlink("./test.ldb");
	talloc_free(tmp_ctx);
	return true;

failed:
	unlink("./test.ldb");
	talloc_free(tmp_ctx);
	return false;
}
Пример #13
0
static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schema *schema, bool write_attributes)
{
	int ret = LDB_SUCCESS;
	struct ldb_result *res;
	struct ldb_result *res_idx;
	struct dsdb_attribute *attr;
	struct ldb_message *mod_msg;
	TALLOC_CTX *mem_ctx;
	struct ldb_message *msg;
	struct ldb_message *msg_idx;

	/* setup our own attribute name to schema handler */
	ldb_schema_attribute_set_override_handler(ldb, dsdb_attribute_handler_override, schema);

	if (!write_attributes) {
		return ret;
	}

	mem_ctx = talloc_new(ldb);
	if (!mem_ctx) {
		return ldb_oom(ldb);
	}

	msg = ldb_msg_new(mem_ctx);
	if (!msg) {
		ldb_oom(ldb);
		goto op_error;
	}
	msg_idx = ldb_msg_new(mem_ctx);
	if (!msg_idx) {
		ldb_oom(ldb);
		goto op_error;
	}
	msg->dn = ldb_dn_new(msg, ldb, "@ATTRIBUTES");
	if (!msg->dn) {
		ldb_oom(ldb);
		goto op_error;
	}
	msg_idx->dn = ldb_dn_new(msg_idx, ldb, "@INDEXLIST");
	if (!msg_idx->dn) {
		ldb_oom(ldb);
		goto op_error;
	}

	ret = ldb_msg_add_string(msg_idx, "@IDXONE", "1");
	if (ret != LDB_SUCCESS) {
		goto op_error;
	}


	ret = ldb_msg_add_string(msg_idx, "@IDXVERSION", SAMDB_INDEXING_VERSION);
	if (ret != LDB_SUCCESS) {
		goto op_error;
	}

	for (attr = schema->attributes; attr; attr = attr->next) {
		const char *syntax = attr->syntax->ldb_syntax;

		if (!syntax) {
			syntax = attr->syntax->ldap_oid;
		}

		/*
		 * Write out a rough approximation of the schema
		 * as an @ATTRIBUTES value, for bootstrapping
		 */
		if (strcmp(syntax, LDB_SYNTAX_INTEGER) == 0) {
			ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "INTEGER");
		} else if (strcmp(syntax, LDB_SYNTAX_DIRECTORY_STRING) == 0) {
			ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "CASE_INSENSITIVE");
		}
		if (ret != LDB_SUCCESS) {
			break;
		}

		if (attr->searchFlags & SEARCH_FLAG_ATTINDEX) {
			ret = ldb_msg_add_string(msg_idx, "@IDXATTR", attr->lDAPDisplayName);
			if (ret != LDB_SUCCESS) {
				break;
			}
		}
	}

	if (ret != LDB_SUCCESS) {
		talloc_free(mem_ctx);
		return ret;
	}

	/*
	 * Try to avoid churning the attributes too much,
	 * we only want to do this if they have changed
	 */
	ret = ldb_search(ldb, mem_ctx, &res, msg->dn, LDB_SCOPE_BASE, NULL,
			 NULL);
	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		ret = ldb_add(ldb, msg);
	} else if (ret != LDB_SUCCESS) {
	} else if (res->count != 1) {
		ret = ldb_add(ldb, msg);
	} else {
		ret = LDB_SUCCESS;
		/* Annoyingly added to our search results */
		ldb_msg_remove_attr(res->msgs[0], "distinguishedName");

		ret = ldb_msg_difference(ldb, mem_ctx,
		                         res->msgs[0], msg, &mod_msg);
		if (ret != LDB_SUCCESS) {
			goto op_error;
		}
		if (mod_msg->num_elements > 0) {
			ret = dsdb_replace(ldb, mod_msg, 0);
		}
		talloc_free(mod_msg);
	}

	if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS || ret == LDB_ERR_INVALID_DN_SYNTAX) {
		/* We might be on a read-only DB or LDAP */
		ret = LDB_SUCCESS;
	}
	if (ret != LDB_SUCCESS) {
		talloc_free(mem_ctx);
		return ret;
	}

	/* Now write out the indexes, as found in the schema (if they have changed) */

	ret = ldb_search(ldb, mem_ctx, &res_idx, msg_idx->dn, LDB_SCOPE_BASE,
			 NULL, NULL);
	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		ret = ldb_add(ldb, msg_idx);
	} else if (ret != LDB_SUCCESS) {
	} else if (res_idx->count != 1) {
		ret = ldb_add(ldb, msg_idx);
	} else {
		ret = LDB_SUCCESS;
		/* Annoyingly added to our search results */
		ldb_msg_remove_attr(res_idx->msgs[0], "distinguishedName");

		ret = ldb_msg_difference(ldb, mem_ctx,
		                         res_idx->msgs[0], msg_idx, &mod_msg);
		if (ret != LDB_SUCCESS) {
			goto op_error;
		}
		if (mod_msg->num_elements > 0) {
			ret = dsdb_replace(ldb, mod_msg, 0);
		}
		talloc_free(mod_msg);
	}
	if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS || ret == LDB_ERR_INVALID_DN_SYNTAX) {
		/* We might be on a read-only DB */
		ret = LDB_SUCCESS;
	}
	talloc_free(mem_ctx);
	return ret;

op_error:
	talloc_free(mem_ctx);
	return ldb_operr(ldb);
}
Пример #14
0
errno_t
sysdb_save_autofsentry(struct sysdb_ctx *sysdb_ctx,
                       struct sss_domain_info *domain,
                       const char *map,
                       const char *key,
                       const char *value,
                       struct sysdb_attrs *attrs)
{
    errno_t ret;
    TALLOC_CTX *tmp_ctx;
    struct ldb_message *msg;
    struct ldb_dn *dn;
    const char *name;

    DEBUG(SSSDBG_TRACE_FUNC,
          ("Adding autofs entry [%s] - [%s]\n", key, value));

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

    if (!attrs) {
        attrs = sysdb_new_attrs(tmp_ctx);
        if (!attrs) {
            ret = ENOMEM;
            goto done;
        }
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS,
                                 SYSDB_AUTOFS_ENTRY_OC);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not set entry object class [%d]: %s\n",
              ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_ENTRY_KEY, key);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not set entry key [%d]: %s\n",
              ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_ENTRY_VALUE, value);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not set entry key [%d]: %s\n",
              ret, strerror(ret)));
        goto done;
    }

    name = talloc_asprintf(tmp_ctx, "%s%s", key, value);
    if (!name) {
        ret = ENOMEM;
        goto done;
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not set name attribute [%d]: %s\n",
              ret, strerror(ret)));
        goto done;
    }

    dn = sysdb_autofsentry_dn(tmp_ctx, sysdb_ctx, domain, map, key, value);
    if (!dn) {
        ret = ENOMEM;
        goto done;
    }

    msg = ldb_msg_new(tmp_ctx);
    if (!msg) {
        ret = ENOMEM;
        goto done;
    }

    msg->dn = dn;
    msg->elements = attrs->a;
    msg->num_elements = attrs->num;

    ret = ldb_add(sysdb_ctx->ldb, msg);
    ret = sysdb_error_to_errno(ret);
done:
    talloc_free(tmp_ctx);
    return ret;
}
Пример #15
0
/* Add a user, SAMR style, including the correct transaction
 * semantics.  Used by the SAMR server and by pdb_samba4 */
NTSTATUS dsdb_add_user(struct ldb_context *ldb,
		       TALLOC_CTX *mem_ctx,
		       const char *account_name,
		       uint32_t acct_flags,
		       struct dom_sid **sid,
		       struct ldb_dn **dn)
{
	const char *name;
	struct ldb_message *msg;
	int ret;
	const char *container, *obj_class=NULL;
	char *cn_name;
	size_t cn_name_len;

	const char *attrs[] = {
		"objectSid",
		"userAccountControl",
		NULL
	};

	uint32_t user_account_control;
	struct ldb_dn *account_dn;
	struct dom_sid *account_sid;

	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	/*
	 * Start a transaction, so we can query and do a subsequent atomic
	 * modify
	 */

	ret = ldb_transaction_start(ldb);
	if (ret != LDB_SUCCESS) {
		DEBUG(0,("Failed to start a transaction for user creation: %s\n",
			 ldb_errstring(ldb)));
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	/* check if the user already exists */
	name = samdb_search_string(ldb, tmp_ctx, NULL,
				   "sAMAccountName",
				   "(&(sAMAccountName=%s)(objectclass=user))",
				   ldb_binary_encode_string(tmp_ctx, account_name));
	if (name != NULL) {
		ldb_transaction_cancel(ldb);
		talloc_free(tmp_ctx);
		return NT_STATUS_USER_EXISTS;
	}

	cn_name = talloc_strdup(tmp_ctx, account_name);
	if (!cn_name) {
		ldb_transaction_cancel(ldb);
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	cn_name_len = strlen(cn_name);
	if (cn_name_len < 1) {
		ldb_transaction_cancel(ldb);
		talloc_free(tmp_ctx);
		return NT_STATUS_INVALID_PARAMETER;
	}

	msg = ldb_msg_new(tmp_ctx);
	if (msg == NULL) {
		ldb_transaction_cancel(ldb);
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	/* This must be one of these values *only* */
	if (acct_flags == ACB_NORMAL) {
		container = "CN=Users";
		obj_class = "user";

	} else if (acct_flags == ACB_WSTRUST) {
		if (cn_name[cn_name_len - 1] != '$') {
			ldb_transaction_cancel(ldb);
			return NT_STATUS_FOOBAR;
		}
		cn_name[cn_name_len - 1] = '\0';
		container = "CN=Computers";
		obj_class = "computer";

	} else if (acct_flags == ACB_SVRTRUST) {
		if (cn_name[cn_name_len - 1] != '$') {
			ldb_transaction_cancel(ldb);
			return NT_STATUS_FOOBAR;
		}
		cn_name[cn_name_len - 1] = '\0';
		container = "OU=Domain Controllers";
		obj_class = "computer";
	} else {
		ldb_transaction_cancel(ldb);
		talloc_free(tmp_ctx);
		return NT_STATUS_INVALID_PARAMETER;
	}

	/* add core elements to the ldb_message for the user */
	msg->dn = ldb_dn_copy(msg, ldb_get_default_basedn(ldb));
	if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,%s", cn_name, container)) {
		ldb_transaction_cancel(ldb);
		talloc_free(tmp_ctx);
		return NT_STATUS_FOOBAR;
	}

	ldb_msg_add_string(msg, "sAMAccountName", account_name);
	ldb_msg_add_string(msg, "objectClass", obj_class);

	/* create the user */
	ret = ldb_add(ldb, msg);
	switch (ret) {
	case LDB_SUCCESS:
		break;
	case LDB_ERR_ENTRY_ALREADY_EXISTS:
		ldb_transaction_cancel(ldb);
		DEBUG(0,("Failed to create user record %s: %s\n",
			 ldb_dn_get_linearized(msg->dn),
			 ldb_errstring(ldb)));
		talloc_free(tmp_ctx);
		return NT_STATUS_USER_EXISTS;
	case LDB_ERR_UNWILLING_TO_PERFORM:
	case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
		ldb_transaction_cancel(ldb);
		DEBUG(0,("Failed to create user record %s: %s\n",
			 ldb_dn_get_linearized(msg->dn),
			 ldb_errstring(ldb)));
		talloc_free(tmp_ctx);
		return NT_STATUS_ACCESS_DENIED;
	default:
		ldb_transaction_cancel(ldb);
		DEBUG(0,("Failed to create user record %s: %s\n",
			 ldb_dn_get_linearized(msg->dn),
			 ldb_errstring(ldb)));
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	account_dn = msg->dn;

	/* retrieve the sid and account control bits for the user just created */
	ret = dsdb_search_one(ldb, tmp_ctx, &msg,
			      account_dn, LDB_SCOPE_BASE, attrs, 0, NULL);

	if (ret != LDB_SUCCESS) {
		ldb_transaction_cancel(ldb);
		DEBUG(0,("Can't locate the account we just created %s: %s\n",
			 ldb_dn_get_linearized(account_dn), ldb_errstring(ldb)));
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}
	account_sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
	if (account_sid == NULL) {
		ldb_transaction_cancel(ldb);
		DEBUG(0,("Apparently we failed to get the objectSid of the just created account record %s\n",
			 ldb_dn_get_linearized(msg->dn)));
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	/* Change the account control to be the correct account type.
	 * The default is for a workstation account */
	user_account_control = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
	user_account_control = (user_account_control &
				~(UF_NORMAL_ACCOUNT |
				  UF_INTERDOMAIN_TRUST_ACCOUNT |
				  UF_WORKSTATION_TRUST_ACCOUNT |
				  UF_SERVER_TRUST_ACCOUNT));
	user_account_control |= ds_acb2uf(acct_flags);

	talloc_free(msg);
	msg = ldb_msg_new(tmp_ctx);
	if (msg == NULL) {
		ldb_transaction_cancel(ldb);
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	msg->dn = account_dn;

	if (samdb_msg_add_uint(ldb, tmp_ctx, msg,
			       "userAccountControl",
			       user_account_control) != LDB_SUCCESS) {
		ldb_transaction_cancel(ldb);
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	/* modify the samdb record */
	ret = dsdb_replace(ldb, msg, 0);
	if (ret != LDB_SUCCESS) {
		DEBUG(0,("Failed to modify account record %s to set userAccountControl: %s\n",
			 ldb_dn_get_linearized(msg->dn),
			 ldb_errstring(ldb)));
		ldb_transaction_cancel(ldb);
		talloc_free(tmp_ctx);

		/* we really need samdb.c to return NTSTATUS */
		return NT_STATUS_UNSUCCESSFUL;
	}

	ret = ldb_transaction_commit(ldb);
	if (ret != LDB_SUCCESS) {
		DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
			 ldb_dn_get_linearized(msg->dn),
			 ldb_errstring(ldb)));
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}
	*dn = talloc_steal(mem_ctx, account_dn);
	*sid = talloc_steal(mem_ctx, account_sid);
	talloc_free(tmp_ctx);
	return NT_STATUS_OK;
}
Пример #16
0
/*
  connect to the group mapping ldb
*/
static bool init_group_mapping(void)
{
	bool existed;
	const char *init_ldif[] = 
		{ "dn: @ATTRIBUTES\n" \
		  "ntName: CASE_INSENSITIVE\n" \
		  "\n",
		  "dn: @INDEXLIST\n" \
		  "@IDXATTR: gidNumber\n" \
		  "@IDXATTR: ntName\n" \
		  "@IDXATTR: member\n" };
	const char *db_path, *tdb_path;
	int ret;
	int flags = 0;

	if (ldb != NULL) {
		return True;
	}

	/* this is needed as Samba3 doesn't have this globally yet */
	ldb_global_init();

	db_path = state_path("group_mapping.ldb");

	ldb = ldb_init(NULL);
	if (ldb == NULL) goto failed;

	/* Ensure this db is created read/write for root only. */
	ldb_set_create_perms(ldb, 0600);

	existed = file_exist(db_path, NULL);

	if (lp_parm_bool(-1, "groupmap", "nosync", False)) {
		flags |= LDB_FLG_NOSYNC;
	}

	if (!lp_use_mmap()) {
		flags |= LDB_FLG_NOMMAP;
	}

	ret = ldb_connect(ldb, db_path, flags, NULL);
	if (ret != LDB_SUCCESS) {
		goto failed;
	}

	/* force the permissions on the ldb to 0600 - this will fix
	   existing databases as well as new ones */
	if (chmod(db_path, 0600) != 0) {
		goto failed;
	}

	if (!existed) {
		/* initialise the ldb with an index */
		struct ldb_ldif *ldif;
		int i;
		for (i=0;i<ARRAY_SIZE(init_ldif);i++) {
			ldif = ldb_ldif_read_string(ldb, &init_ldif[i]);
			if (ldif == NULL) goto failed;
			ret = ldb_add(ldb, ldif->msg);
			talloc_free(ldif);
			if (ret == -1) goto failed;
		}
	}

	/* possibly upgrade */
	tdb_path = state_path("group_mapping.tdb");
	if (file_exist(tdb_path, NULL) && !mapping_upgrade(tdb_path)) {
		unlink(state_path("group_mapping.ldb"));
		goto failed;
	}

	return True;

failed:
	DEBUG(0,("Failed to open group mapping ldb '%s' - '%s'\n",
		 db_path, ldb?ldb_errstring(ldb):strerror(errno)));
	talloc_free(ldb);
	ldb = NULL;
	return False;
}
Пример #17
0
int confdb_init_db(const char *config_file, struct confdb_ctx *cdb)
{
    TALLOC_CTX *tmp_ctx;
    int ret;
    int sret = EOK;
    int version;
    char timestr[21];
    char *lasttimestr;
    bool in_transaction = false;
    const char *config_ldif;
    const char *vals[2] = { timestr, NULL };
    struct ldb_ldif *ldif;
    struct sss_ini_initdata *init_data;


    tmp_ctx = talloc_new(cdb);
    if (tmp_ctx == NULL) {
        DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory.\n");
        return ENOMEM;
    }

    init_data = sss_ini_initdata_init(tmp_ctx);
    if (!init_data) {
        DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory.\n");
        ret = ENOMEM;
        goto done;
    }

    /* Open config file */
    ret = sss_ini_config_file_open(init_data, config_file);
    if (ret != EOK) {
        DEBUG(SSSDBG_TRACE_FUNC,
              "sss_ini_config_file_open failed: %s [%d]\n", strerror(ret),
               ret);
        if (ret == ENOENT) {
            /* sss specific error denoting missing configuration file */
            ret = ERR_MISSING_CONF;
        }
        goto done;
    }

    ret = sss_ini_config_access_check(init_data);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Permission check on config file failed.\n");
        ret = EPERM;
        goto done;
    }

    /* Determine if the conf file has changed since we last updated
     * the confdb
     */
    ret = sss_ini_get_stat(init_data);
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Status check on config file failed.\n");
        ret = errno;
        goto done;
    }

    errno = 0;

    ret = sss_ini_get_mtime(init_data, sizeof(timestr), timestr);
    if (ret <= 0 || ret >= sizeof(timestr)) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Failed to convert time_t to string ??\n");
        ret = errno ? errno : EFAULT;
    }
    ret = confdb_get_string(cdb, tmp_ctx, "config", "lastUpdate",
                            NULL, &lasttimestr);
    if (ret == EOK) {

        /* check if we lastUpdate and last file modification change differ*/
        if ((lasttimestr != NULL) && (strcmp(lasttimestr, timestr) == 0)) {
            /* not changed, get out, nothing more to do */
            ret = EOK;
            goto done;
        }
    } else {
        DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get lastUpdate attribute.\n");
        goto done;
    }

    ret = sss_ini_get_config(init_data, config_file);
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load configuration\n");
        goto done;
    }

    /* Make sure that the config file version matches the confdb version */
    ret = sss_ini_get_cfgobj(init_data, "sssd", "config_file_version");
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Internal error determining config_file_version\n");
        goto done;
    }

    ret = sss_ini_check_config_obj(init_data);
    if (ret != EOK) {
        /* No known version. Assumed to be version 1 */
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Config file is an old version. "
               "Please run configuration upgrade script.\n");
        ret = EINVAL;
        goto done;
    }

    version = sss_ini_get_int_config_value(init_data, 1, -1, &ret);
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE,
                "Config file version could not be determined\n");
        goto done;
    } else if (version < CONFDB_VERSION_INT) {
        DEBUG(SSSDBG_FATAL_FAILURE,
                "Config file is an old version. "
                 "Please run configuration upgrade script.\n");
        ret = EINVAL;
        goto done;
    } else if (version > CONFDB_VERSION_INT) {
        DEBUG(SSSDBG_FATAL_FAILURE,
                "Config file version is newer than confdb\n");
        ret = EINVAL;
        goto done;
    }

    /* Set up a transaction to replace the configuration */
    ret = ldb_transaction_start(cdb->ldb);
    if (ret != LDB_SUCCESS) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Failed to start a transaction for "
               "updating the configuration\n");
        ret = sysdb_error_to_errno(ret);
        goto done;
    }
    in_transaction = true;

    /* Purge existing database */
    ret = confdb_purge(cdb);
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Could not purge existing configuration\n");
        goto done;
    }

    ret = sss_confdb_create_ldif(tmp_ctx, init_data, &config_ldif);
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE, "Could not create LDIF for confdb\n");
        goto done;
    }

    DEBUG(SSSDBG_TRACE_LIBS, "LDIF file to import: \n%s", config_ldif);

    while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) {
        ret = ldb_add(cdb->ldb, ldif->msg);
        if (ret != LDB_SUCCESS) {
            DEBUG(SSSDBG_FATAL_FAILURE,
                    "Failed to initialize DB (%d,[%s]), aborting!\n",
                     ret, ldb_errstring(cdb->ldb));
            ret = EIO;
            goto done;
        }
        ldb_ldif_read_free(cdb->ldb, ldif);
    }

    /* now store the lastUpdate time so that we do not re-init if nothing
     * changed on restart */

    ret = confdb_add_param(cdb, true, "config", "lastUpdate", vals);
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE,
                "Failed to set last update time on db!\n");
        goto done;
    }

    ret = ldb_transaction_commit(cdb->ldb);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
        goto done;
    }
    in_transaction = false;

    ret = EOK;

done:
    if (in_transaction) {
        sret = ldb_transaction_cancel(cdb->ldb);
        if (sret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
        }
    }

    sss_ini_config_destroy(init_data);
    sss_ini_close_file(init_data);

    talloc_zfree(tmp_ctx);
    return ret;
}
Пример #18
0
int sysdb_check_upgrade_02(struct sss_domain_info *domains,
                           const char *db_path)
{
    TALLOC_CTX *tmp_ctx = NULL;
    struct ldb_context *ldb;
    char *ldb_file;
    struct sysdb_ctx *sysdb;
    struct sss_domain_info *dom;
    struct ldb_message_element *el;
    struct ldb_message *msg;
    struct ldb_result *res;
    struct ldb_dn *verdn;
    const char *version = NULL;
    bool do_02_upgrade = false;
    bool ctx_trans = false;
    int ret;

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

    ret = sysdb_get_db_file(tmp_ctx,
                            "local", "UPGRADE",
                            db_path, &ldb_file);
    if (ret != EOK) {
        goto exit;
    }

    ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb);
    if (ret != EOK) {
        DEBUG(1, ("sysdb_ldb_connect failed.\n"));
        return ret;
    }

    verdn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE);
    if (!verdn) {
        ret = EIO;
        goto exit;
    }

    ret = ldb_search(ldb, tmp_ctx, &res,
                     verdn, LDB_SCOPE_BASE,
                     NULL, NULL);
    if (ret != LDB_SUCCESS) {
        ret = EIO;
        goto exit;
    }
    if (res->count > 1) {
        ret = EIO;
        goto exit;
    }

    if (res->count == 1) {
        el = ldb_msg_find_element(res->msgs[0], "version");
        if (el) {
            if (el->num_values != 1) {
                ret = EINVAL;
                goto exit;
            }
            version = talloc_strndup(tmp_ctx,
                                     (char *)(el->values[0].data),
                                     el->values[0].length);
            if (!version) {
                ret = ENOMEM;
                goto exit;
            }

            if (strcmp(version, SYSDB_VERSION) == 0) {
                /* all fine, return */
                ret = EOK;
                goto exit;
            }

            DEBUG(4, ("Upgrading DB from version: %s\n", version));

            if (strcmp(version, SYSDB_VERSION_0_1) == 0) {
                /* convert database */
                ret = sysdb_upgrade_01(ldb, &version);
                if (ret != EOK) goto exit;
            }

            if (strcmp(version, SYSDB_VERSION_0_2) == 0) {
                /* need to convert database to split files */
                do_02_upgrade = true;
            }

        }
    }

    if (!do_02_upgrade) {
        /* not a v2 upgrade, return and let the normal code take over any
        * further upgrade */
        ret = EOK;
        goto exit;
    }

    /* == V2->V3 UPGRADE == */

    DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_3));

    /* ldb uses posix locks,
     * posix is stupid and kills all locks when you close *any* file
     * descriptor associated to the same file.
     * Therefore we must close and reopen the ldb file here */

    /* == Backup and reopen ldb == */

    /* close */
    talloc_zfree(ldb);

    /* backup*/
    ret = backup_file(ldb_file, 0);
    if (ret != EOK) {
        goto exit;
    }

    /* reopen */
    ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb);
    if (ret != EOK) {
        DEBUG(1, ("sysdb_ldb_connect failed.\n"));
        return ret;
    }

    /* open a transaction */
    ret = ldb_transaction_start(ldb);
    if (ret != LDB_SUCCESS) {
        DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
        ret = EIO;
        goto exit;
    }

    /* == Upgrade contents == */

    for (dom = domains; dom; dom = dom->next) {
        struct ldb_dn *domain_dn;
        struct ldb_dn *users_dn;
        struct ldb_dn *groups_dn;
        int i;

        /* skip local */
        if (strcasecmp(dom->provider, "local") == 0) {
            continue;
        }

        /* create new dom db */
        ret = sysdb_domain_init_internal(tmp_ctx, dom,
                                         db_path, false, &sysdb);
        if (ret != EOK) {
            goto done;
        }

        ret = ldb_transaction_start(sysdb->ldb);
        if (ret != LDB_SUCCESS) {
            DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
            ret = EIO;
            goto done;
        }
        ctx_trans = true;

        /* search all entries for this domain in local,
         * copy them all in the new database,
         * then remove them from local */

        domain_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
                                   SYSDB_DOM_BASE, sysdb->domain->name);
        if (!domain_dn) {
            ret = ENOMEM;
            goto done;
        }

        ret = ldb_search(ldb, tmp_ctx, &res,
                         domain_dn, LDB_SCOPE_SUBTREE,
                         NULL, NULL);
        if (ret != LDB_SUCCESS) {
            ret = EIO;
            goto done;
        }

        users_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
                                 SYSDB_TMPL_USER_BASE, sysdb->domain->name);
        if (!users_dn) {
            ret = ENOMEM;
            goto done;
        }
        groups_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
                                   SYSDB_TMPL_GROUP_BASE, sysdb->domain->name);
        if (!groups_dn) {
            ret = ENOMEM;
            goto done;
        }

        for (i = 0; i < res->count; i++) {

            struct ldb_dn *orig_dn;

            msg = res->msgs[i];

            /* skip pre-created congtainers */
            if ((ldb_dn_compare(msg->dn, domain_dn) == 0) ||
                (ldb_dn_compare(msg->dn, users_dn) == 0) ||
                (ldb_dn_compare(msg->dn, groups_dn) == 0)) {
                continue;
            }

            /* regenerate the DN against the new ldb as it may have different
             * casefolding rules (example: name changing from case insensitive
             * to case sensitive) */
            orig_dn = msg->dn;
            msg->dn = ldb_dn_new(msg, sysdb->ldb,
                                 ldb_dn_get_linearized(orig_dn));
            if (!msg->dn) {
                ret = ENOMEM;
                goto done;
            }

            ret = ldb_add(sysdb->ldb, msg);
            if (ret != LDB_SUCCESS) {
                DEBUG(0, ("WARNING: Could not add entry %s,"
                          " to new ldb file! (%d [%s])\n",
                          ldb_dn_get_linearized(msg->dn),
                          ret, ldb_errstring(sysdb->ldb)));
            }

            ret = ldb_delete(ldb, orig_dn);
            if (ret != LDB_SUCCESS) {
                DEBUG(0, ("WARNING: Could not remove entry %s,"
                          " from old ldb file! (%d [%s])\n",
                          ldb_dn_get_linearized(orig_dn),
                          ret, ldb_errstring(ldb)));
            }
        }

        /* now remove the basic containers from local */
        /* these were optional so debug at level 9 in case
         * of failure just for tracing */
        ret = ldb_delete(ldb, groups_dn);
        if (ret != LDB_SUCCESS) {
            DEBUG(9, ("WARNING: Could not remove entry %s,"
                      " from old ldb file! (%d [%s])\n",
                      ldb_dn_get_linearized(groups_dn),
                      ret, ldb_errstring(ldb)));
        }
        ret = ldb_delete(ldb, users_dn);
        if (ret != LDB_SUCCESS) {
            DEBUG(9, ("WARNING: Could not remove entry %s,"
                      " from old ldb file! (%d [%s])\n",
                      ldb_dn_get_linearized(users_dn),
                      ret, ldb_errstring(ldb)));
        }
        ret = ldb_delete(ldb, domain_dn);
        if (ret != LDB_SUCCESS) {
            DEBUG(9, ("WARNING: Could not remove entry %s,"
                      " from old ldb file! (%d [%s])\n",
                      ldb_dn_get_linearized(domain_dn),
                      ret, ldb_errstring(ldb)));
        }

        ret = ldb_transaction_commit(sysdb->ldb);
        if (ret != LDB_SUCCESS) {
            DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret));
            ret = EIO;
            goto done;
        }
        ctx_trans = false;

        talloc_zfree(domain_dn);
        talloc_zfree(groups_dn);
        talloc_zfree(users_dn);
        talloc_zfree(res);
    }

    /* conversion done, upgrade version number */
    msg = ldb_msg_new(tmp_ctx);
    if (!msg) {
        ret = ENOMEM;
        goto done;
    }
    msg->dn = ldb_dn_new(tmp_ctx, 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_3);
    if (ret != LDB_SUCCESS) {
        ret = ENOMEM;
        goto done;
    }

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

    ret = ldb_transaction_commit(ldb);
    if (ret != LDB_SUCCESS) {
        DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret));
        ret = EIO;
        goto exit;
    }

    ret = EOK;

done:
    if (ret != EOK) {
        if (ctx_trans) {
            ret = ldb_transaction_cancel(sysdb->ldb);
            if (ret != LDB_SUCCESS) {
                DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret));
            }
        }
        ret = ldb_transaction_cancel(ldb);
        if (ret != LDB_SUCCESS) {
            DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret));
        }
    }

exit:
    talloc_free(tmp_ctx);
    return ret;
}
Пример #19
0
/*
  remember an established session key for a netr server authentication
  use a simple ldb structure
*/
NTSTATUS schannel_store_session_key_ldb(TALLOC_CTX *mem_ctx,
					struct ldb_context *ldb,
					struct creds_CredentialState *creds)
{
	struct ldb_message *msg;
	struct ldb_val val, seed, client_state, server_state;
	char *f;
	char *sct;
	int ret;

	f = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->negotiate_flags);

	if (f == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	sct = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->secure_channel_type);

	if (sct == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	msg = ldb_msg_new(ldb);
	if (msg == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	msg->dn = ldb_dn_new_fmt(msg, ldb, "computerName=%s", creds->computer_name);
	if ( ! msg->dn) {
		return NT_STATUS_NO_MEMORY;
	}

	val.data = creds->session_key;
	val.length = sizeof(creds->session_key);

	seed.data = creds->seed.data;
	seed.length = sizeof(creds->seed.data);

	client_state.data = creds->client.data;
	client_state.length = sizeof(creds->client.data);
	server_state.data = creds->server.data;
	server_state.length = sizeof(creds->server.data);

	ldb_msg_add_string(msg, "objectClass", "schannelState");
	ldb_msg_add_value(msg, "sessionKey", &val, NULL);
	ldb_msg_add_value(msg, "seed", &seed, NULL);
	ldb_msg_add_value(msg, "clientState", &client_state, NULL);
	ldb_msg_add_value(msg, "serverState", &server_state, NULL);
	ldb_msg_add_string(msg, "negotiateFlags", f);
	ldb_msg_add_string(msg, "secureChannelType", sct);
	ldb_msg_add_string(msg, "accountName", creds->account_name);
	ldb_msg_add_string(msg, "computerName", creds->computer_name);
	ldb_msg_add_string(msg, "flatname", creds->domain);
	samdb_msg_add_dom_sid(ldb, mem_ctx, msg, "objectSid", creds->sid);

	ldb_delete(ldb, msg->dn);

	ret = ldb_add(ldb, msg);

	if (ret != 0) {
		DEBUG(0,("Unable to add %s to session key db - %s\n", 
			 ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb)));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	return NT_STATUS_OK;
}
/**
   \details Initialize the named properties database or return pointer
   to the existing one if already initialized/opened.

   \param mem_ctx pointer to the memory context
   \param ldb_ctx pointer on pointer to the ldb context the function
   returns

   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
 */
enum mapistore_error mapistore_namedprops_init(TALLOC_CTX *mem_ctx, struct ldb_context **_ldb_ctx)
{
	int			ret;
	struct stat		sb;
	struct ldb_context	*ldb_ctx = NULL;
	struct ldb_ldif		*ldif;
	char			*filename;
	FILE			*f;
	struct tevent_context	*ev;
	char			*database;

	/* Sanity checks */
	MAPISTORE_RETVAL_IF(!mem_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
	MAPISTORE_RETVAL_IF(!_ldb_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);

	ev = tevent_context_init(mem_ctx);
	MAPISTORE_RETVAL_IF(!ev, MAPISTORE_ERR_NO_MEMORY, NULL);

	database = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), MAPISTORE_DB_NAMED);
	DEBUG(0, ("database = %s\n", database));

	/* Step 1. Stat the database and populate it if it doesn't exist */
	if (stat(database, &sb) == -1) {
		ldb_ctx = mapistore_ldb_wrap_connect(ldb_ctx, ev, database, 0);
		talloc_free(database);
		MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_DATABASE_INIT, NULL);

		filename = talloc_asprintf(mem_ctx, "%s/mapistore_namedprops.ldif", 
					   mapistore_namedprops_get_ldif_path());
		f = fopen(filename, "r");
		talloc_free(filename);
		MAPISTORE_RETVAL_IF(!f, MAPISTORE_ERROR, NULL);
		
		ldb_transaction_start(ldb_ctx);

		while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) {
			struct ldb_message *normalized_msg;
			ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg);
			MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL);
			ret = ldb_add(ldb_ctx, normalized_msg);
			talloc_free(normalized_msg);
			if (ret != LDB_SUCCESS) {
				fclose(f);
				MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL);
			}
			ldb_ldif_read_free(ldb_ctx, ldif);
		}

		ldb_transaction_commit(ldb_ctx);
		fclose(f);

	} else {
		ldb_ctx = mapistore_ldb_wrap_connect(ldb_ctx, ev, database, 0);
		talloc_free(database);
		MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_DATABASE_INIT, NULL);
	}

	*_ldb_ctx = ldb_ctx;

	return MAPISTORE_SUCCESS;
}
Пример #21
0
static NTSTATUS sldb_create(struct share_context *ctx, const char *name, struct share_info *info, int count)
{
	struct ldb_context *ldb;
	struct ldb_message *msg;
	TALLOC_CTX *tmp_ctx;
	NTSTATUS ret;
	int err, i, j;

	for (i = 0, j = 0; i < count && j != 0x03; i++) {
		if (strcasecmp(info[i].name, SHARE_TYPE) == 0) j |= 0x02;
		if (strcasecmp(info[i].name, SHARE_PATH) == 0) j |= 0x01;
		if (strcasecmp(info[i].name, SHARE_NAME) == 0) {
			if (strcasecmp(name, (char *)info[i].value) != 0) {
				return NT_STATUS_INVALID_PARAMETER;
			}
		}
	}
	if (!name || j != 0x03) {
		return NT_STATUS_INVALID_PARAMETER;
	}
	
	tmp_ctx = talloc_new(NULL);
	if (!tmp_ctx) {
		DEBUG(0,("ERROR: Out of memory!\n"));
		return NT_STATUS_NO_MEMORY;
	}

	ldb = talloc_get_type(ctx->priv_data, struct ldb_context);

	msg = ldb_msg_new(tmp_ctx);
	if (!msg) {
		DEBUG(0,("ERROR: Out of memory!\n"));
		ret = NT_STATUS_NO_MEMORY;
		goto done;
	}

	/* TODO: escape info->name */
	msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", name);
	if (!msg->dn) {
		DEBUG(0,("ERROR: Out of memory!\n"));
		ret = NT_STATUS_NO_MEMORY;
		goto done;
	}

	SHARE_ADD_STRING("objectClass", "top");
	SHARE_ADD_STRING("objectClass", "share");
	SHARE_ADD_STRING("cn", name);
	SHARE_ADD_STRING(SHARE_NAME, name);

	for (i = 0; i < count; i++) {
		if (strcasecmp(info[i].name, SHARE_NAME) == 0) continue;

		switch (info[i].type) {
		case SHARE_INFO_STRING:
			SHARE_ADD_STRING(info[i].name, (char *)info[i].value);
			break;
		case SHARE_INFO_INT:
			SHARE_ADD_INT(info[i].name, *((int *)info[i].value));
			break;
		case SHARE_INFO_BLOB:
			SHARE_ADD_BLOB(info[i].name, (DATA_BLOB *)info[i].value);
			break;
		default:
			DEBUG(2,("ERROR: Invalid share info type for %s\n", info[i].name));
			ret = NT_STATUS_INVALID_PARAMETER;
			goto done;
		}
	}

	/* TODO: Security Descriptor */

	SHARE_ADD_STRING(SHARE_AVAILABLE, "true");
	SHARE_ADD_STRING(SHARE_BROWSEABLE, "true");
	SHARE_ADD_STRING(SHARE_READONLY, "false");
	SHARE_ADD_STRING(SHARE_NTVFS_HANDLER, "unixuid");
	SHARE_ADD_STRING(SHARE_NTVFS_HANDLER, "posix");

	err = ldb_add(ldb, msg);
	if (err != LDB_SUCCESS) {
		DEBUG(2,("ERROR: unable to add share %s to share.ldb\n"
			 "       err=%d [%s]\n", name, err, ldb_errstring(ldb)));
		if (err == LDB_ERR_NO_SUCH_OBJECT) {
			ret = NT_STATUS_OBJECT_NAME_NOT_FOUND;
		} else if (err == LDB_ERR_ENTRY_ALREADY_EXISTS) {
			ret = NT_STATUS_OBJECT_NAME_COLLISION;
		} else {
			ret = NT_STATUS_UNSUCCESSFUL;
		}
		goto done;
	}

	ret = NT_STATUS_OK;
done:
	talloc_free(tmp_ctx);
	return ret;
}
Пример #22
0
NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb,
			       TALLOC_CTX *mem_ctx,
			       const char *alias_name,
			       struct dom_sid **sid,
			       struct ldb_dn **dn)
{
	const char *name;
	struct ldb_message *msg;
	struct dom_sid *alias_sid;
	int ret;

	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	if (ldb_transaction_start(ldb) != LDB_SUCCESS) {
		DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(ldb)));
		return NT_STATUS_INTERNAL_ERROR;
	}

	/* Check if alias already exists */
	name = samdb_search_string(ldb, tmp_ctx, NULL,
				   "sAMAccountName",
				   "(sAMAccountName=%s)(objectclass=group))",
				   ldb_binary_encode_string(mem_ctx, alias_name));

	if (name != NULL) {
		talloc_free(tmp_ctx);
		ldb_transaction_cancel(ldb);
		return NT_STATUS_ALIAS_EXISTS;
	}

	msg = ldb_msg_new(tmp_ctx);
	if (msg == NULL) {
		talloc_free(tmp_ctx);
		ldb_transaction_cancel(ldb);
		return NT_STATUS_NO_MEMORY;
	}

	/* add core elements to the ldb_message for the alias */
	msg->dn = ldb_dn_copy(mem_ctx, ldb_get_default_basedn(ldb));
	ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name);
	if (!msg->dn) {
		talloc_free(tmp_ctx);
		ldb_transaction_cancel(ldb);
		return NT_STATUS_NO_MEMORY;
	}

	ldb_msg_add_string(msg, "sAMAccountName", alias_name);
	ldb_msg_add_string(msg, "objectClass", "group");
	samdb_msg_add_int(ldb, mem_ctx, msg, "groupType", GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);

	/* create the alias */
	ret = ldb_add(ldb, msg);
	switch (ret) {
	case LDB_SUCCESS:
		break;
	case LDB_ERR_ENTRY_ALREADY_EXISTS:
		talloc_free(tmp_ctx);
		ldb_transaction_cancel(ldb);
		return NT_STATUS_ALIAS_EXISTS;
	case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
		talloc_free(tmp_ctx);
		ldb_transaction_cancel(ldb);
		return NT_STATUS_ACCESS_DENIED;
	default:
		DEBUG(0,("Failed to create alias record %s: %s\n",
			 ldb_dn_get_linearized(msg->dn),
			 ldb_errstring(ldb)));
		talloc_free(tmp_ctx);
		ldb_transaction_cancel(ldb);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	/* retrieve the sid for the alias just created */
	alias_sid = samdb_search_dom_sid(ldb, tmp_ctx,
					 msg->dn, "objectSid", NULL);

	if (ldb_transaction_commit(ldb) != LDB_SUCCESS) {
		DEBUG(0, ("Failed to commit transaction in dsdb_add_domain_alias(): %s\n",
			  ldb_errstring(ldb)));
		return NT_STATUS_INTERNAL_ERROR;
	}

	*dn = talloc_steal(mem_ctx, msg->dn);
	*sid = talloc_steal(mem_ctx, alias_sid);
	talloc_free(tmp_ctx);


	return NT_STATUS_OK;
}
Пример #23
0
static int local_db_put_simple(TALLOC_CTX *mem_ctx,
                               struct local_context *lctx,
                               const char *req_path,
                               const char *secret)
{
    struct ldb_message *msg;
    const char *enctype = "masterkey";
    char *enc_secret;
    int ret;

    msg = ldb_msg_new(mem_ctx);
    if (!msg) {
        ret = ENOMEM;
        goto done;
    }

    DEBUG(SSSDBG_TRACE_FUNC, "Adding a secret to [%s]\n", req_path);

    ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
        goto done;
    }

    /* make sure containers exist */
    ret = local_db_check_containers(msg, lctx, msg->dn);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "local_db_check_containers failed for [%s]: [%d]: %s\n",
              ldb_dn_get_linearized(msg->dn), ret, sss_strerror(ret));
        goto done;
    }

    ret = local_db_check_number_of_secrets(msg, lctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "local_db_check_number_of_secrets failed [%d]: %s\n",
              ret, sss_strerror(ret));
        goto done;
    }

    ret = local_encrypt(lctx, msg, secret, enctype, &enc_secret);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "local_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
        goto done;
    }

    ret = ldb_msg_add_string(msg, "type", "simple");
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "ldb_msg_add_string failed adding type:simple [%d]: %s\n",
              ret, sss_strerror(ret));
        goto done;
    }

    ret = ldb_msg_add_string(msg, "enctype", enctype);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "ldb_msg_add_string failed adding enctype [%d]: %s\n",
              ret, sss_strerror(ret));
        goto done;
    }

    ret = ldb_msg_add_string(msg, "secret", enc_secret);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "ldb_msg_add_string failed adding secret [%d]: %s\n",
              ret, sss_strerror(ret));
        goto done;
    }


    ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL));
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "ldb_msg_add_string failed adding creationTime [%d]: %s\n",
              ret, sss_strerror(ret));
        goto done;
    }

    ret = ldb_add(lctx->ldb, msg);
    if (ret != EOK) {
        if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "Secret %s already exists\n", ldb_dn_get_linearized(msg->dn));
            ret = EEXIST;
        } else {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Failed to add secret [%s]: [%d]: %s\n",
                  ldb_dn_get_linearized(msg->dn), ret, ldb_strerror(ret));
            ret = EIO;
        }
        goto done;
    }

    ret = EOK;
done:
    talloc_free(msg);
    return ret;
}
Пример #24
0
static int local_db_create(TALLOC_CTX *mem_ctx,
                           struct local_context *lctx,
                           const char *req_path)
{
    struct ldb_message *msg;
    int ret;

    msg = ldb_msg_new(mem_ctx);
    if (!msg) {
        ret = ENOMEM;
        goto done;
    }

    DEBUG(SSSDBG_TRACE_FUNC, "Creating a container at [%s]\n", req_path);

    ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
        goto done;
    }

    /* make sure containers exist */
    ret = local_db_check_containers(msg, lctx, msg->dn);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "local_db_check_containers failed for [%s]: [%d]: %s\n",
              ldb_dn_get_linearized(msg->dn), ret, sss_strerror(ret));
        goto done;
    }

    ret = local_db_check_containers_nest_level(lctx, msg->dn);
    if (ret != EOK) goto done;

    ret = ldb_msg_add_string(msg, "type", "container");
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "ldb_msg_add_string failed adding type:container [%d]: %s\n",
              ret, sss_strerror(ret));
        goto done;
    }

    ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL));
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "ldb_msg_add_string failed adding creationTime [%d]: %s\n",
              ret, sss_strerror(ret));
        goto done;
    }

    ret = ldb_add(lctx->ldb, msg);
    if (ret != EOK) {
        if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "Secret %s already exists\n", ldb_dn_get_linearized(msg->dn));
            ret = EEXIST;
        } else {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Failed to add secret [%s]: [%d]: %s\n",
                  ldb_dn_get_linearized(msg->dn), ret, ldb_strerror(ret));
            ret = EIO;
        }
        goto done;
    }

    ret = EOK;

done:
    talloc_free(msg);
    return ret;
}
Пример #25
0
/*
 * find out Site specific stuff:
 * 1. Lookup the Site name.
 * 2. Add entry CN=<netbios name>,CN=Servers,CN=<site name>,CN=Sites,CN=Configuration,<domain dn>.
 * TODO: 3.) use DsAddEntry() to create CN=NTDS Settings,CN=<netbios name>,CN=Servers,CN=<site name>,...
 */
NTSTATUS libnet_JoinSite(struct libnet_context *ctx,
                         struct ldb_context *remote_ldb,
                         struct libnet_JoinDomain *libnet_r)
{
    NTSTATUS status;
    TALLOC_CTX *tmp_ctx;

    struct libnet_JoinSite *r;

    struct ldb_dn *server_dn;
    struct ldb_message *msg;
    int rtn;

    const char *server_dn_str;
    const char *config_dn_str;
    struct nbt_name name;
    const char *dest_addr = NULL;

    tmp_ctx = talloc_named(libnet_r, 0, "libnet_JoinSite temp context");
    if (!tmp_ctx) {
        libnet_r->out.error_string = NULL;
        return NT_STATUS_NO_MEMORY;
    }

    r = talloc(tmp_ctx, struct libnet_JoinSite);
    if (!r) {
        libnet_r->out.error_string = NULL;
        talloc_free(tmp_ctx);
        return NT_STATUS_NO_MEMORY;
    }

    make_nbt_name_client(&name, libnet_r->out.samr_binding->host);
    status = resolve_name(lp_resolve_context(ctx->lp_ctx), &name, r, &dest_addr, ctx->event_ctx);
    if (!NT_STATUS_IS_OK(status)) {
        libnet_r->out.error_string = NULL;
        talloc_free(tmp_ctx);
        return status;
    }

    /* Resolve the site name and AD DN's. */
    r->in.dest_address = dest_addr;
    r->in.netbios_name = libnet_r->in.netbios_name;
    r->in.domain_dn_str = libnet_r->out.domain_dn_str;
    r->in.cldap_port = lp_cldap_port(ctx->lp_ctx);

    status = libnet_FindSite(tmp_ctx, ctx, r);
    if (!NT_STATUS_IS_OK(status)) {
        libnet_r->out.error_string =
            talloc_steal(libnet_r, r->out.error_string);
        talloc_free(tmp_ctx);
        return status;
    }

    config_dn_str = r->out.config_dn_str;
    server_dn_str = r->out.server_dn_str;

    /*
     Add entry CN=<netbios name>,CN=Servers,CN=<site name>,CN=Sites,CN=Configuration,<domain dn>.
    */
    msg = ldb_msg_new(tmp_ctx);
    if (!msg) {
        libnet_r->out.error_string = NULL;
        talloc_free(tmp_ctx);
        return NT_STATUS_NO_MEMORY;
    }

    rtn = ldb_msg_add_string(msg, "objectClass", "server");
    if (rtn != 0) {
        libnet_r->out.error_string = NULL;
        talloc_free(tmp_ctx);
        return NT_STATUS_NO_MEMORY;
    }
    rtn = ldb_msg_add_string(msg, "systemFlags", "50000000");
    if (rtn != 0) {
        libnet_r->out.error_string = NULL;
        talloc_free(tmp_ctx);
        return NT_STATUS_NO_MEMORY;
    }
    rtn = ldb_msg_add_string(msg, "serverReference", libnet_r->out.account_dn_str);
    if (rtn != 0) {
        libnet_r->out.error_string = NULL;
        talloc_free(tmp_ctx);
        return NT_STATUS_NO_MEMORY;
    }

    server_dn = ldb_dn_new(tmp_ctx, remote_ldb, server_dn_str);
    if ( ! ldb_dn_validate(server_dn)) {
        libnet_r->out.error_string = talloc_asprintf(libnet_r,
                                     "Invalid server dn: %s",
                                     server_dn_str);
        talloc_free(tmp_ctx);
        return NT_STATUS_UNSUCCESSFUL;
    }

    msg->dn = server_dn;

    rtn = ldb_add(remote_ldb, msg);
    if (rtn == LDB_ERR_ENTRY_ALREADY_EXISTS) {
        int i;

        /* make a 'modify' msg, and only for serverReference */
        msg = ldb_msg_new(tmp_ctx);
        if (!msg) {
            libnet_r->out.error_string = NULL;
            talloc_free(tmp_ctx);
            return NT_STATUS_NO_MEMORY;
        }
        msg->dn = server_dn;

        rtn = ldb_msg_add_string(msg, "serverReference",libnet_r->out.account_dn_str);
        if (rtn != 0) {
            libnet_r->out.error_string = NULL;
            talloc_free(tmp_ctx);
            return NT_STATUS_NO_MEMORY;
        }

        /* mark all the message elements (should be just one)
           as LDB_FLAG_MOD_REPLACE */
        for (i=0; i<msg->num_elements; i++) {
            msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
        }

        rtn = ldb_modify(remote_ldb, msg);
        if (rtn != 0) {
            libnet_r->out.error_string
                = talloc_asprintf(libnet_r,
                                  "Failed to modify server entry %s: %s: %d",
                                  server_dn_str,
                                  ldb_errstring(remote_ldb), rtn);
            talloc_free(tmp_ctx);
            return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
    } else if (rtn != 0) {
        libnet_r->out.error_string
            = talloc_asprintf(libnet_r,
                              "Failed to add server entry %s: %s: %d",
                              server_dn_str, ldb_errstring(remote_ldb),
                              rtn);
        talloc_free(tmp_ctx);
        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    }
    DEBUG(0, ("We still need to perform a DsAddEntry() so that we can create the CN=NTDS Settings container.\n"));

    /* Store the server DN in libnet_r */
    libnet_r->out.server_dn_str = server_dn_str;
    talloc_steal(libnet_r, server_dn_str);

    talloc_free(tmp_ctx);
    return NT_STATUS_OK;
}
Пример #26
0
int sysdb_upgrade_04(struct sysdb_ctx *sysdb, const char **ver)
{
    TALLOC_CTX *tmp_ctx;
    int ret;
    struct ldb_message *msg;

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

    DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_5));

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

    /* Add new index */
    msg = ldb_msg_new(tmp_ctx);
    if (!msg) {
        ret = ENOMEM;
        goto done;
    }
    msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
    if (!msg->dn) {
        ret = ENOMEM;
        goto done;
    }

    ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
    if (ret != LDB_SUCCESS) {
        ret = ENOMEM;
        goto done;
    }
    ret = ldb_msg_add_string(msg, "@IDXATTR", "originalDN");
    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;
    }

    /* Rebuild memberuid and memberoif attributes */
    msg = ldb_msg_new(tmp_ctx);
    if (!msg) {
        ret = ENOMEM;
        goto done;
    }
    msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@MEMBEROF-REBUILD");
    if (!msg->dn) {
        ret = ENOMEM;
        goto done;
    }

    ret = ldb_add(sysdb->ldb, msg);
    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_5);
    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_5, ver);
    talloc_free(tmp_ctx);
    return ret;
}
Пример #27
0
static WERROR sptr_AddPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
				      struct spoolss_AddForm *r)
{
	struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
	struct ldb_message *msg,**msgs;
	const char * const attrs[] = {"flags", NULL };
	int count, ret;

	/* TODO: do checks access here
	 * if (!(server->access_mask & desired_access)) {
	 *	return WERR_FOOBAR;
	 * }
	 */

	switch (r->in.level) {
	case 1:
		if (!r->in.info.info1) {
			return WERR_FOOBAR;
		}
		count = sptr_db_search(sptr_db, mem_ctx,
				       ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
				       &msgs, attrs, "(&(form-name=%s)(objectClass=form))",
				       r->in.info.info1->form_name);

		if (count == 1) return WERR_FOOBAR;
		if (count > 1) return WERR_FOOBAR;
		if (count < 0) return WERR_GENERAL_FAILURE;

		if (r->in.info.info1->flags != SPOOLSS_FORM_USER) {
			return WERR_FOOBAR;
		}

		msg = ldb_msg_new(mem_ctx);
		W_ERROR_HAVE_NO_MEMORY(msg);

		/* add core elements to the ldb_message for the Form */
		msg->dn = ldb_dn_new_fmt(msg, sptr_db, "form-name=%s,CN=Forms,CN=PrintServer", r->in.info.info1->form_name);
		SET_STRING(sptr_db, msg, "objectClass", "form");

		SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags);

		SET_STRING(sptr_db, msg, "form-name", r->in.info.info1->form_name);

		SET_UINT(sptr_db, msg, "size-width", r->in.info.info1->size.width);
		SET_UINT(sptr_db, msg, "size-height", r->in.info.info1->size.height);

		SET_UINT(sptr_db, msg, "area-left", r->in.info.info1->area.left);
		SET_UINT(sptr_db, msg, "area-top", r->in.info.info1->area.top);
		SET_UINT(sptr_db, msg, "area-right", r->in.info.info1->area.right);
		SET_UINT(sptr_db, msg, "area-bottom", r->in.info.info1->area.bottom);
		break;
	default:
		return WERR_UNKNOWN_LEVEL;
	}

	ret = ldb_add(sptr_db, msg);
	if (ret != 0) {
		return WERR_FOOBAR;
	}

	return WERR_OK;
}
Пример #28
0
/*
  remember an established session key for a netr server authentication
  use a simple ldb structure
*/
NTSTATUS schannel_store_session_key_ldb(struct ldb_context *ldb,
					TALLOC_CTX *mem_ctx,
					struct netlogon_creds_CredentialState *creds)
{
	struct ldb_message *msg;
	struct ldb_val val, seed, client_state, server_state;
	struct ldb_val *sid_val;
	char *f;
	char *sct;
	int ret;

	f = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->negotiate_flags);

	if (f == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	sct = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->secure_channel_type);

	if (sct == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	msg = ldb_msg_new(ldb);
	if (msg == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	msg->dn = ldb_dn_new_fmt(msg, ldb, "computerName=%s", creds->computer_name);
	if ( ! msg->dn) {
		return NT_STATUS_NO_MEMORY;
	}

	sid_val = schannel_dom_sid_ldb_val(msg, creds->sid);
	if (sid_val == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	val.data = creds->session_key;
	val.length = sizeof(creds->session_key);

	seed.data = creds->seed.data;
	seed.length = sizeof(creds->seed.data);

	client_state.data = creds->client.data;
	client_state.length = sizeof(creds->client.data);
	server_state.data = creds->server.data;
	server_state.length = sizeof(creds->server.data);

	ldb_msg_add_string(msg, "objectClass", "schannelState");
	ldb_msg_add_value(msg, "sessionKey", &val, NULL);
	ldb_msg_add_value(msg, "seed", &seed, NULL);
	ldb_msg_add_value(msg, "clientState", &client_state, NULL);
	ldb_msg_add_value(msg, "serverState", &server_state, NULL);
	ldb_msg_add_string(msg, "negotiateFlags", f);
	ldb_msg_add_string(msg, "secureChannelType", sct);
	ldb_msg_add_string(msg, "accountName", creds->account_name);
	ldb_msg_add_string(msg, "computerName", creds->computer_name);
	ldb_msg_add_value(msg, "objectSid", sid_val, NULL);

	ret = ldb_add(ldb, msg);
	if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
		int i;
		/* from samdb_replace() */
		/* mark all the message elements as LDB_FLAG_MOD_REPLACE */
		for (i=0;i<msg->num_elements;i++) {
			msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
		}

		ret = ldb_modify(ldb, msg);
	}

	/* We don't need a transaction here, as we either add or
	 * modify records, never delete them, so it must exist */

	if (ret != LDB_SUCCESS) {
		DEBUG(0,("Unable to add %s to session key db - %s\n",
			 ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb)));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	return NT_STATUS_OK;
}
Пример #29
0
errno_t
sysdb_svc_add(TALLOC_CTX *mem_ctx,
              struct sss_domain_info *domain,
              const char *primary_name,
              int port,
              const char **aliases,
              const char **protocols,
              struct ldb_dn **dn)
{
    errno_t ret;
    int lret;
    TALLOC_CTX *tmp_ctx;
    struct ldb_message *msg;
    unsigned long i;

    tmp_ctx = talloc_new(NULL);
    if (!tmp_ctx) return ENOMEM;

    msg = ldb_msg_new(tmp_ctx);
    if (!msg) {
        ret = ENOMEM;
        goto done;
    }

    /* svc dn */
    msg->dn = sysdb_svc_dn(domain->sysdb, msg, domain->name, primary_name);
    if (!msg->dn) {
        ret = ENOMEM;
        goto done;
    }

    /* Objectclass */
    ret = add_string(msg, LDB_FLAG_MOD_ADD,
                     SYSDB_OBJECTCLASS, SYSDB_SVC_CLASS);
    if (ret != EOK) goto done;

    /* Set the primary name */
    ret = add_string(msg, LDB_FLAG_MOD_ADD,
                     SYSDB_NAME, primary_name);
    if (ret != EOK) goto done;

    /* Set the port number */
    ret = add_ulong(msg, LDB_FLAG_MOD_ADD,
                    SYSDB_SVC_PORT, port);
    if (ret != EOK) goto done;

    /* If this service has any aliases, include them */
    if (aliases && aliases[0]) {
        /* Set the name aliases */
        lret = ldb_msg_add_empty(msg, SYSDB_NAME_ALIAS,
                                 LDB_FLAG_MOD_ADD, NULL);
        if (lret != LDB_SUCCESS) {
            ret = sysdb_error_to_errno(lret);
            goto done;
        }
        for (i=0; aliases[i]; i++) {
            lret = ldb_msg_add_string(msg, SYSDB_NAME_ALIAS, aliases[i]);
            if (lret != LDB_SUCCESS) {
                ret = sysdb_error_to_errno(lret);
                goto done;
            }
        }
    }

    /* Set the protocols */
    lret = ldb_msg_add_empty(msg, SYSDB_SVC_PROTO,
                             LDB_FLAG_MOD_ADD, NULL);
    if (lret != LDB_SUCCESS) {
        ret = sysdb_error_to_errno(lret);
        goto done;
    }
    for (i=0; protocols[i]; i++) {
        lret = ldb_msg_add_string(msg, SYSDB_SVC_PROTO, protocols[i]);
        if (lret != LDB_SUCCESS) {
            ret = sysdb_error_to_errno(lret);
            goto done;
        }
    }

    /* creation time */
    ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME,
                    (unsigned long)time(NULL));
    if (ret) goto done;

    lret = ldb_add(domain->sysdb->ldb, msg);
    ret = sysdb_error_to_errno(lret);

    if (ret == EOK && dn) {
        *dn = talloc_steal(mem_ctx, msg->dn);
    }

done:
    if (ret) {
        DEBUG(SSSDBG_TRACE_INTERNAL,
              "Error: %d (%s)\n", ret, strerror(ret));
    }
    talloc_free(tmp_ctx);
    return ret;
}
Пример #30
0
/*
  called by samr_CreateDomainGroup and pdb_samba4
*/
NTSTATUS dsdb_add_domain_group(struct ldb_context *ldb,
			       TALLOC_CTX *mem_ctx,
			       const char *groupname,
			       struct dom_sid **sid,
			       struct ldb_dn **dn)
{
	const char *name;
	struct ldb_message *msg;
	struct dom_sid *group_sid;
	int ret;

	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	/* check if the group already exists */
	name = samdb_search_string(ldb, tmp_ctx, NULL,
				   "sAMAccountName",
				   "(&(sAMAccountName=%s)(objectclass=group))",
				   ldb_binary_encode_string(tmp_ctx, groupname));
	if (name != NULL) {
		return NT_STATUS_GROUP_EXISTS;
	}

	msg = ldb_msg_new(tmp_ctx);
	if (msg == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	/* add core elements to the ldb_message for the user */
	msg->dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(ldb));
	ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", groupname);
	if (!msg->dn) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}
	ldb_msg_add_string(msg, "sAMAccountName", groupname);
	ldb_msg_add_string(msg, "objectClass", "group");

	/* create the group */
	ret = ldb_add(ldb, msg);
	switch (ret) {
	case  LDB_SUCCESS:
		break;
	case  LDB_ERR_ENTRY_ALREADY_EXISTS:
		DEBUG(0,("Failed to create group record %s: %s\n",
			 ldb_dn_get_linearized(msg->dn),
			 ldb_errstring(ldb)));
		talloc_free(tmp_ctx);
		return NT_STATUS_GROUP_EXISTS;
	case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
		DEBUG(0,("Failed to create group record %s: %s\n",
			 ldb_dn_get_linearized(msg->dn),
			 ldb_errstring(ldb)));
		talloc_free(tmp_ctx);
		return NT_STATUS_ACCESS_DENIED;
	default:
		DEBUG(0,("Failed to create group record %s: %s\n",
			 ldb_dn_get_linearized(msg->dn),
			 ldb_errstring(ldb)));
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	/* retrieve the sid for the group just created */
	group_sid = samdb_search_dom_sid(ldb, tmp_ctx,
					 msg->dn, "objectSid", NULL);
	if (group_sid == NULL) {
		return NT_STATUS_UNSUCCESSFUL;
	}

	*dn = talloc_steal(mem_ctx, msg->dn);
	*sid = talloc_steal(mem_ctx, group_sid);
	talloc_free(tmp_ctx);
	return NT_STATUS_OK;
}