From 13c1f1b6f14bf6459e4046f3ffa7d45897b317f5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 31 Jan 2006 03:15:16 +0000 Subject: r13252: Cleanup, both in code, comments and talloc use: In particular, I've used the --leak-report-full option to smbd to track down memory that shouldn't be on a long-term context. This is now talloc_free()ed much earlier. Andrew Bartlett (This used to be commit c6eb74f42989d62c82d2a219251837b09df8491c) --- source4/auth/auth_sam.c | 37 ++++++++++++++++++++++-------- source4/auth/ntlmssp/ntlmssp.h | 1 + source4/auth/ntlmssp/ntlmssp_server.c | 43 ++++++++++++++++++++++++++--------- source4/dsdb/samdb/cracknames.c | 39 +++++++++++++++++++++++-------- source4/kdc/hdb-ldb.c | 35 ++++++++++------------------ 5 files changed, 102 insertions(+), 53 deletions(-) diff --git a/source4/auth/auth_sam.c b/source4/auth/auth_sam.c index 85506fb41b..c28aaf2434 100644 --- a/source4/auth/auth_sam.c +++ b/source4/auth/auth_sam.c @@ -583,6 +583,7 @@ NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx, } talloc_steal(mem_ctx, *msgs); talloc_steal(mem_ctx, *msgs_domain_ref); + talloc_free(tmp_ctx); return NT_STATUS_OK; } @@ -610,7 +611,7 @@ NTSTATUS sam_get_server_info_principal(TALLOC_CTX *mem_ctx, const char *principa return NT_STATUS_INVALID_SYSTEM_SERVICE; } - nt_status = sam_get_results_principal(sam_ctx, mem_ctx, principal, + nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal, &msgs, &msgs_domain_ref); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -638,31 +639,47 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx struct ldb_message **domain_ref_msgs; struct ldb_context *sam_ctx; DATA_BLOB user_sess_key, lm_sess_key; + TALLOC_CTX *tmp_ctx; if (!account_name || !*account_name) { /* 'not for me' */ return NT_STATUS_NOT_IMPLEMENTED; } - sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx)); + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) { + return NT_STATUS_NO_MEMORY; + } + + sam_ctx = samdb_connect(tmp_ctx, system_session(mem_ctx)); if (sam_ctx == NULL) { + talloc_free(tmp_ctx); return NT_STATUS_INVALID_SYSTEM_SERVICE; } - nt_status = authsam_search_account(mem_ctx, sam_ctx, account_name, domain, &msgs, &domain_ref_msgs); - NT_STATUS_NOT_OK_RETURN(nt_status); + nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain, &msgs, &domain_ref_msgs); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(tmp_ctx); + return nt_status; + } - nt_status = authsam_authenticate(ctx->auth_ctx, mem_ctx, sam_ctx, msgs, domain_ref_msgs, user_info, + nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, msgs, domain_ref_msgs, user_info, &user_sess_key, &lm_sess_key); - NT_STATUS_NOT_OK_RETURN(nt_status); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(tmp_ctx); + return nt_status; + } - nt_status = authsam_make_server_info(mem_ctx, sam_ctx, msgs[0], domain_ref_msgs[0], + nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, msgs[0], domain_ref_msgs[0], user_sess_key, lm_sess_key, server_info); - NT_STATUS_NOT_OK_RETURN(nt_status); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(tmp_ctx); + return nt_status; + } - talloc_free(msgs); - talloc_free(domain_ref_msgs); + talloc_steal(mem_ctx, *server_info); + talloc_free(tmp_ctx); return NT_STATUS_OK; } diff --git a/source4/auth/ntlmssp/ntlmssp.h b/source4/auth/ntlmssp/ntlmssp.h index 0742227491..640d2d57fe 100644 --- a/source4/auth/ntlmssp/ntlmssp.h +++ b/source4/auth/ntlmssp/ntlmssp.h @@ -152,6 +152,7 @@ struct gensec_ntlmssp_state * */ NTSTATUS (*check_password)(struct gensec_ntlmssp_state *, + TALLOC_CTX *mem_ctx, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key); const char *server_name; diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index dac1f48f4b..de44d40a50 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -551,6 +551,9 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, gensec_ntlmssp_state->session_key = session_key; } + /* keep the session key around on the new context */ + talloc_steal(gensec_ntlmssp_state, session_key.data); + /* The server might need us to use a partial-strength session key */ ntlmssp_weaken_keys(gensec_ntlmssp_state); @@ -596,10 +599,16 @@ NTSTATUS ntlmssp_server_auth(struct gensec_security *gensec_security, DATA_BLOB lm_session_key = data_blob(NULL, 0); NTSTATUS nt_status; + TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + /* zero the outbound NTLMSSP packet */ *out = data_blob_talloc(out_mem_ctx, NULL, 0); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(gensec_ntlmssp_state, in))) { + talloc_free(mem_ctx); return nt_status; } @@ -612,16 +621,20 @@ NTSTATUS ntlmssp_server_auth(struct gensec_security *gensec_security, /* Finally, actually ask if the password is OK */ - if (!NT_STATUS_IS_OK(nt_status = gensec_ntlmssp_state->check_password(gensec_ntlmssp_state, + if (!NT_STATUS_IS_OK(nt_status = gensec_ntlmssp_state->check_password(gensec_ntlmssp_state, mem_ctx, &user_session_key, &lm_session_key))) { + talloc_free(mem_ctx); return nt_status; } if (gensec_security->want_features & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL|GENSEC_FEATURE_SESSION_KEY)) { - return ntlmssp_server_postauth(gensec_security, &user_session_key, &lm_session_key); + nt_status = ntlmssp_server_postauth(gensec_security, &user_session_key, &lm_session_key); + talloc_free(mem_ctx); + return nt_status; } else { gensec_ntlmssp_state->session_key = data_blob(NULL, 0); + talloc_free(mem_ctx); return NT_STATUS_OK; } } @@ -681,10 +694,12 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct gensec_ntlmssp_state *gensec_n * Return the session keys used on the connection. */ -static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) +static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ntlmssp_state, + TALLOC_CTX *mem_ctx, + DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) { NTSTATUS nt_status; - struct auth_usersupplied_info *user_info = talloc(gensec_ntlmssp_state, struct auth_usersupplied_info); + struct auth_usersupplied_info *user_info = talloc(mem_ctx, struct auth_usersupplied_info); if (!user_info) { return NT_STATUS_NO_MEMORY; } @@ -703,24 +718,30 @@ static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ user_info->password.response.nt = gensec_ntlmssp_state->nt_resp; user_info->password.response.nt.data = talloc_steal(user_info, gensec_ntlmssp_state->nt_resp.data); - nt_status = auth_check_password(gensec_ntlmssp_state->auth_context, gensec_ntlmssp_state, + nt_status = auth_check_password(gensec_ntlmssp_state->auth_context, mem_ctx, user_info, &gensec_ntlmssp_state->server_info); talloc_free(user_info); NT_STATUS_NOT_OK_RETURN(nt_status); + talloc_steal(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info); + if (gensec_ntlmssp_state->server_info->user_session_key.length) { DEBUG(10, ("Got NT session key of length %u\n", (unsigned)gensec_ntlmssp_state->server_info->user_session_key.length)); - *user_session_key = data_blob_talloc(gensec_ntlmssp_state, - gensec_ntlmssp_state->server_info->user_session_key.data, - gensec_ntlmssp_state->server_info->user_session_key.length); + if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->user_session_key.data)) { + return NT_STATUS_NO_MEMORY; + } + + *user_session_key = gensec_ntlmssp_state->server_info->user_session_key; } if (gensec_ntlmssp_state->server_info->lm_session_key.length) { DEBUG(10, ("Got LM session key of length %u\n", (unsigned)gensec_ntlmssp_state->server_info->lm_session_key.length)); - *lm_session_key = data_blob_talloc(gensec_ntlmssp_state, - gensec_ntlmssp_state->server_info->lm_session_key.data, - gensec_ntlmssp_state->server_info->lm_session_key.length); + if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->lm_session_key.data)) { + return NT_STATUS_NO_MEMORY; + } + + *lm_session_key = gensec_ntlmssp_state->server_info->lm_session_key; } return nt_status; } diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c index d86484eb8a..06ba532d40 100644 --- a/source4/dsdb/samdb/cracknames.c +++ b/source4/dsdb/samdb/cracknames.c @@ -44,47 +44,59 @@ static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx, struct drsuapi_DsNameInfo1 *info1); static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, struct ldb_context *ldb_ctx, - TALLOC_CTX *mem_ctx, - const char *alias_from, - char **alias_to) + TALLOC_CTX *mem_ctx, + const char *alias_from, + char **alias_to) { int i; int ret; struct ldb_result *res; struct ldb_message_element *spnmappings; - struct ldb_dn *service_dn = ldb_dn_string_compose(mem_ctx, samdb_base_dn(mem_ctx), + TALLOC_CTX *tmp_ctx; + struct ldb_dn *service_dn; + char *service_dn_str; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) { + return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; + } + + service_dn = ldb_dn_string_compose(tmp_ctx, samdb_base_dn(mem_ctx), "CN=Directory Service,CN=Windows NT" ",CN=Services,CN=Configuration"); - char *service_dn_str = ldb_dn_linearize(mem_ctx, service_dn); + service_dn_str = ldb_dn_linearize(tmp_ctx, service_dn); const char *directory_attrs[] = { "sPNMappings", NULL }; ret = ldb_search(ldb_ctx, service_dn, LDB_SCOPE_BASE, "(objectClass=nTDSService)", - directory_attrs, &res); - talloc_steal(mem_ctx, res); + directory_attrs, &res); if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_search: dn: %s not found: %s", service_dn_str, ldb_errstring(ldb_ctx))); - return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; + return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; } else if (res->count > 1) { + talloc_free(res); DEBUG(1, ("ldb_search: dn: %s found %d times!", service_dn_str, res->count)); return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; } + talloc_steal(tmp_ctx, res); spnmappings = ldb_msg_find_element(res->msgs[0], "sPNMappings"); if (!spnmappings || spnmappings->num_values == 0) { DEBUG(1, ("ldb_search: dn: %s no sPNMappings attribute", service_dn_str)); + talloc_free(tmp_ctx); return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; } for (i = 0; i < spnmappings->num_values; i++) { char *mapping, *p, *str; - mapping = talloc_strdup(mem_ctx, + mapping = talloc_strdup(tmp_ctx, (const char *)spnmappings->values[i].data); if (!mapping) { DEBUG(1, ("LDB_lookup_spn_alias: ldb_search: dn: %s did not have an sPNMapping\n", service_dn_str)); + talloc_free(tmp_ctx); return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; } @@ -94,6 +106,7 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru if (!p) { DEBUG(1, ("ldb_search: dn: %s sPNMapping malformed: %s\n", service_dn_str, mapping)); + talloc_free(tmp_ctx); return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; } p[0] = '\0'; @@ -107,11 +120,14 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru } if (strcasecmp(str, alias_from) == 0) { *alias_to = mapping; + talloc_steal(mem_ctx, mapping); + talloc_free(tmp_ctx); return DRSUAPI_DS_NAME_STATUS_OK; } } while (p); } DEBUG(1, ("LDB_lookup_spn_alias: no alias for service %s applicable\n", alias_from)); + talloc_free(tmp_ctx); return DRSUAPI_DS_NAME_STATUS_NOT_FOUND; } @@ -332,6 +348,8 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, talloc_free(domain); break; } + + /* A LDAP DN as a string */ case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: { name_dn = ldb_dn_explode(mem_ctx, name); domain_filter = NULL; @@ -341,6 +359,8 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, } break; } + + /* A GUID as a string */ case DRSUAPI_DS_NAME_FORMAT_GUID: { struct GUID guid; char *ldap_guid; @@ -372,6 +392,7 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, break; } + /* A S-1234-5678 style string */ case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: { struct dom_sid *sid = dom_sid_parse_talloc(mem_ctx, name); char *ldap_sid; diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c index 86c1b048a7..0306bf3106 100644 --- a/source4/kdc/hdb-ldb.c +++ b/source4/kdc/hdb-ldb.c @@ -509,18 +509,11 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con realm_dn_str = ldb_dn_linearize(mem_ctx, realm_dn); - if (lret != LDB_SUCCESS || res->count == 0) { - krb5_warnx(context, "ldb_search: basedn: '%s' filter: '%s' failed: %s", - realm_dn_str, filter, ldb_errstring(ldb_ctx)); - krb5_set_error_string(context, "ldb_search: basedn: '%s' filter: '%s' failed: %s", - realm_dn_str, filter, ldb_errstring(ldb_ctx)); + if (lret != LDB_SUCCESS) { + DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx))); return HDB_ERR_NOENTRY; - } else if (res->count > 1) { - krb5_warnx(context, "ldb_search: basedn: '%s' filter: '%s' more than 1 entry: %d", - realm_dn_str, filter, res->count); - krb5_set_error_string(context, "ldb_search: basedn: '%s' filter: '%s' more than 1 entry: %d", - realm_dn_str, filter, res->count); - talloc_free(res); + } else if (res->count == 0 || res->count > 1) { + DEBUG(3, ("Failed find a single entry for %s: got %d\n", filter, res->count)); return HDB_ERR_NOENTRY; } talloc_steal(mem_ctx, res->msgs); @@ -548,25 +541,21 @@ static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context ret = ldb_search(ldb_ctx, NULL, LDB_SCOPE_SUBTREE, cross_ref_filter, realm_ref_attrs, &cross_ref_res); - if (ret != LDB_SUCCESS || cross_ref_res->count == 0) { - krb5_warnx(context, "ldb_search: filter: '%s' failed: %s", cross_ref_filter, ldb_errstring(ldb_ctx)); - krb5_set_error_string(context, "ldb_search: filter: '%s' failed: %s", cross_ref_filter, ldb_errstring(ldb_ctx)); - + if (ret != LDB_SUCCESS) { + DEBUG(3, ("Failed to search for %s: %s\n", cross_ref_filter, ldb_errstring(ldb_ctx))); talloc_free(cross_ref_res); return HDB_ERR_NOENTRY; - } else if (cross_ref_res->count > 1) { - krb5_warnx(context, "ldb_search: filter: '%s' more than 1 entry: %d", cross_ref_filter, cross_ref_res->count); - krb5_set_error_string(context, "ldb_search: filter: '%s' more than 1 entry: %d", cross_ref_filter, cross_ref_res->count); - + } else if (cross_ref_res->count == 0 || cross_ref_res->count > 1) { + DEBUG(3, ("Failed find a single entry for %s: got %d\n", cross_ref_filter, cross_ref_res->count)); talloc_free(cross_ref_res); return HDB_ERR_NOENTRY; } if (pmsg) { - *pmsg = talloc_steal(mem_ctx, cross_ref_res->msgs); - } else { - talloc_free(cross_ref_res); + *pmsg = cross_ref_res->msgs; + talloc_steal(mem_ctx, cross_ref_res->msgs); } + talloc_free(cross_ref_res); return 0; } @@ -922,6 +911,7 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag priv->count = res->count; priv->msgs = talloc_steal(priv, res->msgs); + talloc_free(res); db->hdb_openp = priv; @@ -958,7 +948,6 @@ NTSTATUS kdc_hdb_ldb_create(TALLOC_CTX *mem_ctx, { NTSTATUS nt_status; struct auth_session_info *session_info; - struct gensec_security_ops **not_kerberos_list; *db = talloc(mem_ctx, HDB); if (!*db) { krb5_set_error_string(context, "malloc: out of memory"); -- cgit