root/librpc/ndr/uuid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. GUID_from_data_blob
  2. GUID_from_string
  3. NS_GUID_from_string
  4. GUID_random
  5. GUID_zero
  6. GUID_all_zero
  7. GUID_equal
  8. GUID_compare
  9. GUID_string
  10. GUID_string2
  11. GUID_hexstring
  12. NS_GUID_string
  13. policy_handle_empty

   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 "includes.h"
  25 #include "librpc/ndr/libndr.h"
  26 #include "librpc/gen_ndr/ndr_misc.h"
  27 
  28 /**
  29   build a GUID from a string
  30 */
  31 _PUBLIC_ NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid)
     /* [<][>][^][v][top][bottom][index][help] */
  32 {
  33         NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
  34         uint32_t time_low;
  35         uint32_t time_mid, time_hi_and_version;
  36         uint32_t clock_seq[2];
  37         uint32_t node[6];
  38         uint8_t buf16[16];
  39 
  40         DATA_BLOB blob16 = data_blob_const(buf16, sizeof(buf16));
  41         int i;
  42 
  43         if (s->data == NULL) {
  44                 return NT_STATUS_INVALID_PARAMETER;
  45         }
  46 
  47         if (s->length == 36) {
  48                 TALLOC_CTX *mem_ctx;
  49                 const char *string;
  50 
  51                 mem_ctx = talloc_new(NULL);
  52                 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
  53                 string = talloc_strndup(mem_ctx, (const char *)s->data, s->length);
  54                 NT_STATUS_HAVE_NO_MEMORY(string);
  55                 if (11 == sscanf(string,
  56                                  "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  57                                  &time_low, &time_mid, &time_hi_and_version, 
  58                                  &clock_seq[0], &clock_seq[1],
  59                                  &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
  60                         status = NT_STATUS_OK;
  61                 }
  62                 talloc_free(mem_ctx);
  63 
  64         } else if (s->length == 38) {
  65                 TALLOC_CTX *mem_ctx;
  66                 const char *string;
  67 
  68                 mem_ctx = talloc_new(NULL);
  69                 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
  70                 string = talloc_strndup(mem_ctx, (const char *)s->data, s->length);
  71                 NT_STATUS_HAVE_NO_MEMORY(string);
  72                 if (11 == sscanf((const char *)s->data, 
  73                                  "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
  74                                  &time_low, &time_mid, &time_hi_and_version, 
  75                                  &clock_seq[0], &clock_seq[1],
  76                                  &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
  77                         status = NT_STATUS_OK;
  78                 }
  79                 talloc_free(mem_ctx);
  80 
  81         } else if (s->length == 32) {
  82                 size_t rlen = strhex_to_str((char *)blob16.data, blob16.length,
  83                                             (const char *)s->data, s->length);
  84                 if (rlen == blob16.length) {
  85                         /* goto the ndr_pull_struct_blob() path */
  86                         status = NT_STATUS_OK;
  87                         s = &blob16;
  88                 }
  89         }
  90 
  91         if (s->length == 16) {
  92                 enum ndr_err_code ndr_err;
  93                 struct GUID guid2;
  94                 TALLOC_CTX *mem_ctx;
  95 
  96                 mem_ctx = talloc_new(NULL);
  97                 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
  98 
  99                 ndr_err = ndr_pull_struct_blob(s, mem_ctx, NULL, &guid2,
 100                                                (ndr_pull_flags_fn_t)ndr_pull_GUID);
 101                 talloc_free(mem_ctx);
 102                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 103                         return ndr_map_error2ntstatus(ndr_err);
 104                 }
 105                 *guid = guid2;
 106                 return NT_STATUS_OK;
 107         }
 108 
 109         if (!NT_STATUS_IS_OK(status)) {
 110                 return status;
 111         }
 112 
 113         guid->time_low = time_low;
 114         guid->time_mid = time_mid;
 115         guid->time_hi_and_version = time_hi_and_version;
 116         guid->clock_seq[0] = clock_seq[0];
 117         guid->clock_seq[1] = clock_seq[1];
 118         for (i=0;i<6;i++) {
 119                 guid->node[i] = node[i];
 120         }
 121 
 122         return NT_STATUS_OK;
 123 }
 124 
 125 /**
 126   build a GUID from a string
 127 */
 128 _PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
     /* [<][>][^][v][top][bottom][index][help] */
 129 {
 130         DATA_BLOB blob = data_blob_string_const(s);
 131         return GUID_from_data_blob(&blob, guid);
 132         return NT_STATUS_OK;
 133 }
 134 
 135 /**
 136   build a GUID from a string
 137 */
 138 _PUBLIC_ NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid)
     /* [<][>][^][v][top][bottom][index][help] */
 139 {
 140         NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
 141         uint32_t time_low;
 142         uint32_t time_mid, time_hi_and_version;
 143         uint32_t clock_seq[2];
 144         uint32_t node[6];
 145         int i;
 146 
 147         if (s == NULL) {
 148                 return NT_STATUS_INVALID_PARAMETER;
 149         }
 150 
 151         if (11 == sscanf(s, "%08x-%04x%04x-%02x%02x%02x%02x-%02x%02x%02x%02x",
 152                          &time_low, &time_mid, &time_hi_and_version, 
 153                          &clock_seq[0], &clock_seq[1],
 154                          &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
 155                 status = NT_STATUS_OK;
 156         }
 157 
 158         if (!NT_STATUS_IS_OK(status)) {
 159                 return status;
 160         }
 161 
 162         guid->time_low = time_low;
 163         guid->time_mid = time_mid;
 164         guid->time_hi_and_version = time_hi_and_version;
 165         guid->clock_seq[0] = clock_seq[0];
 166         guid->clock_seq[1] = clock_seq[1];
 167         for (i=0;i<6;i++) {
 168                 guid->node[i] = node[i];
 169         }
 170 
 171         return NT_STATUS_OK;
 172 }
 173 
 174 /**
 175  * generate a random GUID
 176  */
 177 _PUBLIC_ struct GUID GUID_random(void)
     /* [<][>][^][v][top][bottom][index][help] */
 178 {
 179         struct GUID guid;
 180 
 181         generate_random_buffer((uint8_t *)&guid, sizeof(guid));
 182         guid.clock_seq[0] = (guid.clock_seq[0] & 0x3F) | 0x80;
 183         guid.time_hi_and_version = (guid.time_hi_and_version & 0x0FFF) | 0x4000;
 184 
 185         return guid;
 186 }
 187 
 188 /**
 189  * generate an empty GUID 
 190  */
 191 _PUBLIC_ struct GUID GUID_zero(void)
     /* [<][>][^][v][top][bottom][index][help] */
 192 {
 193         struct GUID guid;
 194 
 195         ZERO_STRUCT(guid);
 196 
 197         return guid;
 198 }
 199 
 200 _PUBLIC_ bool GUID_all_zero(const struct GUID *u)
     /* [<][>][^][v][top][bottom][index][help] */
 201 {
 202         if (u->time_low != 0 ||
 203             u->time_mid != 0 ||
 204             u->time_hi_and_version != 0 ||
 205             u->clock_seq[0] != 0 ||
 206             u->clock_seq[1] != 0 ||
 207             !all_zero(u->node, 6)) {
 208                 return false;
 209         }
 210         return true;
 211 }
 212 
 213 _PUBLIC_ bool GUID_equal(const struct GUID *u1, const struct GUID *u2)
     /* [<][>][^][v][top][bottom][index][help] */
 214 {
 215         if (u1->time_low != u2->time_low ||
 216             u1->time_mid != u2->time_mid ||
 217             u1->time_hi_and_version != u2->time_hi_and_version ||
 218             u1->clock_seq[0] != u2->clock_seq[0] ||
 219             u1->clock_seq[1] != u2->clock_seq[1] ||
 220             memcmp(u1->node, u2->node, 6) != 0) {
 221                 return false;
 222         }
 223         return true;
 224 }
 225 
 226 _PUBLIC_ int GUID_compare(const struct GUID *u1, const struct GUID *u2)
     /* [<][>][^][v][top][bottom][index][help] */
 227 {
 228         if (u1->time_low != u2->time_low) {
 229                 return u1->time_low - u2->time_low;
 230         }
 231 
 232         if (u1->time_mid != u2->time_mid) {
 233                 return u1->time_mid - u2->time_mid;
 234         }
 235 
 236         if (u1->time_hi_and_version != u2->time_hi_and_version) {
 237                 return u1->time_hi_and_version - u2->time_hi_and_version;
 238         }
 239 
 240         if (u1->clock_seq[0] != u2->clock_seq[0]) {
 241                 return u1->clock_seq[0] - u2->clock_seq[0];
 242         }
 243 
 244         if (u1->clock_seq[1] != u2->clock_seq[1]) {
 245                 return u1->clock_seq[1] - u2->clock_seq[1];
 246         }
 247 
 248         return memcmp(u1->node, u2->node, 6);
 249 }
 250 
 251 /**
 252   its useful to be able to display these in debugging messages
 253 */
 254 _PUBLIC_ char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     /* [<][>][^][v][top][bottom][index][help] */
 255 {
 256         return talloc_asprintf(mem_ctx, 
 257                                "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
 258                                guid->time_low, guid->time_mid,
 259                                guid->time_hi_and_version,
 260                                guid->clock_seq[0],
 261                                guid->clock_seq[1],
 262                                guid->node[0], guid->node[1],
 263                                guid->node[2], guid->node[3],
 264                                guid->node[4], guid->node[5]);
 265 }
 266 
 267 _PUBLIC_ char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     /* [<][>][^][v][top][bottom][index][help] */
 268 {
 269         char *ret, *s = GUID_string(mem_ctx, guid);
 270         ret = talloc_asprintf(mem_ctx, "{%s}", s);
 271         talloc_free(s);
 272         return ret;
 273 }
 274 
 275 _PUBLIC_ char *GUID_hexstring(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     /* [<][>][^][v][top][bottom][index][help] */
 276 {
 277         char *ret;
 278         DATA_BLOB guid_blob;
 279         enum ndr_err_code ndr_err;
 280         TALLOC_CTX *tmp_mem;
 281 
 282         tmp_mem = talloc_new(mem_ctx);
 283         if (!tmp_mem) {
 284                 return NULL;
 285         }
 286         ndr_err = ndr_push_struct_blob(&guid_blob, tmp_mem,
 287                                        NULL,
 288                                        guid,
 289                                        (ndr_push_flags_fn_t)ndr_push_GUID);
 290         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 291                 talloc_free(tmp_mem);
 292                 return NULL;
 293         }
 294 
 295         ret = data_blob_hex_string(mem_ctx, &guid_blob);
 296         talloc_free(tmp_mem);
 297         return ret;
 298 }
 299 
 300 _PUBLIC_ char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     /* [<][>][^][v][top][bottom][index][help] */
 301 {
 302         return talloc_asprintf(mem_ctx, 
 303                                "%08x-%04x%04x-%02x%02x%02x%02x-%02x%02x%02x%02x",
 304                                guid->time_low, guid->time_mid,
 305                                guid->time_hi_and_version,
 306                                guid->clock_seq[0],
 307                                guid->clock_seq[1],
 308                                guid->node[0], guid->node[1],
 309                                guid->node[2], guid->node[3],
 310                                guid->node[4], guid->node[5]);
 311 }
 312 
 313 _PUBLIC_ bool policy_handle_empty(struct policy_handle *h) 
     /* [<][>][^][v][top][bottom][index][help] */
 314 {
 315         return (h->handle_type == 0 && GUID_all_zero(&h->uuid));
 316 }

/* [<][>][^][v][top][bottom][index][help] */