uniqueid.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /* uniqueid.c implementation of entryid functionality */
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <ctype.h>
  17. #include "slap.h"
  18. #define UIDSTR_SIZE 35 /* size of the string representation of the id */
  19. #define MODULE "uniqueid" /* for logging */
  20. static int isValidFormat (const char * buff);
  21. /* All functions that strat with slapi_ are exposed to the plugins */
  22. /* Function: slapi_uniqueIDNew
  23. Description: creates new Slapi_UniqueID object
  24. Parameters: none
  25. Return: pointer to the new uId object if successful
  26. NULL if memory allocation failed
  27. */
  28. Slapi_UniqueID *slapi_uniqueIDNew ()
  29. {
  30. Slapi_UniqueID *uId;
  31. uId = (Slapi_UniqueID*)slapi_ch_malloc (sizeof (Slapi_UniqueID));
  32. if (uId == NULL)
  33. {
  34. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDNew: "
  35. "failed to allocate new id.\n");
  36. return NULL;
  37. }
  38. memset (uId, 0, sizeof (Slapi_UniqueID));
  39. return uId;
  40. }
  41. /* Function: slapi_uniqueIDDestroy
  42. Description: destroys Slapi_UniqueID objects and sets the pointer to NULL
  43. Parameters: uId - id to destroy
  44. Return: none
  45. */
  46. void slapi_uniqueIDDestroy (Slapi_UniqueID **uId)
  47. {
  48. if (uId && *uId)
  49. {
  50. slapi_ch_free ((void**)uId);
  51. *uId = NULL;
  52. }
  53. }
  54. /* Function: slapi_uniqueIDCompare
  55. Description: this function lexically compares two entry ids.
  56. both Ids must have UUID type.
  57. Parameters: uId1, uId2 - ids to compare
  58. Return: -1 if uId1 < uId2
  59. 0 if uId2 == uId2
  60. 1 if uId2 > uId2
  61. UID_BADDATA if invalid pointer passed to the function
  62. */
  63. int slapi_uniqueIDCompare (const Slapi_UniqueID *uId1, const Slapi_UniqueID *uId2){
  64. if (uId1 == NULL || uId2 == NULL)
  65. {
  66. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDCompare: "
  67. "NULL argument passed to the function.\n");
  68. return UID_BADDATA;
  69. }
  70. return(uuid_compare(uId1, uId2));
  71. }
  72. /* Function: slapi_uniqueIDCompareString
  73. Description: this function compares two uniqueids, represented as strings
  74. Parameters: uuid1, uuid2 - ids to compare
  75. Return: 0 if uuid1 == uuid2
  76. non-zero if uuid1 != uuid2 or uuid1 == NULL or uuid2 == NULL
  77. */
  78. int slapi_uniqueIDCompareString(const char *uuid1, const char *uuid2)
  79. {
  80. int return_value = 0; /* assume not equal */
  81. if (NULL != uuid1)
  82. {
  83. if (NULL != uuid2)
  84. {
  85. if (strcmp(uuid1, uuid2) == 0)
  86. {
  87. return_value = 1;
  88. }
  89. }
  90. }
  91. return return_value;
  92. }
  93. /* Function: slapi_uniqueIDFormat
  94. Description: this function converts Slapi_UniqueID to its string representation.
  95. The id format is HHHHHHHH-HHHHHHHH-HHHHHHHH-HHHHHHHH
  96. where H is a hex digit. The data will be outputed in the
  97. network byte order.
  98. Parameters: uId - entry id
  99. buff - buffer in which id is returned; caller must free this
  100. buffer
  101. Return: UID_SUCCESS - function was successfull
  102. UID_BADDATA - invalid parameter passed to the function
  103. UID_MEMORY_ERROR - failed to allocate the buffer
  104. */
  105. int slapi_uniqueIDFormat (const Slapi_UniqueID *uId, char **buff){
  106. guid_t uuid_tmp;
  107. char *ptr;
  108. if (uId == NULL || buff == NULL)
  109. {
  110. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDFormat: "
  111. "NULL argument passed to the function.\n");
  112. return UID_BADDATA;
  113. }
  114. *buff = (char*)slapi_ch_malloc (UIDSTR_SIZE + 1);
  115. if (*buff == NULL)
  116. {
  117. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDFormat: "
  118. "failed to allocate buffer.\n");
  119. return UID_MEMORY_ERROR;
  120. }
  121. uuid_tmp = *uId;
  122. uuid_tmp.time_low = htonl(uuid_tmp.time_low);
  123. uuid_tmp.time_mid = htons(uuid_tmp.time_mid);
  124. uuid_tmp.time_hi_and_version = htons(uuid_tmp.time_hi_and_version);
  125. ptr = slapi_u8_to_hex(((uint8_t *)&uuid_tmp.time_low)[0], *buff, 0);
  126. ptr = slapi_u8_to_hex(((uint8_t *)&uuid_tmp.time_low)[1], ptr, 0);
  127. ptr = slapi_u8_to_hex(((uint8_t *)&uuid_tmp.time_low)[2], ptr, 0);
  128. ptr = slapi_u8_to_hex(((uint8_t *)&uuid_tmp.time_low)[3], ptr, 0);
  129. *ptr++ = '-';
  130. ptr = slapi_u8_to_hex(((uint8_t *)&uuid_tmp.time_mid)[0], ptr, 0);
  131. ptr = slapi_u8_to_hex(((uint8_t *)&uuid_tmp.time_mid)[1], ptr, 0);
  132. ptr = slapi_u8_to_hex(((uint8_t *)&uuid_tmp.time_hi_and_version)[0], ptr, 0);
  133. ptr = slapi_u8_to_hex(((uint8_t *)&uuid_tmp.time_hi_and_version)[1], ptr, 0);
  134. *ptr++ = '-';
  135. ptr = slapi_u8_to_hex(uuid_tmp.clock_seq_hi_and_reserved, ptr, 0);
  136. ptr = slapi_u8_to_hex(uuid_tmp.clock_seq_low, ptr, 0);
  137. ptr = slapi_u8_to_hex(uuid_tmp.node[0], ptr, 0);
  138. ptr = slapi_u8_to_hex(uuid_tmp.node[1], ptr, 0);
  139. *ptr++ = '-';
  140. ptr = slapi_u8_to_hex(uuid_tmp.node[2], ptr, 0);
  141. ptr = slapi_u8_to_hex(uuid_tmp.node[3], ptr, 0);
  142. ptr = slapi_u8_to_hex(uuid_tmp.node[4], ptr, 0);
  143. ptr = slapi_u8_to_hex(uuid_tmp.node[5], ptr, 0);
  144. *ptr = 0;
  145. return UID_SUCCESS;
  146. }
  147. /* Function: slapi_uniqueIDScan
  148. Description: this function converts a string buffer into uniqueID.
  149. Parameters: uId - unique id to be returned
  150. buff - buffer with uniqueID in the format returned by
  151. uniqueIDFormat function
  152. Return: UID_SUCCESS - function was successfull
  153. UID_BADDATA - null parameter(s) or bad format
  154. */
  155. int slapi_uniqueIDScan (Slapi_UniqueID *uId, const char *buff){
  156. if (uId == NULL || buff == NULL)
  157. {
  158. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDScan: "
  159. "NULL argument passed to the function.\n");
  160. return UID_BADDATA;
  161. }
  162. if (!isValidFormat (buff))
  163. {
  164. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDScan: "
  165. "invalid data format.\n");
  166. return UID_BADDATA;
  167. }
  168. ((PRUint8 *) &uId->time_low)[0] = slapi_str_to_u8 (&(buff[0]));
  169. ((PRUint8 *) &uId->time_low)[1] = slapi_str_to_u8 (&(buff[2]));
  170. ((PRUint8 *) &uId->time_low)[2] = slapi_str_to_u8 (&(buff[4]));
  171. ((PRUint8 *) &uId->time_low)[3] = slapi_str_to_u8 (&(buff[6]));
  172. /* next field is at 9 because we skip the - */
  173. ((PRUint8 *) &uId->time_mid)[0] = slapi_str_to_u8 (&(buff[9]));
  174. ((PRUint8 *) &uId->time_mid)[1] = slapi_str_to_u8 (&(buff[11]));
  175. ((PRUint8 *) &uId->time_hi_and_version)[0] = slapi_str_to_u8 (&(buff[13]));
  176. ((PRUint8 *) &uId->time_hi_and_version)[1] = slapi_str_to_u8 (&(buff[15]));
  177. /* next field is at 18 because we skip the - */
  178. uId->clock_seq_hi_and_reserved = slapi_str_to_u8 (&(buff[18]));
  179. uId->clock_seq_low = slapi_str_to_u8 (&(buff[20]));
  180. uId->node[0] = slapi_str_to_u8 (&(buff[22]));
  181. uId->node[1] = slapi_str_to_u8 (&(buff[24]));
  182. /* next field is at 27 because we skip the - */
  183. uId->node[2] = slapi_str_to_u8 (&(buff[27]));
  184. uId->node[3] = slapi_str_to_u8 (&(buff[29]));
  185. uId->node[4] = slapi_str_to_u8 (&(buff[31]));
  186. uId->node[5] = slapi_str_to_u8 (&(buff[33]));
  187. uId->time_low = ntohl(uId->time_low);
  188. uId->time_mid = ntohs(uId->time_mid);
  189. uId->time_hi_and_version = ntohs(uId->time_hi_and_version);
  190. return UID_SUCCESS;
  191. }
  192. /* Function: slapi_uniqueIDIsUUID
  193. Description: tests if given entry id is in UUID format
  194. Parameters: uId - id to test
  195. Return 0 - it is UUID
  196. 1 - it is not UUID
  197. UID_BADDATA - invalid data passed to the function
  198. Note: LPXXX - This call is not used currently. Keep it ???
  199. */
  200. int slapi_uniqueIDIsUUID (const Slapi_UniqueID *uId){
  201. if (uId == NULL)
  202. return UID_BADDATA;
  203. /* Shortening Slapi_UniqueID: This call does nothing */
  204. return (0);
  205. }
  206. /* Name: slapi_uniqueIDSize
  207. Description: returns size of the string version of uniqueID in bytes
  208. Parameters: none
  209. Return: size of the string version of uniqueID in bytes
  210. */
  211. int slapi_uniqueIDSize ()
  212. {
  213. return (UIDSTR_SIZE);
  214. }
  215. /* Name: slapi_uniqueIDDup
  216. Description: duplicates an UniqueID object
  217. Parameters: uId - id to duplicate
  218. Return: duplicate of the Id
  219. */
  220. Slapi_UniqueID* slapi_uniqueIDDup (Slapi_UniqueID *uId)
  221. {
  222. Slapi_UniqueID *uIdDup = slapi_uniqueIDNew ();
  223. memcpy (uIdDup, uId, sizeof (Slapi_UniqueID));
  224. return uIdDup;
  225. }
  226. /* helper functions */
  227. static char* format = "XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX";
  228. static size_t format_len = 35;
  229. /* This function verifies that buff contains data in the correct
  230. format (specified above). */
  231. static int isValidFormat (const char * buff)
  232. {
  233. int i;
  234. if (strlen (buff) != strlen (format))
  235. return UID_BADDATA;
  236. for (i = 0; i < format_len; i++)
  237. {
  238. if (format[i] == '-' && buff [i] != '-')
  239. return 0;
  240. else if (format[i] == 'X' && ! isxdigit (buff[i]))
  241. return 0;
  242. }
  243. return 1;
  244. }