uniqueidgen.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /* uniqueidgen.c - implementation for uniqueID generator */
  42. #include <string.h>
  43. #ifndef _WIN32 /* for ntoh* functions */
  44. #include <sys/types.h>
  45. #include <sys/time.h>
  46. #include <sys/sysinfo.h>
  47. #include <sys/utsname.h>
  48. #endif
  49. #include "nspr.h"
  50. #include "slap.h"
  51. #include "uuid.h"
  52. #define MODULE "uniqueid generator"
  53. /* converts from guid -> UniqueID */
  54. /* static void uuid2UniqueID (const guid_t *uuid, Slapi_UniqueID *uId); */
  55. /* converts from UniqueID -> guid */
  56. /* static void uniqueID2uuid (const Slapi_UniqueID *uId, guid_t *uuid); */
  57. /* validates directory */
  58. static int validDir (const char *configDir);
  59. /* Function: uniqueIDGenInit
  60. Description: this function initializes the generator
  61. Parameters: configDir - directory in which generators state is stored
  62. configDN - DIT entry with state information
  63. mtGen - indicates whether multiple threads will use generator
  64. Return: UID_SUCCESS if function succeeds
  65. UID_BADDATA if invalif directory is passed
  66. UID_SYSTEM_ERROR if any other failure occurs
  67. */
  68. int uniqueIDGenInit (const char *configDir, const Slapi_DN *configDN, PRBool mtGen)
  69. {
  70. int rt;
  71. if ((configDN == NULL && (configDir == NULL || !validDir(configDir))) ||
  72. (configDN && configDir))
  73. {
  74. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDGenInit: invalid arguments\n");
  75. return UID_BADDATA;
  76. }
  77. rt = uuid_init (configDir, configDN, mtGen);
  78. if (rt == UUID_SUCCESS)
  79. return UID_SUCCESS;
  80. else
  81. {
  82. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDGenInit: "
  83. "generator initialization failed\n");
  84. return UID_SYSTEM_ERROR;
  85. }
  86. }
  87. /* Function: uniqueIDGenCleanup
  88. Description: cleanup
  89. Parameters: none
  90. Return: none
  91. */
  92. void uniqueIDGenCleanup (){
  93. uuid_cleanup ();
  94. }
  95. /* Function: slapi_uniqueIDGenerate
  96. Description: this function generates UniqueID; exposed to the plugins.
  97. Parameters: uId - structure in which new id will be return
  98. Return: UID_SUCCESS, if operation is successful
  99. UID_BADDATA, if null pointer is passed to the function
  100. UID_SYSTEM_ERROR, if update to persistent storage failed
  101. */
  102. int slapi_uniqueIDGenerate (Slapi_UniqueID *uId){
  103. int rt;
  104. if (uId == NULL)
  105. {
  106. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDGenerate: "
  107. "NULL paramter is passed to the function.\n");
  108. return UID_BADDATA;
  109. }
  110. rt = uuid_create(uId);
  111. if (rt != UUID_SUCCESS)
  112. {
  113. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDGenerate: "
  114. "id generation failed.\n");
  115. return UID_SYSTEM_ERROR;
  116. }
  117. return UID_SUCCESS;
  118. }
  119. /* Function: slapi_uniqueIDGenerateString
  120. Description: this function generates uniqueid an returns it as a string
  121. This function returns the data in the format generated by
  122. slapi_uniqueIDFormat.
  123. Parameters: uId - buffer to receive the ID. Caller is responsible for
  124. freeing uId buffer.
  125. Return: UID_SUCCESS if function succeeds;
  126. UID_BADDATA if invalid pointer passed to the function;
  127. UID_MEMORY_ERROR if malloc fails;
  128. UID_SYSTEM_ERROR update to persistent storage failed.
  129. */
  130. int slapi_uniqueIDGenerateString (char **uId)
  131. {
  132. Slapi_UniqueID uIdTemp;
  133. int rc;
  134. rc = slapi_uniqueIDGenerate (&uIdTemp);
  135. if (rc != UID_SUCCESS)
  136. return rc;
  137. rc = slapi_uniqueIDFormat (&uIdTemp, uId);
  138. return rc;
  139. }
  140. /* Function: slapi_uniqueIDGenerateFromName
  141. Description: this function generates an id from name. See uuid
  142. draft for more details. This function is thread safe.
  143. Parameters: uId - generated id
  144. uIDBase - uid used for generation to distinguish different
  145. name - buffer containing name from which to generate the id
  146. namelen - length of the name buffer
  147. name spaces
  148. Return: UID_SUCCESS if function succeeds
  149. UID_BADDATA if invalid argument is passed to the
  150. function.
  151. */
  152. int slapi_uniqueIDGenerateFromName (Slapi_UniqueID *uId, const Slapi_UniqueID *uIdBase,
  153. const void *name, int namelen)
  154. {
  155. if (uId == NULL || uIdBase == NULL || name == NULL || namelen <= 0)
  156. {
  157. slapi_log_error (SLAPI_LOG_FATAL, MODULE, "uniqueIDGenerateMT: "
  158. "invalid paramter is passed to the function.\n");
  159. return UID_BADDATA;
  160. }
  161. uuid_create_from_name(uId, *uIdBase, name, namelen);
  162. return UID_SUCCESS;
  163. }
  164. /* Function: slapi_uniqueIDGenerateFromName
  165. Description: this function generates an id from a name and returns
  166. it in the string format. See uuid draft for more
  167. details. This function can be used in both a
  168. singlethreaded and a multithreaded environments.
  169. Parameters: uId - generated id in string form
  170. uIDBase - uid used for generation to distinguish among
  171. different name spaces in string form; NULL means to use
  172. empty id as the base.
  173. name - buffer containing name from which to generate the id
  174. namelen - length of the name buffer
  175. Return: UID_SUCCESS if function succeeds
  176. UID_BADDATA if invalid argument is passed to the
  177. function.
  178. */
  179. int slapi_uniqueIDGenerateFromNameString (char **uId,
  180. const char *uIdBase,
  181. const void *name, int namelen)
  182. {
  183. int rc;
  184. Slapi_UniqueID idBase;
  185. Slapi_UniqueID idGen;
  186. /* just use Id of all 0 as base id */
  187. if (uIdBase == NULL)
  188. {
  189. memset (&idBase, 0, sizeof (idBase));
  190. memset (&idGen, 0, sizeof (idGen));
  191. }
  192. else
  193. {
  194. rc = slapi_uniqueIDScan (&idBase, uIdBase);
  195. if (rc != UID_SUCCESS)
  196. {
  197. return rc;
  198. }
  199. }
  200. rc = slapi_uniqueIDGenerateFromName (&idGen, &idBase, name, namelen);
  201. if (rc != UID_SUCCESS)
  202. {
  203. return rc;
  204. }
  205. rc = slapi_uniqueIDFormat (&idGen, uId);
  206. return rc;
  207. }
  208. /* helper fumctions */
  209. static int validDir(const char *configDir){
  210. PRDir* dir;
  211. /* empty string means this directory */
  212. if (strlen(configDir) == 0)
  213. return 1;
  214. dir = PR_OpenDir(configDir);
  215. if (dir){
  216. PR_CloseDir (dir);
  217. return 1;
  218. }
  219. return 0;
  220. }