LCOV - code coverage report
Current view: top level - librpc/ndr - uuid.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 93 110 84.5 %
Date: 2024-02-28 12:06:22 Functions: 15 16 93.8 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    UUID/GUID functions
       5             : 
       6             :    Copyright (C) Theodore Ts'o               1996, 1997,
       7             :    Copyright (C) Jim McDonough                     2002.
       8             :    Copyright (C) Andrew Tridgell                   2003.
       9             :    
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             :    
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             :    
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "replace.h"
      25             : #include "lib/util/samba_util.h"
      26             : #include "lib/util/genrand.h"
      27             : #include "librpc/ndr/libndr.h"
      28             : #include "librpc/gen_ndr/ndr_misc.h"
      29             : #include "lib/util/util_str_hex.h"
      30             : 
      31   109298251 : _PUBLIC_ NTSTATUS GUID_to_ndr_buf(
      32             :         const struct GUID *guid, struct GUID_ndr_buf *buf)
      33             : {
      34   109298251 :         DATA_BLOB b = { .data = buf->buf, .length = sizeof(buf->buf), };
      35     1461264 :         enum ndr_err_code ndr_err;
      36             : 
      37   109298251 :         ndr_err = ndr_push_struct_into_fixed_blob(
      38             :                 &b, guid, (ndr_push_flags_fn_t)ndr_push_GUID);
      39   109298251 :         return ndr_map_error2ntstatus(ndr_err);
      40             : }
      41             : 
      42             : /**
      43             :   build a NDR blob from a GUID
      44             : */
      45   109202805 : _PUBLIC_ NTSTATUS GUID_to_ndr_blob(const struct GUID *guid, TALLOC_CTX *mem_ctx, DATA_BLOB *b)
      46             : {
      47   109202805 :         struct GUID_ndr_buf buf = { .buf = {0}, };
      48     1459183 :         NTSTATUS status;
      49             : 
      50   109202805 :         status = GUID_to_ndr_buf(guid, &buf);
      51   109202805 :         if (!NT_STATUS_IS_OK(status)) {
      52           0 :                 return status;
      53             :         }
      54             : 
      55   109202805 :         *b = data_blob_talloc(mem_ctx, buf.buf, sizeof(buf.buf));
      56   109202805 :         if (b->data == NULL) {
      57           0 :                 return NT_STATUS_NO_MEMORY;
      58             :         }
      59   109202805 :         return NT_STATUS_OK;
      60             : }
      61             : 
      62             : 
      63             : /**
      64             :   build a GUID from a NDR data blob
      65             : */
      66   236695988 : _PUBLIC_ NTSTATUS GUID_from_ndr_blob(const DATA_BLOB *b, struct GUID *guid)
      67             : {
      68     5448570 :         enum ndr_err_code ndr_err =
      69   236695988 :                 ndr_pull_struct_blob_all_noalloc(b, guid,
      70             :                                                  (ndr_pull_flags_fn_t)ndr_pull_GUID);
      71   236695988 :         return ndr_map_error2ntstatus(ndr_err);
      72             : }
      73             : 
      74             : 
      75             : /**
      76             :   build a GUID from a string
      77             : */
      78   120229617 : _PUBLIC_ NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid)
      79             : {
      80     2688236 :         bool ok;
      81             : 
      82   120229617 :         if (s->data == NULL) {
      83           2 :                 return NT_STATUS_INVALID_PARAMETER;
      84             :         }
      85             : 
      86   120229615 :         if (s->length == 36) {
      87   118366296 :                 ok = parse_guid_string((char *)s->data, guid);
      88   118366296 :                 return ok ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER;
      89             :         }
      90             : 
      91     1863319 :         if (s->length == 38) {
      92        6526 :                 if (s->data[0] != '{' || s->data[37] != '}') {
      93           0 :                         return NT_STATUS_INVALID_PARAMETER;
      94             :                 }
      95        6526 :                 ok = parse_guid_string((char *)s->data + 1, guid);
      96        6526 :                 return ok ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER;
      97             :         }
      98             : 
      99     1856793 :         if (s->length == 32) {
     100           6 :                 uint8_t buf16[16] = {0};
     101           6 :                 DATA_BLOB blob16 = { .data = buf16, .length = sizeof(buf16) };
     102           6 :                 size_t rlen = strhex_to_str((char *)blob16.data, blob16.length,
     103           0 :                                             (const char *)s->data, s->length);
     104           6 :                 if (rlen != blob16.length) {
     105           0 :                         return NT_STATUS_INVALID_PARAMETER;
     106             :                 }
     107             : 
     108           6 :                 return GUID_from_ndr_blob(&blob16, guid);
     109             :         }
     110             : 
     111     1856787 :         if (s->length == 16) {
     112     1856762 :                 return GUID_from_ndr_blob(s, guid);
     113             :         }
     114             : 
     115          25 :         return NT_STATUS_INVALID_PARAMETER;
     116             : }
     117             : 
     118             : /**
     119             :   build a GUID from a string
     120             : */
     121      307032 : _PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
     122             : {
     123      307032 :         DATA_BLOB blob = data_blob_string_const(s);
     124      307032 :         return GUID_from_data_blob(&blob, guid);
     125             : }
     126             : 
     127             : /**
     128             :  * generate a random GUID
     129             :  */
     130     1753654 : _PUBLIC_ struct GUID GUID_random(void)
     131             : {
     132       53957 :         struct GUID guid;
     133             : 
     134     1753654 :         generate_random_buffer((uint8_t *)&guid, sizeof(guid));
     135     1753654 :         guid.clock_seq[0] = (guid.clock_seq[0] & 0x3F) | 0x80;
     136     1753654 :         guid.time_hi_and_version = (guid.time_hi_and_version & 0x0FFF) | 0x4000;
     137             : 
     138     1753654 :         return guid;
     139             : }
     140             : 
     141             : /**
     142             :  * generate an empty GUID 
     143             :  */
     144    65796990 : _PUBLIC_ struct GUID GUID_zero(void)
     145             : {
     146    65796990 :         return (struct GUID) { .time_low = 0 };
     147             : }
     148             : 
     149    86696006 : _PUBLIC_ bool GUID_all_zero(const struct GUID *u)
     150             : {
     151    86696006 :         if (u->time_low != 0 ||
     152    18623213 :             u->time_mid != 0 ||
     153    17713916 :             u->time_hi_and_version != 0 ||
     154    18623213 :             u->clock_seq[0] != 0 ||
     155    18623213 :             u->clock_seq[1] != 0 ||
     156    18623213 :             !all_zero(u->node, 6)) {
     157    68072793 :                 return false;
     158             :         }
     159    17713916 :         return true;
     160             : }
     161             : 
     162    42534710 : _PUBLIC_ bool GUID_equal(const struct GUID *u1, const struct GUID *u2)
     163             : {
     164    42534710 :         return (GUID_compare(u1, u2) == 0);
     165             : }
     166             : 
     167    59908302 : _PUBLIC_ int GUID_compare(const struct GUID *u1, const struct GUID *u2)
     168             : {
     169    59908302 :         if (u1->time_low != u2->time_low) {
     170    52533701 :                 return u1->time_low > u2->time_low ? 1 : -1;
     171             :         }
     172             : 
     173     7374601 :         if (u1->time_mid != u2->time_mid) {
     174        6452 :                 return u1->time_mid > u2->time_mid ? 1 : -1;
     175             :         }
     176             : 
     177     7368149 :         if (u1->time_hi_and_version != u2->time_hi_and_version) {
     178           0 :                 return u1->time_hi_and_version > u2->time_hi_and_version ? 1 : -1;
     179             :         }
     180             : 
     181     7368149 :         if (u1->clock_seq[0] != u2->clock_seq[0]) {
     182       19473 :                 return u1->clock_seq[0] > u2->clock_seq[0] ? 1 : -1;
     183             :         }
     184             : 
     185     7348676 :         if (u1->clock_seq[1] != u2->clock_seq[1]) {
     186        6428 :                 return u1->clock_seq[1] > u2->clock_seq[1] ? 1 : -1;
     187             :         }
     188             : 
     189     7342248 :         return memcmp(u1->node, u2->node, 6);
     190             : }
     191             : 
     192             : /**
     193             :   its useful to be able to display these in debugging messages
     194             : */
     195    31382373 : _PUBLIC_ char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     196             : {
     197      303659 :         struct GUID_txt_buf buf;
     198    31382373 :         return talloc_strdup(mem_ctx, GUID_buf_string(guid, &buf));
     199             : }
     200             : 
     201             : /**
     202             :  * Does the same without allocating memory, using the structure buffer.
     203             :  * Useful for debug messages, so that you do not have to talloc_free the result
     204             :  */
     205    39723171 : _PUBLIC_ char* GUID_buf_string(const struct GUID *guid,
     206             :                                struct GUID_txt_buf *dst)
     207             : {
     208    39723171 :         if (!guid) {
     209           0 :                 return NULL;
     210             :         }
     211    39723171 :         snprintf(dst->buf, sizeof(dst->buf),
     212             :                  "%08"PRIx32"-%04"PRIx16"-%04"PRIx16"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8,
     213    39723171 :                  guid->time_low, guid->time_mid,
     214    39723171 :                  guid->time_hi_and_version,
     215    39723171 :                  guid->clock_seq[0],
     216    39723171 :                  guid->clock_seq[1],
     217    39723171 :                  guid->node[0], guid->node[1],
     218    39723171 :                  guid->node[2], guid->node[3],
     219    39723171 :                  guid->node[4], guid->node[5]);
     220    39723171 :         return dst->buf;
     221             : }
     222             : 
     223          61 : _PUBLIC_ char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     224             : {
     225           2 :         struct GUID_txt_buf buf;
     226          61 :         char *ret = talloc_asprintf(
     227             :                 mem_ctx, "{%s}", GUID_buf_string(guid, &buf));
     228          61 :         return ret;
     229             : }
     230             : 
     231           0 : _PUBLIC_ char *GUID_hexstring(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     232             : {
     233           0 :         char *ret = NULL;
     234           0 :         DATA_BLOB guid_blob = { .data = NULL };
     235           0 :         NTSTATUS status;
     236             : 
     237           0 :         status = GUID_to_ndr_blob(guid, mem_ctx, &guid_blob);
     238           0 :         if (NT_STATUS_IS_OK(status)) {
     239           0 :                 ret = data_blob_hex_string_upper(mem_ctx, &guid_blob);
     240             :         }
     241           0 :         TALLOC_FREE(guid_blob.data);
     242           0 :         return ret;
     243             : }
     244             : 
     245     2040619 : _PUBLIC_ bool ndr_policy_handle_empty(const struct policy_handle *h)
     246             : {
     247     2040619 :         return (h->handle_type == 0 && GUID_all_zero(&h->uuid));
     248             : }
     249             : 
     250         175 : _PUBLIC_ bool ndr_policy_handle_equal(const struct policy_handle *hnd1,
     251             :                                   const struct policy_handle *hnd2)
     252             : {
     253         175 :         if (!hnd1 || !hnd2) {
     254           0 :                 return false;
     255             :         }
     256             : 
     257         175 :         return (memcmp(hnd1, hnd2, sizeof(*hnd1)) == 0);
     258             : }

Generated by: LCOV version 1.14