The branch, master has been updated via 94f5b2f ldb:ldb_msg.c - make "ldb_msg_find_attr_as_*" more robust against invalid values via df9d46a ldb:ldb_msg_check_sanity - clean it up from unneeded stuff via ddb41f2 dsdb:schema/schema_syntax.c - correctly check error code of "ldb_string_utc_to_time" via 6cef940 dsdb:schema/schema_syntax.c - add some empty value checks on validate functions via b7de06e s4:objectclass LDB module - "ldb_msg_sanity_check" call not really needed via 17f3413 ldb:ldbadd/modify tool - return error code when at least one operation has failed via f146992 ldb:tests - "init.ldif" - deactivate empty "seeAlso" attribute via 3cd11b5 ldb:ldb/common/ldb_modules.c - always use LDB error codes if possible via 32cad76 ldb:common/*.c - check for some OOM conditions via 1d8980d s4:objectclass LDB module - fix a comment - add a ")" from 02c6f9d selftest:Samba4: setup DC_* variables in provision_rpc_proxy()
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 94f5b2f41346170fea90b4571f172df124139143 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Wed Apr 6 09:57:51 2011 +0200 ldb:ldb_msg.c - make "ldb_msg_find_attr_as_*" more robust against invalid values - Integer handling was modeled after validate code from "schema_syntax.c". - Double handling was modeled similar, but with a dynamic buffer. I don't know if there is a maximum literal length for double values but an allocation shouldn't a problem here since doubles are rare. - String handlind is enhanced with a terminating "0" test for safety. Reviewed-by: abartlet + metze Autobuild-User: Matthias Dieter Wallnöfer <m...@samba.org> Autobuild-Date: Thu Apr 7 16:38:57 CEST 2011 on sn-devel-104 commit df9d46a353da15f68d299498f36ab0474c8e1e5a Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Thu Apr 7 10:11:46 2011 +0200 ldb:ldb_msg_check_sanity - clean it up from unneeded stuff commit ddb41f2af48caa856ce45338cffaadaa9226c76c Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Mon Apr 4 21:34:12 2011 +0200 dsdb:schema/schema_syntax.c - correctly check error code of "ldb_string_utc_to_time" This one doesn't set ERRNO. An error happens if the result is "0". Reviewed-by: abartlet commit 6cef940b40b859e0b80cad1a679818de2a5b418e Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Mon Apr 4 21:33:11 2011 +0200 dsdb:schema/schema_syntax.c - add some empty value checks on validate functions They are needed since the check in "ldb_msg_sanity_check" will be removed. Reviewed-by: abartlet commit b7de06e8e756eb338e40d319095311f8f7d70cba Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Mon Apr 4 14:04:18 2011 +0200 s4:objectclass LDB module - "ldb_msg_sanity_check" call not really needed This call should only be performed at the beginning of a request. "ldb_msg_sanity_check" checks for DN validity (which should already have been done at the beginning of the request) and empty attributes (which should be done by the "objectclass_attrs" LDB module). Hence it is superflous here. Reviewed-by: abartlet commit 17f34136bf67aa5e739b63aa3ef51d247d6dc901 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Mon Apr 4 12:59:30 2011 +0200 ldb:ldbadd/modify tool - return error code when at least one operation has failed This is required to better detect failures and should raise the compatiblity to "ldapadd"/"ldapmodify". Reviewed-by: abartlet commit f14699287ca7a4f2349658bd2ae602eb30f95bf9 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Thu Apr 7 10:13:45 2011 +0200 ldb:tests - "init.ldif" - deactivate empty "seeAlso" attribute commit 3cd11b5b755795c253a8214b4d1066b0589e3a7b Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Mon Apr 4 10:43:39 2011 +0200 ldb:ldb/common/ldb_modules.c - always use LDB error codes if possible The callers do compare against LDB error codes - hence don't give back "-1". Reviewed-by: Tridge + abartlet commit 32cad7601a55b2c232c4914ab382714f331ae218 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Mon Apr 4 10:26:47 2011 +0200 ldb:common/*.c - check for some OOM conditions Reviewed-by: abartlet commit 1d8980df0494af975278954dce4b24605602ed6f Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Mon Apr 4 14:06:45 2011 +0200 s4:objectclass LDB module - fix a comment - add a ")" Reviewed-by: abartlet ----------------------------------------------------------------------- Summary of changes: source4/dsdb/samdb/ldb_modules/objectclass.c | 7 +- source4/dsdb/schema/schema_syntax.c | 12 ++- source4/lib/ldb/common/ldb.c | 4 + source4/lib/ldb/common/ldb_modules.c | 16 ++- source4/lib/ldb/common/ldb_msg.c | 129 +++++++++++++++++++++----- source4/lib/ldb/tests/init.ldif | 3 +- source4/lib/ldb/tools/ldbadd.c | 6 +- source4/lib/ldb/tools/ldbmodify.c | 7 +- 8 files changed, 141 insertions(+), 43 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index d901584..fd39937 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -354,7 +354,7 @@ static int fix_dn(struct ldb_context *ldb, #endif - /* And replace it with CN=foo (we need the attribute in upper case */ + /* And replace it with CN=foo (we need the attribute in upper case) */ return ldb_dn_set_component(*fixed_dn, 0, upper_rdn_attr, *rdn_val); } @@ -762,11 +762,6 @@ static int objectclass_do_add(struct oc_context *ac) } } - ret = ldb_msg_sanity_check(ldb, msg); - if (ret != LDB_SUCCESS) { - return ret; - } - ret = ldb_build_add_req(&add_req, ldb, ac, msg, ac->req->controls, diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c index 8be87df..ea582db 100644 --- a/source4/dsdb/schema/schema_syntax.c +++ b/source4/dsdb/schema/schema_syntax.c @@ -254,6 +254,10 @@ static WERROR dsdb_syntax_BOOL_validate_ldb(const struct dsdb_syntax_ctx *ctx, for (i=0; i < in->num_values; i++) { int t, f; + if (in->values[i].length == 0) { + return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; + } + t = strncmp("TRUE", (const char *)in->values[i].data, in->values[i].length); @@ -633,9 +637,8 @@ static WERROR dsdb_syntax_NTTIME_UTC_validate_ldb(const struct dsdb_syntax_ctx * } memcpy(buf, in->values[i].data, in->values[i].length); - errno = 0; t = ldb_string_utc_to_time(buf); - if (errno != 0) { + if (t == 0) { return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; } @@ -1379,6 +1382,11 @@ static WERROR _dsdb_syntax_OID_validate_numericoid(const struct dsdb_syntax_ctx char *oid_out; const char *oid = (const char*)in->values[i].data; + if (in->values[i].length == 0) { + talloc_free(tmp_ctx); + return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; + } + if (!ber_write_OID_String(tmp_ctx, &blob, oid)) { DEBUG(0,("ber_write_OID_String() failed for %s\n", oid)); talloc_free(tmp_ctx); diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index d902482..0aadeb0 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -104,6 +104,10 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) } ldb = talloc_zero(mem_ctx, struct ldb_context); + if (ldb == NULL) { + return NULL; + } + /* A new event context so that callers who don't want ldb * operating on thier global event context can work without * having to provide their own private one explicitly */ diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index b382a91..2e1aeb6 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -200,6 +200,9 @@ int ldb_module_connect_backend(struct ldb_context *ldb, /* Default to tdb */ backend = talloc_strdup(ldb, "tdb"); } + if (backend == NULL) { + return ldb_oom(ldb); + } be = ldb_find_backend(backend); @@ -278,14 +281,15 @@ int ldb_register_module(const struct ldb_module_ops *ops) return LDB_ERR_ENTRY_ALREADY_EXISTS; entry = talloc(talloc_autofree_context(), struct ops_list_entry); - if (entry == NULL) - return -1; + if (entry == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } entry->ops = ops; entry->next = registered_modules; registered_modules = entry; - return 0; + return LDB_SUCCESS; } /* @@ -360,7 +364,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) int ret; TALLOC_CTX *mem_ctx = talloc_new(ldb); if (!mem_ctx) { - return LDB_ERR_OPERATIONS_ERROR; + return ldb_oom(ldb); } /* find out which modules we are requested to activate */ @@ -382,7 +386,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) mods_dn = ldb_dn_new(mem_ctx, ldb, "@MODULES"); if (mods_dn == NULL) { talloc_free(mem_ctx); - return -1; + return ldb_oom(ldb); } ret = ldb_search(ldb, mods_dn, &res, mods_dn, LDB_SCOPE_BASE, attrs, "@LIST=*"); @@ -400,7 +404,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) } else if (res->count > 1) { ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out", res->count); talloc_free(mem_ctx); - return -1; + return LDB_ERR_OPERATIONS_ERROR; } else { module_list = ldb_msg_find_attr_as_string(res->msgs[0], "@LIST", NULL); if (!module_list) { diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index d1c77f8..9c5a279 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -391,30 +391,63 @@ int ldb_msg_find_attr_as_int(const struct ldb_message *msg, int default_value) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-2147483648")]; + char *end = NULL; + int ret; + if (!v || !v->data) { return default_value; } - return strtol((const char *)v->data, NULL, 0); + + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; + } + + memcpy(buf, v->data, v->length); + errno = 0; + ret = (int) strtoll(buf, &end, 10); + if (errno != 0) { + return default_value; + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; } -unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, +unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, const char *attr_name, unsigned int default_value) { - unsigned int ret; const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-2147483648")]; + char *end = NULL; + unsigned int ret; + if (!v || !v->data) { return default_value; } - /* in LDAP there're only int32_t values */ - errno = 0; - ret = strtol((const char *)v->data, NULL, 0); - if (errno == 0) { - return ret; + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; } - return strtoul((const char *)v->data, NULL, 0); + memcpy(buf, v->data, v->length); + errno = 0; + ret = (unsigned int) strtoll(buf, &end, 10); + if (errno != 0) { + errno = 0; + ret = (unsigned int) strtoull(buf, &end, 10); + if (errno != 0) { + return default_value; + } + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; } int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, @@ -422,30 +455,63 @@ int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, int64_t default_value) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-9223372036854775808")]; + char *end = NULL; + int64_t ret; + if (!v || !v->data) { return default_value; } - return strtoll((const char *)v->data, NULL, 0); + + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; + } + + memcpy(buf, v->data, v->length); + errno = 0; + ret = (int64_t) strtoll(buf, &end, 10); + if (errno != 0) { + return default_value; + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; } -uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, +uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, const char *attr_name, uint64_t default_value) { - uint64_t ret; const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-9223372036854775808")]; + char *end = NULL; + uint64_t ret; + if (!v || !v->data) { return default_value; } - /* in LDAP there're only int64_t values */ - errno = 0; - ret = strtoll((const char *)v->data, NULL, 0); - if (errno == 0) { - return ret; + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; } - return strtoull((const char *)v->data, NULL, 0); + memcpy(buf, v->data, v->length); + errno = 0; + ret = (uint64_t) strtoll(buf, &end, 10); + if (errno != 0) { + errno = 0; + ret = (uint64_t) strtoull(buf, &end, 10); + if (errno != 0) { + return default_value; + } + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; } double ldb_msg_find_attr_as_double(const struct ldb_message *msg, @@ -453,10 +519,28 @@ double ldb_msg_find_attr_as_double(const struct ldb_message *msg, double default_value) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char *buf; + char *end = NULL; + double ret; + if (!v || !v->data) { return default_value; } - return strtod((const char *)v->data, NULL); + buf = talloc_strndup(msg, (const char *)v->data, v->length); + if (buf == NULL) { + return default_value; + } + + errno = 0; + ret = strtod(buf, &end); + talloc_free(buf); + if (errno != 0) { + return default_value; + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; } int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, @@ -484,6 +568,9 @@ const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, if (!v || !v->data) { return default_value; } + if (v->data[v->length] != '\0') { + return default_value; + } return (const char *)v->data; } @@ -772,7 +859,6 @@ int ldb_msg_sanity_check(struct ldb_context *ldb, /* basic check on DN */ if (msg->dn == NULL) { - /* TODO: return also an error string */ ldb_set_errstring(ldb, "ldb message lacks a DN!"); return LDB_ERR_INVALID_DN_SYNTAX; } @@ -781,13 +867,10 @@ int ldb_msg_sanity_check(struct ldb_context *ldb, for (i = 0; i < msg->num_elements; i++) { for (j = 0; j < msg->elements[i].num_values; j++) { if (msg->elements[i].values[j].length == 0) { - TALLOC_CTX *mem_ctx = talloc_new(ldb); /* an attribute cannot be empty */ - /* TODO: return also an error string */ ldb_asprintf_errstring(ldb, "Element %s has empty attribute in ldb message (%s)!", msg->elements[i].name, ldb_dn_get_linearized(msg->dn)); - talloc_free(mem_ctx); return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } } diff --git a/source4/lib/ldb/tests/init.ldif b/source4/lib/ldb/tests/init.ldif index 2e0b83c..97b4561 100644 --- a/source4/lib/ldb/tests/init.ldif +++ b/source4/lib/ldb/tests/init.ldif @@ -9,12 +9,13 @@ o: UM o: U-M o: U of M description: The University of Michigan at Ann Arbor -seeAlso: postaladdress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481 09 $ US telephonenumber: +1 313 764-1817 associateddomain: example.com +# there was an empty "seeAlso" here + dn: ou=People,o=University of Michigan,c=TEST objectclass: organizationalUnit objectclass: extensibleObject diff --git a/source4/lib/ldb/tools/ldbadd.c b/source4/lib/ldb/tools/ldbadd.c index a528512..47fd261 100644 --- a/source4/lib/ldb/tools/ldbadd.c +++ b/source4/lib/ldb/tools/ldbadd.c @@ -53,7 +53,7 @@ static void usage(struct ldb_context *ldb) static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) { struct ldb_ldif *ldif; - int ret = LDB_SUCCESS; + int fun_ret = LDB_SUCCESS, ret; struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); if (options->controls != NULL && req_ctrls== NULL) { printf("parsing controls failed: %s\n", ldb_errstring(ldb)); @@ -74,6 +74,7 @@ static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) "ERR: Message canonicalize failed - %s\n", ldb_strerror(ret)); failures++; + fun_ret = ret; ldb_ldif_read_free(ldb, ldif); continue; } @@ -84,6 +85,7 @@ static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) ldb_strerror(ret), ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn)); failures++; + fun_ret = ret; } else { (*count)++; if (options->verbose) { @@ -93,7 +95,7 @@ static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) ldb_ldif_read_free(ldb, ldif); } - return ret; + return fun_ret; } diff --git a/source4/lib/ldb/tools/ldbmodify.c b/source4/lib/ldb/tools/ldbmodify.c index 1374765..1e7aa80 100644 --- a/source4/lib/ldb/tools/ldbmodify.c +++ b/source4/lib/ldb/tools/ldbmodify.c @@ -52,7 +52,7 @@ static void usage(struct ldb_context *ldb) static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) { struct ldb_ldif *ldif; - int ret = LDB_SUCCESS; + int fun_ret = LDB_SUCCESS, ret; struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); if (options->controls != NULL && req_ctrls== NULL) { @@ -78,6 +78,7 @@ static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) ldb_strerror(ret), ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn)); failures++; + fun_ret = ret; } else { (*count)++; if (options->verbose) { @@ -89,10 +90,10 @@ static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) if (!feof(f)) { fprintf(stderr, "Failed to parse ldif\n"); - return -1; + fun_ret = LDB_ERR_OPERATIONS_ERROR; } - return ret; + return fun_ret; } int main(int argc, const char **argv) -- Samba Shared Repository