libndr: apply some const and make is_valid_policy_hnd a callback to policy_handle_empty.
[kai/samba.git] / librpc / ndr / uuid.c
index 1e6ee0a3db7b31087b12ca1d94dbc20ef9ced833..445b6dda7e4efed103d7fb14ffcccb44a9fe175c 100644 (file)
 
 #include "includes.h"
 #include "librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+
+/**
+  build a NDR blob from a GUID
+*/
+_PUBLIC_ NTSTATUS GUID_to_ndr_blob(const struct GUID *guid, TALLOC_CTX *mem_ctx, DATA_BLOB *b)
+{
+       enum ndr_err_code ndr_err;
+       ndr_err = ndr_push_struct_blob(b, mem_ctx, guid,
+                                      (ndr_push_flags_fn_t)ndr_push_GUID);
+       return ndr_map_error2ntstatus(ndr_err);
+}
+
+
+/**
+  build a GUID from a NDR data blob
+*/
+_PUBLIC_ NTSTATUS GUID_from_ndr_blob(const DATA_BLOB *b, struct GUID *guid)
+{
+       enum ndr_err_code ndr_err;
+       TALLOC_CTX *mem_ctx;
+
+       mem_ctx = talloc_new(NULL);
+       NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+       ndr_err = ndr_pull_struct_blob_all(b, mem_ctx, guid,
+                                          (ndr_pull_flags_fn_t)ndr_pull_GUID);
+       talloc_free(mem_ctx);
+       return ndr_map_error2ntstatus(ndr_err);
+}
+
 
 /**
   build a GUID from a string
 */
-_PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
+_PUBLIC_ NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid)
 {
        NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
        uint32_t time_low;
        uint32_t time_mid, time_hi_and_version;
        uint32_t clock_seq[2];
        uint32_t node[6];
+       uint8_t buf16[16];
+
+       DATA_BLOB blob16 = data_blob_const(buf16, sizeof(buf16));
        int i;
 
-       if (s == NULL) {
+       if (s->data == NULL) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (11 == sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                        &time_low, &time_mid, &time_hi_and_version, 
-                        &clock_seq[0], &clock_seq[1],
-                        &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
-               status = NT_STATUS_OK;
-       } else if (11 == sscanf(s, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
-                               &time_low, &time_mid, &time_hi_and_version, 
-                               &clock_seq[0], &clock_seq[1],
-                               &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
-               status = NT_STATUS_OK;
+       switch(s->length) {
+       case 36:
+       {
+               TALLOC_CTX *mem_ctx;
+               const char *string;
+
+               mem_ctx = talloc_new(NULL);
+               NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+               string = talloc_strndup(mem_ctx, (const char *)s->data, s->length);
+               NT_STATUS_HAVE_NO_MEMORY(string);
+               if (11 == sscanf(string,
+                                "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+                                &time_low, &time_mid, &time_hi_and_version, 
+                                &clock_seq[0], &clock_seq[1],
+                                &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
+                       status = NT_STATUS_OK;
+               }
+               talloc_free(mem_ctx);
+               break;
+       }
+       case 38:
+       {
+               TALLOC_CTX *mem_ctx;
+               const char *string;
+
+               mem_ctx = talloc_new(NULL);
+               NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+               string = talloc_strndup(mem_ctx, (const char *)s->data, s->length);
+               NT_STATUS_HAVE_NO_MEMORY(string);
+               if (11 == sscanf((const char *)s->data, 
+                                "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+                                &time_low, &time_mid, &time_hi_and_version, 
+                                &clock_seq[0], &clock_seq[1],
+                                &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
+                       status = NT_STATUS_OK;
+               }
+               talloc_free(mem_ctx);
+               break;
+       }
+       case 32:
+       {
+               size_t rlen = strhex_to_str((char *)blob16.data, blob16.length,
+                                           (const char *)s->data, s->length);
+               if (rlen != blob16.length) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               s = &blob16;
+               return GUID_from_ndr_blob(s, guid);
+       }
+       case 16:
+               return GUID_from_ndr_blob(s, guid);
+       default:
+               status = NT_STATUS_INVALID_PARAMETER;
+               break;
        }
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -68,6 +147,15 @@ _PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
        return NT_STATUS_OK;
 }
 
+/**
+  build a GUID from a string
+*/
+_PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
+{
+       DATA_BLOB blob = data_blob_string_const(s);
+       return GUID_from_data_blob(&blob, guid);
+}
+
 /**
   build a GUID from a string
 */
@@ -162,23 +250,23 @@ _PUBLIC_ bool GUID_equal(const struct GUID *u1, const struct GUID *u2)
 _PUBLIC_ int GUID_compare(const struct GUID *u1, const struct GUID *u2)
 {
        if (u1->time_low != u2->time_low) {
-               return u1->time_low - u2->time_low;
+               return u1->time_low > u2->time_low ? 1 : -1;
        }
 
        if (u1->time_mid != u2->time_mid) {
-               return u1->time_mid - u2->time_mid;
+               return u1->time_mid > u2->time_mid ? 1 : -1;
        }
 
        if (u1->time_hi_and_version != u2->time_hi_and_version) {
-               return u1->time_hi_and_version - u2->time_hi_and_version;
+               return u1->time_hi_and_version > u2->time_hi_and_version ? 1 : -1;
        }
 
        if (u1->clock_seq[0] != u2->clock_seq[0]) {
-               return u1->clock_seq[0] - u2->clock_seq[0];
+               return u1->clock_seq[0] > u2->clock_seq[0] ? 1 : -1;
        }
 
        if (u1->clock_seq[1] != u2->clock_seq[1]) {
-               return u1->clock_seq[1] - u2->clock_seq[1];
+               return u1->clock_seq[1] > u2->clock_seq[1] ? 1 : -1;
        }
 
        return memcmp(u1->node, u2->node, 6);
@@ -208,6 +296,28 @@ _PUBLIC_ char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid)
        return ret;
 }
 
+_PUBLIC_ char *GUID_hexstring(TALLOC_CTX *mem_ctx, const struct GUID *guid)
+{
+       char *ret;
+       DATA_BLOB guid_blob;
+       TALLOC_CTX *tmp_mem;
+       NTSTATUS status;
+
+       tmp_mem = talloc_new(mem_ctx);
+       if (!tmp_mem) {
+               return NULL;
+       }
+       status = GUID_to_ndr_blob(guid, tmp_mem, &guid_blob);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(tmp_mem);
+               return NULL;
+       }
+
+       ret = data_blob_hex_string_upper(mem_ctx, &guid_blob);
+       talloc_free(tmp_mem);
+       return ret;
+}
+
 _PUBLIC_ char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
 {
        return talloc_asprintf(mem_ctx, 
@@ -221,7 +331,22 @@ _PUBLIC_ char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
                               guid->node[4], guid->node[5]);
 }
 
-_PUBLIC_ bool policy_handle_empty(struct policy_handle *h) 
+_PUBLIC_ bool policy_handle_empty(const struct policy_handle *h)
 {
        return (h->handle_type == 0 && GUID_all_zero(&h->uuid));
 }
+
+_PUBLIC_ bool is_valid_policy_hnd(const struct policy_handle *hnd)
+{
+       return !policy_handle_empty(hnd);
+}
+
+_PUBLIC_ bool policy_handle_equal(const struct policy_handle *hnd1,
+                                 const struct policy_handle *hnd2)
+{
+       if (!hnd1 || !hnd2) {
+               return false;
+       }
+
+       return (memcmp(hnd1, hnd2, sizeof(*hnd1)) == 0);
+}