summaryrefslogtreecommitdiff
path: root/source3/libads
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libads')
-rw-r--r--source3/libads/ads_struct.c26
-rw-r--r--source3/libads/ldap.c77
-rw-r--r--source3/libads/sasl.c53
3 files changed, 131 insertions, 25 deletions
diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c
index 4b2ab5b40f..a7c8d1a681 100644
--- a/source3/libads/ads_struct.c
+++ b/source3/libads/ads_struct.c
@@ -157,3 +157,29 @@ void ads_destroy(ADS_STRUCT **ads)
}
}
+
+static void ads_display_status_helper(char *m, OM_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;
+ }
+}
+
+void ads_display_status(char * msg, int maj_stat,int min_stat)
+{
+ ads_display_status_helper(msg, maj_stat, GSS_C_GSS_CODE);
+ ads_display_status_helper(msg, min_stat, GSS_C_MECH_CODE);
+}
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 09498b4384..b41a864ae2 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -38,20 +38,24 @@ char *ads_errstr(int rc)
/*
connect to the LDAP server
*/
-int ads_connect(ADS_STRUCT *ads)
+ADS_RETURN_CODE ads_connect(ADS_STRUCT *ads)
{
int version = LDAP_VERSION3;
- int rc;
+ ADS_RETURN_CODE rc;
+
+ rc.error_type = False;
ads->last_attempt = time(NULL);
ads->ld = ldap_open(ads->ldap_server, ads->ldap_port);
if (!ads->ld) {
- return LDAP_SERVER_DOWN;
+ rc.rc = LDAP_SERVER_DOWN;
+ return rc;
}
if (!ads_server_info(ads)) {
DEBUG(1,("Failed to get ldap server info\n"));
- return LDAP_SERVER_DOWN;
+ rc.rc = LDAP_SERVER_DOWN;
+ return rc;
}
ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
@@ -233,6 +237,19 @@ static void dump_binary(const char *field, struct berval **values)
}
/*
+ dump a sid result from ldap
+*/
+static void dump_sid(const char *field, struct berval **values)
+{
+ int i;
+ for (i=0; values[i]; i++) {
+ DOM_SID sid;
+ sid_parse(values[i]->bv_val, values[i]->bv_len, &sid);
+ printf("%s: %s\n", field, sid_string_static(&sid));
+ }
+}
+
+/*
dump a string result from ldap
*/
static void dump_string(const char *field, struct berval **values)
@@ -257,7 +274,7 @@ void ads_dump(ADS_STRUCT *ads, void *res)
void (*handler)(const char *, struct berval **);
} handlers[] = {
{"objectGUID", dump_binary},
- {"objectSid", dump_binary},
+ {"objectSid", dump_sid},
{NULL, NULL}
};
@@ -547,12 +564,16 @@ BOOL ads_server_info(ADS_STRUCT *ads)
*p = 0;
+ SAFE_FREE(ads->server_realm);
+ SAFE_FREE(ads->bind_path);
+
+ ads->server_realm = strdup(p+2);
+ ads->bind_path = ads_build_dn(ads->server_realm);
+
/* in case the realm isn't configured in smb.conf */
if (!ads->realm || !ads->realm[0]) {
SAFE_FREE(ads->realm);
- SAFE_FREE(ads->bind_path);
- ads->realm = strdup(p+2);
- ads->bind_path = ads_build_dn(ads->realm);
+ ads->realm = strdup(ads->server_realm);
}
DEBUG(3,("got ldap server name %s@%s\n",
@@ -561,4 +582,44 @@ BOOL ads_server_info(ADS_STRUCT *ads)
return True;
}
+
+/*
+ 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)
+{
+ const char *attrs[] = {"flatName", "securityIdentifier", NULL};
+ int rc;
+ void *res, *msg;
+ int count, i;
+
+ *num_trusts = 0;
+
+ rc = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs);
+ if (rc) return False;
+
+ count = ads_count_replies(ads, res);
+ if (count == 0) {
+ ads_msgfree(ads, res);
+ return False;
+ }
+
+ (*names) = talloc(mem_ctx, sizeof(char *) * count);
+ (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count);
+ if (! *names || ! *sids) return False;
+
+ 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");
+ ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i]);
+ i++;
+ }
+
+ ads_msgfree(ads, res);
+
+ *num_trusts = i;
+
+ return True;
+}
+
#endif
diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
index dd948b5d4d..b3610b8fdb 100644
--- a/source3/libads/sasl.c
+++ b/source3/libads/sasl.c
@@ -53,9 +53,9 @@ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in)
this routine is much less fragile
see RFC2078 for details
*/
-int ads_sasl_gssapi_bind(ADS_STRUCT *ads)
+ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads)
{
- int rc, minor_status;
+ int minor_status;
gss_name_t serv_name;
gss_buffer_desc input_name;
gss_ctx_id_t context_handle;
@@ -69,15 +69,27 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads)
uint8 *p;
uint32 max_msg_size;
char *sname;
+ ADS_RETURN_CODE rc;
+ krb5_principal principal;
+ krb5_context ctx;
+ krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL};
+ gss_OID_desc nt_principal =
+ {10, "\052\206\110\206\367\022\001\002\002\002"};
+
+ /* we need to fetch a service ticket as the ldap user in the
+ servers realm, regardless of our realm */
+ asprintf(&sname, "ldap/%s@%s", ads->ldap_server_name, ads->server_realm);
+ krb5_init_context(&ctx);
+ krb5_set_default_tgs_ktypes(ctx, enc_types);
+ krb5_parse_name(ctx, sname, &principal);
+ free(sname);
+ krb5_free_context(ctx);
- asprintf(&sname, "ldap@%s.%s", ads->ldap_server_name, ads->realm);
-
- input_name.value = sname;
- input_name.length = strlen(input_name.value);
-
- rc = gss_import_name(&minor_status,&input_name,gss_nt_service_name, &serv_name);
+ input_name.value = &principal;
+ input_name.length = sizeof(principal);
- free(sname);
+ rc.rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name);
+ rc.error_type = False;
context_handle = GSS_C_NO_CONTEXT;
@@ -103,12 +115,17 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads)
gss_release_buffer(&minor_status, &input_token);
}
- if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) goto failed;
+ if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) {
+ rc.minor_status = minor_status;
+ rc.rc = gss_rc;
+ rc.error_type = True;
+ goto failed;
+ }
cred.bv_val = output_token.value;
cred.bv_len = output_token.length;
- rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL,
+ rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL,
&scred);
if (output_token.value) {
@@ -152,7 +169,7 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads)
output_token.length = strlen(ads->bind_path) + 8;
- gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
+ rc.rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
&output_token, &conf_state,
&input_token);
@@ -161,22 +178,24 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads)
cred.bv_val = input_token.value;
cred.bv_len = input_token.length;
- rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL,
+ rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL,
&scred);
gss_release_buffer(&minor_status, &input_token);
- return rc;
failed:
- return gss_rc;
+ return rc;
}
-int ads_sasl_bind(ADS_STRUCT *ads)
+ADS_RETURN_CODE ads_sasl_bind(ADS_STRUCT *ads)
{
#if USE_CYRUS_SASL
- return ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL,
+ 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;
#else
return ads_sasl_gssapi_bind(ads);
#endif