summaryrefslogtreecommitdiffstats
path: root/source/libads
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2001-12-19 12:21:12 +0000
committerAndrew Tridgell <tridge@samba.org>2001-12-19 12:21:12 +0000
commit05a90a28843e0d69183a49a76617c5f32817df16 (patch)
tree5f57ab2af8517c0324932fe349e3beba24c1c7e3 /source/libads
parent344b786efe00f72ed81f0eeb4d422c655d866557 (diff)
downloadsamba-05a90a28843e0d69183a49a76617c5f32817df16.tar.gz
samba-05a90a28843e0d69183a49a76617c5f32817df16.tar.xz
samba-05a90a28843e0d69183a49a76617c5f32817df16.zip
much better ADS error handling system
Diffstat (limited to 'source/libads')
-rw-r--r--source/libads/ads_struct.c34
-rw-r--r--source/libads/krb5_setpw.c36
-rw-r--r--source/libads/ldap.c234
-rw-r--r--source/libads/sasl.c54
4 files changed, 196 insertions, 162 deletions
diff --git a/source/libads/ads_struct.c b/source/libads/ads_struct.c
index 83d423104ea..013491eaed1 100644
--- a/source/libads/ads_struct.c
+++ b/source/libads/ads_struct.c
@@ -22,6 +22,10 @@
#include "includes.h"
+/* 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)
{
char *p, *r;
@@ -156,33 +160,3 @@ void ads_destroy(ADS_STRUCT **ads)
SAFE_FREE(*ads);
}
}
-
-#if HAVE_KRB5
-static void ads_display_status_helper(const char *m, uint32 code, int type)
-{
- int maj_stat, min_stat;
- gss_buffer_desc msg;
- int msg_ctx;
-
- msg_ctx = 0;
- while (1) {
- maj_stat = gss_display_status(&min_stat, code,
- type, GSS_C_NULL_OID,
- &msg_ctx, &msg);
- DEBUG(1, ("GSS-API error %s: %s\n", m,
- (char *)msg.value));
- (void) gss_release_buffer(&min_stat, &msg);
-
- if (!msg_ctx)
- break;
- }
-}
-#endif
-
-void ads_display_status(const char *msg, int maj_stat,int min_stat)
-{
-#if HAVE_KRB5
- ads_display_status_helper(msg, maj_stat, GSS_C_GSS_CODE);
- ads_display_status_helper(msg, min_stat, GSS_C_MECH_CODE);
-#endif
-}
diff --git a/source/libads/krb5_setpw.c b/source/libads/krb5_setpw.c
index 1c3b15d2a57..b46a579263d 100644
--- a/source/libads/krb5_setpw.c
+++ b/source/libads/krb5_setpw.c
@@ -212,8 +212,8 @@ static krb5_error_code parse_setpw_reply(krb5_context context,
return 0;
}
-NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname,
- const char *realm, const char *newpw)
+ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname,
+ const char *realm, const char *newpw)
{
krb5_context context;
krb5_auth_context auth_context = NULL;
@@ -229,13 +229,13 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname,
ret = krb5_init_context(&context);
if (ret) {
DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
ret = krb5_cc_default(context, &ccache);
if (ret) {
DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
ZERO_STRUCT(creds);
@@ -244,7 +244,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname,
ret = krb5_parse_name(context, princ_name, &creds.server);
if (ret) {
DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
free(princ_name);
@@ -252,7 +252,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname,
ret = krb5_parse_name(context, princ_name, &principal);
if (ret) {
DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
free(princ_name);
@@ -263,27 +263,28 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname,
if (ret) {
DEBUG(1,("Failed to get principal from ccache (%s)\n",
error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
if (ret) {
DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY,
NULL, credsp, &ap_req);
if (ret) {
DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT);
if (sock == -1) {
+ int rc = errno;
DEBUG(1,("failed to open kpasswd socket to %s (%s)\n",
kdc_host, strerror(errno)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_SYSTEM(rc);
}
addr_len = sizeof(remote_addr);
@@ -301,19 +302,19 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname,
ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL);
if (ret) {
DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
ret = build_setpw_request(context, auth_context, &ap_req,
hostname, realm, newpw, &chpw_req);
if (ret) {
DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) {
DEBUG(1,("send of chpw failed (%s)\n", strerror(errno)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR(LDAP_ENCODING_ERROR);
}
free(chpw_req.data);
@@ -323,8 +324,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname,
ret = read(sock, chpw_rep.data, chpw_rep.length);
if (ret < 0) {
- DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_SYSTEM(errno);
}
close(sock);
@@ -334,7 +334,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname,
if (ret) {
DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n",
error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
ret = parse_setpw_reply(context, auth_context, &chpw_rep);
@@ -343,10 +343,10 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname,
if (ret) {
DEBUG(1,("parse_setpw_reply failed (%s)\n",
error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
+ return ADS_ERROR_KRB5(ret);
}
- return NT_STATUS_OK;
+ return ADS_SUCCESS;
}
#endif
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
index b41a864ae2e..3452614315f 100644
--- a/source/libads/ldap.c
+++ b/source/libads/ldap.c
@@ -23,39 +23,83 @@
#ifdef HAVE_ADS
-/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a
- realm of the form AA.BB.CC
- caller must free
+/*
+ build a ADS_STATUS structure
+*/
+ADS_STATUS ads_build_error(enum ads_error_type etype,
+ int rc, int minor_status)
+{
+ ADS_STATUS ret;
+ ret.error_type = etype;
+ ret.rc = rc;
+ ret.minor_status = minor_status;
+ return ret;
+}
+
+/*
+ do a rough conversion between ads error codes and NT status codes
+ we'll need to fill this in more
*/
+NTSTATUS ads_ntstatus(ADS_STATUS rc)
+{
+ if (ADS_ERR_OK(rc)) return NT_STATUS_OK;
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
/*
return a string for an error from a ads routine
*/
-char *ads_errstr(int rc)
+const char *ads_errstr(ADS_STATUS status)
{
- return ldap_err2string(rc);
+ gss_buffer_desc msg1, msg2;
+ uint32 minor;
+ int msg_ctx;
+ static char *ret;
+
+ SAFE_FREE(ret);
+ msg_ctx = 0;
+
+ switch (status.error_type) {
+ case ADS_ERROR_KRB5:
+ return error_message(status.rc);
+ case ADS_ERROR_LDAP:
+ return ldap_err2string(status.rc);
+ case ADS_ERROR_SYSTEM:
+ return strerror(status.rc);
+ case ADS_ERROR_GSS:
+ msg1.value = NULL;
+ msg2.value = NULL;
+ gss_display_status(&minor, status.rc, GSS_C_GSS_CODE,
+ GSS_C_NULL_OID, &msg_ctx, &msg1);
+ gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE,
+ GSS_C_NULL_OID, &msg_ctx, &msg2);
+ asprintf(&ret, "%s : %s", (char *)msg1.value, (char *)msg2.value);
+ gss_release_buffer(&minor, &msg1);
+ gss_release_buffer(&minor, &msg2);
+ return ret;
+ }
+
+ return "Unknown ADS error type!?";
}
/*
connect to the LDAP server
*/
-ADS_RETURN_CODE ads_connect(ADS_STRUCT *ads)
+ADS_STATUS ads_connect(ADS_STRUCT *ads)
{
int version = LDAP_VERSION3;
- ADS_RETURN_CODE rc;
-
- rc.error_type = False;
+ ADS_STATUS status;
ads->last_attempt = time(NULL);
ads->ld = ldap_open(ads->ldap_server, ads->ldap_port);
if (!ads->ld) {
- rc.rc = LDAP_SERVER_DOWN;
- return rc;
+ return ADS_ERROR_SYSTEM(errno)
}
- if (!ads_server_info(ads)) {
+ status = ads_server_info(ads);
+ if (!ADS_ERR_OK(status)) {
DEBUG(1,("Failed to get ldap server info\n"));
- rc.rc = LDAP_SERVER_DOWN;
- return rc;
+ return status;
}
ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
@@ -64,33 +108,35 @@ ADS_RETURN_CODE ads_connect(ADS_STRUCT *ads)
ads_kinit_password(ads);
}
- rc = ads_sasl_bind(ads);
- return rc;
+ return ads_sasl_bind(ads);
}
/*
do a search with a timeout
*/
-int ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp,
- const char **attrs, void **res)
+ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
+ const char *exp,
+ const char **attrs, void **res)
{
struct timeval timeout;
+ int rc;
timeout.tv_sec = ADS_SEARCH_TIMEOUT;
timeout.tv_usec = 0;
*res = NULL;
- return ldap_search_ext_s(ads->ld,
- bind_path, scope,
- exp, attrs, 0, NULL, NULL,
- &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res);
+ rc = ldap_search_ext_s(ads->ld,
+ bind_path, scope,
+ exp, attrs, 0, NULL, NULL,
+ &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res);
+ return ADS_ERROR(rc);
}
/*
do a general ADS search
*/
-int ads_search(ADS_STRUCT *ads, void **res,
- const char *exp,
- const char **attrs)
+ADS_STATUS ads_search(ADS_STRUCT *ads, void **res,
+ const char *exp,
+ const char **attrs)
{
return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE,
exp, attrs, res);
@@ -99,9 +145,9 @@ int ads_search(ADS_STRUCT *ads, void **res,
/*
do a search on a specific DistinguishedName
*/
-int ads_search_dn(ADS_STRUCT *ads, void **res,
- const char *dn,
- const char **attrs)
+ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void **res,
+ const char *dn,
+ const char **attrs)
{
return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res);
}
@@ -118,24 +164,24 @@ void ads_msgfree(ADS_STRUCT *ads, void *msg)
/*
find a machine account given a hostname
*/
-int ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host)
+ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host)
{
- int ret;
+ ADS_STATUS status;
char *exp;
/* the easiest way to find a machine account anywhere in the tree
is to look for hostname$ */
asprintf(&exp, "(samAccountName=%s$)", host);
- ret = ads_search(ads, res, exp, NULL);
+ status = ads_search(ads, res, exp, NULL);
free(exp);
- return ret;
+ return status;
}
/*
a convenient routine for adding a generic LDAP record
*/
-int ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...)
+ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...)
{
int i;
va_list ap;
@@ -179,15 +225,16 @@ int ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...)
}
free(mods);
- return ret;
+ return ADS_ERROR(ret);
}
/*
add a machine account to the ADS server
*/
-static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *org_unit)
+static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
+ const char *org_unit)
{
- int ret;
+ ADS_STATUS ret;
char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr;
asprintf(&host_spn, "HOST/%s", hostname);
@@ -317,9 +364,9 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
join a machine to a realm, creating the machine account
and setting the machine password
*/
-int ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit)
+ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit)
{
- int rc;
+ ADS_STATUS status;
LDAPMessage *res;
char *host;
@@ -327,80 +374,78 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit)
host = strdup(hostname);
strlower(host);
- rc = ads_find_machine_acct(ads, (void **)&res, host);
- if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) {
+ status = ads_find_machine_acct(ads, (void **)&res, host);
+ if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {
DEBUG(0, ("Host account for %s already exists\n", host));
- return LDAP_SUCCESS;
+ return ADS_SUCCESS;
}
- rc = ads_add_machine_acct(ads, host, org_unit);
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(rc)));
- return rc;
+ status = ads_add_machine_acct(ads, host, org_unit);
+ if (!ADS_ERR_OK(status)) {
+ DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(status)));
+ return status;
}
- rc = ads_find_machine_acct(ads, (void **)&res, host);
- if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) {
+ status = ads_find_machine_acct(ads, (void **)&res, host);
+ if (!ADS_ERR_OK(status)) {
DEBUG(0, ("Host account test failed\n"));
- /* hmmm, we need NTSTATUS */
- return -1;
+ return status;
}
free(host);
- return LDAP_SUCCESS;
+ return status;
}
/*
delete a machine from the realm
*/
-int ads_leave_realm(ADS_STRUCT *ads, const char *hostname)
+ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname)
{
- int rc;
+ ADS_STATUS status;
void *res;
char *hostnameDN, *host;
+ int rc;
/* hostname must be lowercase */
host = strdup(hostname);
strlower(host);
- rc = ads_find_machine_acct(ads, &res, host);
- if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) {
+ status = ads_find_machine_acct(ads, &res, host);
+ if (!ADS_ERR_OK(status)) {
DEBUG(0, ("Host account for %s does not exist.\n", host));
- return -1;
+ return status;
}
hostnameDN = ldap_get_dn(ads->ld, (LDAPMessage *)res);
rc = ldap_delete_s(ads->ld, hostnameDN);
ldap_memfree(hostnameDN);
if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldap_delete_s: %s\n", ads_errstr(rc)));
- return rc;
+ return ADS_ERROR(rc);
}
- rc = ads_find_machine_acct(ads, &res, host);
- if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1 ) {
- DEBUG(0, ("Failed to remove host account.\n"));
- /*hmmm, we need NTSTATUS */
- return -1;
+ status = ads_find_machine_acct(ads, &res, host);
+ if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {
+ DEBUG(0, ("Failed to remove host account.\n"));
+ return status;
}
free(host);
- return LDAP_SUCCESS;
+ return status;
}
-NTSTATUS ads_set_machine_password(ADS_STRUCT *ads,
- const char *hostname,
- const char *password)
+ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
+ const char *hostname,
+ const char *password)
{
- NTSTATUS ret;
+ ADS_STATUS status;
char *host = strdup(hostname);
strlower(host);
- ret = krb5_set_password(ads->kdc_server, host, ads->realm, password);
+ status = krb5_set_password(ads->kdc_server, host, ads->realm, password);
free(host);
- return ret;
+ return status;
}
/*
@@ -510,18 +555,22 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
/* find the update serial number - this is the core of the ldap cache */
-BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn)
+ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn)
{
const char *attrs[] = {"highestCommittedUSN", NULL};
- int rc;
+ ADS_STATUS status;
void *res;
- BOOL ret;
- rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
- if (rc || ads_count_replies(ads, res) != 1) return False;
- ret = ads_pull_uint32(ads, res, "highestCommittedUSN", usn);
+ status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
+ if (!ADS_ERR_OK(status)) return status;
+
+ if (ads_count_replies(ads, res) != 1) {
+ return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
+ }
+
+ ads_pull_uint32(ads, res, "highestCommittedUSN", usn);
ads_msgfree(ads, res);
- return ret;
+ return ADS_SUCCESS;
}
@@ -529,26 +578,25 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn)
The ldapServiceName field on w2k looks like this:
vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG
*/
-BOOL ads_server_info(ADS_STRUCT *ads)
+ADS_STATUS ads_server_info(ADS_STRUCT *ads)
{
const char *attrs[] = {"ldapServiceName", NULL};
- int rc;
+ ADS_STATUS status;
void *res;
char **values;
char *p;
- rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
- if (rc || ads_count_replies(ads, res) != 1) return False;
+ status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
+ if (!ADS_ERR_OK(status)) return status;
values = ldap_get_values(ads->ld, res, "ldapServiceName");
-
- if (!values || !values[0]) return False;
+ if (!values || !values[0]) return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
p = strchr(values[0], ':');
if (!p) {
ldap_value_free(values);
ldap_msgfree(res);
- return False;
+ return ADS_ERROR(LDAP_DECODING_ERROR);
}
SAFE_FREE(ads->ldap_server_name);
@@ -559,7 +607,7 @@ BOOL ads_server_info(ADS_STRUCT *ads)
ldap_value_free(values);
ldap_msgfree(res);
SAFE_FREE(ads->ldap_server_name);
- return False;
+ return ADS_ERROR(LDAP_DECODING_ERROR);
}
*p = 0;
@@ -579,35 +627,35 @@ BOOL ads_server_info(ADS_STRUCT *ads)
DEBUG(3,("got ldap server name %s@%s\n",
ads->ldap_server_name, ads->realm));
- return True;
+ return ADS_SUCCESS;
}
/*
find the list of trusted domains
*/
-BOOL ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
- int *num_trusts, char ***names, DOM_SID **sids)
+ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
+ int *num_trusts, char ***names, DOM_SID **sids)
{
const char *attrs[] = {"flatName", "securityIdentifier", NULL};
- int rc;
+ ADS_STATUS status;
void *res, *msg;
int count, i;
*num_trusts = 0;
- rc = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs);
- if (rc) return False;
+ status = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs);
+ if (!ADS_ERR_OK(status)) return status;
count = ads_count_replies(ads, res);
if (count == 0) {
ads_msgfree(ads, res);
- return False;
+ return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
}
(*names) = talloc(mem_ctx, sizeof(char *) * count);
(*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count);
- if (! *names || ! *sids) return False;
+ if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY);
for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
(*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName");
@@ -619,7 +667,7 @@ BOOL ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
*num_trusts = i;
- return True;
+ return ADS_SUCCESS;
}
#endif
diff --git a/source/libads/sasl.c b/source/libads/sasl.c
index b3610b8fdb7..48873252f08 100644
--- a/source/libads/sasl.c
+++ b/source/libads/sasl.c
@@ -53,7 +53,7 @@ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in)
this routine is much less fragile
see RFC2078 for details
*/
-ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads)
+ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
{
int minor_status;
gss_name_t serv_name;
@@ -65,11 +65,11 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads)
struct berval cred;
struct berval *scred;
int i=0;
- int gss_rc;
+ int gss_rc, rc;
uint8 *p;
uint32 max_msg_size;
char *sname;
- ADS_RETURN_CODE rc;
+ ADS_STATUS status;
krb5_principal principal;
krb5_context ctx;
krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL};
@@ -88,8 +88,10 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads)
input_name.value = &principal;
input_name.length = sizeof(principal);
- rc.rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name);
- rc.error_type = False;
+ gss_rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name);
+ if (gss_rc) {
+ return ADS_ERROR_GSS(gss_rc, minor_status);
+ }
context_handle = GSS_C_NO_CONTEXT;
@@ -116,17 +118,19 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads)
}
if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) {
- rc.minor_status = minor_status;
- rc.rc = gss_rc;
- rc.error_type = True;
- goto failed;
+ status = ADS_ERROR_GSS(gss_rc, minor_status);
+ goto failed;
}
cred.bv_val = output_token.value;
cred.bv_len = output_token.length;
- rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL,
+ rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL,
&scred);
+ if (rc != LDAP_SASL_BIND_IN_PROGRESS) {
+ status = ADS_ERROR(rc);
+ goto failed;
+ }
if (output_token.value) {
gss_release_buffer(&minor_status, &output_token);
@@ -140,13 +144,17 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads)
input_token.length = 0;
}
- if (gss_rc != GSS_S_CONTINUE_NEEDED) break;
+ if (gss_rc == 0) break;
}
gss_release_name(&minor_status, &serv_name);
gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token,
&conf_state,NULL);
+ if (gss_rc) {
+ status = ADS_ERROR_GSS(gss_rc, minor_status);
+ goto failed;
+ }
gss_release_buffer(&minor_status, &input_token);
@@ -169,33 +177,37 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads)
output_token.length = strlen(ads->bind_path) + 8;
- rc.rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
+ gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
&output_token, &conf_state,
&input_token);
+ if (gss_rc) {
+ status = ADS_ERROR_GSS(gss_rc, minor_status);
+ goto failed;
+ }
free(output_token.value);
cred.bv_val = input_token.value;
cred.bv_len = input_token.length;
- rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL,
+ rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL,
&scred);
+ status = ADS_ERROR(rc);
gss_release_buffer(&minor_status, &input_token);
failed:
- return rc;
+ return status;
}
-ADS_RETURN_CODE ads_sasl_bind(ADS_STRUCT *ads)
+ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
{
#if USE_CYRUS_SASL
- ADS_RETURN_CODE rc;
- rc.error_type = False;
- rc.rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL,
- LDAP_SASL_QUIET,
- sasl_interact, NULL);
- return rc;
+ int rc;
+ rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL,
+ LDAP_SASL_QUIET,
+ sasl_interact, NULL);
+ return ADS_ERROR(rc);
#else
return ads_sasl_gssapi_bind(ads);
#endif