much better ADS error handling system
authorAndrew Tridgell <tridge@samba.org>
Wed, 19 Dec 2001 12:21:12 +0000 (12:21 +0000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 19 Dec 2001 12:21:12 +0000 (12:21 +0000)
(This used to be commit 05a90a28843e0d69183a49a76617c5f32817df16)

source3/include/ads.h
source3/libads/ads_struct.c
source3/libads/krb5_setpw.c
source3/libads/ldap.c
source3/libads/sasl.c
source3/nsswitch/winbindd_ads.c
source3/nsswitch/winbindd_proto.h
source3/script/mkproto.awk
source3/utils/net_ads.c

index 4a20d0e79fd71555eece6f4034412752d315b6d3..884f2aa6ef76e49ab28e3d22317198dd03262e3a 100644 (file)
@@ -18,16 +18,26 @@ typedef struct {
        char *server_realm;
 } ADS_STRUCT;
 
+/* there are 4 possible types of errors the ads subsystem can produce */
+enum ads_error_type {ADS_ERROR_KRB5, ADS_ERROR_GSS, 
+                    ADS_ERROR_LDAP, ADS_ERROR_SYSTEM};
+
 typedef struct {
-       /* Type of error returned by ads_connect: */
-       /* True corresponds GSS API, False - LDAP */
-       int error_type;
-       /* For error_type = False rc describes LDAP error */
+       enum ads_error_type error_type;
        int rc;
-       /* For error_type = True rc and minor_status describe GSS API error */
+       /* For error_type = ADS_ERROR_GSS minor_status describe GSS API error */
        /* Where rc represents major_status of GSS API error */
        int minor_status;
-} ADS_RETURN_CODE;
+} ADS_STATUS;
+
+/* macros to simplify error returning */
+#define ADS_ERROR(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0);
+#define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc, 0);
+#define ADS_ERROR_KRB5(rc) ads_build_error(ADS_ERROR_KRB5, rc, 0);
+#define ADS_ERROR_GSS(rc, minor) ads_build_error(ADS_ERROR_GSS, rc, minor);
+
+#define ADS_ERR_OK(status) ((status).rc == 0)
+#define ADS_SUCCESS ADS_ERROR(0)
 
 /* time between reconnect attempts */
 #define ADS_RECONNECT_TIME 5
index 83d423104eaadc221387f8b4c24579445a6f133a..013491eaed132969210604e3f8fc52c7d5eb9d24 100644 (file)
 
 #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
-}
index 1c3b15d2a5706b91e6a6700b561d63dfa5e64bd0..b46a579263df56762764c7baba1a186c80f2cf3c 100644 (file)
@@ -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
index b41a864ae2e6a0088463fb68e67be72ce840d60b..3452614315fce250ac9fc383bb86ff74b802794f 100644 (file)
 
 #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
index b3610b8fdb7c1f126be38efee65818c72f8ead5f..48873252f082a28b2dedaf908f9b80dc9a7ba3f0 100644 (file)
@@ -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
index c988e697ee95462374d7848999b783add6599df8..749adafcb6f0d31dc058a9774d21779490b54a67 100644 (file)
@@ -32,64 +32,61 @@ static char *primary_realm;
   a wrapper around ldap_search_s that retries depending on the error code
   this is supposed to catch dropped connections and auto-reconnect
 */
