Start implementing the server-sde NETLOGON PAC verification.
authorAndrew Bartlett <abartlet@samba.org>
Fri, 29 Aug 2008 08:05:06 +0000 (18:05 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 29 Aug 2008 08:05:06 +0000 (18:05 +1000)
source/rpc_server/netlogon/dcerpc_netlogon.c

index 763e6a327e1f7cfb93cdf265a21ae437c00b6dd6..5672d29cb2852845fa2ea8353756b6a5fd8fecf4 100644 (file)
@@ -488,7 +488,52 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal
                
        case NetlogonGenericInformation:
        {
-               /* Until we get enough information for an implemetnation */
+               if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
+                       creds_arcfour_crypt(creds, 
+                                           r->in.logon.generic->data, r->in.logon.generic->length);
+               } else {
+                       /* Using DES to verify kerberos tickets makes no sense */
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               if (strcmp(r->in.logon.generic->package_name.string, "Kerberos")) {
+                       struct PAC_Validate pac_validate;
+                       DATA_BLOB srv_sig;
+                       struct PAC_SIGNATURE_DATA kdc_sig;
+                       DATA_BLOB pac_validate_blob = data_blob_const(r->in.logon.generic->data, 
+                                                                     r->in.logon.generic->length);
+                       ndr_err = ndr_pull_struct_blob(&pac_validate_blob, mem_ctx, 
+                                                      lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 
+                                                      &pac_validate,
+                                                      (ndr_pull_flags_fn_t)ndr_pull_PAC_Validate);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                               return NT_STATUS_INVALID_PARAMETER;
+                       }
+
+                       if (pac_validate->MessageType != 3) {
+                               /* We don't implement any other message types - such as certificate validation - yet */
+                               return NT_STATUS_INVALID_PARAMETER;
+                       }
+                       
+                       if (pac_validate->ChecksumAndSignature.length != (pac_validate->ChecksumLength + pac_validate->SignatureLength)
+                           || pac_validate->ChecksumAndSignature.length < pac_validate->ChecksumLength
+                           || pac_validate->ChecksumAndSignature.length < pac_validate->SignatureLength ) {
+                               return NT_STATUS_INVALID_PARAMETER;
+                       }
+
+                       srv_sig = data_blob_const(pac_validate->ChecksumAndSignature.data, 
+                                                 pac_validate->ChecksumLength);
+
+                       kdc_sig.type = pac_validate->SignatureType;
+                       kdc_sig.signature = data_blob_const(&pac_validate->ChecksumAndSignature.data[pac_validate->ChecksumLength],
+                                                           pac_validate->SignatureLength);
+                       check_pac_checksum(mem_ctx, srv_sig, &kdc_sig, 
+                                          context, keyblock);
+                                          
+
+               }
+
+               /* Until we get an implemetnation of these other packages */
                return NT_STATUS_INVALID_PARAMETER;
        }
        default: