diff options
Diffstat (limited to 'source3/libads/ads_struct.c')
-rw-r--r-- | source3/libads/ads_struct.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c new file mode 100644 index 0000000000..489f301ae2 --- /dev/null +++ b/source3/libads/ads_struct.c @@ -0,0 +1,175 @@ +/* + Unix SMB/CIFS implementation. + ads (active directory) utility library + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* return a ldap dn path from a string, given separators and field name + caller must free +*/ +char *ads_build_path(const char *realm, const char *sep, const char *field, int reverse) +{ + char *p, *r; + int numbits = 0; + char *ret; + int len; + + r = strdup(realm); + + if (!r || !*r) return r; + + for (p=r; *p; p++) { + if (strchr(sep, *p)) numbits++; + } + + len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1; + + ret = malloc(len); + strlcpy(ret,field, len); + p=strtok(r,sep); + strlcat(ret, p, len); + + while ((p=strtok(NULL,sep))) { + char *s; + if (reverse) { + asprintf(&s, "%s%s,%s", field, p, ret); + } else { + asprintf(&s, "%s,%s%s", ret, field, p); + } + free(ret); + ret = s; + } + + free(r); + + return ret; +} + +/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a + realm of the form AA.BB.CC + caller must free +*/ +char *ads_build_dn(const char *realm) +{ + return ads_build_path(realm, ".", "dc=", 0); +} + + +#ifdef HAVE_LDAP +/* + find the ldap server from DNS +*/ +static char *find_ldap_server(ADS_STRUCT *ads) +{ + char *list = NULL; + struct in_addr ip; + + if (ads->realm && + ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { + char *p; + p = strchr(list, ':'); + if (p) *p = 0; + return list; + } + + /* get desperate, find the domain controller IP */ + if (resolve_name(lp_workgroup(), &ip, 0x1B)) { + return strdup(inet_ntoa(ip)); + } + + return NULL; +} + +#else + +static char *find_ldap_server(ADS_STRUCT *ads) +{ + /* Without LDAP this doesn't make much sense */ + return NULL; +} + +#endif + +#ifndef LDAP_PORT +#define LDAP_PORT 389 +#endif + +/* + initialise a ADS_STRUCT, ready for some ads_ ops +*/ +ADS_STRUCT *ads_init(const char *realm, + const char *ldap_server, + const char *bind_path, + const char *password) +{ + ADS_STRUCT *ads; + + ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads)); + ZERO_STRUCTP(ads); + + ads->realm = realm? strdup(realm) : NULL; + ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; + ads->bind_path = bind_path? strdup(bind_path) : NULL; + ads->ldap_port = LDAP_PORT; + if (password) ads->password = strdup(password); + + if (!ads->realm) { + ads->realm = strdup(lp_realm()); + if (!ads->realm[0]) { + SAFE_FREE(ads->realm); + } + } + if (!ads->bind_path && ads->realm) { + ads->bind_path = ads_build_dn(ads->realm); + } + if (!ads->ldap_server) { + ads->ldap_server = strdup(lp_ads_server()); + if (!ads->ldap_server[0]) { + ads->ldap_server = find_ldap_server(ads); + } + } + if (!ads->kdc_server) { + /* assume its the same as LDAP */ + ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL; + } + + return ads; +} + +/* + free the memory used by the ADS structure initialized with 'ads_init(...)' +*/ +void ads_destroy(ADS_STRUCT **ads) +{ + if (ads && *ads) { +#if HAVE_LDAP + if ((*ads)->ld) ldap_unbind((*ads)->ld); +#endif + SAFE_FREE((*ads)->realm); + SAFE_FREE((*ads)->ldap_server); + SAFE_FREE((*ads)->ldap_server_name); + SAFE_FREE((*ads)->kdc_server); + SAFE_FREE((*ads)->bind_path); + SAFE_FREE((*ads)->password); + SAFE_FREE((*ads)->user_name); + ZERO_STRUCTP(*ads); + SAFE_FREE(*ads); + } +} |