LCOV - code coverage report
Current view: top level - librpc/ndr - uuid.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 92 108 85.2 %
Date: 2024-05-31 13:13:24 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/debug.h"
      26             : #include "lib/util/samba_util.h"
      27             : #include "lib/util/genrand.h"
      28             : #include "librpc/ndr/libndr.h"
      29             : #include "librpc/gen_ndr/ndr_misc.h"
      30             : #include "lib/util/util_str_hex.h"
      31             : 
      32   110974005 : _PUBLIC_ void GUID_to_ndr_buf(const struct GUID *guid,
      33             :                               struct GUID_ndr_buf *buf)
      34             : {
      35   110974005 :         DATA_BLOB b = { .data = buf->buf, .length = sizeof(buf->buf), };
      36     1441079 :         enum ndr_err_code ndr_err;
      37             : 
      38   110974005 :         ndr_err = ndr_push_struct_into_fixed_blob(
      39             :                 &b, guid, (ndr_push_flags_fn_t)ndr_push_GUID);
      40   110974005 :         SMB_ASSERT(NDR_ERR_CODE_IS_SUCCESS(ndr_err));
      41   110974005 : }
      42             : 
      43             : /**
      44             :   build a NDR blob from a GUID
      45             : */
      46   110889562 : _PUBLIC_ NTSTATUS GUID_to_ndr_blob(const struct GUID *guid, TALLOC_CTX *mem_ctx, DATA_BLOB *b)
      47             : {
      48   110889562 :         struct GUID_ndr_buf buf = { .buf = {0}, };
      49             : 
      50   110889562 :         GUID_to_ndr_buf(guid, &buf);
      51             : 
      52   110889562 :         *b = data_blob_talloc(mem_ctx, buf.buf, sizeof(buf.buf));
      53   110889562 :         if (b->data == NULL) {
      54           0 :                 return NT_STATUS_NO_MEMORY;
      55             :         }
      56   110889562 :         return NT_STATUS_OK;
      57             : }
      58             : 
      59             : 
      60             : /**
      61             :   build a GUID from a NDR data blob
      62             : */
      63   240747679 : _PUBLIC_ NTSTATUS GUID_from_ndr_blob(const DATA_BLOB *b, struct GUID *guid)
      64             : {
      65     5521722 :         enum ndr_err_code ndr_err =
      66   240747679 :                 ndr_pull_struct_blob_all_noalloc(b, guid,
      67             :                                                  (ndr_pull_flags_fn_t)ndr_pull_GUID);
      68   240747679 :         return ndr_map_error2ntstatus(ndr_err);
      69             : }
      70             : 
      71             : 
      72             : /**
      73             :   build a GUID from a string
      74             : */
      75   121901629 : _PUBLIC_ NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid)
      76             : {
      77     2668079 :         bool ok;
      78             : 
      79   121901629 :         if (s->data == NULL) {
      80           2 :                 return NT_STATUS_INVALID_PARAMETER;
      81             :         }
      82             : 
      83   121901627 :         if (s->length == 36) {
      84   120041120 :                 ok = parse_guid_string((char *)s->data, guid);
      85   120041120 :                 return ok ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER;
      86             :         }
      87             : 
      88     1860507 :         if (s->length == 38) {
      89        6526 :                 if (s->data[0] != '{' || s->data[37] != '}') {
      90           0 :                         return NT_STATUS_INVALID_PARAMETER;
      91             :                 }
      92        6526 :                 ok = parse_guid_string((char *)s->data + 1, guid);
      93        6526 :                 return ok ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER;
      94             :         }
      95             : 
      96     1853981 :         if (s->length == 32) {
      97           6 :                 uint8_t buf16[16] = {0};
      98           6 :                 DATA_BLOB blob16 = { .data = buf16, .length = sizeof(buf16) };
      99           6 :                 size_t rlen = strhex_to_str((char *)blob16.data, blob16.length,
     100           0 :                                             (const char *)s->data, s->length);
     101           6 :                 if (rlen != blob16.length) {
     102           0 :                         return NT_STATUS_INVALID_PARAMETER;
     103             :                 }
     104             : 
     105           6 :                 return GUID_from_ndr_blob(&blob16, guid);
     106             :         }
     107             : 
     108     1853975 :         if (s->length == 16) {
     109     1853950 :                 return GUID_from_ndr_blob(s, guid);
     110             :         }
     111             : 
     112          25 :         return NT_STATUS_INVALID_PARAMETER;
     113             : }
     114             : 
     115             : /**
     116             :   build a GUID from a string
     117             : */
     118      308305 : _PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
     119             : {
     120      308305 :         DATA_BLOB blob = data_blob_string_const(s);
     121      308305 :         return GUID_from_data_blob(&blob, guid);
     122             : }
     123             : 
     124             : /**
     125             :  * generate a random GUID
     126             :  */
     127     1726334 : _PUBLIC_ struct GUID GUID_random(void)
     128             : {
     129       54139 :         struct GUID guid;
     130             : 
     131     1726334 :         generate_random_buffer((uint8_t *)&guid, sizeof(guid));
     132     1726334 :         guid.clock_seq[0] = (guid.clock_seq[0] & 0x3F) | 0x80;
     133     1726334 :         guid.time_hi_and_version = (guid.time_hi_and_version & 0x0FFF) | 0x4000;
     134             : 
     135     1726334 :         return guid;
     136             : }
     137             : 
     138             : /**
     139             :  * generate an empty GUID 
     140             :  */
     141    66906731 : _PUBLIC_ struct GUID GUID_zero(void)
     142             : {
     143    66906731 :         return (struct GUID) { .time_low = 0 };
     144             : }
     145             : 
     146    87222349 : _PUBLIC_ bool GUID_all_zero(const struct GUID *u)
     147             : {
     148    87222349 :         if (u->time_low != 0 ||
     149    18254457 :             u->time_mid != 0 ||
     150    17363844 :             u->time_hi_and_version != 0 ||
     151    18254457 :             u->clock_seq[0] != 0 ||
     152    18254457 :             u->clock_seq[1] != 0 ||
     153    18254457 :             !all_zero(u->node, 6)) {
     154    68967892 :                 return false;
     155             :         }
     156    17363844 :         return true;
     157             : }
     158             : 
     159    42694154 : _PUBLIC_ bool GUID_equal(const struct GUID *u1, const struct GUID *u2)
     160             : {
     161    42694154 :         return (GUID_compare(u1, u2) == 0);
     162             : }
     163             : 
     164    60332721 : _PUBLIC_ int GUID_compare(const struct GUID *u1, const struct GUID *u2)
     165             : {
     166    60332721 :         if (u1->time_low != u2->time_low) {
     167    52867011 :                 return u1->time_low > u2->time_low ? 1 : -1;
     168             :         }
     169             : 
     170     7465710 :         if (u1->time_mid != u2->time_mid) {
     171        6374 :                 return u1->time_mid > u2->time_mid ? 1 : -1;
     172             :         }
     173             : 
     174     7459336 :         if (u1->time_hi_and_version != u2->time_hi_and_version) {
     175           0 :                 return u1->time_hi_and_version > u2->time_hi_and_version ? 1 : -1;
     176             :         }
     177             : 
     178     7459336 :         if (u1->clock_seq[0] != u2->clock_seq[0]) {
     179       19239 :                 return u1->clock_seq[0] > u2->clock_seq[0] ? 1 : -1;
     180             :         }
     181             : 
     182     7440097 :         if (u1->clock_seq[1] != u2->clock_seq[1]) {
     183        6350 :                 return u1->clock_seq[1] > u2->clock_seq[1] ? 1 : -1;
     184             :         }
     185             : 
     186     7433747 :         return memcmp(u1->node, u2->node, 6);
     187             : }
     188             : 
     189             : /**
     190             :   its useful to be able to display these in debugging messages
     191             : */
     192    31909164 : _PUBLIC_ char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     193             : {
     194      301518 :         struct GUID_txt_buf buf;
     195    31909164 :         return talloc_strdup(mem_ctx, GUID_buf_string(guid, &buf));
     196             : }
     197             : 
     198             : /**
     199             :  * Does the same without allocating memory, using the structure buffer.
     200             :  * Useful for debug messages, so that you do not have to talloc_free the result
     201             :  */
     202    40373458 : _PUBLIC_ char* GUID_buf_string(const struct GUID *guid,
     203             :                                struct GUID_txt_buf *dst)
     204             : {
     205    40373458 :         if (!guid) {
     206           0 :                 return NULL;
     207             :         }
     208    40373458 :         snprintf(dst->buf, sizeof(dst->buf),
     209             :                  "%08"PRIx32"-%04"PRIx16"-%04"PRIx16"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8,
     210    40373458 :                  guid->time_low, guid->time_mid,
     211    40373458 :                  guid->time_hi_and_version,
     212    40373458 :                  guid->clock_seq[0],
     213    40373458 :                  guid->clock_seq[1],
     214    40373458 :                  guid->node[0], guid->node[1],
     215    40373458 :                  guid->node[2], guid->node[3],
     216    40373458 :                  guid->node[4], guid->node[5]);
     217    40373458 :         return dst->buf;
     218             : }
     219             : 
     220          61 : _PUBLIC_ char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     221             : {
     222           2 :         struct GUID_txt_buf buf;
     223          61 :         char *ret = talloc_asprintf(
     224             :                 mem_ctx, "{%s}", GUID_buf_string(guid, &buf));
     225          61 :         return ret;
     226             : }
     227             : 
     228           0 : _PUBLIC_ char *GUID_hexstring(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     229             : {
     230           0 :         char *ret = NULL;
     231           0 :         DATA_BLOB guid_blob = { .data = NULL };
     232           0 :         NTSTATUS status;
     233             : 
     234           0 :         status = GUID_to_ndr_blob(guid, mem_ctx, &guid_blob);
     235           0 :         if (NT_STATUS_IS_OK(status)) {
     236           0 :                 ret = data_blob_hex_string_upper(mem_ctx, &guid_blob);
     237             :         }
     238           0 :         TALLOC_FREE(guid_blob.data);
     239           0 :         return ret;
     240             : }
     241             : 
     242     2030739 : _PUBLIC_ bool ndr_policy_handle_empty(const struct policy_handle *h)
     243             : {
     244     2030739 :         return (h->handle_type == 0 && GUID_all_zero(&h->uuid));
     245             : }
     246             : 
     247         175 : _PUBLIC_ bool ndr_policy_handle_equal(const struct policy_handle *hnd1,
     248             :                                   const struct policy_handle *hnd2)
     249             : {
     250         175 :         if (!hnd1 || !hnd2) {
     251           0 :                 return false;
     252             :         }
     253             : 
     254         175 :         return (memcmp(hnd1, hnd2, sizeof(*hnd1)) == 0);
     255             : }

Generated by: LCOV version 1.14