⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldb.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   Unix SMB/CIFS implementation.   Registry interface   Copyright (C) Jelmer Vernooij  2004-2007.   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program.  If not, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "registry.h"#include "lib/ldb/include/ldb.h"#include "lib/ldb/include/ldb_errors.h"#include "ldb_wrap.h"#include "librpc/gen_ndr/winreg.h"#include "param/param.h"static struct hive_operations reg_backend_ldb;struct ldb_key_data{	struct hive_key key;	struct ldb_context *ldb;	struct ldb_dn *dn;	struct ldb_message **subkeys, **values;	int subkey_count, value_count;};static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, 				 struct smb_iconv_convenience *iconv_convenience,				 struct ldb_message *msg,				 const char **name, uint32_t *type,				 DATA_BLOB *data){	const struct ldb_val *val;	uint32_t value_type;	if (name != NULL)		*name = talloc_strdup(mem_ctx,				      ldb_msg_find_attr_as_string(msg, "value",				      NULL));	value_type = ldb_msg_find_attr_as_uint(msg, "type", 0);	if (type != NULL)		*type = value_type; 	val = ldb_msg_find_ldb_val(msg, "data");	switch (value_type)	{	case REG_SZ:	case REG_EXPAND_SZ:		data->length = convert_string_talloc(mem_ctx, iconv_convenience, CH_UTF8, CH_UTF16,						     val->data, val->length,						     (void **)&data->data);		break;	case REG_DWORD: {		uint32_t tmp = strtoul((char *)val->data, NULL, 0);		*data = data_blob_talloc(mem_ctx, &tmp, 4);		}		break;	default:		*data = data_blob_talloc(mem_ctx, val->data, val->length);		break;	}}static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx,					      TALLOC_CTX *mem_ctx,					      const char *name,					      uint32_t type, DATA_BLOB data){	struct ldb_val val;	struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message);	char *type_s;	ldb_msg_add_string(msg, "value", talloc_strdup(mem_ctx, name));	switch (type) {	case REG_SZ:	case REG_EXPAND_SZ:		val.length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX,						   (void *)data.data,						   data.length,						   (void **)&val.data);		ldb_msg_add_value(msg, "data", &val, NULL);		break;	case REG_DWORD:		ldb_msg_add_string(msg, "data",				   talloc_asprintf(mem_ctx, "0x%x",				   		   IVAL(data.data, 0)));		break;	default:		ldb_msg_add_value(msg, "data", &data, NULL);	}	type_s = talloc_asprintf(mem_ctx, "%u", type);	ldb_msg_add_string(msg, "type", type_s);	return msg;}static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value){	struct ldb_val val;	val.data = discard_const_p(uint8_t, value);	val.length = strlen(value);	return ldb_dn_escape_value(mem_ctx, val);}static int reg_close_ldb_key(struct ldb_key_data *key){	if (key->subkeys != NULL) {		talloc_free(key->subkeys);		key->subkeys = NULL;	}	if (key->values != NULL) {		talloc_free(key->values);		key->values = NULL;	}	return 0;}static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx,				      const struct hive_key *from,				      const char *path, const char *add){	TALLOC_CTX *local_ctx;	struct ldb_dn *ret;	char *mypath = talloc_strdup(mem_ctx, path);	char *begin;	struct ldb_key_data *kd = talloc_get_type(from, struct ldb_key_data);	struct ldb_context *ldb = kd->ldb;	local_ctx = talloc_new(mem_ctx);	if (add) {		ret = ldb_dn_new(mem_ctx, ldb, add);	} else {		ret = ldb_dn_new(mem_ctx, ldb, NULL);	}	if (!ldb_dn_validate(ret)) {		talloc_free(ret);		talloc_free(local_ctx);		return NULL;	}	while (mypath) {		char *keyname;		begin = strrchr(mypath, '\\');		if (begin) keyname = begin + 1;		else keyname = mypath;		if(strlen(keyname)) {			if (!ldb_dn_add_base_fmt(ret, "key=%s",						 reg_ldb_escape(local_ctx,								keyname)))			{				talloc_free(local_ctx);				return NULL;			}		}		if(begin) {			*begin = '\0';		} else {			break;		}	}	ldb_dn_add_base(ret, kd->dn);	talloc_free(local_ctx);	return ret;}static WERROR cache_subkeys(struct ldb_key_data *kd){	struct ldb_context *c = kd->ldb;	struct ldb_result *res;	int ret;	ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res);	if (ret != LDB_SUCCESS) {		DEBUG(0, ("Error getting subkeys for '%s': %s\n",			ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));		return WERR_FOOBAR;	}	kd->subkey_count = res->count;	kd->subkeys = talloc_steal(kd, res->msgs);	talloc_free(res);	return WERR_OK;}static WERROR cache_values(struct ldb_key_data *kd){	struct ldb_context *c = kd->ldb;	struct ldb_result *res;	int ret;	ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL,			 "(value=*)", NULL, &res);	if (ret != LDB_SUCCESS) {		DEBUG(0, ("Error getting values for '%s': %s\n",			ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));		return WERR_FOOBAR;	}	kd->value_count = res->count;	kd->values = talloc_steal(kd, res->msgs);	talloc_free(res);	return WERR_OK;}static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx,				   const struct hive_key *k, uint32_t idx,				   const char **name,				   const char **classname,				   NTTIME *last_mod_time){	struct ldb_message_element *el;	struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);	/* Do a search if necessary */	if (kd->subkeys == NULL) {		W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));	}	if (idx >= kd->subkey_count)		return WERR_NO_MORE_ITEMS;	el = ldb_msg_find_element(kd->subkeys[idx], "key");	SMB_ASSERT(el != NULL);	SMB_ASSERT(el->num_values != 0);	if (name != NULL)		*name = talloc_strdup(mem_ctx, (char *)el->values[0].data);	if (classname != NULL)		*classname = NULL; /* TODO: Store properly */	if (last_mod_time != NULL)		*last_mod_time = 0; /* TODO: we need to add this to the						ldb backend properly */	return WERR_OK;}static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k,				  int idx, const char **name,				  uint32_t *data_type, DATA_BLOB *data){	struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);	/* Do the search if necessary */	if (kd->values == NULL) {		W_ERROR_NOT_OK_RETURN(cache_values(kd));	}	if (idx >= kd->value_count)		return WERR_NO_MORE_ITEMS;	reg_ldb_unpack_value(mem_ctx, lp_iconv_convenience(global_loadparm), kd->values[idx],			     name, data_type, data);	return WERR_OK;}static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k,			    const char *name, uint32_t *data_type,			    DATA_BLOB *data){	struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);	struct ldb_context *c = kd->ldb;	struct ldb_result *res;	int ret;	char *query = talloc_asprintf(mem_ctx, "(value=%s)", name);	ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, query, NULL, &res);	talloc_free(query);	if (ret != LDB_SUCCESS) {		DEBUG(0, ("Error getting values for '%s': %s\n",			ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));		return WERR_FOOBAR;	}	if (res->count == 0)		return WERR_BADFILE;	reg_ldb_unpack_value(mem_ctx, lp_iconv_convenience(global_loadparm), res->msgs[0], NULL, data_type, data);	return WERR_OK;}static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h,			   const char *name, struct hive_key **key){	struct ldb_result *res;	struct ldb_dn *ldap_path;	int ret;	struct ldb_key_data *newkd;	struct ldb_key_data *kd = talloc_get_type(h, struct ldb_key_data);	struct ldb_context *c = kd->ldb;	ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL);	ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res);	if (ret != LDB_SUCCESS) {		DEBUG(3, ("Error opening key '%s': %s\n",			ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));		return WERR_FOOBAR;	} else if (res->count == 0) {		DEBUG(3, ("Key '%s' not found\n",			ldb_dn_get_linearized(ldap_path)));		talloc_free(res);		return WERR_BADFILE;	}	newkd = talloc_zero(mem_ctx, struct ldb_key_data);	newkd->key.ops = &reg_backend_ldb;	newkd->ldb = talloc_reference(newkd, kd->ldb);	newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn);	*key = (struct hive_key *)newkd;	talloc_free(res);	return WERR_OK;}WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location,			 struct auth_session_info *session_info,			 struct cli_credentials *credentials,			 struct event_context *ev_ctx,			 struct loadparm_context *lp_ctx,			 struct hive_key **k){	struct ldb_key_data *kd;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -