diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-10-08 02:21:49 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-10-08 02:21:49 +0200 |
commit | 99b2089752e202adbf4113b1854636e1db2f97c7 (patch) | |
tree | d5f4be4c26a1f39fc91beeebb75044d2ced89d41 /source4 | |
parent | 68837ff597bd39ff215ef30b4616692d2e31b1b4 (diff) | |
parent | 2024d87cf5ffa0633225ed189fa48f0f56151e7e (diff) | |
download | samba-99b2089752e202adbf4113b1854636e1db2f97c7.tar.gz samba-99b2089752e202adbf4113b1854636e1db2f97c7.tar.bz2 samba-99b2089752e202adbf4113b1854636e1db2f97c7.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba
Diffstat (limited to 'source4')
-rw-r--r-- | source4/auth/gensec/gensec.c | 8 | ||||
-rw-r--r-- | source4/auth/gensec/gensec.h | 2 | ||||
-rw-r--r-- | source4/auth/gensec/spnego.c | 15 | ||||
-rw-r--r-- | source4/dsdb/samdb/cracknames.c | 58 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/partition.c | 17 | ||||
-rw-r--r-- | source4/dsdb/schema/schema_description.c | 27 | ||||
-rw-r--r-- | source4/heimdal/kdc/krb5tgs.c | 34 | ||||
-rw-r--r-- | source4/kdc/hdb-samba4.c | 15 | ||||
-rw-r--r-- | source4/librpc/idl/drsblobs.idl | 10 | ||||
-rw-r--r-- | source4/librpc/idl/drsuapi.idl | 2 | ||||
-rw-r--r-- | source4/librpc/idl/misc.idl | 8 | ||||
-rw-r--r-- | source4/rpc_server/dcesrv_auth.c | 4 | ||||
-rw-r--r-- | source4/rpc_server/lsa/dcesrv_lsa.c | 68 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 52 | ||||
-rw-r--r-- | source4/torture/rpc/drsuapi_cracknames.c | 1 | ||||
-rw-r--r-- | source4/torture/rpc/lsa.c | 17 | ||||
-rw-r--r-- | source4/utils/ad2oLschema.c | 14 |
17 files changed, 261 insertions, 91 deletions
diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index 0edb34d740..5d57383d2a 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -490,6 +490,7 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, NT_STATUS_HAVE_NO_MEMORY(*gensec_security); (*gensec_security)->ops = NULL; + (*gensec_security)->private_data = NULL; ZERO_STRUCT((*gensec_security)->target); ZERO_STRUCT((*gensec_security)->peer_addr); @@ -525,6 +526,7 @@ _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, (*gensec_security)->private_data = NULL; (*gensec_security)->subcontext = true; + (*gensec_security)->want_features = parent->want_features; (*gensec_security)->event_ctx = parent->event_ctx; (*gensec_security)->msg_ctx = parent->msg_ctx; (*gensec_security)->lp_ctx = parent->lp_ctx; @@ -1015,7 +1017,11 @@ _PUBLIC_ NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_C _PUBLIC_ void gensec_want_feature(struct gensec_security *gensec_security, uint32_t feature) { - gensec_security->want_features |= feature; + if (!gensec_security->ops || !gensec_security->ops->want_feature) { + gensec_security->want_features |= feature; + return; + } + gensec_security->ops->want_feature(gensec_security, feature); } /** diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index 84fc26d127..0b31882ddd 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -133,6 +133,8 @@ struct gensec_security_ops { NTSTATUS (*session_key)(struct gensec_security *gensec_security, DATA_BLOB *session_key); NTSTATUS (*session_info)(struct gensec_security *gensec_security, struct auth_session_info **session_info); + void (*want_feature)(struct gensec_security *gensec_security, + uint32_t feature); bool (*have_feature)(struct gensec_security *gensec_security, uint32_t feature); bool enabled; diff --git a/source4/auth/gensec/spnego.c b/source4/auth/gensec/spnego.c index 1855e0583d..bf991616bd 100644 --- a/source4/auth/gensec/spnego.c +++ b/source4/auth/gensec/spnego.c @@ -1094,6 +1094,20 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } +static void gensec_spnego_want_feature(struct gensec_security *gensec_security, + uint32_t feature) +{ + struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; + + if (!spnego_state || !spnego_state->sub_sec_security) { + gensec_security->want_features |= feature; + return; + } + + gensec_want_feature(spnego_state->sub_sec_security, + feature); +} + static bool gensec_spnego_have_feature(struct gensec_security *gensec_security, uint32_t feature) { @@ -1133,6 +1147,7 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .unwrap_packets = gensec_spnego_unwrap_packets, .session_key = gensec_spnego_session_key, .session_info = gensec_spnego_session_info, + .want_feature = gensec_spnego_want_feature, .have_feature = gensec_spnego_have_feature, .enabled = true, .priority = GENSEC_SPNEGO diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c index e02e8d81a6..ca87159c58 100644 --- a/source4/dsdb/samdb/cracknames.c +++ b/source4/dsdb/samdb/cracknames.c @@ -356,15 +356,7 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, const char *result_filter = NULL; struct ldb_dn *name_dn = NULL; - struct smb_krb5_context *smb_krb5_context; - ret = smb_krb5_init_context(mem_ctx, - ldb_get_event_context(sam_ctx), - (struct loadparm_context *)ldb_get_opaque(sam_ctx, "loadparm"), - &smb_krb5_context); - - if (ret) { - return WERR_NOMEM; - } + struct smb_krb5_context *smb_krb5_context = NULL; info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; info1->dns_domain_name = NULL; @@ -380,6 +372,30 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, /* here we need to set the domain_filter and/or the result_filter */ switch (format_offered) { + case DRSUAPI_DS_NAME_FORMAT_UNKNOWN: + { + int i; + enum drsuapi_DsNameFormat formats[] = { + DRSUAPI_DS_NAME_FORMAT_FQDN_1779, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, + DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, DRSUAPI_DS_NAME_FORMAT_CANONICAL, + DRSUAPI_DS_NAME_FORMAT_GUID, DRSUAPI_DS_NAME_FORMAT_DISPLAY, + DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL, + DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY, + DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX + }; + WERROR werr; + for (i=0; i < ARRAY_SIZE(formats); i++) { + werr = DsCrackNameOneName(sam_ctx, mem_ctx, format_flags, formats[i], format_desired, name, info1); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + if (info1->status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) { + return werr; + } + } + return werr; + } + case DRSUAPI_DS_NAME_FORMAT_CANONICAL: case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: { @@ -534,6 +550,16 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL: { krb5_principal principal; char *unparsed_name; + + ret = smb_krb5_init_context(mem_ctx, + ldb_get_event_context(sam_ctx), + (struct loadparm_context *)ldb_get_opaque(sam_ctx, "loadparm"), + &smb_krb5_context); + + if (ret) { + return WERR_NOMEM; + } + ret = krb5_parse_name(smb_krb5_context->krb5_context, name, &principal); if (ret) { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; @@ -560,6 +586,16 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, krb5_principal principal; char *unparsed_name_short; char *service; + + ret = smb_krb5_init_context(mem_ctx, + ldb_get_event_context(sam_ctx), + (struct loadparm_context *)ldb_get_opaque(sam_ctx, "loadparm"), + &smb_krb5_context); + + if (ret) { + return WERR_NOMEM; + } + ret = krb5_parse_name(smb_krb5_context->krb5_context, name, &principal); if (ret == 0 && principal->name.name_string.len < 2) { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; @@ -1265,7 +1301,7 @@ NTSTATUS crack_auto_name_to_nt4_name(TALLOC_CTX *mem_ctx, const char **nt4_domain, const char **nt4_account) { - uint32_t format_offered = DRSUAPI_DS_NAME_FORMAT_UKNOWN; + uint32_t format_offered = DRSUAPI_DS_NAME_FORMAT_UNKNOWN; /* Handle anonymous bind */ if (!name || !*name) { @@ -1282,6 +1318,8 @@ NTSTATUS crack_auto_name_to_nt4_name(TALLOC_CTX *mem_ctx, format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT; } else if (strchr_m(name, '/')) { format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL; + } else { + return NT_STATUS_NO_SUCH_USER; } return crack_name_to_nt4_name(mem_ctx, ev_ctx, lp_ctx, format_offered, name, nt4_domain, nt4_account); diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 8e4483a78e..b452b66d56 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -589,7 +589,6 @@ static int partition_delete(struct ldb_module *module, struct ldb_request *req) /* rename */ static int partition_rename(struct ldb_module *module, struct ldb_request *req) { - int i, matched = -1; /* Find backend */ struct dsdb_control_current_partition *backend, *backend2; @@ -619,22 +618,6 @@ static int partition_rename(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_AFFECTS_MULTIPLE_DSAS; } - for (i=0; data && data->partitions && data->partitions[i]; i++) { - if (ldb_dn_compare_base(data->partitions[i]->dn, req->op.rename.olddn) == 0) { - matched = i; - } - } - - if (matched > 0) { - ldb_asprintf_errstring(module->ldb, - "Cannot rename from %s to %s, subtree rename would cross partition %s: %s", - ldb_dn_get_linearized(req->op.rename.olddn), - ldb_dn_get_linearized(req->op.rename.newdn), - ldb_dn_get_linearized(data->partitions[matched]->dn), - ldb_strerror(LDB_ERR_AFFECTS_MULTIPLE_DSAS)); - return LDB_ERR_AFFECTS_MULTIPLE_DSAS; - } - return partition_replicate(module, req, req->op.rename.olddn); } diff --git a/source4/dsdb/schema/schema_description.c b/source4/dsdb/schema/schema_description.c index 6884c5284e..c3c37b4653 100644 --- a/source4/dsdb/schema/schema_description.c +++ b/source4/dsdb/schema/schema_description.c @@ -33,7 +33,6 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx, const char *seperator, const char *oid, const char *name, - const char *description, const char *equality, const char *substring, const char *syntax, @@ -46,15 +45,6 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx, "NAME '%s'%s", name, seperator); IF_NULL_FAIL_RET(schema_entry); - if (description) { -#if 0 - /* Need a way to escape ' characters from the description */ - schema_entry = talloc_asprintf_append(schema_entry, - "DESC '%s'%s", description, seperator); - IF_NULL_FAIL_RET(schema_entry); -#endif - } - if (equality) { schema_entry = talloc_asprintf_append(schema_entry, "EQUALITY %s%s", equality, seperator); @@ -104,7 +94,7 @@ char *schema_attribute_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_att " ", attribute->attributeID_oid, attribute->lDAPDisplayName, - NULL, NULL, NULL, talloc_asprintf(tmp_ctx, "'%s'", syntax), + NULL, NULL, talloc_asprintf(tmp_ctx, "'%s'", syntax), attribute->isSingleValued, attribute->systemOnly); talloc_free(tmp_ctx); @@ -149,7 +139,6 @@ char *schema_class_description(TALLOC_CTX *mem_ctx, const char *oid, const char *name, const char **auxillary_classes, - const char *description, const char *subClassOf, int objectClassCategory, char **must, @@ -164,12 +153,6 @@ char *schema_class_description(TALLOC_CTX *mem_ctx, "NAME '%s'%s", name, seperator); IF_NULL_FAIL_RET(schema_entry); - if (description) { - schema_entry = talloc_asprintf_append(schema_entry, - "DESC '%s'%s", description, seperator); - IF_NULL_FAIL_RET(schema_entry); - } - if (auxillary_classes) { schema_entry = talloc_asprintf_append(schema_entry, "AUX ( "); @@ -262,7 +245,6 @@ char *schema_class_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_class * " ", class->governsID_oid, class->lDAPDisplayName, - NULL, NULL, class->subClassOf, class->objectClassCategory, @@ -308,8 +290,11 @@ char *schema_class_to_dITContentRule(TALLOC_CTX *mem_ctx, const struct dsdb_clas class->governsID_oid, class->lDAPDisplayName, (const char **)aux_class_list, - NULL, - class->subClassOf, + NULL, /* Must not specify a + * SUP (subclass) in + * ditContentRules + * per MS-ADTS + * 3.1.1.3.1.1.1 */ -1, must_attr_list, may_attr_list); talloc_free(tmp_ctx); return schema_description; diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index 19dff5e01d..d557da2a5b 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -1393,6 +1393,8 @@ tgs_build_reply(krb5_context context, char opt_str[128]; int signedpath = 0; + Key *tkey; + memset(&sessionkey, 0, sizeof(sessionkey)); memset(&adtkt, 0, sizeof(adtkt)); krb5_data_zero(&rspac); @@ -1630,26 +1632,22 @@ server_lookup: } /* check PAC if not cross realm and if there is one */ - if (!cross_realm) { - Key *tkey; - - ret = hdb_enctype2key(context, &krbtgt->entry, - krbtgt_etype, &tkey); - if(ret) { - kdc_log(context, config, 0, + ret = hdb_enctype2key(context, &krbtgt->entry, + krbtgt_etype, &tkey); + if(ret) { + kdc_log(context, config, 0, "Failed to find key for krbtgt PAC check"); - goto out; - } + goto out; + } - ret = check_PAC(context, config, cp, - client, server, ekey, &tkey->key, - tgt, &rspac, &signedpath); - if (ret) { - kdc_log(context, config, 0, - "Verify PAC failed for %s (%s) from %s with %s", - spn, cpn, from, krb5_get_err_text(context, ret)); - goto out; - } + ret = check_PAC(context, config, cp, + client, server, ekey, &tkey->key, + tgt, &rspac, &signedpath); + if (ret) { + kdc_log(context, config, 0, + "Verify PAC failed for %s (%s) from %s with %s", + spn, cpn, from, krb5_get_err_text(context, ret)); + goto out; } /* also check the krbtgt for signature */ diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index d7317f17d4..51f464cd09 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -757,13 +757,20 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, goto out; } - ndr_err = ndr_pull_struct_blob_all(password_val, mem_ctx, private->iconv_convenience, &password_blob, + ndr_err = ndr_pull_struct_blob(password_val, mem_ctx, private->iconv_convenience, &password_blob, (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { ret = EINVAL; goto out; } + entry_ex->entry.kvno = -1; + for (i=0; i < password_blob.count; i++) { + if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_VERSION) { + entry_ex->entry.kvno = password_blob.current->array[i].AuthInfo.version.version; + } + } + for (i=0; i < password_blob.count; i++) { if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) { password_utf16 = data_blob_const(password_blob.current->array[i].AuthInfo.clear.password, @@ -806,6 +813,8 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, entry_ex->entry.keys.len++; } + entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal))); + ret = copy_Principal(principal, entry_ex->entry.principal); if (ret) { krb5_clear_error_string(context); @@ -1148,7 +1157,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, msg[0], realm_ref_msg_1[0], entry_ex); if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); + krb5_warnx(context, "LDB_fetch: self krbtgt message2entry failed"); } return ret; @@ -1186,7 +1195,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, principal, direction, msg[0], entry_ex); if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); + krb5_warnx(context, "LDB_fetch: trust_message2entry failed"); } return ret; diff --git a/source4/librpc/idl/drsblobs.idl b/source4/librpc/idl/drsblobs.idl index 31fe8a359e..4274d2000a 100644 --- a/source4/librpc/idl/drsblobs.idl +++ b/source4/librpc/idl/drsblobs.idl @@ -409,21 +409,23 @@ interface drsblobs { [size_is(1)] AuthenticationInformation array[]; } AuthenticationInformationArray; + /* This is nopull,nopush because we pass count down to the + * manual parser of AuthenticationInformationArray */ typedef [public,nopull,nopush,noprint,gensize] struct { uint32 count; [relative] AuthenticationInformationArray *current; [relative] AuthenticationInformationArray *previous; } trustAuthInOutBlob; + void decode_trustAuthInOut( + [in] trustAuthInOutBlob blob + ); + typedef [public,gensize] struct { uint32 count; [relative] AuthenticationInformation *current[count]; } trustCurrentPasswords; - void decode_trustAuthInOut( - [in] trustAuthInOutBlob blob - ); - typedef [public,nopull] struct { uint8 confounder[512]; [subcontext(0),subcontext_size(outgoing_size)] trustCurrentPasswords outgoing; diff --git a/source4/librpc/idl/drsuapi.idl b/source4/librpc/idl/drsuapi.idl index 76858b2d5c..a41bc9cf19 100644 --- a/source4/librpc/idl/drsuapi.idl +++ b/source4/librpc/idl/drsuapi.idl @@ -877,7 +877,7 @@ interface drsuapi } drsuapi_DsNameFlags; typedef [v1_enum] enum { - DRSUAPI_DS_NAME_FORMAT_UKNOWN = 0, + DRSUAPI_DS_NAME_FORMAT_UNKNOWN = 0, DRSUAPI_DS_NAME_FORMAT_FQDN_1779 = 1, DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT = 2, DRSUAPI_DS_NAME_FORMAT_DISPLAY = 3, diff --git a/source4/librpc/idl/misc.idl b/source4/librpc/idl/misc.idl index 8331977398..791b86466c 100644 --- a/source4/librpc/idl/misc.idl +++ b/source4/librpc/idl/misc.idl @@ -30,9 +30,11 @@ interface misc /* Only SEC_CHAN_WKSTA can forward requests to other domains. */ typedef [public] enum { - SEC_CHAN_WKSTA = 2, - SEC_CHAN_DOMAIN = 4, - SEC_CHAN_BDC = 6 + SEC_CHAN_NULL = 0, + SEC_CHAN_WKSTA = 2, + SEC_CHAN_DNS_DOMAIN = 3, + SEC_CHAN_DOMAIN = 4, + SEC_CHAN_BDC = 6 } netr_SchannelType; /* SAM database types */ diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 52d5631cfd..bef7e4be78 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -95,6 +95,10 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) return false; } + if (call->conn->state_flags & DCESRV_CALL_STATE_FLAG_HEADER_SIGNING) { + gensec_want_feature(auth->gensec_security, GENSEC_FEATURE_SIGN_PKT_HEADER); + } + return true; } diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 5e3be84cc5..836fd8dc62 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -727,13 +727,46 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NT_STATUS_INVALID_PARAMETER; } + + if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) { + if (auth_struct.incoming.count > 1) { + return NT_STATUS_INVALID_PARAMETER; + } + } } if (auth_struct.incoming.count) { + int i; + struct trustAuthInOutBlob incoming; + + incoming.count = auth_struct.incoming.count; + incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray); + if (!incoming.current) { + return NT_STATUS_NO_MEMORY; + } + + incoming.current->array = *auth_struct.incoming.current; + if (!incoming.current->array) { + return NT_STATUS_NO_MEMORY; + } + + incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray); + if (!incoming.previous) { + return NT_STATUS_NO_MEMORY; + } + incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count); + if (!incoming.previous->array) { + return NT_STATUS_NO_MEMORY; + } + + for (i = 0; i < incoming.count; i++) { + incoming.previous->array[i].LastUpdateTime = 0; + incoming.previous->array[i].AuthType = 0; + } ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), - &auth_struct.incoming, - (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); + &incoming, + (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NT_STATUS_INVALID_PARAMETER; } @@ -742,10 +775,37 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc } if (auth_struct.outgoing.count) { + int i; + struct trustAuthInOutBlob outgoing; + + outgoing.count = auth_struct.outgoing.count; + outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray); + if (!outgoing.current) { + return NT_STATUS_NO_MEMORY; + } + + outgoing.current->array = *auth_struct.outgoing.current; + if (!outgoing.current->array) { + return NT_STATUS_NO_MEMORY; + } + + outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray); + if (!outgoing.previous) { + return NT_STATUS_NO_MEMORY; + } + outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count); + if (!outgoing.previous->array) { + return NT_STATUS_NO_MEMORY; + } + + for (i = 0; i < outgoing.count; i++) { + outgoing.previous->array[i].LastUpdateTime = 0; + outgoing.previous->array[i].AuthType = 0; + } ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), - &auth_struct.outgoing, - (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); + &outgoing, + (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NT_STATUS_INVALID_PARAMETER; } diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index d5f7d2afae..b948d1210e 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -87,6 +87,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca const char *attrs[] = {"unicodePwd", "userAccountControl", "objectSid", NULL}; + const char *trust_dom_attrs[] = {"flatname", NULL}; + const char *account_name; + ZERO_STRUCTP(r->out.credentials); *r->out.rid = 0; *r->out.negotiate_flags = *r->in.negotiate_flags; @@ -101,10 +104,54 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca if (sam_ctx == NULL) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } + + if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) { + char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name); + char *flatname; + if (!encoded_account) { + return NT_STATUS_NO_MEMORY; + } + + /* Kill the trailing dot */ + if (encoded_account[strlen(encoded_account)-1] == '.') { + encoded_account[strlen(encoded_account)-1] = '\0'; + } + + /* pull the user attributes */ + num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, trust_dom_attrs, + "(&(trustPartner=%s)(objectclass=trustedDomain))", + encoded_account); + + if (num_records == 0) { + DEBUG(3,("Couldn't find trust [%s] in samdb.\n", + encoded_account)); + return NT_STATUS_ACCESS_DENIED; + } + + if (num_records > 1) { + DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name)); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL); + if (!flatname) { + /* No flatname for this trust - we can't proceed */ + return NT_STATUS_ACCESS_DENIED; + } + account_name = talloc_asprintf(mem_ctx, "%s$", flatname); + + if (!account_name) { + return NT_STATUS_NO_MEMORY; + } + + } else { + account_name = r->in.account_name; + } + /* pull the user attributes */ num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs, "(&(sAMAccountName=%s)(objectclass=user))", - r->in.account_name); + ldb_binary_encode_string(mem_ctx, account_name)); if (num_records == 0) { DEBUG(3,("Couldn't find user [%s] in samdb.\n", @@ -130,7 +177,8 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control)); return NT_STATUS_ACCESS_DENIED; } - } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) { + } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || + r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) { if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) { DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control)); diff --git a/source4/torture/rpc/drsuapi_cracknames.c b/source4/torture/rpc/drsuapi_cracknames.c index fbda69df57..a9a614953d 100644 --- a/source4/torture/rpc/drsuapi_cracknames.c +++ b/source4/torture/rpc/drsuapi_cracknames.c @@ -39,6 +39,7 @@ static bool test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, bool ret = true; struct drsuapi_DsCrackNames r; enum drsuapi_DsNameFormat formats[] = { + DRSUAPI_DS_NAME_FORMAT_UNKNOWN, DRSUAPI_DS_NAME_FORMAT_FQDN_1779, DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, DRSUAPI_DS_NAME_FORMAT_DISPLAY, diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index efbdecab13..245ed1e41b 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -1899,7 +1899,11 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, /* NO_MORE_ENTRIES is allowed */ if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) { - return true; + if (domains.count == 0) { + return true; + } + printf("EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); + return false; } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) { /* Windows 2003 gets this off by one on the first run */ if (r.out.domains->count < 3 || r.out.domains->count > 4) { @@ -1950,7 +1954,11 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, /* NO_MORE_ENTRIES is allowed */ if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) { - return true; + if (domains_ex.count == 0) { + return true; + } + printf("EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); + return false; } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) { /* Windows 2003 gets this off by one on the first run */ if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) { @@ -2115,7 +2123,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, /* Try different trust types too */ - /* 1 == downleven (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */ + /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */ trustinfo.trust_type = (((i / 3) + 1) % 3) + 1; trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION; @@ -2160,6 +2168,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); ret = false; } else if (!q.out.info) { + printf("QueryTrustedDomainInfo level 1 failed to return an info pointer\n"); ret = false; } else { if (strcmp(q.out.info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) { @@ -2188,11 +2197,13 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, /* now that we have some domains to look over, we can test the enum calls */ if (!test_EnumTrustDom(p, mem_ctx, handle)) { + printf("test_EnumTrustDom failed\n"); ret = false; } for (i=0; i<12; i++) { if (!test_DeleteTrustedDomainBySid(p, mem_ctx, handle, domsid[i])) { + printf("test_DeleteTrustedDomainBySid failed\n"); ret = false; } } diff --git a/source4/utils/ad2oLschema.c b/source4/utils/ad2oLschema.c index 3c2ffe7a00..c579112b45 100644 --- a/source4/utils/ad2oLschema.c +++ b/source4/utils/ad2oLschema.c @@ -221,7 +221,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch for (attribute=schema->attributes; attribute; attribute = attribute->next) { const char *name = attribute->lDAPDisplayName; - const char *description = attribute->adminDescription; const char *oid = attribute->attributeID_oid; const char *syntax = attribute->attributeSyntax_oid; const char *equality = NULL, *substring = NULL; @@ -270,7 +269,16 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch } } - schema_entry = schema_attribute_description(mem_ctx, target, seperator, oid, name, description, equality, substring, syntax, single_value, false); + schema_entry = schema_attribute_description(mem_ctx, + target, + seperator, + oid, + name, + equality, + substring, + syntax, + single_value, + false); if (schema_entry == NULL) { ret.failures++; @@ -291,7 +299,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch /* This is already sorted to have 'top' and similar classes first */ for (objectclass=schema->classes; objectclass; objectclass = objectclass->next) { const char *name = objectclass->lDAPDisplayName; - const char *description = objectclass->adminDescription; const char *oid = objectclass->governsID_oid; const char *subClassOf = objectclass->subClassOf; int objectClassCategory = objectclass->objectClassCategory; @@ -356,7 +363,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch oid, name, NULL, - description, subClassOf, objectClassCategory, must, |