-int ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, 
-                       const char *exp,
-                       const char **attrs, void **res)
+ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, 
+                              const char *exp,
+                              const char **attrs, void **res)
 {
-       int rc = -1;
-       ADS_RETURN_CODE rc2;
+       ADS_STATUS status;
        int count = 3;
 
        if (!ads->ld &&
            time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) {
-               return LDAP_SERVER_DOWN;
+               return ADS_ERROR(LDAP_SERVER_DOWN);
        }
 
        while (count--) {
-               rc = ads_do_search(ads, bind_path, scope, exp, attrs, res);
-               if (rc == 0) {
+               status = ads_do_search(ads, bind_path, scope, exp, attrs, res);
+               if (ADS_ERR_OK(status)) {
                        DEBUG(5,("Search for %s gave %d replies\n",
                                 exp, ads_count_replies(ads, *res)));
-                       return rc;
+                       return status;
                }
 
                if (*res) ads_msgfree(ads, *res);
                *res = NULL;
-               DEBUG(1,("Reopening ads connection after error %s\n", ads_errstr(rc)));
+               DEBUG(1,("Reopening ads connection after error %s\n", 
+                        ads_errstr(status)));
                if (ads->ld) {
                        /* we should unbind here, but that seems to trigger openldap bugs :(
                           ldap_unbind(ads->ld); 
                        */
                }
                ads->ld = NULL;
-               rc2 = ads_connect(ads);
-               if (rc2.rc) {
-                   DEBUG(1,("ads_search_retry: failed to reconnect:\n"));
-                   if(rc2.error_type) 
-                       ads_display_status("", rc2.rc, rc2.minor_status);
-                   else 
-                       DEBUG(1,("LDAP error: %s\n", ads_errstr(rc2.rc)));
-                   
-                   ads_destroy(&ads);
-                   return rc2.rc;
+               status = ads_connect(ads);
+               if (!ADS_ERR_OK(status)) {
+                       DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n",
+                                ads_errstr(status)));
+                       ads_destroy(&ads);
+                       return status;
                }
        }
-       DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(rc)));
-       return rc;
+
+       DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(status)));
+       return status;
 }
 
 
-int ads_search_retry(ADS_STRUCT *ads, void **res, 
-                    const char *exp, 
-                    const char **attrs)
+ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res, 
+                           const char *exp, 
+                           const char **attrs)
 {
        return ads_do_search_retry(ads, ads->bind_path, LDAP_SCOPE_SUBTREE,
                                   exp, attrs, res);
 }
 
-int ads_search_retry_dn(ADS_STRUCT *ads, void **res, 
-                       const char *dn, 
-                       const char **attrs)
+ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, 
+                              const char *dn, 
+                              const char **attrs)
 {
        return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE,
                                   "(objectclass=*)", attrs, res);
@@ -102,7 +99,7 @@ int ads_search_retry_dn(ADS_STRUCT *ads, void **res,
 static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
 {
        ADS_STRUCT *ads;
-       ADS_RETURN_CODE rc;
+       ADS_STATUS status;
        char *ccache;
        struct in_addr server_ip;
 
@@ -130,14 +127,10 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
        SAFE_FREE(ads->password);
        ads->password = secrets_fetch_machine_password();
 
-       rc = ads_connect(ads);
-       if (rc.rc) {
-               DEBUG(1,("ads_connect for domain %s failed:\n", domain->name));
-               if(rc.error_type) 
-                   ads_display_status("", rc.rc, rc.minor_status);
-               else 
-                   DEBUG(1,("LDAP error: %s\n", ads_errstr(rc.rc)));
-                   
+       status = ads_connect(ads);
+       if (!ADS_ERR_OK(status)) {
+               DEBUG(1,("ads_connect for domain %s failed: %s\n", 
+                        domain->name, ads_errstr(status)));
                ads_destroy(&ads);
                return NULL;
        }
@@ -183,7 +176,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
        ADS_STRUCT *ads = NULL;
        const char *attrs[] = {"sAMAccountName", "name", "objectSid", "primaryGroupID", 
                               "sAMAccountType", NULL};
-       int rc, i, count;
+       int i, count;
+       ADS_STATUS rc;
        void *res = NULL;
        void *msg = NULL;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@@ -196,7 +190,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
        if (!ads) goto done;
 
        rc = ads_search_retry(ads, &res, "(objectCategory=user)", attrs);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
                goto done;
        }
@@ -270,7 +264,8 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
        ADS_STRUCT *ads = NULL;
        const char *attrs[] = {"sAMAccountName", "name", "objectSid", 
                               "sAMAccountType", NULL};
-       int rc, i, count;
+       int i, count;
+       ADS_STATUS rc;
        void *res = NULL;
        void *msg = NULL;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@@ -283,7 +278,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
        if (!ads) goto done;
 
        rc = ads_search_retry(ads, &res, "(objectCategory=group)", attrs);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
                goto done;
        }
@@ -351,7 +346,8 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
 {
        ADS_STRUCT *ads = NULL;
        const char *attrs[] = {"objectSid", "sAMAccountType", NULL};
-       int rc, count;
+       int count;
+       ADS_STATUS rc;
        void *res = NULL;
        char *exp;
        uint32 t;
@@ -373,7 +369,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
        asprintf(&exp, "(sAMAccountName=%s)", name2);
        rc = ads_search_retry(ads, &res, exp, attrs);
        free(exp);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc)));
                goto done;
        }
@@ -415,7 +411,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
 {
        ADS_STRUCT *ads = NULL;
        const char *attrs[] = {"sAMAccountName", "sAMAccountType", NULL};
-       int rc;
+       ADS_STATUS rc;
        void *msg = NULL;
        char *exp;
        char *sidstr;
@@ -433,7 +429,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
        rc = ads_search_retry(ads, &msg, exp, attrs);
        free(exp);
        free(sidstr);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("sid_to_name ads_search: %s\n", ads_errstr(rc)));
                goto done;
        }
@@ -466,7 +462,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
        ADS_STRUCT *ads = NULL;
        const char *attrs[] = {"sAMAccountName", "name", "objectSid", 
                               "primaryGroupID", NULL};
-       int rc, count;
+       ADS_STATUS rc;
+       int count;
        void *msg = NULL;
        char *exp;
        DOM_SID sid;
@@ -485,7 +482,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
        rc = ads_search_retry(ads, &msg, exp, attrs);
        free(exp);
        free(sidstr);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("query_user(rid=%d) ads_search: %s\n", user_rid, ads_errstr(rc)));
                goto done;
        }
@@ -531,7 +528,8 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
        ADS_STRUCT *ads = NULL;
        const char *attrs[] = {"distinguishedName", NULL};
        const char *attrs2[] = {"tokenGroups", "primaryGroupID", NULL};
-       int rc, count;
+       ADS_STATUS rc;
+       int count;
        void *msg = NULL;
        char *exp;
        char *user_dn;
@@ -558,7 +556,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
        rc = ads_search_retry(ads, &msg, exp, attrs);
        free(exp);
        free(sidstr);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("lookup_usergroups(rid=%d) ads_search: %s\n", user_rid, ads_errstr(rc)));
                goto done;
        }
@@ -568,7 +566,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
        if (msg) ads_msgfree(ads, msg);
 
        rc = ads_search_retry_dn(ads, &msg, user_dn, attrs2);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("lookup_usergroups(rid=%d) ads_search tokenGroups: %s\n", user_rid, ads_errstr(rc)));
                goto done;
        }
@@ -607,7 +605,8 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
        DOM_SID group_sid;
        char *sidstr;
        const char *attrs[] = {"sAMAccountName", "objectSid", "sAMAccountType", NULL};
-       int rc, count;
+       ADS_STATUS rc;
+       int count;
        void *res=NULL, *msg=NULL;
        ADS_STRUCT *ads = NULL;
        char *exp;
@@ -626,7 +625,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
        rc = ads_search_retry(ads, &res, exp, attrs);
        free(exp);
        free(sidstr);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
                goto done;
        }
@@ -674,17 +673,15 @@ done:
 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
 {
        ADS_STRUCT *ads = NULL;
+       ADS_STATUS rc;
 
        *seq = DOM_SEQUENCE_NONE;
 
        ads = ads_cached_connection(domain);
        if (!ads) return NT_STATUS_UNSUCCESSFUL;
 
-       if (!ads_USN(ads, seq)) {
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       return NT_STATUS_OK;
+       rc = ads_USN(ads, seq);
+       return ads_ntstatus(rc);
 }
 
 /* get a list of trusted domains */
@@ -695,6 +692,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
                                DOM_SID **dom_sids)
 {
        ADS_STRUCT *ads = NULL;
+       ADS_STATUS rc;
 
        *num_domains = 0;
        *names = NULL;
@@ -702,11 +700,9 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
        ads = ads_cached_connection(domain);
        if (!ads) return NT_STATUS_UNSUCCESSFUL;
 
-       if (!ads_trusted_domains(ads, mem_ctx, num_domains, names, dom_sids)) {
-               return NT_STATUS_UNSUCCESSFUL;
-       }
+       rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, dom_sids);
 
-       return NT_STATUS_OK;
+       return ads_ntstatus(rc);
 }
 
 /* find the domain sid for a domain */
@@ -716,14 +712,14 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
        const char *attrs[] = {"objectSid", NULL};
        ADS_STRUCT *ads = NULL;
        void *res;
-       int rc;
+       ADS_STATUS rc;
 
        ads = ads_cached_connection(domain);
        if (!ads) goto done;
 
        rc = ads_do_search(ads, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", 
                           attrs, &res);
-       if (rc) goto done;
+       if (!ADS_ERR_OK(rc)) goto done;
        if (ads_pull_sid(ads, res, "objectSid", sid)) {
                status = NT_STATUS_OK;
        }
index d50469d978eae2943bfed60df7fe019eef9522a2..f0badc4331bce2ad73914d00873da0e2b0be2701 100644 (file)
@@ -9,15 +9,15 @@ int main(int argc, char **argv);
 
 /* The following definitions come from nsswitch/winbindd_ads.c  */
 
-int ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, 
-                       const char *exp,
-                       const char **attrs, void **res);
-int ads_search_retry(ADS_STRUCT *ads, void **res, 
-                    const char *exp, 
-                    const char **attrs);
-int ads_search_retry_dn(ADS_STRUCT *ads, void **res, 
-                       const char *dn, 
-                       const char **attrs);
+ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, 
+                              const char *exp,
+                              const char **attrs, void **res);
+ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res, 
+                           const char *exp, 
+                           const char **attrs);
+ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, 
+                              const char *dn, 
+                              const char **attrs);
 
 /* The following definitions come from nsswitch/winbindd_cache.c  */
 
index 7c8bc3d6cfbc2e11cef5c2322d9ef677c4713fa3..36f5b0afd122ff56016bbde12d9c3fc67fbb8f69 100644 (file)
@@ -122,7 +122,7 @@ END {
     gotstart = 1;
   }
 
