LCOV - code coverage report
Current view: top level - librpc/ndr - uuid.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 81 103 78.6 %
Date: 2024-06-13 04:01:37 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    72328693 : _PUBLIC_ NTSTATUS GUID_to_ndr_buf(
      32             :         const struct GUID *guid, struct GUID_ndr_buf *buf)
      33             : {
      34    72328693 :         DATA_BLOB b = { .data = buf->buf, .length = sizeof(buf->buf), };
      35             :         enum ndr_err_code ndr_err;
      36             : 
      37    72328693 :         ndr_err = ndr_push_struct_into_fixed_blob(
      38             :                 &b, guid, (ndr_push_flags_fn_t)ndr_push_GUID);
      39    72328693 :         return ndr_map_error2ntstatus(ndr_err);
      40             : }
      41             : 
      42             : /**
      43             :   build a NDR blob from a GUID
      44             : */
      45    72305545 : _PUBLIC_ NTSTATUS GUID_to_ndr_blob(const struct GUID *guid, TALLOC_CTX *mem_ctx, DATA_BLOB *b)
      46             : {
      47    72305545 :         struct GUID_ndr_buf buf = { .buf = {0}, };
      48             :         NTSTATUS status;
      49             : 
      50    72305545 :         status = GUID_to_ndr_buf(guid, &buf);
      51    72305545 :         if (!NT_STATUS_IS_OK(status)) {
      52           0 :                 return status;
      53             :         }
      54             : 
      55    72305545 :         *b = data_blob_talloc(mem_ctx, buf.buf, sizeof(buf.buf));
      56    72305545 :         if (b->data == NULL) {
      57           0 :                 return NT_STATUS_NO_MEMORY;
      58             :         }
      59    72305545 :         return NT_STATUS_OK;
      60             : }
      61             : 
      62             : 
      63             : /**
      64             :   build a GUID from a NDR data blob
      65             : */
      66   160124928 : _PUBLIC_ NTSTATUS GUID_from_ndr_blob(const DATA_BLOB *b, struct GUID *guid)
      67             : {
      68   120568983 :         enum ndr_err_code ndr_err =
      69    39555945 :                 ndr_pull_struct_blob_all_noalloc(b, guid,
      70             :                                                  (ndr_pull_flags_fn_t)ndr_pull_GUID);
      71   160124928 :         return ndr_map_error2ntstatus(ndr_err);
      72             : }
      73             : 
      74             : 
      75             : /**
      76             :   build a GUID from a string
      77             : */
      78    81119066 : _PUBLIC_ NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid)
      79             : {
      80             :         bool ok;
      81             : 
      82    81119066 :         if (s->data == NULL) {
      83           0 :                 return NT_STATUS_INVALID_PARAMETER;
      84             :         }
      85             : 
      86    81119066 :         if (s->length == 36) {
      87    79891757 :                 ok = parse_guid_string((char *)s->data, guid);
      88    79891757 :                 return ok ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER;
      89             :         }
      90             : 
      91     1227309 :         if (s->length == 38) {
      92        1054 :                 if (s->data[0] != '{' || s->data[37] != '}') {
      93           0 :                         return NT_STATUS_INVALID_PARAMETER;
      94             :                 }
      95        1054 :                 ok = parse_guid_string((char *)s->data + 1, guid);
      96        1054 :                 return ok ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER;
      97             :         }
      98             : 
      99     1226255 :         if (s->length == 32) {
     100           0 :                 uint8_t buf16[16] = {0};
     101           0 :                 DATA_BLOB blob16 = { .data = buf16, .length = sizeof(buf16) };
     102           0 :                 size_t rlen = strhex_to_str((char *)blob16.data, blob16.length,
     103           0 :                                             (const char *)s->data, s->length);
     104           0 :                 if (rlen != blob16.length) {
     105           0 :                         return NT_STATUS_INVALID_PARAMETER;
     106             :                 }
     107             : 
     108           0 :                 return GUID_from_ndr_blob(&blob16, guid);
     109             :         }
     110             : 
     111     1226255 :         if (s->length == 16) {
     112     1226247 :                 return GUID_from_ndr_blob(s, guid);
     113             :         }
     114             : 
     115           8 :         return NT_STATUS_INVALID_PARAMETER;
     116             : }
     117             : 
     118             : /**
     119             :   build a GUID from a string
     120             : */
     121     1334477 : _PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
     122             : {
     123     1334477 :         DATA_BLOB blob = data_blob_string_const(s);
     124     1334477 :         return GUID_from_data_blob(&blob, guid);
     125             : }
     126             : 
     127             : /**
     128             :  * generate a random GUID
     129             :  */
     130      972997 : _PUBLIC_ struct GUID GUID_random(void)
     131             : {
     132             :         struct GUID guid;
     133             : 
     134      972997 :         generate_random_buffer((uint8_t *)&guid, sizeof(guid));
     135      972997 :         guid.clock_seq[0] = (guid.clock_seq[0] & 0x3F) | 0x80;
     136      972997 :         guid.time_hi_and_version = (guid.time_hi_and_version & 0x0FFF) | 0x4000;
     137             : 
     138      972997 :         return guid;
     139             : }
     140             : 
     141             : /**
     142             :  * generate an empty GUID 
     143             :  */
     144    45613891 : _PUBLIC_ struct GUID GUID_zero(void)
     145             : {
     146    45613891 :         return (struct GUID) { .time_low = 0 };
     147             : }
     148             : 
     149    58128392 : _PUBLIC_ bool GUID_all_zero(const struct GUID *u)
     150             : {
     151    65901975 :         if (u->time_low != 0 ||
     152    16897153 :             u->time_mid != 0 ||
     153    16897153 :             u->time_hi_and_version != 0 ||
     154    16851766 :             u->clock_seq[0] != 0 ||
     155    16793546 :             u->clock_seq[1] != 0 ||
     156     9065350 :             !all_zero(u->node, 6)) {
     157    49063042 :                 return false;
     158             :         }
     159     9065350 :         return true;
     160             : }
     161             : 
     162    29545318 : _PUBLIC_ bool GUID_equal(const struct GUID *u1, const struct GUID *u2)
     163             : {
     164    29545318 :         return (GUID_compare(u1, u2) == 0);
     165             : }
     166             : 
     167    40747019 : _PUBLIC_ int GUID_compare(const struct GUID *u1, const struct GUID *u2)
     168             : {
     169    40747019 :         if (u1->time_low != u2->time_low) {
     170    36126657 :                 return u1->time_low > u2->time_low ? 1 : -1;
     171             :         }
     172             : 
     173     4620362 :         if (u1->time_mid != u2->time_mid) {
     174        2849 :                 return u1->time_mid > u2->time_mid ? 1 : -1;
     175             :         }
     176             : 
     177     4617513 :         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     4617513 :         if (u1->clock_seq[0] != u2->clock_seq[0]) {
     182        8613 :                 return u1->clock_seq[0] > u2->clock_seq[0] ? 1 : -1;
     183             :         }
     184             : 
     185     4608900 :         if (u1->clock_seq[1] != u2->clock_seq[1]) {
     186        2840 :                 return u1->clock_seq[1] > u2->clock_seq[1] ? 1 : -1;
     187             :         }
     188             : 
     189     4606060 :         return memcmp(u1->node, u2->node, 6);
     190             : }
     191             : 
     192             : /**
     193             :   its useful to be able to display these in debugging messages
     194             : */
     195    17862365 : _PUBLIC_ char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     196             : {
     197             :         struct GUID_txt_buf buf;
     198    17862365 :         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    24882680 : _PUBLIC_ char* GUID_buf_string(const struct GUID *guid,
     206             :                                struct GUID_txt_buf *dst)
     207             : {
     208    24882680 :         if (!guid) {
     209           0 :                 return NULL;
     210             :         }
     211   228195236 :         snprintf(dst->buf, sizeof(dst->buf),
     212             :                  "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
     213    24882680 :                  guid->time_low, guid->time_mid,
     214    24882680 :                  guid->time_hi_and_version,
     215    24882680 :                  guid->clock_seq[0],
     216    24882680 :                  guid->clock_seq[1],
     217    47472964 :                  guid->node[0], guid->node[1],
     218    47472964 :                  guid->node[2], guid->node[3],
     219    47472964 :                  guid->node[4], guid->node[5]);
     220    24882680 :         return dst->buf;
     221             : }
     222             : 
     223          51 : _PUBLIC_ char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     224             : {
     225             :         struct GUID_txt_buf buf;
     226          51 :         char *ret = talloc_asprintf(
     227             :                 mem_ctx, "{%s}", GUID_buf_string(guid, &buf));
     228          51 :         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             :         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      372367 : _PUBLIC_ bool ndr_policy_handle_empty(const struct policy_handle *h)
     246             : {
     247      372367 :         return (h->handle_type == 0 && GUID_all_zero(&h->uuid));
     248             : }
     249             : 
     250         161 : _PUBLIC_ bool ndr_policy_handle_equal(const struct policy_handle *hnd1,
     251             :                                   const struct policy_handle *hnd2)
     252             : {
     253         161 :         if (!hnd1 || !hnd2) {
     254           0 :                 return false;
     255             :         }
     256             : 
     257         161 :         return (memcmp(hnd1, hnd2, sizeof(*hnd1)) == 0);
     258             : }

Generated by: LCOV version 1.13