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