-  if( $0 ~ /^ADS_STRUCT|^ADS_RETURN_CODE|^DATA_BLOB|^ASN1_DATA|^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum.*\(|^NT_USER_TOKEN|^SAM_ACCOUNT/ ) {
+  if( $0 ~ /^ADS_STRUCT|^ADS_STATUS|^DATA_BLOB|^ASN1_DATA|^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum.*\(|^NT_USER_TOKEN|^SAM_ACCOUNT/ ) {
     gotstart = 1;
   }
 
index 0d7b641771f6a5658119f587f196c780ff8c763a..3bfc9d935cc9b746f07600673f79989373491647 100644 (file)
@@ -68,7 +68,7 @@ static int net_ads_info(int argc, const char **argv)
 static ADS_STRUCT *ads_startup(void)
 {
        ADS_STRUCT *ads;
-       ADS_RETURN_CODE rc;
+       ADS_STATUS status;
        extern char *opt_password;
        extern char *opt_user_name;
 
@@ -87,12 +87,9 @@ static ADS_STRUCT *ads_startup(void)
        ads->password = strdup(opt_password);
        ads->user_name = strdup(opt_user_name);
 
-       rc = ads_connect(ads);
-       if (rc.rc) {
-               if(rc.error_type) 
-                   ads_display_status("ads_connect", rc.rc, rc.minor_status);
-               else
-                   d_printf("ads_connect: %s\n", ads_errstr(rc.rc));
+       status = ads_connect(ads);
+       if (!ADS_ERR_OK(status)) {
+               d_printf("ads_connect: %s\n", ads_errstr(status));
                return NULL;
        }
        return ads;
@@ -101,13 +98,13 @@ static ADS_STRUCT *ads_startup(void)
 static int net_ads_user(int argc, const char **argv)
 {
        ADS_STRUCT *ads;
-       int rc;
+       ADS_STATUS rc;
        void *res;
        const char *attrs[] = {"sAMAccountName", "name", "objectSid", NULL};
 
        if (!(ads = ads_startup())) return -1;
        rc = ads_search(ads, &res, "(objectclass=user)", attrs);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                d_printf("ads_search: %s\n", ads_errstr(rc));
                return -1;
        }
@@ -125,13 +122,13 @@ static int net_ads_user(int argc, const char **argv)
 static int net_ads_group(int argc, const char **argv)
 {
        ADS_STRUCT *ads;
-       int rc;
+       ADS_STATUS rc;
        void *res;
        const char *attrs[] = {"sAMAccountName", "name", "objectSid", NULL};
 
        if (!(ads = ads_startup())) return -1;
        rc = ads_search(ads, &res, "(objectclass=group)", attrs);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                d_printf("ads_search: %s\n", ads_errstr(rc));
                return -1;
        }
@@ -148,14 +145,14 @@ static int net_ads_group(int argc, const char **argv)
 static int net_ads_status(int argc, const char **argv)
 {
        ADS_STRUCT *ads;
-       int rc;
+       ADS_STATUS rc;
        extern pstring global_myname;
        void *res;
 
        if (!(ads = ads_startup())) return -1;
 
        rc = ads_find_machine_acct(ads, &res, global_myname);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                d_printf("ads_find_machine_acct: %s\n", ads_errstr(rc));
                return -1;
        }
@@ -173,7 +170,7 @@ static int net_ads_status(int argc, const char **argv)
 static int net_ads_leave(int argc, const char **argv)
 {
        ADS_STRUCT *ads = NULL;
-       int rc;
+       ADS_STATUS rc;
        extern pstring global_myname;
 
        if (!(ads = ads_startup())) {
@@ -186,7 +183,7 @@ static int net_ads_leave(int argc, const char **argv)
        }
 
        rc = ads_leave_realm(ads, global_myname);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
            d_printf("Failed to delete host '%s' from the '%s' realm.\n", 
                     global_myname, ads->realm);
            return -1;
@@ -200,11 +197,10 @@ static int net_ads_leave(int argc, const char **argv)
 static int net_ads_join(int argc, const char **argv)
 {
        ADS_STRUCT *ads;
-       int rc;
+       ADS_STATUS rc;
        char *password;
        char *tmp_password;
        extern pstring global_myname;
-       NTSTATUS status;
        const char *org_unit = "Computers";
        char *dn;
        void *res;
@@ -227,25 +223,25 @@ static int net_ads_join(int argc, const char **argv)
        free(dn);
        ads_msgfree(ads, res);
 
-       if (rc == LDAP_NO_SUCH_OBJECT) {
+       if (rc.error_type == ADS_ERROR_LDAP && rc.rc == LDAP_NO_SUCH_OBJECT) {
                d_printf("ads_join_realm: organisational unit %s does not exist\n", org_unit);
-               return rc;
+               return -1;
        }
 
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                d_printf("ads_join_realm: %s\n", ads_errstr(rc));
                return -1;
        }       
 
        rc = ads_join_realm(ads, global_myname, org_unit);
-       if (rc) {
+       if (!ADS_ERR_OK(rc)) {
                d_printf("ads_join_realm: %s\n", ads_errstr(rc));
                return -1;
        }
 
-       status = ads_set_machine_password(ads, global_myname, password);
-       if (!NT_STATUS_IS_OK(status)) {
-               d_printf("ads_set_machine_password: %s\n", get_nt_error_msg(status));
+       rc = ads_set_machine_password(ads, global_myname, password);
+       if (!ADS_ERR_OK(rc)) {
+               d_printf("ads_set_machine_password: %s\n", ads_errstr(rc));
                return -1;
        }