/source3/libads/ads_struct.c

https://bitbucket.org/knarf/samba · C · 213 lines · 133 code · 38 blank · 42 comment · 22 complexity · d62d1df1a1a39345ee0ba37d09b8a3a3 MD5 · raw file

  1. /*
  2. Unix SMB/CIFS implementation.
  3. ads (active directory) utility library
  4. Copyright (C) Andrew Tridgell 2001
  5. Copyright (C) Andrew Bartlett 2001
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "includes.h"
  18. #include "ads.h"
  19. /* return a ldap dn path from a string, given separators and field name
  20. caller must free
  21. */
  22. char *ads_build_path(const char *realm, const char *sep, const char *field, int reverse)
  23. {
  24. char *p, *r;
  25. int numbits = 0;
  26. char *ret;
  27. int len;
  28. char *saveptr;
  29. r = SMB_STRDUP(realm);
  30. if (!r || !*r) {
  31. return r;
  32. }
  33. for (p=r; *p; p++) {
  34. if (strchr(sep, *p)) {
  35. numbits++;
  36. }
  37. }
  38. len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1;
  39. ret = (char *)SMB_MALLOC(len);
  40. if (!ret) {
  41. free(r);
  42. return NULL;
  43. }
  44. if (strlcpy(ret,field, len) >= len) {
  45. /* Truncate ! */
  46. free(r);
  47. free(ret);
  48. return NULL;
  49. }
  50. p=strtok_r(r, sep, &saveptr);
  51. if (p) {
  52. if (strlcat(ret, p, len) >= len) {
  53. free(r);
  54. free(ret);
  55. return NULL;
  56. }
  57. while ((p=strtok_r(NULL, sep, &saveptr)) != NULL) {
  58. int retval;
  59. char *s = NULL;
  60. if (reverse)
  61. retval = asprintf(&s, "%s%s,%s", field, p, ret);
  62. else
  63. retval = asprintf(&s, "%s,%s%s", ret, field, p);
  64. free(ret);
  65. if (retval == -1) {
  66. free(r);
  67. return NULL;
  68. }
  69. ret = SMB_STRDUP(s);
  70. free(s);
  71. }
  72. }
  73. free(r);
  74. return ret;
  75. }
  76. /* return a dn of the form "dc=AA,dc=BB,dc=CC" from a
  77. realm of the form AA.BB.CC
  78. caller must free
  79. */
  80. char *ads_build_dn(const char *realm)
  81. {
  82. return ads_build_path(realm, ".", "dc=", 0);
  83. }
  84. /* return a DNS name in the for aa.bb.cc from the DN
  85. "dc=AA,dc=BB,dc=CC". caller must free
  86. */
  87. char *ads_build_domain(const char *dn)
  88. {
  89. char *dnsdomain = NULL;
  90. /* result should always be shorter than the DN */
  91. if ( (dnsdomain = SMB_STRDUP( dn )) == NULL ) {
  92. DEBUG(0,("ads_build_domain: malloc() failed!\n"));
  93. return NULL;
  94. }
  95. if (!strlower_m( dnsdomain )) {
  96. SAFE_FREE(dnsdomain);
  97. return NULL;
  98. }
  99. all_string_sub( dnsdomain, "dc=", "", 0);
  100. all_string_sub( dnsdomain, ",", ".", 0 );
  101. return dnsdomain;
  102. }
  103. #ifndef LDAP_PORT
  104. #define LDAP_PORT 389
  105. #endif
  106. /*
  107. initialise a ADS_STRUCT, ready for some ads_ ops
  108. */
  109. ADS_STRUCT *ads_init(const char *realm,
  110. const char *workgroup,
  111. const char *ldap_server)
  112. {
  113. ADS_STRUCT *ads;
  114. int wrap_flags;
  115. ads = SMB_XMALLOC_P(ADS_STRUCT);
  116. ZERO_STRUCTP(ads);
  117. ads->server.realm = realm? SMB_STRDUP(realm) : NULL;
  118. ads->server.workgroup = workgroup ? SMB_STRDUP(workgroup) : NULL;
  119. ads->server.ldap_server = ldap_server? SMB_STRDUP(ldap_server) : NULL;
  120. /* the caller will own the memory by default */
  121. ads->is_mine = 1;
  122. wrap_flags = lp_client_ldap_sasl_wrapping();
  123. if (wrap_flags == -1) {
  124. wrap_flags = 0;
  125. }
  126. ads->auth.flags = wrap_flags;
  127. /* Start with the configured page size when the connection is new,
  128. * we will drop it by half we get a timeout. */
  129. ads->config.ldap_page_size = lp_ldap_page_size();
  130. return ads;
  131. }
  132. /****************************************************************
  133. ****************************************************************/
  134. bool ads_set_sasl_wrap_flags(ADS_STRUCT *ads, int flags)
  135. {
  136. if (!ads) {
  137. return false;
  138. }
  139. ads->auth.flags = flags;
  140. return true;
  141. }
  142. /*
  143. free the memory used by the ADS structure initialized with 'ads_init(...)'
  144. */
  145. void ads_destroy(ADS_STRUCT **ads)
  146. {
  147. if (ads && *ads) {
  148. bool is_mine;
  149. is_mine = (*ads)->is_mine;
  150. #if HAVE_LDAP
  151. ads_disconnect(*ads);
  152. #endif
  153. SAFE_FREE((*ads)->server.realm);
  154. SAFE_FREE((*ads)->server.workgroup);
  155. SAFE_FREE((*ads)->server.ldap_server);
  156. SAFE_FREE((*ads)->auth.realm);
  157. SAFE_FREE((*ads)->auth.password);
  158. SAFE_FREE((*ads)->auth.user_name);
  159. SAFE_FREE((*ads)->auth.kdc_server);
  160. SAFE_FREE((*ads)->auth.ccache_name);
  161. SAFE_FREE((*ads)->config.realm);
  162. SAFE_FREE((*ads)->config.bind_path);
  163. SAFE_FREE((*ads)->config.ldap_server_name);
  164. SAFE_FREE((*ads)->config.server_site_name);
  165. SAFE_FREE((*ads)->config.client_site_name);
  166. SAFE_FREE((*ads)->config.schema_path);
  167. SAFE_FREE((*ads)->config.config_path);
  168. ZERO_STRUCTP(*ads);
  169. if ( is_mine )
  170. SAFE_FREE(*ads);
  171. }
  172. }