lib: Make sid_parse return the parsed length
[samba.git] / source4 / dsdb / common / util.c
index e2ed8405c93a1d775ba56e5f615531292c2327eb..411d1dd22b05d2d55fe674b5f9837b7d7b69cf45 100644 (file)
@@ -202,26 +202,6 @@ struct dom_sid *samdb_search_dom_sid(struct ldb_context *sam_ldb,
        return sid;     
 }
 
-/*
-  return the count of the number of records in the sam matching the query
-*/
-int samdb_search_count(struct ldb_context *sam_ldb,
-                      TALLOC_CTX *mem_ctx,
-                      struct ldb_dn *basedn,
-                      const char *format, ...) _PRINTF_ATTRIBUTE(4,5)
-{
-       va_list ap;
-       const char *attrs[] = { NULL };
-       int ret;
-
-       va_start(ap, format);
-       ret = gendb_search_v(sam_ldb, mem_ctx, basedn, NULL, attrs, format, ap);
-       va_end(ap);
-
-       return ret;
-}
-
-
 /*
   search the sam for a single integer attribute in exactly 1 record
 */
@@ -362,7 +342,7 @@ uint32_t samdb_result_rid_from_sid(TALLOC_CTX *mem_ctx, const struct ldb_message
 struct dom_sid *samdb_result_dom_sid(TALLOC_CTX *mem_ctx, const struct ldb_message *msg, 
                                     const char *attr)
 {
-       bool ok;
+       struct sid_parse_ret ret;
        const struct ldb_val *v;
        struct dom_sid *sid;
        v = ldb_msg_find_ldb_val(msg, attr);
@@ -373,8 +353,8 @@ struct dom_sid *samdb_result_dom_sid(TALLOC_CTX *mem_ctx, const struct ldb_messa
        if (sid == NULL) {
                return NULL;
        }
-       ok = sid_parse(v->data, v->length, sid);
-       if (!ok) {
+       ret = sid_parse(v->data, v->length, sid);
+       if (ret.len == -1) {
                talloc_free(sid);
                return NULL;
        }
@@ -1441,21 +1421,24 @@ failed:
 }
 
 /*
-  work out the ntds settings invocationId for the current open ldb
+  work out the ntds settings invocationID/objectGUID for the current open ldb
 */
-const struct GUID *samdb_ntds_invocation_id(struct ldb_context *ldb)
+static const struct GUID *samdb_ntds_GUID(struct ldb_context *ldb,
+                                         const char *attribute,
+                                         const char *cache_name)
 {
        TALLOC_CTX *tmp_ctx;
-       const char *attrs[] = { "invocationId", NULL };
+       const char *attrs[] = { attribute, NULL };
        int ret;
        struct ldb_result *res;
-       struct GUID *invocation_id;
+       struct GUID *ntds_guid;
+       struct ldb_dn *ntds_settings_dn = NULL;
+       const char *errstr = NULL;
 
        /* see if we have a cached copy */
-       invocation_id = (struct GUID *)ldb_get_opaque(ldb, "cache.invocation_id");
-       if (invocation_id) {
-               SMB_ASSERT(!GUID_all_zero(invocation_id));
-               return invocation_id;
+       ntds_guid = (struct GUID *)ldb_get_opaque(ldb, cache_name);
+       if (ntds_guid != NULL) {
+               return ntds_guid;
        }
 
        tmp_ctx = talloc_new(ldb);
@@ -1463,148 +1446,85 @@ const struct GUID *samdb_ntds_invocation_id(struct ldb_context *ldb)
                goto failed;
        }
 
-       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL);
+       ntds_settings_dn = samdb_ntds_settings_dn(ldb, tmp_ctx);
+       if (ntds_settings_dn == NULL) {
+               errstr = "samdb_ntds_settings_dn() returned NULL";
+               goto failed;
+       }
+
+       ret = ldb_search(ldb, tmp_ctx, &res, ntds_settings_dn,
+                        LDB_SCOPE_BASE, attrs, NULL);
        if (ret) {
+               errstr = ldb_errstring(ldb);
                goto failed;
        }
 
        if (res->count != 1) {
+               errstr = "incorrect number of results from base search";
                goto failed;
        }
 
-       invocation_id = talloc(tmp_ctx, struct GUID);
-       if (!invocation_id) {
+       ntds_guid = talloc(tmp_ctx, struct GUID);
+       if (ntds_guid == NULL) {
                goto failed;
        }
 
-       *invocation_id = samdb_result_guid(res->msgs[0], "invocationId");
-       if (GUID_all_zero(invocation_id)) {
-               if (ldb_msg_find_ldb_val(res->msgs[0], "invocationId")) {
-                       DEBUG(0, ("Failed to find our own NTDS Settings invocationId in the ldb!\n"));  
+       *ntds_guid = samdb_result_guid(res->msgs[0], attribute);
+
+       if (GUID_all_zero(ntds_guid)) {
+               if (ldb_msg_find_ldb_val(res->msgs[0], attribute)) {
+                       errstr = "failed to find the GUID attribute";
                } else {
-                       DEBUG(0, ("Failed to find parse own NTDS Settings invocationId from the ldb!\n"));
+                       errstr = "failed to parse the GUID";
                }
                goto failed;
        }
 
        /* cache the domain_sid in the ldb */
-       if (ldb_set_opaque(ldb, "cache.invocation_id", invocation_id) != LDB_SUCCESS) {
+       if (ldb_set_opaque(ldb, cache_name, ntds_guid) != LDB_SUCCESS) {
+               errstr = "ldb_set_opaque() failed";
                goto failed;
        }
 
-       talloc_steal(ldb, invocation_id);
+       talloc_steal(ldb, ntds_guid);
        talloc_free(tmp_ctx);
 
-       return invocation_id;
+       return ntds_guid;
 
 failed:
-       DEBUG(1,("Failed to find our own NTDS Settings invocationId in the ldb!\n"));
+       DBG_WARNING("Failed to find our own NTDS Settings %s in the ldb: %s!\n",
+                   attribute, errstr);
        talloc_free(tmp_ctx);
        return NULL;
 }
 
-bool samdb_set_ntds_invocation_id(struct ldb_context *ldb, const struct GUID *invocation_id_in)
-{
-       TALLOC_CTX *tmp_ctx;
-       struct GUID *invocation_id_new;
-       struct GUID *invocation_id_old;
-
-       /* see if we have a cached copy */
-       invocation_id_old = (struct GUID *)ldb_get_opaque(ldb, 
-                                                        "cache.invocation_id");
-
-       tmp_ctx = talloc_new(ldb);
-       if (tmp_ctx == NULL) {
-               goto failed;
-       }
-
-       invocation_id_new = talloc(tmp_ctx, struct GUID);
-       if (!invocation_id_new) {
-               goto failed;
-       }
-
-       SMB_ASSERT(!GUID_all_zero(invocation_id_in));
-       *invocation_id_new = *invocation_id_in;
-
-       /* cache the domain_sid in the ldb */
-       if (ldb_set_opaque(ldb, "cache.invocation_id", invocation_id_new) != LDB_SUCCESS) {
-               goto failed;
-       }
-
-       talloc_steal(ldb, invocation_id_new);
-       talloc_free(tmp_ctx);
-       talloc_free(invocation_id_old);
-
-       return true;
-
-failed:
-       DEBUG(1,("Failed to set our own cached invocationId in the ldb!\n"));
-       talloc_free(tmp_ctx);
-       return false;
-}
-
 /*
   work out the ntds settings objectGUID for the current open ldb
 */
 const struct GUID *samdb_ntds_objectGUID(struct ldb_context *ldb)
 {
-       TALLOC_CTX *tmp_ctx;
-       const char *attrs[] = { "objectGUID", NULL };
-       int ret;
-       struct ldb_result *res;
-       struct GUID *ntds_guid;
-
-       /* see if we have a cached copy */
-       ntds_guid = (struct GUID *)ldb_get_opaque(ldb, "cache.ntds_guid");
-       if (ntds_guid) {
-               return ntds_guid;
-       }
-
-       tmp_ctx = talloc_new(ldb);
-       if (tmp_ctx == NULL) {
-               goto failed;
-       }
-
-       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL);
-       if (ret) {
-               goto failed;
-       }
-
-       if (res->count != 1) {
-               goto failed;
-       }
-
-       ntds_guid = talloc(tmp_ctx, struct GUID);
-       if (!ntds_guid) {
-               goto failed;
-       }
-
-       *ntds_guid = samdb_result_guid(res->msgs[0], "objectGUID");
-
-       /* cache the domain_sid in the ldb */
-       if (ldb_set_opaque(ldb, "cache.ntds_guid", ntds_guid) != LDB_SUCCESS) {
-               goto failed;
-       }
-
-       talloc_steal(ldb, ntds_guid);
-       talloc_free(tmp_ctx);
-
-       return ntds_guid;
+       return samdb_ntds_GUID(ldb, "objectGUID", "cache.ntds_guid");
+}
 
-failed:
-       DEBUG(1,("Failed to find our own NTDS Settings objectGUID in the ldb!\n"));
-       talloc_free(tmp_ctx);
-       return NULL;
+/*
+  work out the ntds settings invocationId for the current open ldb
+*/
+const struct GUID *samdb_ntds_invocation_id(struct ldb_context *ldb)
+{
+       return samdb_ntds_GUID(ldb, "invocationId", "cache.invocation_id");
 }
 
-bool samdb_set_ntds_objectGUID(struct ldb_context *ldb, const struct GUID *ntds_guid_in)
+static bool samdb_set_ntds_GUID(struct ldb_context *ldb,
+                               const struct GUID *ntds_guid_in,
+                               const char *attribute,
+                               const char *cache_name)
 {
        TALLOC_CTX *tmp_ctx;
        struct GUID *ntds_guid_new;
        struct GUID *ntds_guid_old;
 
        /* see if we have a cached copy */
-       ntds_guid_old = (struct GUID *)ldb_get_opaque(ldb, "cache.ntds_guid");
+       ntds_guid_old = (struct GUID *)ldb_get_opaque(ldb, cache_name);
 
        tmp_ctx = talloc_new(ldb);
        if (tmp_ctx == NULL) {
@@ -1619,7 +1539,7 @@ bool samdb_set_ntds_objectGUID(struct ldb_context *ldb, const struct GUID *ntds_
        *ntds_guid_new = *ntds_guid_in;
 
        /* cache the domain_sid in the ldb */
-       if (ldb_set_opaque(ldb, "cache.ntds_guid", ntds_guid_new) != LDB_SUCCESS) {
+       if (ldb_set_opaque(ldb, cache_name, ntds_guid_new) != LDB_SUCCESS) {
                goto failed;
        }
 
@@ -1630,11 +1550,28 @@ bool samdb_set_ntds_objectGUID(struct ldb_context *ldb, const struct GUID *ntds_
        return true;
 
 failed:
-       DEBUG(1,("Failed to set our own cached invocationId in the ldb!\n"));
+       DBG_WARNING("Failed to set our own cached %s in the ldb!\n",
+                   attribute);
        talloc_free(tmp_ctx);
        return false;
 }
 
+bool samdb_set_ntds_objectGUID(struct ldb_context *ldb, const struct GUID *ntds_guid_in)
+{
+       return samdb_set_ntds_GUID(ldb,
+                                  ntds_guid_in,
+                                  "objectGUID",
+                                  "cache.ntds_guid");
+}
+
+bool samdb_set_ntds_invocation_id(struct ldb_context *ldb, const struct GUID *invocation_id_in)
+{
+       return samdb_set_ntds_GUID(ldb,
+                                  invocation_id_in,
+                                  "invocationId",
+                                  "cache.invocation_id");
+}
+
 /*
   work out the server dn for the current open ldb
 */
@@ -1893,10 +1830,13 @@ const char *samdb_client_site_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
                                   bool fallback)
 {
        const char *attrs[] = { "cn", "siteObject", NULL };
-       struct ldb_dn *sites_container_dn, *subnets_dn, *sites_dn;
-       struct ldb_result *res;
-       const struct ldb_val *val;
-       const char *site_name = NULL, *l_subnet_name = NULL;
+       struct ldb_dn *sites_container_dn = NULL;
+       struct ldb_dn *subnets_dn = NULL;
+       struct ldb_dn *sites_dn = NULL;
+       struct ldb_result *res = NULL;
+       const struct ldb_val *val = NULL;
+       const char *site_name = NULL;
+       const char *l_subnet_name = NULL;
        const char *allow_list[2] = { NULL, NULL };
        unsigned int i, count;
        int ret;
@@ -1911,14 +1851,12 @@ const char *samdb_client_site_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
 
        sites_container_dn = samdb_sites_dn(ldb, mem_ctx);
        if (sites_container_dn == NULL) {
-               return NULL;
+               goto exit;
        }
 
        subnets_dn = ldb_dn_copy(mem_ctx, sites_container_dn);
        if ( ! ldb_dn_add_child_fmt(subnets_dn, "CN=Subnets")) {
-               talloc_free(sites_container_dn);
-               talloc_free(subnets_dn);
-               return NULL;
+               goto exit;
        }
 
        ret = ldb_search(ldb, mem_ctx, &res, subnets_dn, LDB_SCOPE_ONELEVEL,
@@ -1926,9 +1864,7 @@ const char *samdb_client_site_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                count = 0;
        } else if (ret != LDB_SUCCESS) {
-               talloc_free(sites_container_dn);
-               talloc_free(subnets_dn);
-               return NULL;
+               goto exit;
        } else {
                count = res->count;
        }
@@ -1953,7 +1889,7 @@ const char *samdb_client_site_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
                        site_name = talloc_strdup(mem_ctx,
                                                  (const char *) val->data);
 
-                       talloc_free(sites_dn);
+                       TALLOC_FREE(sites_dn);
 
                        break;
                }
@@ -1974,7 +1910,6 @@ const char *samdb_client_site_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
                        LDB_SCOPE_SUBTREE,
                        "(objectClass=site)");
                if (ret != LDB_SUCCESS) {
-                       site_name = NULL;
                        goto exit;
                }
                if (cnt == 1) {
@@ -1990,9 +1925,9 @@ const char *samdb_client_site_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
        }
 
 exit:
-       talloc_free(sites_container_dn);
-       talloc_free(subnets_dn);
-       talloc_free(res);
+       TALLOC_FREE(sites_container_dn);
+       TALLOC_FREE(subnets_dn);
+       TALLOC_FREE(res);
 
        return site_name;
 }
@@ -3895,6 +3830,7 @@ NTSTATUS dsdb_get_extended_dn_guid(struct ldb_dn *dn, struct GUID *guid, const c
 NTSTATUS dsdb_get_extended_dn_uint64(struct ldb_dn *dn, uint64_t *val, const char *component_name)
 {
        const struct ldb_val *v;
+       int error = 0;
 
        v = ldb_dn_get_extended_component(dn, component_name);
        if (v == NULL) {
@@ -3909,7 +3845,10 @@ NTSTATUS dsdb_get_extended_dn_uint64(struct ldb_dn *dn, uint64_t *val, const cha
                memcpy(s, v->data, v->length);
                s[v->length] = 0;
 
-               *val = strtoull(s, NULL, 0);
+               *val = strtoull_err(s, NULL, 0, &error);
+               if (error != 0) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
        }
        return NT_STATUS_OK;
 }
@@ -3928,6 +3867,7 @@ NTSTATUS dsdb_get_extended_dn_nttime(struct ldb_dn *dn, NTTIME *nttime, const ch
 NTSTATUS dsdb_get_extended_dn_uint32(struct ldb_dn *dn, uint32_t *val, const char *component_name)
 {
        const struct ldb_val *v;
+       int error = 0;
 
        v = ldb_dn_get_extended_component(dn, component_name);
        if (v == NULL) {
@@ -3941,7 +3881,10 @@ NTSTATUS dsdb_get_extended_dn_uint32(struct ldb_dn *dn, uint32_t *val, const cha
                char s[v->length + 1];
                memcpy(s, v->data, v->length);
                s[v->length] = 0;
-               *val = strtoul(s, NULL, 0);
+               *val = strtoul_err(s, NULL, 0, &error);
+               if (error != 0) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
        }
 
        return NT_STATUS_OK;
@@ -3995,6 +3938,7 @@ uint32_t dsdb_dn_val_rmd_flags(const struct ldb_val *val)
        const char *p;
        uint32_t flags;
        char *end;
+       int error = 0;
 
        if (val->length < 13) {
                return 0;
@@ -4003,8 +3947,8 @@ uint32_t dsdb_dn_val_rmd_flags(const struct ldb_val *val)
        if (!p) {
                return 0;
        }
-       flags = strtoul(p+11, &end, 10);
-       if (!end || *end != '>') {
+       flags = strtoul_err(p+11, &end, 10, &error);
+       if (!end || *end != '>' || error != 0) {
                /* it must end in a > */
                return 0;
        }
@@ -5865,7 +5809,8 @@ static int dsdb_count_domain_callback(
        case LDB_REPLY_ENTRY:
        {
                struct dsdb_count_domain_context *context = NULL;
-               bool ok, in_domain;
+               struct sid_parse_ret ret;
+               bool in_domain;
                struct dom_sid sid;
                const struct ldb_val *v;
 
@@ -5880,8 +5825,8 @@ static int dsdb_count_domain_callback(
                        break;
                }
 
-               ok = sid_parse(v->data, v->length, &sid);
-               if (!ok) {
+               ret = sid_parse(v->data, v->length, &sid);
+               if (ret.len == -1) {
                        break;
                }