Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/libads/authdata.c

    r414 r745  
    2626#include "librpc/gen_ndr/ndr_krb5pac.h"
    2727#include "smb_krb5.h"
    28 #include "authdata.h"
     28#include "libads/kerberos_proto.h"
    2929
    3030#ifdef HAVE_KRB5
     
    6969}
    7070
    71 /****************************************************************
    72 ****************************************************************/
    73 
    74  NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx,
     71/**
     72* @brief Decode a blob containing a NDR envoded PAC structure
     73*
     74* @param mem_ctx          - The memory context
     75* @param pac_data_blob    - The data blob containing the NDR encoded data
     76* @param context          - The Kerberos Context
     77* @param service_keyblock - The Service Key used to verify the checksum
     78* @param client_principal - The client principal
     79* @param tgs_authtime     - The ticket timestamp
     80* @param pac_data_out     - [out] The decoded PAC
     81*
     82* @return - A NTSTATUS error code
     83*/
     84NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx,
    7585                         DATA_BLOB *pac_data_blob,
    7686                         krb5_context context,
     
    101111        DATA_BLOB *kdc_sig_blob = NULL;
    102112
     113        bool bool_ret;
     114
    103115        *pac_data_out = NULL;
    104116
     
    111123        }
    112124
    113         ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data,
    114                         NULL, pac_data,
     125        ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data, pac_data,
    115126                       (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
    116127        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    127138        }
    128139
    129         ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data_raw,
    130                                        NULL, pac_data_raw,
    131                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW);
     140        ndr_err = ndr_pull_struct_blob(
     141                                pac_data_blob, pac_data_raw, pac_data_raw,
     142                                (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW);
    132143        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    133144                status = ndr_map_error2ntstatus(ndr_err);
     
    145156        if (pac_data->num_buffers != pac_data_raw->num_buffers) {
    146157                /* we need logon_ingo, service_key and kdc_key */
    147                 DEBUG(0,("misparse!  PAC_DATA has %d buffers while PAC_DATA_RAW has %d\n",
    148                          pac_data->num_buffers, pac_data_raw->num_buffers));
     158                DEBUG(0, ("misparse! PAC_DATA has %d buffers while "
     159                          "PAC_DATA_RAW has %d\n", pac_data->num_buffers,
     160                          pac_data_raw->num_buffers));
    149161                return NT_STATUS_INVALID_PARAMETER;
    150162        }
    151163
    152164        for (i=0; i < pac_data->num_buffers; i++) {
    153                 if (pac_data->buffers[i].type != pac_data_raw->buffers[i].type) {
    154                         DEBUG(0,("misparse!  PAC_DATA buffer %d has type %d while PAC_DATA_RAW has %d\n",
    155                                  i, pac_data->buffers[i].type, pac_data->buffers[i].type));
     165                struct PAC_BUFFER *data_buf = &pac_data->buffers[i];
     166                struct PAC_BUFFER_RAW *raw_buf = &pac_data_raw->buffers[i];
     167
     168                if (data_buf->type != raw_buf->type) {
     169                        DEBUG(0, ("misparse! PAC_DATA buffer %d has type "
     170                                  "%d while PAC_DATA_RAW has %d\n", i,
     171                                  data_buf->type, raw_buf->type));
    156172                        return NT_STATUS_INVALID_PARAMETER;
    157173                }
    158                 switch (pac_data->buffers[i].type) {
    159                         case PAC_TYPE_LOGON_INFO:
    160                                 if (!pac_data->buffers[i].info) {
    161                                         break;
    162                                 }
    163                                 logon_info = pac_data->buffers[i].info->logon_info.info;
     174                switch (data_buf->type) {
     175                case PAC_TYPE_LOGON_INFO:
     176                        if (!data_buf->info) {
    164177                                break;
    165                         case PAC_TYPE_SRV_CHECKSUM:
    166                                 if (!pac_data->buffers[i].info) {
    167                                         break;
    168                                 }
    169                                 srv_sig_ptr = &pac_data->buffers[i].info->srv_cksum;
    170                                 srv_sig_blob = &pac_data_raw->buffers[i].info->remaining;
     178                        }
     179                        logon_info = data_buf->info->logon_info.info;
     180                        break;
     181                case PAC_TYPE_SRV_CHECKSUM:
     182                        if (!data_buf->info) {
    171183                                break;
    172                         case PAC_TYPE_KDC_CHECKSUM:
    173                                 if (!pac_data->buffers[i].info) {
    174                                         break;
    175                                 }
    176                                 kdc_sig_ptr = &pac_data->buffers[i].info->kdc_cksum;
    177                                 kdc_sig_blob = &pac_data_raw->buffers[i].info->remaining;
     184                        }
     185                        srv_sig_ptr = &data_buf->info->srv_cksum;
     186                        srv_sig_blob = &raw_buf->info->remaining;
     187                        break;
     188                case PAC_TYPE_KDC_CHECKSUM:
     189                        if (!data_buf->info) {
    178190                                break;
    179                         case PAC_TYPE_LOGON_NAME:
    180                                 logon_name = &pac_data->buffers[i].info->logon_name;
    181                                 break;
    182                         default:
    183                                 break;
     191                        }
     192                        kdc_sig_ptr = &data_buf->info->kdc_cksum;
     193                        kdc_sig_blob = &raw_buf->info->remaining;
     194                        break;
     195                case PAC_TYPE_LOGON_NAME:
     196                        logon_name = &data_buf->info->logon_name;
     197                        break;
     198                default:
     199                        break;
    184200                }
    185201        }
     
    205221        }
    206222
    207         /* Find and zero out the signatures, as required by the signing algorithm */
    208 
    209         /* We find the data blobs above, now we parse them to get at the exact portion we should zero */
    210         ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe,
    211                                        NULL, kdc_sig_wipe,
    212                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
     223        /* Find and zero out the signatures,
     224         * as required by the signing algorithm */
     225
     226        /* We find the data blobs above,
     227         * now we parse them to get at the exact portion we should zero */
     228        ndr_err = ndr_pull_struct_blob(
     229                        kdc_sig_blob, kdc_sig_wipe, kdc_sig_wipe,
     230                        (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    213231        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    214232                status = ndr_map_error2ntstatus(ndr_err);
     
    218236        }
    219237
    220         ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe,
    221                                        NULL, srv_sig_wipe,
    222                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
     238        ndr_err = ndr_pull_struct_blob(
     239                        srv_sig_blob, srv_sig_wipe, srv_sig_wipe,
     240                        (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    223241        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    224242                status = ndr_map_error2ntstatus(ndr_err);
     
    229247
    230248        /* Now zero the decoded structure */
    231         memset(kdc_sig_wipe->signature.data, '\0', kdc_sig_wipe->signature.length);
    232         memset(srv_sig_wipe->signature.data, '\0', srv_sig_wipe->signature.length);
     249        memset(kdc_sig_wipe->signature.data,
     250                '\0', kdc_sig_wipe->signature.length);
     251        memset(srv_sig_wipe->signature.data,
     252                '\0', srv_sig_wipe->signature.length);
    233253
    234254        /* and reencode, back into the same place it came from */
    235         ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw,
    236                                        NULL, kdc_sig_wipe,
    237                                        (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
     255        ndr_err = ndr_push_struct_blob(
     256                        kdc_sig_blob, pac_data_raw, kdc_sig_wipe,
     257                        (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
    238258        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    239259                status = ndr_map_error2ntstatus(ndr_err);
     
    242262                return status;
    243263        }
    244         ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw,
    245                                        NULL, srv_sig_wipe,
    246                                        (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
     264        ndr_err = ndr_push_struct_blob(
     265                        srv_sig_blob, pac_data_raw, srv_sig_wipe,
     266                        (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
    247267        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    248268                status = ndr_map_error2ntstatus(ndr_err);
     
    253273
    254274        /* push out the whole structure, but now with zero'ed signatures */
    255         ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw,
    256                                        NULL, pac_data_raw,
    257                                        (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW);
     275        ndr_err = ndr_push_struct_blob(
     276                        &modified_pac_blob, pac_data_raw, pac_data_raw,
     277                        (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW);
    258278        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    259279                status = ndr_map_error2ntstatus(ndr_err);
     
    269289                                 service_keyblock);
    270290        if (ret) {
    271                 DEBUG(1, ("PAC Decode: Failed to verify the service signature: %s\n",
    272                           error_message(ret)));
     291                DEBUG(1, ("PAC Decode: Failed to verify the service "
     292                          "signature: %s\n", error_message(ret)));
    273293                return NT_STATUS_ACCESS_DENIED;
    274294        }
     
    278298
    279299        if (tgs_authtime_nttime != logon_name->logon_time) {
    280                 DEBUG(2, ("PAC Decode: Logon time mismatch between ticket and PAC!\n"));
    281                 DEBUG(2, ("PAC Decode: PAC: %s\n", nt_time_string(mem_ctx, logon_name->logon_time)));
    282                 DEBUG(2, ("PAC Decode: Ticket: %s\n", nt_time_string(mem_ctx, tgs_authtime_nttime)));
     300                DEBUG(2, ("PAC Decode: "
     301                          "Logon time mismatch between ticket and PAC!\n"));
     302                DEBUG(2, ("PAC Decode: PAC: %s\n",
     303                          nt_time_string(mem_ctx, logon_name->logon_time)));
     304                DEBUG(2, ("PAC Decode: Ticket: %s\n",
     305                          nt_time_string(mem_ctx, tgs_authtime_nttime)));
    283306                return NT_STATUS_ACCESS_DENIED;
    284307        }
    285308
    286         ret = smb_krb5_parse_name_norealm(context, logon_name->account_name,
    287                                     &client_principal_pac);
     309        ret = smb_krb5_parse_name_norealm(context,
     310                                          logon_name->account_name,
     311                                          &client_principal_pac);
    288312        if (ret) {
    289                 DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n",
    290                           logon_name->account_name,
    291                           error_message(ret)));
    292                 return NT_STATUS_INVALID_PARAMETER;
    293         }
    294 
    295         if (!smb_krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) {
    296                 DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n",
    297                           logon_name->account_name));
    298                 krb5_free_principal(context, client_principal_pac);
     313                DEBUG(2, ("Could not parse name from PAC: [%s]:%s\n",
     314                          logon_name->account_name, error_message(ret)));
     315                return NT_STATUS_INVALID_PARAMETER;
     316        }
     317
     318        bool_ret = smb_krb5_principal_compare_any_realm(context,
     319                                                        client_principal,
     320                                                        client_principal_pac);
     321
     322        krb5_free_principal(context, client_principal_pac);
     323
     324        if (!bool_ret) {
     325                DEBUG(2, ("Name in PAC [%s] does not match principal name "
     326                          "in ticket\n", logon_name->account_name));
    299327                return NT_STATUS_ACCESS_DENIED;
    300328        }
     
    320348
    321349/****************************************************************
    322 ****************************************************************/
    323 
    324 struct PAC_LOGON_INFO *get_logon_info_from_pac(struct PAC_DATA *pac_data)
    325 {
    326         int i;
    327 
    328         for (i=0; i < pac_data->num_buffers; i++) {
    329 
    330                 if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) {
    331                         continue;
    332                 }
    333 
    334                 return pac_data->buffers[i].info->logon_info.info;
    335         }
    336 
    337         return NULL;
    338 }
    339 
    340 /****************************************************************
     350Given a username, password and other details, return the
     351PAC_LOGON_INFO (the structure containing the important user
     352information such as groups).
    341353****************************************************************/
    342354
     
    352364                             time_t renewable_time,
    353365                             const char *impersonate_princ_s,
    354                              struct PAC_DATA **pac_ret)
     366                             struct PAC_LOGON_INFO **logon_info)
    355367{
    356368        krb5_error_code ret;
    357369        NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
    358370        DATA_BLOB tkt, ap_rep, sesskey1, sesskey2;
    359         struct PAC_DATA *pac_data = NULL;
    360371        char *client_princ_out = NULL;
    361372        const char *auth_princ = NULL;
     
    425436        }
    426437
    427         ret = cli_krb5_get_ticket(local_service,
     438        ret = cli_krb5_get_ticket(mem_ctx,
     439                                  local_service,
    428440                                  time_offset,
    429441                                  &tkt,
     
    448460                                   &tkt,
    449461                                   &client_princ_out,
    450                                    &pac_data,
     462                                   logon_info,
    451463                                   &ap_rep,
    452464                                   &sesskey2,
     
    458470        }
    459471
    460         if (!pac_data) {
     472        if (!*logon_info) {
    461473                DEBUG(1,("no PAC\n"));
    462474                status = NT_STATUS_INVALID_PARAMETER;
    463475                goto out;
    464476        }
    465 
    466         *pac_ret = pac_data;
    467477
    468478out:
     
    481491}
    482492
    483 /****************************************************************
    484 ****************************************************************/
    485 
    486 static NTSTATUS kerberos_return_pac_logon_info(TALLOC_CTX *mem_ctx,
    487                                                const char *name,
    488                                                const char *pass,
    489                                                time_t time_offset,
    490                                                time_t *expire_time,
    491                                                time_t *renew_till_time,
    492                                                const char *cache_name,
    493                                                bool request_pac,
    494                                                bool add_netbios_addr,
    495                                                time_t renewable_time,
    496                                                const char *impersonate_princ_s,
    497                                                struct PAC_LOGON_INFO **logon_info)
    498 {
    499         NTSTATUS status;
    500         struct PAC_DATA *pac_data = NULL;
    501         struct PAC_LOGON_INFO *info = NULL;
    502 
    503         status = kerberos_return_pac(mem_ctx,
    504                                      name,
    505                                      pass,
    506                                      time_offset,
    507                                      expire_time,
    508                                      renew_till_time,
    509                                      cache_name,
    510                                      request_pac,
    511                                      add_netbios_addr,
    512                                      renewable_time,
    513                                      impersonate_princ_s,
    514                                      &pac_data);
    515         if (!NT_STATUS_IS_OK(status)) {
    516                 return status;
    517         }
    518 
    519         if (!pac_data) {
    520                 DEBUG(3,("no pac\n"));
    521                 return NT_STATUS_INVALID_USER_BUFFER;
    522         }
    523 
    524         info = get_logon_info_from_pac(pac_data);
    525         if (!info) {
    526                 DEBUG(1,("no logon_info\n"));
    527                 return NT_STATUS_INVALID_USER_BUFFER;
    528         }
    529 
    530         *logon_info = info;
    531 
    532         return NT_STATUS_OK;
    533 }
    534 
    535 /****************************************************************
    536 ****************************************************************/
    537 
    538 NTSTATUS kerberos_return_info3_from_pac(TALLOC_CTX *mem_ctx,
    539                                         const char *name,
    540                                         const char *pass,
    541                                         time_t time_offset,
    542                                         time_t *expire_time,
    543                                         time_t *renew_till_time,
    544                                         const char *cache_name,
    545                                         bool request_pac,
    546                                         bool add_netbios_addr,
    547                                         time_t renewable_time,
    548                                         const char *impersonate_princ_s,
    549                                         struct netr_SamInfo3 **info3)
    550 {
    551         NTSTATUS status;
    552         struct PAC_LOGON_INFO *logon_info = NULL;
    553 
    554         status = kerberos_return_pac_logon_info(mem_ctx,
    555                                                 name,
    556                                                 pass,
    557                                                 time_offset,
    558                                                 expire_time,
    559                                                 renew_till_time,
    560                                                 cache_name,
    561                                                 request_pac,
    562                                                 add_netbios_addr,
    563                                                 renewable_time,
    564                                                 impersonate_princ_s,
    565                                                 &logon_info);
    566         if (!NT_STATUS_IS_OK(status)) {
    567                 return status;
    568         }
    569 
    570         *info3 = &logon_info->info3;
    571 
    572         return NT_STATUS_OK;
    573 }
    574493#endif
Note: See TracChangeset for help on using the changeset viewer.