s4:wrepl_server: Correctly read ‘type’ element
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Tue, 5 Sep 2023 23:03:02 +0000 (11:03 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 14 Sep 2023 21:35:29 +0000 (21:35 +0000)
winsdb_message() stores this element as hexadecimal, which format
ldb_msg_find_attr_as_uint() cannot cope with. Permit this element to be
in either decimal or hexadecimal format.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/wrepl_server/wrepl_server.c

index 59c45f605f58ed83afecebaf8f60db0ca5e58bb3..c97b816b1a8997da94053e9fda972d1b6f27b5e3 100644 (file)
@@ -130,6 +130,44 @@ struct wreplsrv_partner *wreplsrv_find_partner(struct wreplsrv_service *service,
        return NULL;
 }
 
+static uint32_t wreplsrv_find_attr_as_uint32(const struct ldb_message *msg,
+                                            const char *attr_name,
+                                            uint32_t default_value)
+{
+       const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name);
+       char buf[sizeof("-2147483648")] = {};
+       char *end = NULL;
+       uint32_t ret;
+       int base = 10;
+
+       if (!v || !v->data) {
+               return default_value;
+       }
+
+       if (v->length >= sizeof(buf)) {
+               return default_value;
+       }
+
+       memcpy(buf, v->data, v->length);
+       if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
+               base = 16;
+       }
+
+       errno = 0;
+       ret = strtoll(buf, &end, base);
+       if (errno == ERANGE || errno == EINVAL) {
+               errno = 0;
+               ret = strtoull(buf, &end, base);
+               if (errno == ERANGE || errno == EINVAL) {
+                       return default_value;
+               }
+       }
+       if (end && end[0] != '\0') {
+               return default_value;
+       }
+       return ret;
+}
+
 /*
   load our replication partners
 */
@@ -200,7 +238,7 @@ NTSTATUS wreplsrv_load_partners(struct wreplsrv_service *service)
                partner->our_address            = ldb_msg_find_attr_as_string(res->msgs[i], "ourAddress", NULL);
                talloc_steal(partner, partner->our_address);
 
-               partner->type                   = ldb_msg_find_attr_as_uint(res->msgs[i], "type", WINSREPL_PARTNER_BOTH);
+               partner->type                   = wreplsrv_find_attr_as_uint32(res->msgs[i], "type", WINSREPL_PARTNER_BOTH);
                partner->pull.interval          = ldb_msg_find_attr_as_uint(res->msgs[i], "pullInterval",
                                                                    WINSREPL_DEFAULT_PULL_INTERVAL);
                partner->pull.retry_interval    = ldb_msg_find_attr_as_uint(res->msgs[i], "pullRetryInterval",