summaryrefslogtreecommitdiff
path: root/source3/libads
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libads')
-rw-r--r--source3/libads/ads_struct.c182
-rw-r--r--source3/libads/kerberos.c5
-rw-r--r--source3/libads/ldap.c103
3 files changed, 186 insertions, 104 deletions
diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c
new file mode 100644
index 0000000000..be0374225b
--- /dev/null
+++ b/source3/libads/ads_struct.c
@@ -0,0 +1,182 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ 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"
+
+static char *ads_build_dn(const char *realm)
+{
+ char *p, *r;
+ int numdots = 0;
+ char *ret;
+ int len;
+
+ r = strdup(realm);
+
+ if (!r || !*r) return r;
+
+ for (p=r; *p; p++) {
+ if (*p == '.') numdots++;
+ }
+
+ len = (numdots+1)*4 + strlen(r) + 1;
+
+ ret = malloc(len);
+ strlcpy(ret,"dc=", len);
+ p=strtok(r,".");
+ strlcat(ret, p, len);
+
+ while ((p=strtok(NULL,"."))) {
+ strlcat(ret,",dc=", len);
+ strlcat(ret, p, len);
+ }
+
+ free(r);
+
+ return ret;
+}
+
+#ifdef HAVE_KRB5
+
+/*
+ get the default relm from krb5.conf
+*/
+static char *get_default_realm(ADS_STRUCT *ads)
+{
+ BOOL ret;
+ krb5_context context;
+ char *realm;
+
+ ret = krb5_init_context(&context);
+ if (ret) {
+ DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret)));
+ return NULL;
+ }
+
+ ret = krb5_get_default_realm(context, &realm);
+ if (ret) {
+ DEBUG(1,("krb5_get_default_realm failed (%s)\n", error_message(ret)));
+ krb5_free_context(context);
+ return NULL;
+ } else {
+ DEBUG(5,("krb5_get_default_realm got (%s)\n", realm));
+ }
+ krb5_free_context(context);
+
+ return realm;
+}
+
+#else
+static char *get_default_realm(ADS_STRUCT *ads)
+{
+ /* We can't do this if we don't have krb5,
+ but save linking nightmares */
+ DEBUG(5,("get_default_realm: not compiled with krb5.\n"));
+ return NULL;
+}
+
+#endif
+
+#ifdef HAVE_LDAP
+/*
+ find the ldap server from DNS
+*/
+static char *find_ldap_server(ADS_STRUCT *ads)
+{
+ char *list = NULL;
+
+ if (ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) {
+ char *p;
+ p = strchr(list, ':');
+ if (p) *p = 0;
+ return list;
+ }
+
+ return NULL;
+}
+
+#else
+
+static char *find_ldap_server(ADS_STRUCT *ads)
+{
+ /* Without LDAP this doesn't make much sense */
+ return NULL;
+}
+
+#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)
+{
+ ADS_STRUCT *ads;
+
+ ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads));
+ memset(ads, 0, sizeof(*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 (!ads->realm) {
+ ads->realm = lp_realm();
+ if (!ads->realm[0]) {
+ ads->realm = get_default_realm(ads);
+ }
+ }
+ if (!ads->bind_path) {
+ ads->bind_path = ads_build_dn(ads->realm);
+ }
+ if (!ads->ldap_server) {
+ ads->ldap_server = 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 (False && (ads) && (*ads)) {
+ if ((*ads)->ld) ldap_unbind((*ads)->ld);
+ SAFE_FREE((*ads)->realm);
+ SAFE_FREE((*ads)->ldap_server);
+ SAFE_FREE((*ads)->kdc_server);
+ SAFE_FREE((*ads)->bind_path);
+ ZERO_STRUCTP(*ads);
+ SAFE_FREE(*ads);
+ }
+}
+
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index e4e946f0ce..a3aa8b1661 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -27,7 +27,7 @@
verify an incoming ticket and parse out the principal name and
authorization_data if available
*/
-NTSTATUS ads_verify_ticket(const DATA_BLOB *ticket,
+NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
char **principal, DATA_BLOB *auth_data)
{
krb5_context context;
@@ -66,9 +66,10 @@ NTSTATUS ads_verify_ticket(const DATA_BLOB *ticket,
return NT_STATUS_LOGON_FAILURE;
}
- ret = krb5_set_default_realm(context, lp_realm());
+ ret = krb5_set_default_realm(context, ads->realm);
if (ret) {
DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret)));
+ ads_destroy(&ads);
return NT_STATUS_LOGON_FAILURE;
}
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 49e803a49d..3e24273dc7 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -27,38 +27,6 @@
realm of the form AA.BB.CC
caller must free
*/
-static char *ads_build_dn(const char *realm)
-{
- char *p, *r;
- int numdots = 0;
- char *ret;
- int len;
-
- r = strdup(realm);
-
- if (!r || !*r) return r;
-
- for (p=r; *p; p++) {
- if (*p == '.') numdots++;
- }
-
- len = (numdots+1)*4 + strlen(r) + 1;
-
- ret = malloc(len);
- strlcpy(ret,"dc=", len);
- p=strtok(r,".");
- strlcat(ret, p, len);
-
- while ((p=strtok(NULL,"."))) {
- strlcat(ret,",dc=", len);
- strlcat(ret, p, len);
- }
-
- free(r);
-
- return ret;
-}
-
/*
return a string for an error from a ads routine
*/
@@ -68,75 +36,6 @@ char *ads_errstr(int rc)
}
/*
- find the ldap server from DNS
-*/
-static char *find_ldap_server(ADS_STRUCT *ads)
-{
- char *list = NULL;
-
- if (ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) {
- char *p;
- p = strchr(list, ':');
- if (p) *p = 0;
- return list;
- }
-
- return NULL;
-}
-
-/*
- initialise a ADS_STRUCT, ready for some ads_ ops
-*/
-ADS_STRUCT *ads_init(const char *realm,
- const char *ldap_server,
- const char *bind_path)
-{
- ADS_STRUCT *ads;
-
- ads = (ADS_STRUCT *)malloc(sizeof(*ads));
- if (!ads) return NULL;
- memset(ads, 0, sizeof(*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 (!ads->realm) {
- ads->realm = lp_realm();
- }
- if (!ads->bind_path) {
- ads->bind_path = ads_build_dn(ads->realm);
- }
- if (!ads->ldap_server) {
- ads->ldap_server = 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->ld) ldap_unbind(ads->ld);
- SAFE_FREE(ads->realm);
- SAFE_FREE(ads->ldap_server);
- SAFE_FREE(ads->kdc_server);
- SAFE_FREE(ads->bind_path);
- ZERO_STRUCTP(ads);
- free(ads);
-}
-
-/*
this is a minimal interact function, just enough for SASL to talk
GSSAPI/kerberos to W2K
Error handling is a bit of a problem. I can't see how to get Cyrus-sasl
@@ -474,7 +373,7 @@ BOOL ads_USN(ADS_STRUCT *ads, unsigned *usn)
void *res;
rc = ldap_search_s(ads->ld, ads->bind_path,
- LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage *)&res);
+ LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)&res);
if (rc || ads_count_replies(ads, res) != 1) return False;
return False;
}