diff options
Diffstat (limited to 'source3/libads')
-rw-r--r-- | source3/libads/ads_struct.c | 26 | ||||
-rw-r--r-- | source3/libads/ldap.c | 77 | ||||
-rw-r--r-- | source3/libads/sasl.c | 53 |
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 |