📄 schema_init.c
字号:
/* Unix SMB/CIFS mplementation. DSDB schema header Copyright (C) Stefan Metzmacher <metze@samba.org> 2006 Copyright (C) Andrew Bartlett <abartlet@samba.org> 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 "dsdb/samdb/samdb.h"#include "lib/ldb/include/ldb_errors.h"#include "lib/util/dlinklist.h"#include "librpc/gen_ndr/ndr_misc.h"#include "librpc/gen_ndr/ndr_drsuapi.h"#include "librpc/gen_ndr/ndr_drsblobs.h"#include "param/param.h"struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience){ struct dsdb_schema *schema = talloc_zero(mem_ctx, struct dsdb_schema); if (!schema) { return NULL; } schema->iconv_convenience = iconv_convenience; return schema;}WERROR dsdb_load_oid_mappings_drsuapi(struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr){ uint32_t i,j; schema->prefixes = talloc_array(schema, struct dsdb_schema_oid_prefix, ctr->num_mappings); W_ERROR_HAVE_NO_MEMORY(schema->prefixes); for (i=0, j=0; i < ctr->num_mappings; i++) { if (ctr->mappings[i].oid.oid == NULL) { return WERR_INVALID_PARAM; } if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) { if (ctr->mappings[i].id_prefix != 0) { return WERR_INVALID_PARAM; } /* the magic value should be in the last array member */ if (i != (ctr->num_mappings - 1)) { return WERR_INVALID_PARAM; } if (ctr->mappings[i].oid.__ndr_size != 21) { return WERR_INVALID_PARAM; } schema->schema_info = talloc_strdup(schema, ctr->mappings[i].oid.oid); W_ERROR_HAVE_NO_MEMORY(schema->schema_info); } else { /* the last array member should contain the magic value not a oid */ if (i == (ctr->num_mappings - 1)) { return WERR_INVALID_PARAM; } schema->prefixes[j].id = ctr->mappings[i].id_prefix<<16; schema->prefixes[j].oid = talloc_asprintf(schema->prefixes, "%s.", ctr->mappings[i].oid.oid); W_ERROR_HAVE_NO_MEMORY(schema->prefixes[j].oid); schema->prefixes[j].oid_len = strlen(schema->prefixes[j].oid); j++; } } schema->num_prefixes = j; return WERR_OK;}WERROR dsdb_load_oid_mappings_ldb(struct dsdb_schema *schema, const struct ldb_val *prefixMap, const struct ldb_val *schemaInfo){ WERROR status; enum ndr_err_code ndr_err; struct prefixMapBlob pfm; char *schema_info; TALLOC_CTX *mem_ctx = talloc_new(schema); W_ERROR_HAVE_NO_MEMORY(mem_ctx); ndr_err = ndr_pull_struct_blob(prefixMap, mem_ctx, schema->iconv_convenience, &pfm, (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); talloc_free(mem_ctx); return ntstatus_to_werror(nt_status); } if (pfm.version != PREFIX_MAP_VERSION_DSDB) { talloc_free(mem_ctx); return WERR_FOOBAR; } if (schemaInfo->length != 21 && schemaInfo->data[0] == 0xFF) { talloc_free(mem_ctx); return WERR_FOOBAR; } /* append the schema info as last element */ pfm.ctr.dsdb.num_mappings++; pfm.ctr.dsdb.mappings = talloc_realloc(mem_ctx, pfm.ctr.dsdb.mappings, struct drsuapi_DsReplicaOIDMapping, pfm.ctr.dsdb.num_mappings); W_ERROR_HAVE_NO_MEMORY(pfm.ctr.dsdb.mappings); schema_info = data_blob_hex_string(pfm.ctr.dsdb.mappings, schemaInfo); W_ERROR_HAVE_NO_MEMORY(schema_info); pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].id_prefix = 0; pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.__ndr_size = schemaInfo->length; pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.oid = schema_info; /* call the drsuapi version */ status = dsdb_load_oid_mappings_drsuapi(schema, &pfm.ctr.dsdb); talloc_free(mem_ctx); W_ERROR_NOT_OK_RETURN(status); return WERR_OK;}WERROR dsdb_get_oid_mappings_drsuapi(const struct dsdb_schema *schema, bool include_schema_info, TALLOC_CTX *mem_ctx, struct drsuapi_DsReplicaOIDMapping_Ctr **_ctr){ struct drsuapi_DsReplicaOIDMapping_Ctr *ctr; uint32_t i; ctr = talloc(mem_ctx, struct drsuapi_DsReplicaOIDMapping_Ctr); W_ERROR_HAVE_NO_MEMORY(ctr); ctr->num_mappings = schema->num_prefixes; if (include_schema_info) ctr->num_mappings++; ctr->mappings = talloc_array(schema, struct drsuapi_DsReplicaOIDMapping, ctr->num_mappings); W_ERROR_HAVE_NO_MEMORY(ctr->mappings); for (i=0; i < schema->num_prefixes; i++) { ctr->mappings[i].id_prefix = schema->prefixes[i].id>>16; ctr->mappings[i].oid.oid = talloc_strndup(ctr->mappings, schema->prefixes[i].oid, schema->prefixes[i].oid_len - 1); W_ERROR_HAVE_NO_MEMORY(ctr->mappings[i].oid.oid); } if (include_schema_info) { ctr->mappings[i].id_prefix = 0; ctr->mappings[i].oid.oid = talloc_strdup(ctr->mappings, schema->schema_info); W_ERROR_HAVE_NO_MEMORY(ctr->mappings[i].oid.oid); } *_ctr = ctr; return WERR_OK;}WERROR dsdb_get_oid_mappings_ldb(const struct dsdb_schema *schema, TALLOC_CTX *mem_ctx, struct ldb_val *prefixMap, struct ldb_val *schemaInfo){ WERROR status; enum ndr_err_code ndr_err; struct drsuapi_DsReplicaOIDMapping_Ctr *ctr; struct prefixMapBlob pfm; status = dsdb_get_oid_mappings_drsuapi(schema, false, mem_ctx, &ctr); W_ERROR_NOT_OK_RETURN(status); pfm.version = PREFIX_MAP_VERSION_DSDB; pfm.reserved = 0; pfm.ctr.dsdb = *ctr; ndr_err = ndr_push_struct_blob(prefixMap, mem_ctx, schema->iconv_convenience, &pfm, (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); talloc_free(ctr); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); return ntstatus_to_werror(nt_status); } *schemaInfo = strhex_to_data_blob(schema->schema_info); W_ERROR_HAVE_NO_MEMORY(schemaInfo->data); talloc_steal(mem_ctx, schemaInfo->data); return WERR_OK;}WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr){ uint32_t i,j; for (i=0; i < ctr->num_mappings; i++) { if (ctr->mappings[i].oid.oid == NULL) { return WERR_INVALID_PARAM; } if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) { if (ctr->mappings[i].id_prefix != 0) { return WERR_INVALID_PARAM; } /* the magic value should be in the last array member */ if (i != (ctr->num_mappings - 1)) { return WERR_INVALID_PARAM; } if (ctr->mappings[i].oid.__ndr_size != 21) { return WERR_INVALID_PARAM; } if (strcasecmp(schema->schema_info, ctr->mappings[i].oid.oid) != 0) { return WERR_DS_DRA_SCHEMA_MISMATCH; } } else { /* the last array member should contain the magic value not a oid */ if (i == (ctr->num_mappings - 1)) { return WERR_INVALID_PARAM; } for (j=0; j < schema->num_prefixes; j++) { size_t oid_len; if (schema->prefixes[j].id != (ctr->mappings[i].id_prefix<<16)) { continue; } oid_len = strlen(ctr->mappings[i].oid.oid); if (oid_len != (schema->prefixes[j].oid_len - 1)) { return WERR_DS_DRA_SCHEMA_MISMATCH; } if (strncmp(ctr->mappings[i].oid.oid, schema->prefixes[j].oid, oid_len) != 0) { return WERR_DS_DRA_SCHEMA_MISMATCH; } break; } if (j == schema->num_prefixes) { return WERR_DS_DRA_SCHEMA_MISMATCH; } } } return WERR_OK;}WERROR dsdb_map_oid2int(const struct dsdb_schema *schema, const char *in, uint32_t *out){ uint32_t i; for (i=0; i < schema->num_prefixes; i++) { const char *val_str; char *end_str; unsigned val; if (strncmp(schema->prefixes[i].oid, in, schema->prefixes[i].oid_len) != 0) { continue; } val_str = in + schema->prefixes[i].oid_len; end_str = NULL; errno = 0; if (val_str[0] == '\0') { return WERR_INVALID_PARAM; } /* two '.' chars are invalid */ if (val_str[0] == '.') { return WERR_INVALID_PARAM; } val = strtoul(val_str, &end_str, 10); if (end_str[0] == '.' && end_str[1] != '\0') { /* * if it's a '.' and not the last char * then maybe an other mapping apply */ continue; } else if (end_str[0] != '\0') { return WERR_INVALID_PARAM; } else if (val > 0xFFFF) { return WERR_INVALID_PARAM; } *out = schema->prefixes[i].id | val; return WERR_OK; } return WERR_DS_NO_MSDS_INTID;}WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CTX *mem_ctx, const char **out){ uint32_t i; for (i=0; i < schema->num_prefixes; i++) { const char *val; if (schema->prefixes[i].id != (in & 0xFFFF0000)) { continue; } val = talloc_asprintf(mem_ctx, "%s%u", schema->prefixes[i].oid, in & 0xFFFF); W_ERROR_HAVE_NO_MEMORY(val); *out = val; return WERR_OK; } return WERR_DS_NO_MSDS_INTID;}#define GET_STRING_LDB(msg, attr, mem_ctx, p, elem, strict) do { \ (p)->elem = samdb_result_string(msg, attr, NULL);\ if (strict && (p)->elem == NULL) { \ d_printf("%s: %s == NULL\n", __location__, attr); \ return WERR_INVALID_PARAM; \ } \ talloc_steal(mem_ctx, (p)->elem); \} while (0)#define GET_STRING_LIST_LDB(msg, attr, mem_ctx, p, elem, strict) do { \ int get_string_list_counter; \ struct ldb_message_element *get_string_list_el = ldb_msg_find_element(msg, attr); \ if (get_string_list_el == NULL) { \ if (strict) { \ d_printf("%s: %s == NULL\n", __location__, attr); \ return WERR_INVALID_PARAM; \ } else { \ (p)->elem = NULL; \ break; \ } \ } \ (p)->elem = talloc_array(mem_ctx, const char *, get_string_list_el->num_values + 1); \ for (get_string_list_counter=0; \ get_string_list_counter < get_string_list_el->num_values; \ get_string_list_counter++) { \ (p)->elem[get_string_list_counter] = talloc_strndup((p)->elem, \ (const char *)get_string_list_el->values[get_string_list_counter].data, \ get_string_list_el->values[get_string_list_counter].length); \ if (!(p)->elem[get_string_list_counter]) { \ d_printf("%s: talloc_strndup failed for %s\n", __location__, attr); \ return WERR_NOMEM; \ } \ (p)->elem[get_string_list_counter+1] = NULL; \ } \ talloc_steal(mem_ctx, (p)->elem); \} while (0)#define GET_BOOL_LDB(msg, attr, p, elem, strict) do { \ const char *str; \ str = samdb_result_string(msg, attr, NULL);\ if (str == NULL) { \ if (strict) { \ d_printf("%s: %s == NULL\n", __location__, attr); \ return WERR_INVALID_PARAM; \ } else { \ (p)->elem = false; \ } \ } else if (strcasecmp("TRUE", str) == 0) { \ (p)->elem = true; \ } else if (strcasecmp("FALSE", str) == 0) { \ (p)->elem = false; \ } else { \ d_printf("%s: %s == %s\n", __location__, attr, str); \ return WERR_INVALID_PARAM; \ } \} while (0)#define GET_UINT32_LDB(msg, attr, p, elem) do { \ (p)->elem = samdb_result_uint(msg, attr, 0);\} while (0)#define GET_GUID_LDB(msg, attr, p, elem) do { \ (p)->elem = samdb_result_guid(msg, attr);\} while (0)#define GET_BLOB_LDB(msg, attr, mem_ctx, p, elem) do { \ const struct ldb_val *_val;\ _val = ldb_msg_find_ldb_val(msg, attr);\ if (_val) {\ (p)->elem = *_val;\ talloc_steal(mem_ctx, (p)->elem.data);\ } else {\ ZERO_STRUCT((p)->elem);\ }\} while (0)WERROR dsdb_attribute_from_ldb(const struct dsdb_schema *schema, struct ldb_message *msg, TALLOC_CTX *mem_ctx, struct dsdb_attribute *attr){ WERROR status; GET_STRING_LDB(msg, "cn", mem_ctx, attr, cn, false); GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, true); GET_STRING_LDB(msg, "attributeID", mem_ctx, attr, attributeID_oid, true); if (schema->num_prefixes == 0) { /* set an invalid value */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -