From: Stefan Metzmacher Date: Fri, 15 Nov 2024 15:24:25 +0000 (+0100) Subject: schannel.idl: change netlogon_creds_CredentialState layout for 4.22 X-Git-Tag: tdb-1.4.13~404 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2b6a68b80fbe26bc8ab9bfd38aff1be340ba68a;p=thirdparty%2Fsamba.git schannel.idl: change netlogon_creds_CredentialState layout for 4.22 This breaks compat with 4.21 and moves stuff out of netlogon_creds_CredentialState_extra_info. It also prepares support for netr_ServerAuthenticateKerberos() Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c index 5bcc8351172..cdf591ec28c 100644 --- a/libcli/auth/credentials.c +++ b/libcli/auth/credentials.c @@ -515,18 +515,12 @@ netlogon_creds_alloc(TALLOC_CTX *mem_ctx, return NULL; } - creds->ex = talloc_zero(creds, - struct netlogon_creds_CredentialState_extra_info); - if (creds->ex == NULL) { - talloc_free(creds); - return NULL; - } - creds->ex->client_requested_flags = client_requested_flags; - creds->ex->auth_time = now; + creds->client_requested_flags = client_requested_flags; + creds->auth_time = now; if (client_sid != NULL) { - creds->ex->client_sid = *client_sid; + creds->client_sid = *client_sid; } else { - creds->ex->client_sid = global_sid_NULL; + creds->client_sid = global_sid_NULL; } return creds; diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c index 256ab009012..cfce9743741 100644 --- a/libcli/auth/netlogon_creds_cli.c +++ b/libcli/auth/netlogon_creds_cli.c @@ -1615,7 +1615,7 @@ static void netlogon_creds_cli_auth_srvauth_done(struct tevent_req *subreq) return; } - state->creds->ex->client_sid.sub_auths[0] = state->rid; + state->creds->client_sid.sub_auths[0] = state->rid; status = netlogon_creds_cli_store_internal(state->context, state->creds); if (tevent_req_nterror(req, status)) { @@ -2039,11 +2039,7 @@ static void netlogon_creds_cli_check_client_caps(struct tevent_req *subreq) return; } - if (state->creds->ex != NULL) { - requested_flags = state->creds->ex->client_requested_flags; - } else { - requested_flags = state->context->client.proposed_flags; - } + requested_flags = state->creds->client_requested_flags; if (state->client_caps.requested_flags != requested_flags) { status = NT_STATUS_DOWNGRADE_DETECTED; diff --git a/libcli/auth/schannel_state_tdb.c b/libcli/auth/schannel_state_tdb.c index b823ab6471d..6deeff08288 100644 --- a/libcli/auth/schannel_state_tdb.c +++ b/libcli/auth/schannel_state_tdb.c @@ -88,10 +88,6 @@ NTSTATUS schannel_store_session_key_tdb(struct db_context *db_sc, char *name_upper; NTSTATUS status; - if (creds->ex == NULL) { - return NT_STATUS_INTERNAL_ERROR; - } - if (strlen(creds->computer_name) > 15) { /* * We may want to check for a completely @@ -199,11 +195,6 @@ NTSTATUS schannel_fetch_session_key_tdb(struct db_context *db_sc, NDR_PRINT_DEBUG(netlogon_creds_CredentialState, creds); } - if (creds->ex == NULL) { - status = NT_STATUS_INTERNAL_ERROR; - goto done; - } - DEBUG(3,("schannel_fetch_session_key_tdb: restored schannel info key %s\n", keystr)); diff --git a/librpc/idl/schannel.idl b/librpc/idl/schannel.idl index 8905d514f55..a891cda6961 100644 --- a/librpc/idl/schannel.idl +++ b/librpc/idl/schannel.idl @@ -16,65 +16,19 @@ interface schannel typedef [flag(NDR_PAHEX)] struct { /* - * These were only used on the server part - * with a single dom_sid for the client_sid. - * - * On the server we use CLEAR_IF_FIRST, - * so db layout changes don't matter there, - * but on the client side we need to handle - * the ctdb case were CLEAR_IF_FIRST only - * works if all cluster nodes are restarted. - * - * As this was a single dom_sid before, - * we add some magic in order to let - * old code (on other nodes to parse the new layout). - * - * We have basically this definition of dom_sid: - * - * typedef struct { - * uint8 sid_rev_num; - * [range(0,15)] int8 num_auths; - * uint8 id_auth[6]; - * uint32 sub_auths[num_auths]; - * } dom_sid; - * - * It means it consumes at least 8 bytes while - * and it's also 4 byte aligned (before sid_rev_num). - * The largest sid would have 68 bytes. - * - * The old client side code would see a sid like - * this: S-1-RSV-CRF-ATL-ATH-257-0-RID - * - * RSV => reserved (the last 4 bytes of id_auth) - * - * CRF => client_requested_flags (sub_auths[0] - * - * Note NTTIME used ndr_pull_udlong, it's not NTTIME_hyper! - * ATL => low 4 bytes of auth_time (sub_auths[1]) - * ATH => high 4 bytes of auth_time (sub_auths[2]) - * - * From client_sid (S-1-0-RID): sub_auth[3-5] - * - * 257 => 0x01 0x01 0x00 0x00 = - * (sid_rev_num = 1, num_auths =1, - * id_auth[0] = 0, id_auth[1] = 0) - * 0 => id_auth[2-6] - * - * RID => the RID of the client - * - * It means the magic needs to simulate - * num_auths = 6 + * This can be used in order to + * make backward compatible changes, + * see commits: + * 518f57b93bdb84900d3b58cd94bdf1046f82a5a6 + * dfbc5e5a19420311eac3db5ede1c665a9198395d + * 8b972fea0978101575f847eac33b09d2fd8d02e7 */ - [value(0x00000601)] uint32 magic; - [value(0)] uint32 reserved; - netr_NegotiateFlags client_requested_flags; - NTTIME auth_time; - dom_sid client_sid; + dom_sid dummy_sid; } netlogon_creds_CredentialState_extra_info; typedef [public,flag(NDR_PAHEX)] struct { - netr_NegotiateFlags negotiate_flags; - uint8 session_key[16]; + [value(0)] uint32 zero_flags; + [flag(NDR_SECRET)] uint8 session_key[16]; uint32 sequence; netr_Credential seed; netr_Credential client; @@ -82,7 +36,32 @@ interface schannel netr_SchannelType secure_channel_type; [string,charset(UTF8)] uint8 computer_name[]; [string,charset(UTF8)] uint8 account_name[]; - netlogon_creds_CredentialState_extra_info *ex; + /* + * magic1 used to be a pointer to + * in 4.21 and older. + * + * magic2 was 'magic' or the first + * for 4 bytes of dom_sid (in 4.19) + * + * magic3 was the first 4 bytes of + * dom_sid in 4.21 and 4.20. + * + * With 4.22 we break the compat! + * So we have all of them as UINT32_MAX + * which means the parsing of a new record would + * fail in older releases. + */ + [value(0xFFFFFFFF)] uint32 magic1; + [value(0xFFFFFFFF)] uint32 magic2; + netr_NegotiateFlags negotiate_flags; + netr_NegotiateFlags client_requested_flags; + NTTIME auth_time; + [value(0xFFFFFFFF)] uint32 magic3; + dom_sid28 client_sid; + [value(0)] boolean8 reserved1; + /* here's some padding ... */ + [value(0)] hyper reserved2; + [value(NULL)] netlogon_creds_CredentialState_extra_info *ex; } netlogon_creds_CredentialState; /* This is used in the schannel_store.tdb */ diff --git a/librpc/rpc/server/netlogon/schannel_util.c b/librpc/rpc/server/netlogon/schannel_util.c index 359f4b8ed08..5f4c12934df 100644 --- a/librpc/rpc/server/netlogon/schannel_util.c +++ b/librpc/rpc/server/netlogon/schannel_util.c @@ -70,7 +70,7 @@ static NTSTATUS dcesrv_netr_check_schannel_get_state(struct dcesrv_call_state *d DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC, struct dcesrv_netr_check_schannel_state); if (s != NULL) { - if (!dom_sid_equal(&s->account_sid, &creds->ex->client_sid)) { + if (!dom_sid_equal(&s->account_sid, &creds->client_sid)) { goto new_state; } if (s->auth_type != auth_type) { @@ -92,7 +92,7 @@ new_state: return NT_STATUS_NO_MEMORY; } - s->account_sid = creds->ex->client_sid; + s->account_sid = creds->client_sid; s->auth_type = auth_type; s->auth_level = auth_level; s->result = NT_STATUS_MORE_PROCESSING_REQUIRED; diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index 2ba16d423e3..1d36fd58df8 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -1346,7 +1346,7 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p, TALLOC_FREE(creds); return status; } - client_sid = &creds->ex->client_sid; + client_sid = &creds->client_sid; DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n", r->in.computer_name, creds->computer_name)); @@ -1415,7 +1415,7 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p, TALLOC_FREE(creds); return status; } - client_sid = &creds->ex->client_sid; + client_sid = &creds->client_sid; DBG_NOTICE("Server Password Set2 by remote " "machine:[%s] on account [%s]\n", @@ -2361,7 +2361,7 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p, break; case 2: r->out.capabilities->requested_flags = - creds->ex->client_requested_flags; + creds->client_requested_flags; break; } diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 01a5f9f6e9d..3a75e046839 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1031,7 +1031,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call r->in.credential, r->out.return_authenticator, &creds); NT_STATUS_NOT_OK_RETURN(nt_status); - client_sid = &creds->ex->client_sid; + client_sid = &creds->client_sid; sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call); if (sam_ctx == NULL) { @@ -1084,7 +1084,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal r->in.credential, r->out.return_authenticator, &creds); NT_STATUS_NOT_OK_RETURN(nt_status); - client_sid = &creds->ex->client_sid; + client_sid = &creds->client_sid; sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call); if (sam_ctx == NULL) { @@ -1431,7 +1431,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base_call(struct dcesrv_netr_LogonSamL user_info->netlogon_trust_account.account_name = creds->account_name; user_info->netlogon_trust_account.sid - = &creds->ex->client_sid; + = &creds->client_sid; break; default: @@ -2527,7 +2527,7 @@ static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_c break; case 2: r->out.capabilities->requested_flags = - creds->ex->client_requested_flags; + creds->client_requested_flags; break; } @@ -2784,7 +2784,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal talloc_free(frame); } NT_STATUS_NOT_OK_RETURN(status); - client_sid = &creds->ex->client_sid; + client_sid = &creds->client_sid; /* We want to avoid connecting as system. */ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call); @@ -3184,7 +3184,7 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal &creds); NT_STATUS_NOT_OK_RETURN(nt_status); - client_sid = &creds->ex->client_sid; + client_sid = &creds->client_sid; switch (creds->secure_channel_type) { case SEC_CHAN_BDC: @@ -4583,7 +4583,7 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } - client_sid = &creds->ex->client_sid; + client_sid = &creds->client_sid; /* TODO: check r->in.server_name is our name */ @@ -4788,7 +4788,7 @@ static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call r->out.return_authenticator, &creds); NT_STATUS_NOT_OK_RETURN(nt_status); - client_sid = &creds->ex->client_sid; + client_sid = &creds->client_sid; if (creds->secure_channel_type != SEC_CHAN_RODC) { return NT_STATUS_ACCESS_DENIED;