Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

Location:
vendor/current/source3/libads
Files:
10 added
1 deleted
19 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libads/ads_status.c

    r414 r740  
    2323#include "includes.h"
    2424#include "smb_krb5.h"
     25#include "smb_ldap.h"
     26#include "libads/ads_status.h"
    2527
    2628/*
  • vendor/current/source3/libads/ads_struct.c

    r414 r740  
    44   Copyright (C) Andrew Tridgell 2001
    55   Copyright (C) Andrew Bartlett 2001
    6    
     6
    77   This program is free software; you can redistribute it and/or modify
    88   it under the terms of the GNU General Public License as published by
    99   the Free Software Foundation; either version 3 of the License, or
    1010   (at your option) any later version.
    11    
     11
    1212   This program is distributed in the hope that it will be useful,
    1313   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1515   GNU General Public License for more details.
    16    
     16
    1717   You should have received a copy of the GNU General Public License
    1818   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2020
    2121#include "includes.h"
     22#include "ads.h"
    2223
    2324/* return a ldap dn path from a string, given separators and field name
     
    5657        if (p) {
    5758                strlcat(ret, p, len);
    58        
     59
    5960                while ((p=strtok_r(NULL, sep, &saveptr)) != NULL) {
    6061                        int retval;
     
    9394{
    9495        char *dnsdomain = NULL;
    95        
     96
    9697        /* result should always be shorter than the DN */
    9798
     
    123124        ADS_STRUCT *ads;
    124125        int wrap_flags;
    125        
     126
    126127        ads = SMB_XMALLOC_P(ADS_STRUCT);
    127128        ZERO_STRUCTP(ads);
    128        
     129
    129130        ads->server.realm = realm? SMB_STRDUP(realm) : NULL;
    130131        ads->server.workgroup = workgroup ? SMB_STRDUP(workgroup) : NULL;
     
    150151
    151152        return ads;
     153}
     154
     155/****************************************************************
     156****************************************************************/
     157
     158bool ads_set_sasl_wrap_flags(ADS_STRUCT *ads, int flags)
     159{
     160        if (!ads) {
     161                return false;
     162        }
     163
     164        ads->auth.flags = flags;
     165
     166        return true;
    152167}
    153168
     
    180195                SAFE_FREE((*ads)->config.schema_path);
    181196                SAFE_FREE((*ads)->config.config_path);
    182                
     197
    183198                ZERO_STRUCTP(*ads);
    184199
  • vendor/current/source3/libads/authdata.c

    r414 r740  
    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
  • vendor/current/source3/libads/cldap.c

    r414 r740  
    2424#include "../libcli/cldap/cldap.h"
    2525#include "../lib/tsocket/tsocket.h"
     26#include "libads/cldap.h"
    2627
    2728/*******************************************************************
     
    9394        io.in.map_response      = false;
    9495
    95         status = cldap_netlogon(cldap, NULL, reply, &io);
     96        status = cldap_netlogon(cldap, reply, &io);
    9697        if (!NT_STATUS_IS_OK(status)) {
    9798                DEBUG(2,("cldap_netlogon() failed: %s\n", nt_errstr(status)));
  • vendor/current/source3/libads/disp_sec.c

    r414 r740  
    1919
    2020#include "includes.h"
     21#include "ads.h"
     22#include "libads/ldap_schema.h"
     23#include "../libcli/security/secace.h"
     24#include "../librpc/ndr/libndr.h"
     25
     26/* for ADS */
     27#define SEC_RIGHTS_FULL_CTRL            0xf01ff
    2128
    2229#ifdef HAVE_LDAP
     
    2835        {SEC_RIGHTS_FULL_CTRL,          "[Full Control]"},
    2936
    30         {SEC_RIGHTS_LIST_CONTENTS,      "[List Contents]"},
    31         {SEC_RIGHTS_LIST_OBJECT,        "[List Object]"},
    32 
    33         {SEC_RIGHTS_READ_ALL_PROP,      "[Read All Properties]"},       
    34         {SEC_RIGHTS_READ_PERMS,         "[Read Permissions]"}, 
    35 
    36         {SEC_RIGHTS_WRITE_ALL_VALID,    "[All validate writes]"},
    37         {SEC_RIGHTS_WRITE_ALL_PROP,     "[Write All Properties]"},
    38 
    39         {SEC_RIGHTS_MODIFY_PERMS,       "[Modify Permissions]"},
    40         {SEC_RIGHTS_MODIFY_OWNER,       "[Modify Owner]"},
    41 
    42         {SEC_RIGHTS_CREATE_CHILD,       "[Create All Child Objects]"},
    43 
    44         {SEC_RIGHTS_DELETE,             "[Delete]"},
    45         {SEC_RIGHTS_DELETE_SUBTREE,     "[Delete Subtree]"},
    46         {SEC_RIGHTS_DELETE_CHILD,       "[Delete All Child Objects]"},
    47 
    48         {SEC_RIGHTS_CHANGE_PASSWD,      "[Change Password]"},   
    49         {SEC_RIGHTS_RESET_PASSWD,       "[Reset Password]"},
     37        {SEC_ADS_LIST,                  "[List Contents]"},
     38        {SEC_ADS_LIST_OBJECT,           "[List Object]"},
     39
     40        {SEC_ADS_READ_PROP,             "[Read All Properties]"},
     41        {SEC_STD_READ_CONTROL,          "[Read Permissions]"},
     42
     43        {SEC_ADS_SELF_WRITE,            "[All validate writes]"},
     44        {SEC_ADS_WRITE_PROP,            "[Write All Properties]"},
     45
     46        {SEC_STD_WRITE_DAC,             "[Modify Permissions]"},
     47        {SEC_STD_WRITE_OWNER,           "[Modify Owner]"},
     48
     49        {SEC_ADS_CREATE_CHILD,          "[Create All Child Objects]"},
     50
     51        {SEC_STD_DELETE,                "[Delete]"},
     52        {SEC_ADS_DELETE_TREE,           "[Delete Subtree]"},
     53        {SEC_ADS_DELETE_CHILD,          "[Delete All Child Objects]"},
     54
     55        {SEC_ADS_CONTROL_ACCESS,        "[Change Password]"},
     56        {SEC_ADS_CONTROL_ACCESS,        "[Reset Password]"},
    5057
    5158        {0,                             0}
     
    130137
    131138/* display ACE */
    132 static void ads_disp_ace(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, SEC_ACE *sec_ace)
     139static void ads_disp_ace(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct security_ace *sec_ace)
    133140{
    134141        const char *access_type = "UNKNOWN";
     
    174181
    175182/* display ACL */
    176 static void ads_disp_acl(SEC_ACL *sec_acl, const char *type)
     183static void ads_disp_acl(struct security_acl *sec_acl, const char *type)
    177184{
    178185        if (!sec_acl)
     
    188195
    189196/* display SD */
    190 void ads_disp_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, SEC_DESC *sd)
     197void ads_disp_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct security_descriptor *sd)
    191198{
    192199        int i;
  • vendor/current/source3/libads/dns.c

    r414 r740  
    2020
    2121#include "includes.h"
     22#include "libads/dns.h"
     23#include "../librpc/ndr/libndr.h"
    2224
    2325/* AIX resolv.h uses 'class' in struct ns_rr */
     
    297299        static time_t last_dns_check = 0;
    298300        static NTSTATUS last_dns_status = NT_STATUS_OK;
    299         time_t now = time(NULL);
     301        time_t now = time_mono(NULL);
    300302
    301303        /* Try to prevent bursts of DNS lookups if the server is down */
     
    332334                                        "talloc() failed!\n"));
    333335                                last_dns_status = NT_STATUS_NO_MEMORY;
    334                                 last_dns_check = time(NULL);
     336                                last_dns_check = time_mono(NULL);
    335337                                return last_dns_status;
    336338                        }
     
    351353                                last_dns_status = NT_STATUS_CONNECTION_REFUSED;
    352354                        }
    353                         last_dns_check = time(NULL);
     355                        last_dns_check = time_mono(NULL);
    354356                        return last_dns_status;
    355357                }
     
    365367                                TALLOC_FREE( buffer );
    366368                                last_dns_status = NT_STATUS_BUFFER_TOO_SMALL;
    367                                 last_dns_check = time(NULL);
     369                                last_dns_check = time_mono(NULL);
    368370                                return last_dns_status;
    369371                        }
     
    378380        *resp_length = resp_len;
    379381
    380         last_dns_check = time(NULL);
     382        last_dns_check = time_mono(NULL);
    381383        last_dns_status = NT_STATUS_OK;
    382384        return last_dns_status;
     
    564566        }
    565567
    566         qsort( dcs, idx, sizeof(struct dns_rr_srv), QSORT_CAST dnssrvcmp );
     568        TYPESAFE_QSORT(dcs, idx, dnssrvcmp );
    567569
    568570        *dclist = dcs;
     
    727729}
    728730
    729 /****************************************************************************
    730  Store and fetch the AD client sitename.
    731 ****************************************************************************/
    732 
    733 #define SITENAME_KEY    "AD_SITENAME/DOMAIN/%s"
    734 
    735 static char *sitename_key(const char *realm)
    736 {
    737         char *keystr;
    738 
    739         if (asprintf_strupper_m(&keystr, SITENAME_KEY, realm) == -1) {
    740                 return NULL;
    741         }
    742 
    743         return keystr;
    744 }
    745 
    746 
    747 /****************************************************************************
    748  Store the AD client sitename.
    749  We store indefinately as every new CLDAP query will re-write this.
    750 ****************************************************************************/
    751 
    752 bool sitename_store(const char *realm, const char *sitename)
    753 {
    754         time_t expire;
    755         bool ret = False;
    756         char *key;
    757 
    758         if (!realm || (strlen(realm) == 0)) {
    759                 DEBUG(0,("sitename_store: no realm\n"));
    760                 return False;
    761         }
    762 
    763         key = sitename_key(realm);
    764 
    765         if (!sitename || (sitename && !*sitename)) {
    766                 DEBUG(5,("sitename_store: deleting empty sitename!\n"));
    767                 ret = gencache_del(key);
    768                 SAFE_FREE(key);
    769                 return ret;
    770         }
    771 
    772         expire = get_time_t_max(); /* Store indefinately. */
    773 
    774         DEBUG(10,("sitename_store: realm = [%s], sitename = [%s], expire = [%u]\n",
    775                 realm, sitename, (unsigned int)expire ));
    776 
    777         ret = gencache_set( key, sitename, expire );
    778         SAFE_FREE(key);
    779         return ret;
    780 }
    781 
    782 /****************************************************************************
    783  Fetch the AD client sitename.
    784  Caller must free.
    785 ****************************************************************************/
    786 
    787 char *sitename_fetch(const char *realm)
    788 {
    789         char *sitename = NULL;
    790         time_t timeout;
    791         bool ret = False;
    792         const char *query_realm;
    793         char *key;
    794 
    795         if (!realm || (strlen(realm) == 0)) {
    796                 query_realm = lp_realm();
    797         } else {
    798                 query_realm = realm;
    799         }
    800 
    801         key = sitename_key(query_realm);
    802 
    803         ret = gencache_get( key, &sitename, &timeout );
    804         SAFE_FREE(key);
    805         if ( !ret ) {
    806                 DEBUG(5,("sitename_fetch: No stored sitename for %s\n",
    807                         query_realm));
    808         } else {
    809                 DEBUG(5,("sitename_fetch: Returning sitename for %s: \"%s\"\n",
    810                         query_realm, sitename ));
    811         }
    812         return sitename;
    813 }
    814 
    815 /****************************************************************************
    816  Did the sitename change ?
    817 ****************************************************************************/
    818 
    819 bool stored_sitename_changed(const char *realm, const char *sitename)
    820 {
    821         bool ret = False;
    822 
    823         char *new_sitename;
    824 
    825         if (!realm || (strlen(realm) == 0)) {
    826                 DEBUG(0,("stored_sitename_changed: no realm\n"));
    827                 return False;
    828         }
    829 
    830         new_sitename = sitename_fetch(realm);
    831 
    832         if (sitename && new_sitename && !strequal(sitename, new_sitename)) {
    833                 ret = True;
    834         } else if ((sitename && !new_sitename) ||
    835                         (!sitename && new_sitename)) {
    836                 ret = True;
    837         }
    838         SAFE_FREE(new_sitename);
    839         return ret;
    840 }
    841 
    842731/********************************************************************
    843732 Query with optional sitename.
  • vendor/current/source3/libads/kerberos.c

    r478 r740  
    1212   the Free Software Foundation; either version 3 of the License, or
    1313   (at your option) any later version.
    14    
     14
    1515   This program is distributed in the hope that it will be useful,
    1616   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1717   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1818   GNU General Public License for more details.
    19    
     19
    2020   You should have received a copy of the GNU General Public License
    2121   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2323
    2424#include "includes.h"
     25#include "system/filesys.h"
    2526#include "smb_krb5.h"
     27#include "../librpc/gen_ndr/ndr_misc.h"
     28#include "libads/kerberos_proto.h"
     29#include "secrets.h"
    2630
    2731#ifdef HAVE_KRB5
     
    9195        data_blob_free(&edata);
    9296
    93         ndr_err = ndr_pull_struct_blob_all(&unwrapped_edata, mem_ctx, NULL,
    94                         &parsed_edata,
    95                         (ndr_pull_flags_fn_t)ndr_pull_KRB5_EDATA_NTSTATUS);
     97        ndr_err = ndr_pull_struct_blob_all(&unwrapped_edata, mem_ctx,
     98                &parsed_edata, (ndr_pull_flags_fn_t)ndr_pull_KRB5_EDATA_NTSTATUS);
    9699        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    97100                data_blob_free(&unwrapped_edata);
     
    191194                goto out;
    192195        }
    193        
     196
    194197        if ((code = smb_krb5_parse_name(ctx, principal, &me))) {
    195198                goto out;
     
    230233                goto out;
    231234        }
    232        
     235
    233236        if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
    234237                goto out;
     
    283286        }
    284287        return code;
    285 }
    286 
    287 
    288 
    289 /* run kinit to setup our ccache */
    290 int ads_kinit_password(ADS_STRUCT *ads)
    291 {
    292         char *s;
    293         int ret;
    294         const char *account_name;
    295         fstring acct_name;
    296 
    297         if (ads->auth.flags & ADS_AUTH_USER_CREDS) {
    298                 account_name = ads->auth.user_name;
    299                 goto got_accountname;
    300         }
    301 
    302         if ( IS_DC ) {
    303                 /* this will end up getting a ticket for DOMAIN@RUSTED.REA.LM */
    304                 account_name = lp_workgroup();
    305         } else {
    306                 /* always use the sAMAccountName for security = domain */
    307                 /* global_myname()$@REA.LM */
    308                 if ( lp_security() == SEC_DOMAIN ) {
    309                         fstr_sprintf( acct_name, "%s$", global_myname() );
    310                         account_name = acct_name;
    311                 }
    312                 else
    313                         /* This looks like host/global_myname()@REA.LM */
    314                         account_name = ads->auth.user_name;
    315         }
    316 
    317  got_accountname:
    318         if (asprintf(&s, "%s@%s", account_name, ads->auth.realm) == -1) {
    319                 return KRB5_CC_NOMEM;
    320         }
    321 
    322         if (!ads->auth.password) {
    323                 SAFE_FREE(s);
    324                 return KRB5_LIBOS_CANTREADPWD;
    325         }
    326        
    327         ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset,
    328                         &ads->auth.tgt_expire, NULL, NULL, False, False, ads->auth.renewable,
    329                         NULL);
    330 
    331         if (ret) {
    332                 DEBUG(0,("kerberos_kinit_password %s failed: %s\n",
    333                          s, error_message(ret)));
    334         }
    335         SAFE_FREE(s);
    336         return ret;
    337288}
    338289
     
    349300                return code;
    350301        }
    351  
     302
    352303        if (!cc_name) {
    353304                if ((code = krb5_cc_default(ctx, &cc))) {
     
    592543        char *unparsed_name = NULL, *salt_princ_s = NULL;
    593544        krb5_principal ret_princ = NULL;
    594        
     545
    595546        /* lookup new key first */
    596547
    597548        if ( (salt_princ_s = kerberos_secrets_fetch_des_salt()) == NULL ) {
    598        
     549
    599550                /* look under the old key.  If this fails, just use the standard key */
    600551
     
    611562                ret_princ = NULL;
    612563        }
    613        
     564
    614565        TALLOC_FREE(unparsed_name);
    615566        SAFE_FREE(salt_princ_s);
    616        
     567
    617568        return ret_princ;
    618569}
     
    655606        if (smb_krb5_parse_name(context, princ_s, &princ) != 0) {
    656607                goto out;
    657                
    658608        }
    659609        if (smb_krb5_unparse_name(talloc_tos(), context, princ, &unparsed_name) != 0) {
  • vendor/current/source3/libads/kerberos_keytab.c

    r414 r740  
    2828#include "includes.h"
    2929#include "smb_krb5.h"
     30#include "ads.h"
     31#include "secrets.h"
    3032
    3133#ifdef HAVE_KRB5
     
    3436**********************************************************************/
    3537
    36 int smb_krb5_kt_add_entry_ext(krb5_context context,
    37                               krb5_keytab keytab,
    38                               krb5_kvno kvno,
    39                               const char *princ_s,
    40                               krb5_enctype *enctypes,
    41                               krb5_data password,
    42                               bool no_salt,
    43                               bool keep_old_entries)
     38static krb5_error_code seek_and_delete_old_entries(krb5_context context,
     39                                                   krb5_keytab keytab,
     40                                                   krb5_kvno kvno,
     41                                                   const char *princ_s,
     42                                                   krb5_principal princ,
     43                                                   bool flush,
     44                                                   bool keep_old_entries)
    4445{
    45         krb5_error_code ret = 0;
     46        krb5_error_code ret;
    4647        krb5_kt_cursor cursor;
     48        krb5_kt_cursor zero_csr;
    4749        krb5_keytab_entry kt_entry;
    48         krb5_principal princ = NULL;
    49         int i;
     50        krb5_keytab_entry zero_kt_entry;
    5051        char *ktprinc = NULL;
    5152
     53        ZERO_STRUCT(cursor);
     54        ZERO_STRUCT(zero_csr);
    5255        ZERO_STRUCT(kt_entry);
    53         ZERO_STRUCT(cursor);
    54        
    55         ret = smb_krb5_parse_name(context, princ_s, &princ);
    56         if (ret) {
    57                 DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret)));
    58                 goto out;
    59         }
    60 
    61         /* Seek and delete old keytab entries */
     56        ZERO_STRUCT(zero_kt_entry);
     57
    6258        ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    63         if (ret != KRB5_KT_END && ret != ENOENT ) {
    64                 DEBUG(3,("smb_krb5_kt_add_entry_ext: Will try to delete old keytab entries\n"));
    65                 while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
    66                         bool compare_name_ok = False;
    67 
    68                         ret = smb_krb5_unparse_name(talloc_tos(), context, kt_entry.principal, &ktprinc);
     59        if (ret == KRB5_KT_END || ret == ENOENT ) {
     60                /* no entries */
     61                return 0;
     62        }
     63
     64        DEBUG(3, (__location__ ": Will try to delete old keytab entries\n"));
     65        while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
     66                bool name_ok = False;
     67
     68                if (!flush && (princ_s != NULL)) {
     69                        ret = smb_krb5_unparse_name(talloc_tos(), context,
     70                                                    kt_entry.principal,
     71                                                    &ktprinc);
    6972                        if (ret) {
    70                                 DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_unparse_name failed (%s)\n",
    71                                         error_message(ret)));
     73                                DEBUG(1, (__location__
     74                                          ": smb_krb5_unparse_name failed "
     75                                          "(%s)\n", error_message(ret)));
    7276                                goto out;
    7377                        }
    7478
    75                         /*---------------------------------------------------------------------------
    76                          * Save the entries with kvno - 1.   This is what microsoft does
    77                          * to allow people with existing sessions that have kvno - 1 to still
    78                          * work.   Otherwise, when the password for the machine changes, all
    79                          * kerberizied sessions will 'break' until either the client reboots or
    80                          * the client's session key expires and they get a new session ticket
    81                          * with the new kvno.
    82                          */
    83 
    8479#ifdef HAVE_KRB5_KT_COMPARE
    85                         compare_name_ok = (krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True);
     80                        name_ok = krb5_kt_compare(context, &kt_entry,
     81                                                  princ, 0, 0);
    8682#else
    87                         compare_name_ok = (strcmp(ktprinc, princ_s) == 0);
     83                        name_ok = (strcmp(ktprinc, princ_s) == 0);
    8884#endif
    8985
    90                         if (!compare_name_ok) {
    91                                 DEBUG(10,("smb_krb5_kt_add_entry_ext: ignoring keytab entry principal %s, kvno = %d\n",
    92                                         ktprinc, kt_entry.vno));
     86                        if (!name_ok) {
     87                                DEBUG(10, (__location__ ": ignoring keytab "
     88                                           "entry principal %s, kvno = %d\n",
     89                                           ktprinc, kt_entry.vno));
     90
     91                                /* Not a match,
     92                                 * just free this entry and continue. */
     93                                ret = smb_krb5_kt_free_entry(context,
     94                                                             &kt_entry);
     95                                ZERO_STRUCT(kt_entry);
     96                                if (ret) {
     97                                        DEBUG(1, (__location__
     98                                                  ": smb_krb5_kt_free_entry "
     99                                                  "failed (%s)\n",
     100                                                  error_message(ret)));
     101                                        goto out;
     102                                }
     103
     104                                TALLOC_FREE(ktprinc);
     105                                continue;
    93106                        }
    94107
    95108                        TALLOC_FREE(ktprinc);
    96 
    97                         if (compare_name_ok) {
    98                                 if (kt_entry.vno == kvno - 1) {
    99                                         DEBUG(5,("smb_krb5_kt_add_entry_ext: Saving previous (kvno %d) entry for principal: %s.\n",
    100                                                 kvno - 1, princ_s));
    101                                 } else if (!keep_old_entries) {
    102                                         DEBUG(5,("smb_krb5_kt_add_entry_ext: Found old entry for principal: %s (kvno %d) - trying to remove it.\n",
    103                                                 princ_s, kt_entry.vno));
    104                                         ret = krb5_kt_end_seq_get(context, keytab, &cursor);
    105                                         ZERO_STRUCT(cursor);
    106                                         if (ret) {
    107                                                 DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_end_seq_get() failed (%s)\n",
    108                                                         error_message(ret)));
    109                                                 goto out;
    110                                         }
    111                                         ret = krb5_kt_remove_entry(context, keytab, &kt_entry);
    112                                         if (ret) {
    113                                                 DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_remove_entry failed (%s)\n",
    114                                                         error_message(ret)));
    115                                                 goto out;
    116                                         }
    117 
    118                                         DEBUG(5,("smb_krb5_kt_add_entry_ext: removed old entry for principal: %s (kvno %d).\n",
    119                                                 princ_s, kt_entry.vno));
    120 
    121                                         ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    122                                         if (ret) {
    123                                                 DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_start_seq failed (%s)\n",
    124                                                         error_message(ret)));
    125                                                 goto out;
    126                                         }
    127                                         ret = smb_krb5_kt_free_entry(context, &kt_entry);
    128                                         ZERO_STRUCT(kt_entry);
    129                                         if (ret) {
    130                                                 DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_remove_entry failed (%s)\n",
    131                                                         error_message(ret)));
    132                                                 goto out;
    133                                         }
    134                                         continue;
    135                                 }
    136                         }
    137 
    138                         /* Not a match, just free this entry and continue. */
    139                         ret = smb_krb5_kt_free_entry(context, &kt_entry);
    140                         ZERO_STRUCT(kt_entry);
    141                         if (ret) {
    142                                 DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_kt_free_entry failed (%s)\n", error_message(ret)));
    143                                 goto out;
    144                         }
    145                 }
     109                }
     110
     111                /*------------------------------------------------------------
     112                 * Save the entries with kvno - 1. This is what microsoft does
     113                 * to allow people with existing sessions that have kvno - 1
     114                 * to still work. Otherwise, when the password for the machine
     115                 * changes, all kerberizied sessions will 'break' until either
     116                 * the client reboots or the client's session key expires and
     117                 * they get a new session ticket with the new kvno.
     118                 */
     119
     120                if (!flush && (kt_entry.vno == kvno - 1)) {
     121                        DEBUG(5, (__location__ ": Saving previous (kvno %d) "
     122                                  "entry for principal: %s.\n",
     123                                  kvno - 1, princ_s));
     124                        continue;
     125                }
     126
     127                if (keep_old_entries) {
     128                        DEBUG(5, (__location__ ": Saving old (kvno %d) "
     129                                  "entry for principal: %s.\n",
     130                                  kvno, princ_s));
     131                        continue;
     132                }
     133
     134                DEBUG(5, (__location__ ": Found old entry for principal: %s "
     135                          "(kvno %d) - trying to remove it.\n",
     136                          princ_s, kt_entry.vno));
    146137
    147138                ret = krb5_kt_end_seq_get(context, keytab, &cursor);
    148139                ZERO_STRUCT(cursor);
    149140                if (ret) {
    150                         DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_end_seq_get failed (%s)\n",error_message(ret)));
    151                         goto out;
    152                 }
    153         }
    154 
    155         /* Ensure we don't double free. */
    156         ZERO_STRUCT(kt_entry);
    157         ZERO_STRUCT(cursor);
    158 
    159         /* If we get here, we have deleted all the old entries with kvno's not equal to the current kvno-1. */
    160 
    161         /* Now add keytab entries for all encryption types */
    162         for (i = 0; enctypes[i]; i++) {
    163                 krb5_keyblock *keyp;
    164 
    165                 keyp = KRB5_KT_KEY(&kt_entry);
    166 
    167                 if (create_kerberos_key_from_string(context, princ, &password, keyp, enctypes[i], no_salt)) {
    168                         continue;
    169                 }
    170 
    171                 kt_entry.principal = princ;
    172                 kt_entry.vno       = kvno;
    173 
    174                 DEBUG(3,("smb_krb5_kt_add_entry_ext: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n",
    175                         princ_s, enctypes[i], kt_entry.vno));
    176                 ret = krb5_kt_add_entry(context, keytab, &kt_entry);
    177                 krb5_free_keyblock_contents(context, keyp);
     141                        DEBUG(1, (__location__ ": krb5_kt_end_seq_get() "
     142                                  "failed (%s)\n", error_message(ret)));
     143                        goto out;
     144                }
     145                ret = krb5_kt_remove_entry(context, keytab, &kt_entry);
     146                if (ret) {
     147                        DEBUG(1, (__location__ ": krb5_kt_remove_entry() "
     148                                  "failed (%s)\n", error_message(ret)));
     149                        goto out;
     150                }
     151
     152                DEBUG(5, (__location__ ": removed old entry for principal: "
     153                          "%s (kvno %d).\n", princ_s, kt_entry.vno));
     154
     155                ret = krb5_kt_start_seq_get(context, keytab, &cursor);
     156                if (ret) {
     157                        DEBUG(1, (__location__ ": krb5_kt_start_seq() failed "
     158                                  "(%s)\n", error_message(ret)));
     159                        goto out;
     160                }
     161                ret = smb_krb5_kt_free_entry(context, &kt_entry);
    178162                ZERO_STRUCT(kt_entry);
    179163                if (ret) {
    180                         DEBUG(1,("smb_krb5_kt_add_entry_ext: adding entry to keytab failed (%s)\n", error_message(ret)));
    181                         goto out;
    182                 }
    183         }
    184 
     164                        DEBUG(1, (__location__ ": krb5_kt_remove_entry() "
     165                                  "failed (%s)\n", error_message(ret)));
     166                        goto out;
     167                }
     168        }
    185169
    186170out:
    187         {
    188                 krb5_keytab_entry zero_kt_entry;
    189                 ZERO_STRUCT(zero_kt_entry);
    190                 if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
    191                         smb_krb5_kt_free_entry(context, &kt_entry);
    192                 }
    193         }
    194         if (princ) {
    195                 krb5_free_principal(context, princ);
    196         }
    197        
    198         {
    199                 krb5_kt_cursor zero_csr;
    200                 ZERO_STRUCT(zero_csr);
    201                 if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
    202                         krb5_kt_end_seq_get(context, keytab, &cursor); 
    203                 }
    204         }
    205        
    206         return (int)ret;
     171        if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
     172                smb_krb5_kt_free_entry(context, &kt_entry);
     173        }
     174        if (keytab) {
     175                if (memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) {
     176                        krb5_kt_end_seq_get(context, keytab, &cursor);
     177                }
     178        }
     179
     180        return ret;
    207181}
    208182
     
    212186                                 const char *princ_s,
    213187                                 krb5_enctype *enctypes,
    214                                  krb5_data password)
     188                                 krb5_data password,
     189                                 bool no_salt,
     190                                 bool keep_old_entries)
    215191{
    216         return smb_krb5_kt_add_entry_ext(context,
    217                                          keytab,
    218                                          kvno,
    219                                          princ_s,
    220                                          enctypes,
    221                                          password,
    222                                          false,
    223                                          false);
     192        krb5_error_code ret;
     193        krb5_keytab_entry kt_entry;
     194        krb5_principal princ = NULL;
     195        int i;
     196
     197        ZERO_STRUCT(kt_entry);
     198
     199        ret = smb_krb5_parse_name(context, princ_s, &princ);
     200        if (ret) {
     201                DEBUG(1, (__location__ ": smb_krb5_parse_name(%s) "
     202                          "failed (%s)\n", princ_s, error_message(ret)));
     203                goto out;
     204        }
     205
     206        /* Seek and delete old keytab entries */
     207        ret = seek_and_delete_old_entries(context, keytab, kvno,
     208                                          princ_s, princ, false,
     209                                          keep_old_entries);
     210        if (ret) {
     211                goto out;
     212        }
     213
     214        /* If we get here, we have deleted all the old entries with kvno's
     215         * not equal to the current kvno-1. */
     216
     217        /* Now add keytab entries for all encryption types */
     218        for (i = 0; enctypes[i]; i++) {
     219                krb5_keyblock *keyp;
     220
     221                keyp = KRB5_KT_KEY(&kt_entry);
     222
     223                if (create_kerberos_key_from_string(context, princ,
     224                                                    &password, keyp,
     225                                                    enctypes[i], no_salt)) {
     226                        continue;
     227                }
     228
     229                kt_entry.principal = princ;
     230                kt_entry.vno       = kvno;
     231
     232                DEBUG(3, (__location__ ": adding keytab entry for (%s) with "
     233                          "encryption type (%d) and version (%d)\n",
     234                          princ_s, enctypes[i], kt_entry.vno));
     235                ret = krb5_kt_add_entry(context, keytab, &kt_entry);
     236                krb5_free_keyblock_contents(context, keyp);
     237                ZERO_STRUCT(kt_entry);
     238                if (ret) {
     239                        DEBUG(1, (__location__ ": adding entry to keytab "
     240                                  "failed (%s)\n", error_message(ret)));
     241                        goto out;
     242                }
     243        }
     244
     245out:
     246        if (princ) {
     247                krb5_free_principal(context, princ);
     248        }
     249
     250        return (int)ret;
    224251}
    225252
     
    235262        krb5_data password;
    236263        krb5_kvno kvno;
    237         krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, 0, 0 };
    238         char *princ_s = NULL, *short_princ_s = NULL;
     264        krb5_enctype enctypes[4] = {
     265                ENCTYPE_DES_CBC_CRC,
     266                ENCTYPE_DES_CBC_MD5,
     267                ENCTYPE_ARCFOUR_HMAC,
     268                0
     269        };
     270        char *princ_s = NULL;
     271        char *short_princ_s = NULL;
    239272        char *password_s = NULL;
    240273        char *my_fqdn;
    241         TALLOC_CTX *ctx = NULL;
     274        TALLOC_CTX *tmpctx = NULL;
    242275        char *machine_name;
    243 
    244 #if defined(ENCTYPE_ARCFOUR_HMAC)
    245         enctypes[2] = ENCTYPE_ARCFOUR_HMAC;
    246 #endif
     276        ADS_STATUS aderr;
    247277
    248278        initialize_krb5_error_table();
    249279        ret = krb5_init_context(&context);
    250280        if (ret) {
    251                 DEBUG(1,("ads_keytab_add_entry: could not krb5_init_context: %s\n",error_message(ret)));
     281                DEBUG(1, (__location__ ": could not krb5_init_context: %s\n",
     282                          error_message(ret)));
    252283                return -1;
    253284        }
     
    255286        ret = smb_krb5_open_keytab(context, NULL, True, &keytab);
    256287        if (ret) {
    257                 DEBUG(1,("ads_keytab_add_entry: smb_krb5_open_keytab failed (%s)\n", error_message(ret)));
     288                DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n",
     289                          error_message(ret)));
    258290                goto out;
    259291        }
     
    261293        /* retrieve the password */
    262294        if (!secrets_init()) {
    263                 DEBUG(1,("ads_keytab_add_entry: secrets_init failed\n"));
     295                DEBUG(1, (__location__ ": secrets_init failed\n"));
    264296                ret = -1;
    265297                goto out;
     
    267299        password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
    268300        if (!password_s) {
    269                 DEBUG(1,("ads_keytab_add_entry: failed to fetch machine password\n"));
     301                DEBUG(1, (__location__ ": failed to fetch machine password\n"));
    270302                ret = -1;
    271303                goto out;
     
    276308
    277309        /* we need the dNSHostName value here */
    278        
    279         if ( (ctx = talloc_init("ads_keytab_add_entry")) == NULL ) {
    280                 DEBUG(0,("ads_keytab_add_entry: talloc() failed!\n"));
    281                 ret = -1;
    282                 goto out;
    283         }
    284        
    285         if ( (my_fqdn = ads_get_dnshostname( ads, ctx, global_myname())) == NULL ) {
    286                 DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's dns name in AD!\n"));
    287                 ret = -1;
    288                 goto out;       
    289         }
    290        
    291         if ( (machine_name = ads_get_samaccountname( ads, ctx, global_myname())) == NULL ) {
    292                 DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's short name in AD!\n"));
    293                 ret = -1;
    294                 goto out;       
     310        tmpctx = talloc_init(__location__);
     311        if (!tmpctx) {
     312                DEBUG(0, (__location__ ": talloc_init() failed!\n"));
     313                ret = -1;
     314                goto out;
     315        }
     316
     317        my_fqdn = ads_get_dnshostname(ads, tmpctx, global_myname());
     318        if (!my_fqdn) {
     319                DEBUG(0, (__location__ ": unable to determine machine "
     320                          "account's dns name in AD!\n"));
     321                ret = -1;
     322                goto out;
     323        }
     324
     325        machine_name = ads_get_samaccountname(ads, tmpctx, global_myname());
     326        if (!machine_name) {
     327                DEBUG(0, (__location__ ": unable to determine machine "
     328                          "account's short name in AD!\n"));
     329                ret = -1;
     330                goto out;
    295331        }
    296332        /*strip the trailing '$' */
    297333        machine_name[strlen(machine_name)-1] = '\0';
    298                
     334
    299335        /* Construct our principal */
    300 
    301336        if (strchr_m(srvPrinc, '@')) {
    302337                /* It's a fully-named principal. */
    303                 if (asprintf(&princ_s, "%s", srvPrinc) == -1) {
     338                princ_s = talloc_asprintf(tmpctx, "%s", srvPrinc);
     339                if (!princ_s) {
    304340                        ret = -1;
    305341                        goto out;
     
    307343        } else if (srvPrinc[strlen(srvPrinc)-1] == '$') {
    308344                /* It's the machine account, as used by smbclient clients. */
    309                 if (asprintf(&princ_s, "%s@%s", srvPrinc, lp_realm()) == -1) {
     345                princ_s = talloc_asprintf(tmpctx, "%s@%s",
     346                                          srvPrinc, lp_realm());
     347                if (!princ_s) {
    310348                        ret = -1;
    311349                        goto out;
     
    315353                 * can obtain credentials for it and double-check the salt value
    316354                 * used to generate the service's keys. */
    317                  
    318                 if (asprintf(&princ_s, "%s/%s@%s", srvPrinc, my_fqdn, lp_realm()) == -1) {
     355
     356                princ_s = talloc_asprintf(tmpctx, "%s/%s@%s",
     357                                          srvPrinc, my_fqdn, lp_realm());
     358                if (!princ_s) {
    319359                        ret = -1;
    320360                        goto out;
    321361                }
    322                 if (asprintf(&short_princ_s, "%s/%s@%s", srvPrinc, machine_name, lp_realm()) == -1) {
     362                short_princ_s = talloc_asprintf(tmpctx, "%s/%s@%s",
     363                                                srvPrinc, machine_name,
     364                                                lp_realm());
     365                if (!princ_s) {
    323366                        ret = -1;
    324367                        goto out;
    325368                }
    326                
    327                 /* According to http://support.microsoft.com/kb/326985/en-us,
    328                    certain principal names are automatically mapped to the host/...
    329                    principal in the AD account.  So only create these in the
    330                    keytab, not in AD.  --jerry */
    331                    
    332                 if ( !strequal( srvPrinc, "cifs" ) && !strequal(srvPrinc, "host" ) ) {
    333                         DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s));
    334                        
    335                         if (!ADS_ERR_OK(ads_add_service_principal_name(ads, global_myname(), my_fqdn, srvPrinc))) {
    336                                 DEBUG(1,("ads_keytab_add_entry: ads_add_service_principal_name failed.\n"));
     369
     370                /* According to http://support.microsoft.com/kb/326985/en-us,
     371                   certain principal names are automatically mapped to the
     372                   host/... principal in the AD account.
     373                   So only create these in the keytab, not in AD.  --jerry */
     374
     375                if (!strequal(srvPrinc, "cifs") &&
     376                    !strequal(srvPrinc, "host")) {
     377                        DEBUG(3, (__location__ ": Attempting to add/update "
     378                                  "'%s'\n", princ_s));
     379
     380                        aderr = ads_add_service_principal_name(ads,
     381                                        global_myname(), my_fqdn, srvPrinc);
     382                        if (!ADS_ERR_OK(aderr)) {
     383                                DEBUG(1, (__location__ ": failed to "
     384                                         "ads_add_service_principal_name.\n"));
    337385                                goto out;
    338386                        }
     
    340388        }
    341389
    342         kvno = (krb5_kvno) ads_get_machine_kvno(ads, global_myname());
    343         if (kvno == -1) {       /* -1 indicates failure, everything else is OK */
    344                 DEBUG(1,("ads_keytab_add_entry: ads_get_machine_kvno failed to determine the system's kvno.\n"));
    345                 ret = -1;
    346                 goto out;
    347         }
    348        
     390        kvno = (krb5_kvno)ads_get_machine_kvno(ads, global_myname());
     391        if (kvno == -1) {
     392                /* -1 indicates failure, everything else is OK */
     393                DEBUG(1, (__location__ ": ads_get_machine_kvno failed to "
     394                         "determine the system's kvno.\n"));
     395                ret = -1;
     396                goto out;
     397        }
     398
    349399        /* add the fqdn principal to the keytab */
    350        
    351         ret = smb_krb5_kt_add_entry( context, keytab, kvno, princ_s, enctypes, password );
    352         if ( ret ) {
    353                 DEBUG(1,("ads_keytab_add_entry: Failed to add entry to keytab file\n"));
    354                 goto out;
    355         }
    356        
     400        ret = smb_krb5_kt_add_entry(context, keytab, kvno,
     401                                    princ_s, enctypes, password,
     402                                    false, false);
     403        if (ret) {
     404                DEBUG(1, (__location__ ": Failed to add entry to keytab\n"));
     405                goto out;
     406        }
     407
    357408        /* add the short principal name if we have one */
    358        
    359         if ( short_princ_s ) {
    360                 ret = smb_krb5_kt_add_entry( context, keytab, kvno, short_princ_s, enctypes, password );
    361                 if ( ret ) {
    362                         DEBUG(1,("ads_keytab_add_entry: Failed to add short entry to keytab file\n"));
     409        if (short_princ_s) {
     410                ret = smb_krb5_kt_add_entry(context, keytab, kvno,
     411                                            short_princ_s, enctypes, password,
     412                                            false, false);
     413                if (ret) {
     414                        DEBUG(1, (__location__
     415                                  ": Failed to add short entry to keytab\n"));
    363416                        goto out;
    364417                }
     
    366419
    367420out:
    368         SAFE_FREE( princ_s );
    369         SAFE_FREE( short_princ_s );
    370         TALLOC_FREE( ctx );
    371        
     421        TALLOC_FREE(tmpctx);
     422
    372423        if (keytab) {
    373424                krb5_kt_close(context, keytab);
     
    388439        krb5_context context = NULL;
    389440        krb5_keytab keytab = NULL;
    390         krb5_kt_cursor cursor;
    391         krb5_keytab_entry kt_entry;
    392441        krb5_kvno kvno;
    393 
    394         ZERO_STRUCT(kt_entry);
    395         ZERO_STRUCT(cursor);
     442        ADS_STATUS aderr;
    396443
    397444        initialize_krb5_error_table();
    398445        ret = krb5_init_context(&context);
    399446        if (ret) {
    400                 DEBUG(1,("ads_keytab_flush: could not krb5_init_context: %s\n",error_message(ret)));
     447                DEBUG(1, (__location__ ": could not krb5_init_context: %s\n",
     448                          error_message(ret)));
    401449                return ret;
    402450        }
     
    404452        ret = smb_krb5_open_keytab(context, NULL, True, &keytab);
    405453        if (ret) {
    406                 DEBUG(1,("ads_keytab_flush: smb_krb5_open_keytab failed (%s)\n", error_message(ret)));
    407                 goto out;
    408         }
    409 
    410         kvno = (krb5_kvno) ads_get_machine_kvno(ads, global_myname());
    411         if (kvno == -1) {       /* -1 indicates a failure */
    412                 DEBUG(1,("ads_keytab_flush: Error determining the system's kvno.\n"));
    413                 goto out;
    414         }
    415 
    416         ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    417         if (ret != KRB5_KT_END && ret != ENOENT) {
    418                 while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
    419                         ret = krb5_kt_end_seq_get(context, keytab, &cursor);
    420                         ZERO_STRUCT(cursor);
    421                         if (ret) {
    422                                 DEBUG(1,("ads_keytab_flush: krb5_kt_end_seq_get() failed (%s)\n",error_message(ret)));
    423                                 goto out;
    424                         }
    425                         ret = krb5_kt_remove_entry(context, keytab, &kt_entry);
    426                         if (ret) {
    427                                 DEBUG(1,("ads_keytab_flush: krb5_kt_remove_entry failed (%s)\n",error_message(ret)));
    428                                 goto out;
    429                         }
    430                         ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    431                         if (ret) {
    432                                 DEBUG(1,("ads_keytab_flush: krb5_kt_start_seq failed (%s)\n",error_message(ret)));
    433                                 goto out;
    434                         }
    435                         ret = smb_krb5_kt_free_entry(context, &kt_entry);
    436                         ZERO_STRUCT(kt_entry);
    437                         if (ret) {
    438                                 DEBUG(1,("ads_keytab_flush: krb5_kt_remove_entry failed (%s)\n",error_message(ret)));
    439                                 goto out;
    440                         }
    441                 }
    442         }
    443 
    444         /* Ensure we don't double free. */
    445         ZERO_STRUCT(kt_entry);
    446         ZERO_STRUCT(cursor);
    447 
    448         if (!ADS_ERR_OK(ads_clear_service_principal_names(ads, global_myname()))) {
    449                 DEBUG(1,("ads_keytab_flush: Error while clearing service principal listings in LDAP.\n"));
     454                DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n",
     455                          error_message(ret)));
     456                goto out;
     457        }
     458
     459        kvno = (krb5_kvno)ads_get_machine_kvno(ads, global_myname());
     460        if (kvno == -1) {
     461                /* -1 indicates a failure */
     462                DEBUG(1, (__location__ ": Error determining the kvno.\n"));
     463                goto out;
     464        }
     465
     466        /* Seek and delete old keytab entries */
     467        ret = seek_and_delete_old_entries(context, keytab, kvno,
     468                                          NULL, NULL, true, false);
     469        if (ret) {
     470                goto out;
     471        }
     472
     473        aderr = ads_clear_service_principal_names(ads, global_myname());
     474        if (!ADS_ERR_OK(aderr)) {
     475                DEBUG(1, (__location__ ": Error while clearing service "
     476                          "principal listings in LDAP.\n"));
    450477                goto out;
    451478        }
    452479
    453480out:
    454 
    455         {
    456                 krb5_keytab_entry zero_kt_entry;
    457                 ZERO_STRUCT(zero_kt_entry);
    458                 if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
    459                         smb_krb5_kt_free_entry(context, &kt_entry);
    460                 }
    461         }
    462         {
    463                 krb5_kt_cursor zero_csr;
    464                 ZERO_STRUCT(zero_csr);
    465                 if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
    466                         krb5_kt_end_seq_get(context, keytab, &cursor); 
    467                 }
    468         }
    469481        if (keytab) {
    470482                krb5_kt_close(context, keytab);
     
    491503        char *sam_account_name, *upn;
    492504        char **oldEntries = NULL, *princ_s[26];
    493         TALLOC_CTX *ctx = NULL;
    494         fstring machine_name;
     505        TALLOC_CTX *tmpctx = NULL;
     506        char *machine_name;
     507
     508        /* these are the main ones we need */
     509        ret = ads_keytab_add_entry(ads, "host");
     510        if (ret != 0) {
     511                DEBUG(1, (__location__ ": ads_keytab_add_entry failed while "
     512                          "adding 'host' principal.\n"));
     513                return ret;
     514        }
     515
     516
     517#if 0   /* don't create the CIFS/... keytab entries since no one except smbd
     518           really needs them and we will fall back to verifying against
     519           secrets.tdb */
     520
     521        ret = ads_keytab_add_entry(ads, "cifs"));
     522        if (ret != 0 ) {
     523                DEBUG(1, (__location__ ": ads_keytab_add_entry failed while "
     524                          "adding 'cifs'.\n"));
     525                return ret;
     526        }
     527#endif
    495528
    496529        memset(princ_s, '\0', sizeof(princ_s));
    497 
    498         fstrcpy( machine_name, global_myname() );
    499 
    500         /* these are the main ones we need */
    501        
    502         if ( (ret = ads_keytab_add_entry(ads, "host") ) != 0 ) {
    503                 DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding 'host'.\n"));
    504                 return ret;
    505         }
    506 
    507 
    508 #if 0   /* don't create the CIFS/... keytab entries since no one except smbd
    509            really needs them and we will fall back to verifying against secrets.tdb */
    510            
    511         if ( (ret = ads_keytab_add_entry(ads, "cifs")) != 0 ) {
    512                 DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding 'cifs'.\n"));
    513                 return ret;
    514         }
    515 #endif
    516 
    517         if ( (ctx = talloc_init("ads_keytab_create_default")) == NULL ) {
    518                 DEBUG(0,("ads_keytab_create_default: talloc() failed!\n"));
    519                 return -1;
    520         }
    521 
    522         /* now add the userPrincipalName and sAMAccountName entries */
    523 
    524         if ( (sam_account_name = ads_get_samaccountname( ads, ctx, machine_name)) == NULL ) {
    525                 DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's name in AD!\n"));
    526                 TALLOC_FREE( ctx );
    527                 return -1;     
    528         }
    529 
    530         /* upper case the sAMAccountName to make it easier for apps to
    531            know what case to use in the keytab file */
    532 
    533         strupper_m( sam_account_name );
    534 
    535         if ( (ret = ads_keytab_add_entry(ads, sam_account_name )) != 0 ) {
    536                 DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding sAMAccountName (%s)\n",
    537                         sam_account_name));
    538                 return ret;
    539         }
    540        
    541         /* remember that not every machine account will have a upn */
    542                
    543         upn = ads_get_upn( ads, ctx, machine_name);
    544         if ( upn ) {
    545                 if ( (ret = ads_keytab_add_entry(ads, upn)) != 0 ) {
    546                         DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding UPN (%s)\n",
    547                                 upn));
    548                         TALLOC_FREE( ctx );
    549                         return ret;
    550                 }
    551         }
    552 
    553         /* Now loop through the keytab and update any other existing entries... */
    554        
    555         kvno = (krb5_kvno) ads_get_machine_kvno(ads, machine_name);
    556         if (kvno == -1) {
    557                 DEBUG(1,("ads_keytab_create_default: ads_get_machine_kvno failed to determine the system's kvno.\n"));
    558                 TALLOC_FREE(ctx);
    559                 return -1;
    560         }
    561        
    562         DEBUG(3,("ads_keytab_create_default: Searching for keytab entries to "
    563                 "preserve and update.\n"));
    564 
    565530        ZERO_STRUCT(kt_entry);
    566531        ZERO_STRUCT(cursor);
     
    569534        ret = krb5_init_context(&context);
    570535        if (ret) {
    571                 DEBUG(1,("ads_keytab_create_default: could not krb5_init_context: %s\n",error_message(ret)));
    572                 TALLOC_FREE(ctx);
     536                DEBUG(1, (__location__ ": could not krb5_init_context: %s\n",
     537                          error_message(ret)));
    573538                return ret;
    574539        }
    575540
     541        tmpctx = talloc_init(__location__);
     542        if (!tmpctx) {
     543                DEBUG(0, (__location__ ": talloc_init() failed!\n"));
     544                ret = -1;
     545                goto done;
     546        }
     547
     548        machine_name = talloc_strdup(tmpctx, global_myname());
     549        if (!machine_name) {
     550                ret = -1;
     551                goto done;
     552        }
     553
     554        /* now add the userPrincipalName and sAMAccountName entries */
     555        sam_account_name = ads_get_samaccountname(ads, tmpctx, machine_name);
     556        if (!sam_account_name) {
     557                DEBUG(0, (__location__ ": unable to determine machine "
     558                          "account's name in AD!\n"));
     559                ret = -1;
     560                goto done;
     561        }
     562
     563        /* upper case the sAMAccountName to make it easier for apps to
     564           know what case to use in the keytab file */
     565        strupper_m(sam_account_name);
     566
     567        ret = ads_keytab_add_entry(ads, sam_account_name);
     568        if (ret != 0) {
     569                DEBUG(1, (__location__ ": ads_keytab_add_entry() failed "
     570                          "while adding sAMAccountName (%s)\n",
     571                          sam_account_name));
     572                goto done;
     573        }
     574
     575        /* remember that not every machine account will have a upn */
     576        upn = ads_get_upn(ads, tmpctx, machine_name);
     577        if (upn) {
     578                ret = ads_keytab_add_entry(ads, upn);
     579                if (ret != 0) {
     580                        DEBUG(1, (__location__ ": ads_keytab_add_entry() "
     581                                  "failed while adding UPN (%s)\n", upn));
     582                        goto done;
     583                }
     584        }
     585
     586        /* Now loop through the keytab and update any other existing entries */
     587        kvno = (krb5_kvno)ads_get_machine_kvno(ads, machine_name);
     588        if (kvno == -1) {
     589                DEBUG(1, (__location__ ": ads_get_machine_kvno() failed to "
     590                          "determine the system's kvno.\n"));
     591                goto done;
     592        }
     593
     594        DEBUG(3, (__location__ ": Searching for keytab entries to preserve "
     595                  "and update.\n"));
     596
    576597        ret = smb_krb5_open_keytab(context, NULL, True, &keytab);
    577598        if (ret) {
    578                 DEBUG(1,("ads_keytab_create_default: smb_krb5_open_keytab failed (%s)\n", error_message(ret)));
     599                DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n",
     600                          error_message(ret)));
    579601                goto done;
    580602        }
     
    582604        ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    583605        if (ret != KRB5_KT_END && ret != ENOENT ) {
    584                 while ((ret = krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) == 0) {
     606                while ((ret = krb5_kt_next_entry(context, keytab,
     607                                                 &kt_entry, &cursor)) == 0) {
    585608                        smb_krb5_kt_free_entry(context, &kt_entry);
    586609                        ZERO_STRUCT(kt_entry);
     
    592615
    593616        /*
    594          * Hmmm. There is no "rewind" function for the keytab. This means we have a race condition
    595          * where someone else could add entries after we've counted them. Re-open asap to minimise
    596          * the race. JRA.
     617         * Hmmm. There is no "rewind" function for the keytab. This means we
     618         * have a race condition where someone else could add entries after
     619         * we've counted them. Re-open asap to minimise the race. JRA.
    597620         */
    598        
    599         DEBUG(3, ("ads_keytab_create_default: Found %d entries in the keytab.\n", found));
     621        DEBUG(3, (__location__ ": Found %d entries in the keytab.\n", found));
    600622        if (!found) {
    601623                goto done;
    602624        }
    603         oldEntries = talloc_array(ctx, char *, found );
     625
     626        oldEntries = talloc_array(tmpctx, char *, found);
    604627        if (!oldEntries) {
    605                 DEBUG(1,("ads_keytab_create_default: Failed to allocate space to store the old keytab entries (malloc failed?).\n"));
     628                DEBUG(1, (__location__ ": Failed to allocate space to store "
     629                          "the old keytab entries (talloc failed?).\n"));
    606630                ret = -1;
    607631                goto done;
     
    610634
    611635        ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    612         if (ret != KRB5_KT_END && ret != ENOENT ) {
    613                 while (krb5_kt_next_entry(context, keytab, &kt_entry, &cursor) == 0) {
    614                         if (kt_entry.vno != kvno) {
    615                                 char *ktprinc = NULL;
    616                                 char *p;
    617 
    618                                 /* This returns a malloc'ed string in ktprinc. */
    619                                 ret = smb_krb5_unparse_name(oldEntries, context, kt_entry.principal, &ktprinc);
    620                                 if (ret) {
    621                                         DEBUG(1,("smb_krb5_unparse_name failed (%s)\n", error_message(ret)));
    622                                         goto done;
     636        if (ret == KRB5_KT_END || ret == ENOENT) {
     637                krb5_kt_end_seq_get(context, keytab, &cursor);
     638                ZERO_STRUCT(cursor);
     639                goto done;
     640        }
     641
     642        while (krb5_kt_next_entry(context, keytab, &kt_entry, &cursor) == 0) {
     643                if (kt_entry.vno != kvno) {
     644                        char *ktprinc = NULL;
     645                        char *p;
     646
     647                        /* This returns a malloc'ed string in ktprinc. */
     648                        ret = smb_krb5_unparse_name(oldEntries, context,
     649                                                    kt_entry.principal,
     650                                                    &ktprinc);
     651                        if (ret) {
     652                                DEBUG(1, (__location__
     653                                         ": smb_krb5_unparse_name failed "
     654                                         "(%s)\n", error_message(ret)));
     655                                goto done;
     656                        }
     657                        /*
     658                         * From looking at the krb5 source they don't seem to
     659                         * take locale or mb strings into account.
     660                         * Maybe this is because they assume utf8 ?
     661                         * In this case we may need to convert from utf8 to
     662                         * mb charset here ? JRA.
     663                         */
     664                        p = strchr_m(ktprinc, '@');
     665                        if (p) {
     666                                *p = '\0';
     667                        }
     668
     669                        p = strchr_m(ktprinc, '/');
     670                        if (p) {
     671                                *p = '\0';
     672                        }
     673                        for (i = 0; i < found; i++) {
     674                                if (!oldEntries[i]) {
     675                                        oldEntries[i] = ktprinc;
     676                                        break;
    623677                                }
    624                                 /*
    625                                  * From looking at the krb5 source they don't seem to take locale
    626                                  * or mb strings into account. Maybe this is because they assume utf8 ?
    627                                  * In this case we may need to convert from utf8 to mb charset here ? JRA.
    628                                  */
    629                                 p = strchr_m(ktprinc, '@');
    630                                 if (p) {
    631                                         *p = '\0';
    632                                 }
    633 
    634                                 p = strchr_m(ktprinc, '/');
    635                                 if (p) {
    636                                         *p = '\0';
    637                                 }
    638                                 for (i = 0; i < found; i++) {
    639                                         if (!oldEntries[i]) {
    640                                                 oldEntries[i] = ktprinc;
    641                                                 break;
    642                                         }
    643                                         if (!strcmp(oldEntries[i], ktprinc)) {
    644                                                 TALLOC_FREE(ktprinc);
    645                                                 break;
    646                                         }
    647                                 }
    648                                 if (i == found) {
     678                                if (!strcmp(oldEntries[i], ktprinc)) {
    649679                                        TALLOC_FREE(ktprinc);
     680                                        break;
    650681                                }
    651682                        }
    652                         smb_krb5_kt_free_entry(context, &kt_entry);
    653                         ZERO_STRUCT(kt_entry);
    654                 }
    655                 ret = 0;
    656                 for (i = 0; oldEntries[i]; i++) {
    657                         ret |= ads_keytab_add_entry(ads, oldEntries[i]);
    658                         TALLOC_FREE(oldEntries[i]);
    659                 }
    660                 krb5_kt_end_seq_get(context, keytab, &cursor);
    661         }
     683                        if (i == found) {
     684                                TALLOC_FREE(ktprinc);
     685                        }
     686                }
     687                smb_krb5_kt_free_entry(context, &kt_entry);
     688                ZERO_STRUCT(kt_entry);
     689        }
     690        ret = 0;
     691        for (i = 0; oldEntries[i]; i++) {
     692                ret |= ads_keytab_add_entry(ads, oldEntries[i]);
     693                TALLOC_FREE(oldEntries[i]);
     694        }
     695        krb5_kt_end_seq_get(context, keytab, &cursor);
    662696        ZERO_STRUCT(cursor);
    663697
    664698done:
    665 
    666699        TALLOC_FREE(oldEntries);
    667         TALLOC_FREE(ctx);
     700        TALLOC_FREE(tmpctx);
    668701
    669702        {
    670703                krb5_keytab_entry zero_kt_entry;
    671704                ZERO_STRUCT(zero_kt_entry);
    672                 if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
     705                if (memcmp(&zero_kt_entry, &kt_entry,
     706                                sizeof(krb5_keytab_entry))) {
    673707                        smb_krb5_kt_free_entry(context, &kt_entry);
    674708                }
     
    677711                krb5_kt_cursor zero_csr;
    678712                ZERO_STRUCT(zero_csr);
    679                 if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
    680                         krb5_kt_end_seq_get(context, keytab, &cursor); 
     713                if ((memcmp(&cursor, &zero_csr,
     714                                sizeof(krb5_kt_cursor)) != 0) && keytab) {
     715                        krb5_kt_end_seq_get(context, keytab, &cursor);
    681716                }
    682717        }
     
    708743        ret = krb5_init_context(&context);
    709744        if (ret) {
    710                 DEBUG(1,("ads_keytab_list: could not krb5_init_context: %s\n",error_message(ret)));
     745                DEBUG(1, (__location__ ": could not krb5_init_context: %s\n",
     746                          error_message(ret)));
    711747                return ret;
    712748        }
     
    714750        ret = smb_krb5_open_keytab(context, keytab_name, False, &keytab);
    715751        if (ret) {
    716                 DEBUG(1,("ads_keytab_list: smb_krb5_open_keytab failed (%s)\n", error_message(ret)));
     752                DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n",
     753                          error_message(ret)));
    717754                goto out;
    718755        }
     
    720757        ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    721758        if (ret) {
     759                ZERO_STRUCT(cursor);
    722760                goto out;
    723761        }
     
    726764
    727765        while (krb5_kt_next_entry(context, keytab, &kt_entry, &cursor) == 0) {
    728        
     766
    729767                char *princ_s = NULL;
    730768                char *etype_s = NULL;
    731769                krb5_enctype enctype = 0;
    732770
    733                 ret = smb_krb5_unparse_name(talloc_tos(), context, kt_entry.principal, &princ_s);
     771                ret = smb_krb5_unparse_name(talloc_tos(), context,
     772                                            kt_entry.principal, &princ_s);
    734773                if (ret) {
    735774                        goto out;
     
    739778
    740779                ret = smb_krb5_enctype_to_string(context, enctype, &etype_s);
    741                 if (ret) {
    742                         if (asprintf(&etype_s, "UNKNOWN: %d\n", enctype) == -1)
    743                         {
    744                                 TALLOC_FREE(princ_s);
    745                                 goto out;
    746                         }
     780                if (ret &&
     781                    (asprintf(&etype_s, "UNKNOWN: %d\n", enctype) == -1)) {
     782                        TALLOC_FREE(princ_s);
     783                        goto out;
    747784                }
    748785
     
    771808                krb5_keytab_entry zero_kt_entry;
    772809                ZERO_STRUCT(zero_kt_entry);
    773                 if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
     810                if (memcmp(&zero_kt_entry, &kt_entry,
     811                                sizeof(krb5_keytab_entry))) {
    774812                        smb_krb5_kt_free_entry(context, &kt_entry);
    775813                }
     
    778816                krb5_kt_cursor zero_csr;
    779817                ZERO_STRUCT(zero_csr);
    780                 if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
    781                         krb5_kt_end_seq_get(context, keytab, &cursor); 
     818                if ((memcmp(&cursor, &zero_csr,
     819                                sizeof(krb5_kt_cursor)) != 0) && keytab) {
     820                        krb5_kt_end_seq_get(context, keytab, &cursor);
    782821                }
    783822        }
  • vendor/current/source3/libads/kerberos_verify.c

    r478 r740  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   kerberos utility library
    44   Copyright (C) Andrew Tridgell 2001
    55   Copyright (C) Remus Koos 2001
    6    Copyright (C) Luke Howard 2003   
     6   Copyright (C) Luke Howard 2003
    77   Copyright (C) Guenther Deschner 2003, 2005
    88   Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
    99   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
    1010   Copyright (C) Jeremy Allison 2007
    11    
     11
    1212   This program is free software; you can redistribute it and/or modify
    1313   it under the terms of the GNU General Public License as published by
    1414   the Free Software Foundation; either version 3 of the License, or
    1515   (at your option) any later version.
    16    
     16
    1717   This program is distributed in the hope that it will be useful,
    1818   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1919   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2020   GNU General Public License for more details.
    21    
     21
    2222   You should have received a copy of the GNU General Public License
    2323   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2626#include "includes.h"
    2727#include "smb_krb5.h"
     28#include "libads/kerberos_proto.h"
     29#include "secrets.h"
     30#include "../librpc/gen_ndr/krb5pac.h"
    2831
    2932#ifdef HAVE_KRB5
     
    114117}
    115118
    116 /**********************************************************************************
    117  Try to verify a ticket using the system keytab... the system keytab has kvno -1 entries, so
    118  it's more like what microsoft does... see comment in utils/net_ads.c in the
    119  ads_keytab_add_entry function for details.
    120 ***********************************************************************************/
     119/******************************************************************************
     120 Try to verify a ticket using the system keytab... the system keytab has
     121 kvno -1 entries, so it's more like what microsoft does... see comment in
     122 utils/net_ads.c in the ads_keytab_add_entry function for details.
     123******************************************************************************/
    121124
    122125static bool ads_keytab_verify_ticket(krb5_context context,
     
    132135        krb5_kt_cursor kt_cursor;
    133136        krb5_keytab_entry kt_entry;
    134         char *valid_princ_formats[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
     137        char *valid_princ_formats[7] = { NULL, NULL, NULL,
     138                                         NULL, NULL, NULL, NULL };
    135139        char *entry_princ_s = NULL;
    136140        fstring my_name, my_fqdn;
     
    138142        int number_matched_principals = 0;
    139143        krb5_data packet;
     144        int err;
    140145
    141146        *pp_tkt = NULL;
     
    152157        name_to_fqdn(my_fqdn, global_myname());
    153158
    154         if (asprintf(&valid_princ_formats[0], "%s$@%s", my_name, lp_realm()) == -1) {
    155                 goto out;
    156         }
    157         if (asprintf(&valid_princ_formats[1], "host/%s@%s", my_name, lp_realm()) == -1) {
    158                 goto out;
    159         }
    160         if (asprintf(&valid_princ_formats[2], "host/%s@%s", my_fqdn, lp_realm()) == -1) {
    161                 goto out;
    162         }
    163         if (asprintf(&valid_princ_formats[3], "host/%s.%s@%s", my_name, lp_realm(), lp_realm()) == -1) {
    164                 goto out;
    165         }
    166         if (asprintf(&valid_princ_formats[4], "cifs/%s@%s", my_name, lp_realm()) == -1) {
    167                 goto out;
    168         }
    169         if (asprintf(&valid_princ_formats[5], "cifs/%s@%s", my_fqdn, lp_realm()) == -1) {
    170                 goto out;
    171         }
    172         if (asprintf(&valid_princ_formats[6], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm()) == -1) {
     159        err = asprintf(&valid_princ_formats[0],
     160                        "%s$@%s", my_name, lp_realm());
     161        if (err == -1) {
     162                goto out;
     163        }
     164        err = asprintf(&valid_princ_formats[1],
     165                        "host/%s@%s", my_name, lp_realm());
     166        if (err == -1) {
     167                goto out;
     168        }
     169        err = asprintf(&valid_princ_formats[2],
     170                        "host/%s@%s", my_fqdn, lp_realm());
     171        if (err == -1) {
     172                goto out;
     173        }
     174        err = asprintf(&valid_princ_formats[3],
     175                        "host/%s.%s@%s", my_name, lp_realm(), lp_realm());
     176        if (err == -1) {
     177                goto out;
     178        }
     179        err = asprintf(&valid_princ_formats[4],
     180                        "cifs/%s@%s", my_name, lp_realm());
     181        if (err == -1) {
     182                goto out;
     183        }
     184        err = asprintf(&valid_princ_formats[5],
     185                        "cifs/%s@%s", my_fqdn, lp_realm());
     186        if (err == -1) {
     187                goto out;
     188        }
     189        err = asprintf(&valid_princ_formats[6],
     190                        "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm());
     191        if (err == -1) {
    173192                goto out;
    174193        }
     
    179198        ret = smb_krb5_open_keytab(context, NULL, False, &keytab);
    180199        if (ret) {
    181                 DEBUG(1, ("ads_keytab_verify_ticket: smb_krb5_open_keytab failed (%s)\n", error_message(ret)));
     200                DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n",
     201                          error_message(ret)));
    182202                goto out;
    183203        }
     
    189209        ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor);
    190210        if (ret) {
    191                 DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret)));
     211                DEBUG(1, (__location__ ": krb5_kt_start_seq_get failed (%s)\n",
     212                          error_message(ret)));
    192213                goto out;
    193214        }
    194215 
    195         while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) {
    196                 ret = smb_krb5_unparse_name(talloc_tos(), context, kt_entry.principal, &entry_princ_s);
     216        while (!auth_ok &&
     217               (krb5_kt_next_entry(context, keytab,
     218                                   &kt_entry, &kt_cursor) == 0)) {
     219                ret = smb_krb5_unparse_name(talloc_tos(), context,
     220                                            kt_entry.principal,
     221                                            &entry_princ_s);
    197222                if (ret) {
    198                         DEBUG(1, ("ads_keytab_verify_ticket: smb_krb5_unparse_name failed (%s)\n",
    199                                 error_message(ret)));
     223                        DEBUG(1, (__location__ ": smb_krb5_unparse_name "
     224                                  "failed (%s)\n", error_message(ret)));
    200225                        goto out;
    201226                }
     
    212237                        *pp_tkt = NULL;
    213238
    214                         ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, &packet,
    215                                                                       kt_entry.principal, keytab,
    216                                                                       NULL, pp_tkt, keyblock);
     239                        ret = krb5_rd_req_return_keyblock_from_keytab(context,
     240                                                &auth_context, &packet,
     241                                                kt_entry.principal, keytab,
     242                                                NULL, pp_tkt, keyblock);
    217243
    218244                        if (ret) {
    219                                 DEBUG(10,("ads_keytab_verify_ticket: "
    220                                         "krb5_rd_req_return_keyblock_from_keytab(%s) failed: %s\n",
    221                                         entry_princ_s, error_message(ret)));
    222 
    223                                 /* workaround for MIT:
     245                                DEBUG(10, (__location__ ": krb5_rd_req_return"
     246                                           "_keyblock_from_keytab(%s) "
     247                                           "failed: %s\n", entry_princ_s,
     248                                           error_message(ret)));
     249
     250                                /* workaround for MIT:
    224251                                * as krb5_ktfile_get_entry will explicitly
    225252                                * close the krb5_keytab as soon as krb5_rd_req
     
    228255                                * there is no point in querying more keytab
    229256                                * entries - Guenther */
    230                                        
    231                                 if (ret == KRB5KRB_AP_ERR_TKT_NYV || 
     257
     258                                if (ret == KRB5KRB_AP_ERR_TKT_NYV ||
    232259                                    ret == KRB5KRB_AP_ERR_TKT_EXPIRED ||
    233260                                    ret == KRB5KRB_AP_ERR_SKEW) {
     
    235262                                }
    236263                        } else {
    237                                 DEBUG(3,("ads_keytab_verify_ticket: "
    238                                         "krb5_rd_req_return_keyblock_from_keytab succeeded for principal %s\n",
    239                                         entry_princ_s));
     264                                DEBUG(3, (__location__ ": krb5_rd_req_return"
     265                                          "_keyblock_from_keytab succeeded "
     266                                          "for principal %s\n",
     267                                          entry_princ_s));
    240268                                auth_ok = True;
    241269                                break;
     
    254282        ZERO_STRUCT(kt_cursor);
    255283
    256   out:
    257        
     284out:
     285
    258286        for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
    259287                SAFE_FREE(valid_princ_formats[i]);
    260288        }
    261        
     289
    262290        if (!auth_ok) {
    263291                if (!number_matched_principals) {
    264                         DEBUG(3, ("ads_keytab_verify_ticket: no keytab principals matched expected file service name.\n"));
     292                        DEBUG(3, (__location__ ": no keytab principals "
     293                                  "matched expected file service name.\n"));
    265294                } else {
    266                         DEBUG(3, ("ads_keytab_verify_ticket: krb5_rd_req failed for all %d matched keytab principals\n",
    267                                 number_matched_principals));
     295                        DEBUG(3, (__location__ ": krb5_rd_req failed for "
     296                                  "all %d matched keytab principals\n",
     297                                  number_matched_principals));
    268298                }
    269299        }
     
    274304                krb5_keytab_entry zero_kt_entry;
    275305                ZERO_STRUCT(zero_kt_entry);
    276                 if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
     306                if (memcmp(&zero_kt_entry, &kt_entry,
     307                           sizeof(krb5_keytab_entry))) {
    277308                        smb_krb5_kt_free_entry(context, &kt_entry);
    278309                }
     
    282313                krb5_kt_cursor zero_csr;
    283314                ZERO_STRUCT(zero_csr);
    284                 if ((memcmp(&kt_cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
     315                if ((memcmp(&kt_cursor, &zero_csr,
     316                            sizeof(krb5_kt_cursor)) != 0) && keytab) {
    285317                        krb5_kt_end_seq_get(context, keytab, &kt_cursor);
    286318                }
     
    294326}
    295327
    296 /**********************************************************************************
     328/*****************************************************************************
    297329 Try to verify a ticket using the secrets.tdb.
    298 ***********************************************************************************/
     330******************************************************************************/
    299331
    300332static krb5_error_code ads_secrets_verify_ticket(krb5_context context,
     
    312344        /* Let's make some room for 2 password (old and new)*/
    313345        krb5_data passwords[2];
    314         krb5_enctype enctypes[] = {
    315 #if defined(ENCTYPE_ARCFOUR_HMAC)
     346        krb5_enctype enctypes[] = {
    316347                ENCTYPE_ARCFOUR_HMAC,
    317 #endif
    318                 ENCTYPE_DES_CBC_CRC,
    319                 ENCTYPE_DES_CBC_MD5,
     348                ENCTYPE_DES_CBC_CRC,
     349                ENCTYPE_DES_CBC_MD5,
    320350                ENCTYPE_NULL
    321351        };
     
    335365        }
    336366
    337         password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
     367        password_s = secrets_fetch_machine_password(lp_workgroup(),
     368                                                    NULL, NULL);
    338369        if (!password_s) {
    339                 DEBUG(1,("ads_secrets_verify_ticket: failed to fetch machine password\n"));
     370                DEBUG(1,(__location__ ": failed to fetch machine password\n"));
    340371                *perr = KRB5_LIBOS_CANTREADPWD;
    341372                return False;
     
    347378        password_s = secrets_fetch_prev_machine_password(lp_workgroup());
    348379        if (password_s) {
    349                 DEBUG(10,("ads_secrets_verify_ticket: found previous password\n"));
     380                DEBUG(10, (__location__ ": found previous password\n"));
    350381                passwords[1].data = password_s;
    351382                passwords[1].length = strlen(password_s);
     
    357388        packet.data = (char *)ticket->data;
    358389
    359         /* We need to setup a auth context with each possible encoding type in turn. */
     390        /* We need to setup a auth context with each possible encoding type
     391         * in turn. */
    360392        for (j=0; j<2 && passwords[j].length; j++) {
    361393
     
    368400                        }
    369401
    370                         if (create_kerberos_key_from_string(context, host_princ, &passwords[j], key, enctypes[i], false)) {
     402                        if (create_kerberos_key_from_string(context,
     403                                                host_princ, &passwords[j],
     404                                                key, enctypes[i], false)) {
    371405                                SAFE_FREE(key);
    372406                                continue;
    373407                        }
    374408
    375                         krb5_auth_con_setuseruserkey(context, auth_context, key);
    376 
    377                         if (!(ret = krb5_rd_req(context, &auth_context, &packet,
    378                                                 NULL,
    379                                                 NULL, NULL, pp_tkt))) {
    380                                 DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n",
    381                                         (unsigned int)enctypes[i] ));
     409                        krb5_auth_con_setuseruserkey(context,
     410                                                        auth_context, key);
     411
     412                        if (!(ret = krb5_rd_req(context, &auth_context,
     413                                                &packet, NULL, NULL,
     414                                                NULL, pp_tkt))) {
     415                                DEBUG(10, (__location__ ": enc type [%u] "
     416                                           "decrypted message !\n",
     417                                           (unsigned int)enctypes[i]));
    382418                                auth_ok = True;
    383419                                cont = false;
     
    388424
    389425                        DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10,
    390                                         ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n",
    391                                         (unsigned int)enctypes[i], error_message(ret)));
    392 
    393                         /* successfully decrypted but ticket is just not valid at the moment */
     426                                (__location__ ": enc type [%u] failed to "
     427                                 "decrypt with error %s\n",
     428                                 (unsigned int)enctypes[i],
     429                                 error_message(ret)));
     430
     431                        /* successfully decrypted but ticket is just not
     432                         * valid at the moment */
    394433                        if (ret == KRB5KRB_AP_ERR_TKT_NYV ||
    395434                            ret == KRB5KRB_AP_ERR_TKT_EXPIRED ||
     
    417456}
    418457
    419 /**********************************************************************************
    420  Verify an incoming ticket and parse out the principal name and 
     458/*****************************************************************************
     459 Verify an incoming ticket and parse out the principal name and
    421460 authorization_data if available.
    422 ***********************************************************************************/
     461******************************************************************************/
    423462
    424463NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
     
    427466                           const DATA_BLOB *ticket,
    428467                           char **principal,
    429                            struct PAC_DATA **pac_data,
     468                           struct PAC_LOGON_INFO **logon_info,
    430469                           DATA_BLOB *ap_rep,
    431470                           DATA_BLOB *session_key,
     
    443482        time_t authtime;
    444483        krb5_error_code ret = 0;
    445         int flags = 0; 
     484        int flags = 0;
    446485        krb5_principal host_princ = NULL;
    447486        krb5_const_principal client_principal = NULL;
     
    455494
    456495        *principal = NULL;
    457         *pac_data = NULL;
     496        *logon_info = NULL;
    458497        *ap_rep = data_blob_null;
    459498        *session_key = data_blob_null;
     
    462501        ret = krb5_init_context(&context);
    463502        if (ret) {
    464                 DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret)));
     503                DEBUG(1, (__location__ ": krb5_init_context failed (%s)\n",
     504                          error_message(ret)));
    465505                return NT_STATUS_LOGON_FAILURE;
    466506        }
     
    472512        ret = krb5_set_default_realm(context, realm);
    473513        if (ret) {
    474                 DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret)));
     514                DEBUG(1, (__location__ ": krb5_set_default_realm "
     515                          "failed (%s)\n", error_message(ret)));
    475516                goto out;
    476517        }
     
    482523        ret = krb5_auth_con_init(context, &auth_context);
    483524        if (ret) {
    484                 DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret)));
     525                DEBUG(1, (__location__ ": krb5_auth_con_init failed (%s)\n",
     526                          error_message(ret)));
    485527                goto out;
    486528        }
     
    500542        ret = smb_krb5_parse_name(context, host_princ_s, &host_princ);
    501543        if (ret) {
    502                 DEBUG(1,("ads_verify_ticket: smb_krb5_parse_name(%s) failed (%s)\n",
    503                                         host_princ_s, error_message(ret)));
    504                 goto out;
    505         }
    506 
    507 
    508         if ( use_replay_cache ) {
    509                
    510                 /* Lock a mutex surrounding the replay as there is no 
    511                    locking in the MIT krb5 code surrounding the replay 
     544                DEBUG(1, (__location__ ": smb_krb5_parse_name(%s) "
     545                          "failed (%s)\n", host_princ_s, error_message(ret)));
     546                goto out;
     547        }
     548
     549
     550        if (use_replay_cache) {
     551
     552                /* Lock a mutex surrounding the replay as there is no
     553                   locking in the MIT krb5 code surrounding the replay
    512554                   cache... */
    513555
    514                 mutex = grab_named_mutex(talloc_tos(), "replay cache mutex",
    515                                          10);
     556                mutex = grab_named_mutex(talloc_tos(),
     557                                         "replay cache mutex", 10);
    516558                if (mutex == NULL) {
    517                         DEBUG(1,("ads_verify_ticket: unable to protect "
    518                                  "replay cache with mutex.\n"));
     559                        DEBUG(1, (__location__ ": unable to protect replay "
     560                                  "cache with mutex.\n"));
    519561                        ret = KRB5_CC_IO;
    520562                        goto out;
    521563                }
    522564
    523                 /* JRA. We must set the rcache here. This will prevent 
     565                /* JRA. We must set the rcache here. This will prevent
    524566                   replay attacks. */
    525                
    526                 ret = krb5_get_server_rcache(context,
    527                                              krb5_princ_component(context, host_princ, 0),
    528                                              &rcache);
     567
     568                ret = krb5_get_server_rcache(
     569                                context,
     570                                krb5_princ_component(context, host_princ, 0),
     571                                &rcache);
    529572                if (ret) {
    530                         DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache "
    531                                  "failed (%s)\n", error_message(ret)));
     573                        DEBUG(1, (__location__ ": krb5_get_server_rcache "
     574                                  "failed (%s)\n", error_message(ret)));
    532575                        goto out;
    533576                }
     
    535578                ret = krb5_auth_con_setrcache(context, auth_context, rcache);
    536579                if (ret) {
    537                         DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache "
    538                                  "failed (%s)\n", error_message(ret)));
     580                        DEBUG(1, (__location__ ": krb5_auth_con_setrcache "
     581                                  "failed (%s)\n", error_message(ret)));
    539582                        goto out;
    540583                }
     
    575618        }
    576619
    577         if ( use_replay_cache ) {               
     620        if (use_replay_cache) {
    578621                TALLOC_FREE(mutex);
    579622#if 0
     
    583626                }
    584627#endif
    585         }       
     628        }
    586629
    587630        if (!auth_ok) {
    588                 DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n",
    589                          error_message(ret)));
     631                DEBUG(3, (__location__ ": krb5_rd_req with auth "
     632                          "failed (%s)\n", error_message(ret)));
    590633                /* Try map the error return in case it's something like
    591634                 * a clock skew error.
    592635                 */
    593636                sret = krb5_to_nt_status(ret);
    594                 if (NT_STATUS_IS_OK(sret) || NT_STATUS_EQUAL(sret,NT_STATUS_UNSUCCESSFUL)) {
     637                if (NT_STATUS_IS_OK(sret) ||
     638                    NT_STATUS_EQUAL(sret,NT_STATUS_UNSUCCESSFUL)) {
    595639                        sret = NT_STATUS_LOGON_FAILURE;
    596640                }
    597                 DEBUG(10,("ads_verify_ticket: returning error %s\n",
    598                         nt_errstr(sret) ));
    599                 goto out;
    600         } 
    601        
     641                DEBUG(10, (__location__ ": returning error %s\n",
     642                           nt_errstr(sret) ));
     643                goto out;
     644        }
     645
    602646        authtime = get_authtime_from_tkt(tkt);
    603647        client_principal = get_principal_from_tkt(tkt);
     
    605649        ret = krb5_mk_rep(context, auth_context, &packet);
    606650        if (ret) {
    607                 DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n",
    608                         error_message(ret)));
     651                DEBUG(3, (__location__ ": Failed to generate mutual "
     652                          "authentication reply (%s)\n", error_message(ret)));
    609653                goto out;
    610654        }
     
    616660        }
    617661
    618         get_krb5_smb_session_key(context, auth_context, session_key, True);
    619         dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length);
     662        get_krb5_smb_session_key(mem_ctx, context,
     663                                 auth_context, session_key, true);
     664        dump_data_pw("SMB session key (from ticket)\n",
     665                     session_key->data, session_key->length);
    620666
    621667#if 0
     
    623669#endif
    624670
    625         /* continue when no PAC is retrieved or we couldn't decode the PAC 
     671        /* continue when no PAC is retrieved or we couldn't decode the PAC
    626672           (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set, or
    627673           Kerberos tickets encrypted using a DES key) - Guenther */
     
    629675        got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt);
    630676        if (!got_auth_data) {
    631                 DEBUG(3,("ads_verify_ticket: did not retrieve auth data. continuing without PAC\n"));
     677                DEBUG(3, (__location__ ": did not retrieve auth data. "
     678                          "continuing without PAC\n"));
    632679        }
    633680
    634681        if (got_auth_data) {
    635                 pac_ret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data);
     682                struct PAC_DATA *pac_data;
     683                pac_ret = decode_pac_data(mem_ctx, &auth_data, context,
     684                                          keyblock, client_principal,
     685                                          authtime, &pac_data);
     686                data_blob_free(&auth_data);
    636687                if (!NT_STATUS_IS_OK(pac_ret)) {
    637                         DEBUG(3,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(pac_ret)));
    638                         *pac_data = NULL;
    639                 }
    640                 data_blob_free(&auth_data);
     688                        DEBUG(3, (__location__ ": failed to decode "
     689                                  "PAC_DATA: %s\n", nt_errstr(pac_ret)));
     690                } else {
     691                        uint32_t i;
     692                        for (i = 0; i < pac_data->num_buffers; i++) {
     693
     694                                if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) {
     695                                        continue;
     696                                }
     697
     698                                *logon_info = pac_data->buffers[i].info->logon_info.info;
     699                        }
     700
     701                        if (!*logon_info) {
     702                                DEBUG(1, ("correctly decoded PAC but found "
     703                                          "no logon_info! "
     704                                          "This should not happen\n"));
     705                                return NT_STATUS_INVALID_USER_BUFFER;
     706                        }
     707                }
    641708        }
    642709
     
    659726#endif
    660727
    661         if ((ret = smb_krb5_unparse_name(mem_ctx, context, client_principal, principal))) {
    662                 DEBUG(3,("ads_verify_ticket: smb_krb5_unparse_name failed (%s)\n",
    663                          error_message(ret)));
     728        ret = smb_krb5_unparse_name(mem_ctx, context,
     729                                    client_principal, principal);
     730        if (ret) {
     731                DEBUG(3, (__location__ ": smb_krb5_unparse_name "
     732                          "failed (%s)\n", error_message(ret)));
    664733                sret = NT_STATUS_LOGON_FAILURE;
    665734                goto out;
     
    668737        sret = NT_STATUS_OK;
    669738
    670  out:
     739out:
    671740
    672741        TALLOC_FREE(mutex);
  • vendor/current/source3/libads/krb5_setpw.c

    r414 r740  
    2121#include "includes.h"
    2222#include "smb_krb5.h"
     23#include "libads/kerberos_proto.h"
     24#include "../lib/util/asn1.h"
    2325
    2426#ifdef HAVE_KRB5
     
    574576        krb5_error_code ret = 0;
    575577        krb5_context context = NULL;
    576         krb5_principal principal = NULL;
    577         char *princ_name = NULL;
    578         char *realm = NULL;
     578        const char *realm = NULL;
     579        unsigned int realm_len = 0;
    579580        krb5_creds creds, *credsp = NULL;
    580 #if KRB5_PRINC_REALM_RETURNS_REALM
    581         krb5_realm orig_realm;
    582 #else
    583         krb5_data orig_realm;
    584 #endif
    585581        krb5_ccache ccache = NULL;
    586582
     
    605601        }
    606602
    607         realm = strchr_m(princ, '@');
    608         if (!realm) {
    609                 krb5_cc_close(context, ccache);
    610                 krb5_free_context(context);
    611                 DEBUG(1,("Failed to get realm\n"));
    612                 return ADS_ERROR_KRB5(-1);
    613         }
    614         realm++;
    615 
    616         if (asprintf(&princ_name, "kadmin/changepw@%s", realm) == -1) {
     603        ret = krb5_cc_get_principal(context, ccache, &creds.client);
     604        if (ret) {
    617605                krb5_cc_close(context, ccache);
    618606                krb5_free_context(context);
    619                 DEBUG(1,("asprintf failed\n"));
    620                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    621         }
    622 
    623         ret = smb_krb5_parse_name(context, princ_name, &creds.server);
    624         if (ret) {
    625                 krb5_cc_close(context, ccache);
    626                 krb5_free_context(context);
    627                 DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret)));
    628                 return ADS_ERROR_KRB5(ret);
    629         }
    630 
    631         /* parse the principal we got as a function argument */
    632         ret = smb_krb5_parse_name(context, princ, &principal);
    633         if (ret) {
    634                 krb5_cc_close(context, ccache);
    635                 krb5_free_principal(context, creds.server);
    636                 krb5_free_context(context);
    637                 DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret)));
    638                 free(princ_name);
    639                 return ADS_ERROR_KRB5(ret);
    640         }
    641 
    642         free(princ_name);
    643 
    644         /* The creds.server principal takes ownership of this memory.
    645                 Remember to set back to original value before freeing. */
    646         orig_realm = *krb5_princ_realm(context, creds.server);
    647         krb5_princ_set_realm(context, creds.server, krb5_princ_realm(context, principal));
    648        
    649         ret = krb5_cc_get_principal(context, ccache, &creds.client);
    650         if (ret) {
    651                 krb5_cc_close(context, ccache);
    652                 krb5_princ_set_realm(context, creds.server, &orig_realm);
    653                 krb5_free_principal(context, creds.server);
    654                 krb5_free_principal(context, principal);
    655                 krb5_free_context(context);
    656                 DEBUG(1,("Failed to get principal from ccache (%s)\n",
     607                DEBUG(1,("Failed to get principal from ccache (%s)\n",
    657608                         error_message(ret)));
    658609                return ADS_ERROR_KRB5(ret);
    659610        }
    660        
    661         ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
     611
     612        realm = smb_krb5_principal_get_realm(context, creds.client);
     613        realm_len = strlen(realm);
     614        ret = krb5_build_principal(context,
     615                                   &creds.server,
     616                                   realm_len,
     617                                   realm, "kadmin", "changepw", NULL);
     618
     619        ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
    662620        if (ret) {
    663621                krb5_cc_close(context, ccache);
    664622                krb5_free_principal(context, creds.client);
    665                 krb5_princ_set_realm(context, creds.server, &orig_realm);
    666623                krb5_free_principal(context, creds.server);
    667                 krb5_free_principal(context, principal);
     624                krb5_free_context(context);
     625                DEBUG(1,("krb5_build_prinipal_ext (%s)\n", error_message(ret)));
     626                return ADS_ERROR_KRB5(ret);
     627        }
     628       
     629        ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
     630        if (ret) {
     631                krb5_cc_close(context, ccache);
     632                krb5_free_principal(context, creds.client);
     633                krb5_free_principal(context, creds.server);
    668634                krb5_free_context(context);
    669635                DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret)));
     
    679645        krb5_free_creds(context, credsp);
    680646        krb5_free_principal(context, creds.client);
    681         krb5_princ_set_realm(context, creds.server, &orig_realm);
    682647        krb5_free_principal(context, creds.server);
    683         krb5_free_principal(context, principal);
    684648        krb5_cc_close(context, ccache);
    685649        krb5_free_context(context);
     
    729693    krb5_creds creds;
    730694    char *chpw_princ = NULL, *password;
     695    const char *realm = NULL;
    731696
    732697    initialize_krb5_error_table();
     
    750715    krb5_get_init_creds_opt_set_proxiable(&opts, 0);
    751716
     717    realm = smb_krb5_principal_get_realm(context, princ);
     718
    752719    /* We have to obtain an INITIAL changepw ticket for changing password */
    753     if (asprintf(&chpw_princ, "kadmin/changepw@%s",
    754                                 (char *) krb5_princ_realm(context, princ)) == -1) {
     720    if (asprintf(&chpw_princ, "kadmin/changepw@%s", realm) == -1) {
    755721        krb5_free_context(context);
    756722        DEBUG(1,("ads_krb5_chg_password: asprintf fail\n"));
     
    807773}
    808774
    809 
    810 /**
    811  * Set the machine account password
    812  * @param ads connection to ads server
    813  * @param hostname machine whose password is being set
    814  * @param password new password
    815  * @return status of password change
    816  **/
    817 ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
    818                                     const char *machine_account,
    819                                     const char *password)
    820 {
    821         ADS_STATUS status;
    822         char *principal = NULL;
    823 
    824         /*
    825           we need to use the '$' form of the name here (the machine account name),
    826           as otherwise the server might end up setting the password for a user
    827           instead
    828          */
    829         if (asprintf(&principal, "%s@%s", machine_account, ads->config.realm) < 0) {
    830                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    831         }
    832        
    833         status = ads_krb5_set_password(ads->auth.kdc_server, principal,
    834                                        password, ads->auth.time_offset);
    835        
    836         SAFE_FREE(principal);
    837         return status;
    838 }
    839775#endif
  • vendor/current/source3/libads/ldap.c

    r581 r740  
    2323
    2424#include "includes.h"
    25 #include "lib/ldb/include/ldb.h"
     25#include "ads.h"
     26#include "libads/sitename_cache.h"
     27#include "libads/cldap.h"
     28#include "libads/dns.h"
     29#include "../libds/common/flags.h"
     30#include "smbldap.h"
     31#include "../libcli/security/security.h"
    2632
    2733#ifdef HAVE_LDAP
     
    4955****************************************************************/
    5056
    51 static void gotalarm_sig(void)
     57static void gotalarm_sig(int signum)
    5258{
    5359        gotalarm = 1;
     
    6470        /* Setup timeout */
    6571        gotalarm = 0;
    66         CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
     72        CatchSignal(SIGALRM, gotalarm_sig);
    6773        alarm(to);
    6874        /* End setup timeout. */
     
    7884
    7985        /* Teardown timeout. */
    80         CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
     86        CatchSignal(SIGALRM, SIG_IGN);
    8187        alarm(0);
    8288
     
    104110        /* Setup alarm timeout.... Do we need both of these ? JRA. */
    105111        gotalarm = 0;
    106         CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
     112        CatchSignal(SIGALRM, gotalarm_sig);
    107113        alarm(lp_ldap_timeout());
    108114        /* End setup timeout. */
     
    113119
    114120        /* Teardown timeout. */
    115         CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
     121        CatchSignal(SIGALRM, SIG_IGN);
    116122        alarm(0);
    117123
     
    265271                        SMB_STRDUP(cldap_reply.client_site);
    266272        }
    267         ads->server.workgroup          = SMB_STRDUP(cldap_reply.domain);
     273        ads->server.workgroup          = SMB_STRDUP(cldap_reply.domain_name);
    268274
    269275        ads->ldap.port = gc ? LDAP_GC_PORT : LDAP_PORT;
     
    277283
    278284        /* Store our site name. */
    279         sitename_store( cldap_reply.domain, cldap_reply.client_site);
     285        sitename_store( cldap_reply.domain_name, cldap_reply.client_site);
    280286        sitename_store( cldap_reply.dns_domain, cldap_reply.client_site);
    281287
     
    593599
    594600        ZERO_STRUCT(ads->ldap);
    595         ads->ldap.last_attempt  = time(NULL);
     601        ads->ldap.last_attempt  = time_mono(NULL);
    596602        ads->ldap.wrap_type     = ADS_SASLWRAP_TYPE_PLAIN;
    597603
     
    16021608        if (!org_unit || !*org_unit) {
    16031609
    1604                 ret = ads_default_ou_string(ads, WELL_KNOWN_GUID_COMPUTERS);
     1610                ret = ads_default_ou_string(ads, DS_GUID_COMPUTERS_CONTAINER);
    16051611
    16061612                /* samba4 might not yet respond to a wellknownobject-query */
     
    21232129        int i;
    21242130        for (i=0; values[i]; i++) {
    2125 
    2126                 UUID_FLAT guid;
    2127                 struct GUID tmp;
    2128 
    2129                 memcpy(guid.info, values[i]->bv_val, sizeof(guid.info));
    2130                 smb_uuid_unpack(guid, &tmp);
    2131                 printf("%s: %s\n", field, GUID_string(talloc_tos(), &tmp));
     2131                NTSTATUS status;
     2132                DATA_BLOB in = data_blob_const(values[i]->bv_val, values[i]->bv_len);
     2133                struct GUID guid;
     2134
     2135                status = GUID_from_ndr_blob(&in, &guid);
     2136                if (NT_STATUS_IS_OK(status)) {
     2137                        printf("%s: %s\n", field, GUID_string(talloc_tos(), &guid));
     2138                } else {
     2139                        printf("%s: INVALID GUID\n", field);
     2140                }
    21322141        }
    21332142}
     
    21402149        int i;
    21412150        for (i=0; values[i]; i++) {
    2142                 DOM_SID sid;
     2151                struct dom_sid sid;
    21432152                fstring tmp;
    21442153                if (!sid_parse(values[i]->bv_val, values[i]->bv_len, &sid)) {
    2145                         continue;
     2154                        return;
    21462155                }
    21472156                printf("%s: %s\n", field, sid_to_fstring(tmp, &sid));
     
    26052614 bool ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct GUID *guid)
    26062615{
    2607         char **values;
    2608         UUID_FLAT flat_guid;
    2609 
    2610         values = ldap_get_values(ads->ldap.ld, msg, "objectGUID");
    2611         if (!values)
    2612                 return False;
    2613 
    2614         if (values[0]) {
    2615                 memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT));
    2616                 smb_uuid_unpack(flat_guid, guid);
    2617                 ldap_value_free(values);
    2618                 return True;
    2619         }
    2620         ldap_value_free(values);
    2621         return False;
    2622 
    2623 }
    2624 
    2625 
    2626 /**
    2627  * pull a single DOM_SID from a ADS result
     2616        DATA_BLOB blob;
     2617        NTSTATUS status;
     2618
     2619        if (!smbldap_talloc_single_blob(talloc_tos(), ads->ldap.ld, msg, "objectGUID",
     2620                                        &blob)) {
     2621                return false;
     2622        }
     2623
     2624        status = GUID_from_ndr_blob(&blob, guid);
     2625        talloc_free(blob.data);
     2626        return NT_STATUS_IS_OK(status);
     2627}
     2628
     2629
     2630/**
     2631 * pull a single struct dom_sid from a ADS result
    26282632 * @param ads connection to ads server
    26292633 * @param msg Results of search
     
    26332637*/
    26342638 bool ads_pull_sid(ADS_STRUCT *ads, LDAPMessage *msg, const char *field,
    2635                    DOM_SID *sid)
     2639                   struct dom_sid *sid)
    26362640{
    26372641        return smbldap_pull_sid(ads->ldap.ld, msg, field, sid);
     
    26392643
    26402644/**
    2641  * pull an array of DOM_SIDs from a ADS result
     2645 * pull an array of struct dom_sids from a ADS result
    26422646 * @param ads connection to ads server
    26432647 * @param mem_ctx TALLOC_CTX for allocating sid array
     
    26482652 **/
    26492653 int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
    2650                    LDAPMessage *msg, const char *field, DOM_SID **sids)
     2654                   LDAPMessage *msg, const char *field, struct dom_sid **sids)
    26512655{
    26522656        struct berval **values;
     
    26632667
    26642668        if (i) {
    2665                 (*sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, i);
     2669                (*sids) = TALLOC_ARRAY(mem_ctx, struct dom_sid, i);
    26662670                if (!(*sids)) {
    26672671                        ldap_value_free_len(values);
     
    26872691
    26882692/**
    2689  * pull a SEC_DESC from a ADS result
     2693 * pull a struct security_descriptor from a ADS result
    26902694 * @param ads connection to ads server
    26912695 * @param mem_ctx TALLOC_CTX for allocating sid array
    26922696 * @param msg Results of search
    26932697 * @param field Attribute to retrieve
    2694  * @param sd Pointer to *SEC_DESC to store result (talloc()ed)
     2698 * @param sd Pointer to *struct security_descriptor to store result (talloc()ed)
    26952699 * @return boolean inidicating success
    26962700*/
    26972701 bool ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
    2698                   LDAPMessage *msg, const char *field, SEC_DESC **sd)
     2702                  LDAPMessage *msg, const char *field,
     2703                  struct security_descriptor **sd)
    26992704{
    27002705        struct berval **values;
     
    29282933 * @return status of search
    29292934 **/
    2930 ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid)
     2935ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, struct dom_sid *sid)
    29312936{
    29322937        const char *attrs[] = {"objectSid", NULL};
     
    31673172
    31683173/**
    3169  * pull a DOM_SID from an extended dn string
     3174 * pull a struct dom_sid from an extended dn string
    31703175 * @param mem_ctx TALLOC_CTX
    31713176 * @param extended_dn string
    31723177 * @param flags string type of extended_dn
    3173  * @param sid pointer to a DOM_SID
     3178 * @param sid pointer to a struct dom_sid
    31743179 * @return NT_STATUS_OK on success,
    31753180 *         NT_INVALID_PARAMETER on error,
     
    31793184                                        const char *extended_dn,
    31803185                                        enum ads_extended_dn_flags flags,
    3181                                         DOM_SID *sid)
     3186                                        struct dom_sid *sid)
    31823187{
    31833188        char *p, *q, *dn;
     
    32543259
    32553260/**
    3256  * pull an array of DOM_SIDs from a ADS result
     3261 * pull an array of struct dom_sids from a ADS result
    32573262 * @param ads connection to ads server
    32583263 * @param mem_ctx TALLOC_CTX for allocating sid array
     
    32683273                                   const char *field,
    32693274                                   enum ads_extended_dn_flags flags,
    3270                                    DOM_SID **sids)
     3275                                   struct dom_sid **sids)
    32713276{
    32723277        int i;
     
    32803285        }
    32813286
    3282         (*sids) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, dn_count + 1);
     3287        (*sids) = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, dn_count + 1);
    32833288        if (!(*sids)) {
    32843289                TALLOC_FREE(dn_strings);
     
    34983503
    34993504        hostnameDN = ads_get_dn(ads, talloc_tos(), (LDAPMessage *)msg);
     3505        if (hostnameDN == NULL) {
     3506                SAFE_FREE(host);
     3507                return ADS_ERROR_SYSTEM(ENOENT);
     3508        }
    35003509
    35013510        rc = ldap_delete_ext_s(ads->ldap.ld, hostnameDN, pldap_control, NULL);
     
    35853594 * @param mem_ctx TALLOC_CTX for allocating sid array
    35863595 * @param dn of LDAP object
    3587  * @param user_sid pointer to DOM_SID (objectSid)
    3588  * @param primary_group_sid pointer to DOM_SID (self composed)
     3596 * @param user_sid pointer to struct dom_sid (objectSid)
     3597 * @param primary_group_sid pointer to struct dom_sid (self composed)
    35893598 * @param sids pointer to sid array to allocate
    35903599 * @param num_sids counter of SIDs pulled
     
    35943603                              TALLOC_CTX *mem_ctx,
    35953604                              const char *dn,
    3596                               DOM_SID *user_sid,
    3597                               DOM_SID *primary_group_sid,
    3598                               DOM_SID **sids,
     3605                              struct dom_sid *user_sid,
     3606                              struct dom_sid *primary_group_sid,
     3607                              struct dom_sid **sids,
    35993608                              size_t *num_sids)
    36003609{
     
    36033612        int count = 0;
    36043613        size_t tmp_num_sids;
    3605         DOM_SID *tmp_sids;
    3606         DOM_SID tmp_user_sid;
    3607         DOM_SID tmp_primary_group_sid;
     3614        struct dom_sid *tmp_sids;
     3615        struct dom_sid tmp_user_sid;
     3616        struct dom_sid tmp_primary_group_sid;
    36083617        uint32 pgid;
    36093618        const char *attrs[] = {
     
    36393648                 * domsid */
    36403649
    3641                 DOM_SID domsid;
    3642                 uint32 dummy_rid;
     3650                struct dom_sid domsid;
    36433651
    36443652                sid_copy(&domsid, &tmp_user_sid);
    36453653
    3646                 if (!sid_split_rid(&domsid, &dummy_rid)) {
     3654                if (!sid_split_rid(&domsid, NULL)) {
    36473655                        ads_msgfree(ads, res);
    36483656                        return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
  • vendor/current/source3/libads/ldap_printer.c

    r427 r740  
    1919
    2020#include "includes.h"
    21 #include "../librpc/gen_ndr/cli_spoolss.h"
     21#include "ads.h"
     22#include "rpc_client/rpc_client.h"
     23#include "../librpc/gen_ndr/ndr_spoolss_c.h"
     24#include "rpc_client/cli_spoolss.h"
     25#include "registry/reg_objects.h"
    2226
    2327#ifdef HAVE_ADS
     
    4347        }
    4448        if (ads_count_replies(ads, *res) != 1) {
    45                 if (res) {
    46                         ads_msgfree(ads, *res);
    47                         *res = NULL;
    48                 }
     49                ads_msgfree(ads, *res);
     50                *res = NULL;
    4951                return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
    5052        }
    5153        srv_dn = ldap_get_dn(ads->ldap.ld, *res);
    5254        if (srv_dn == NULL) {
    53                 if (res) {
    54                         ads_msgfree(ads, *res);
    55                         *res = NULL;
    56                 }
     55                ads_msgfree(ads, *res);
     56                *res = NULL;
    5757                return ADS_ERROR(LDAP_NO_MEMORY);
    5858        }
     
    6060        if (srv_cn == NULL) {
    6161                ldap_memfree(srv_dn);
    62                 if (res) {
    63                         ads_msgfree(ads, *res);
    64                         *res = NULL;
    65                 }
    66                 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
    67         }
    68         if (res) {
    6962                ads_msgfree(ads, *res);
    7063                *res = NULL;
    71         }
     64                return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
     65        }
     66        ads_msgfree(ads, *res);
     67        *res = NULL;
    7268
    7369        if (asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer) == -1) {
     
    120116*/
    121117static bool map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
    122                    const struct regval_blob *value)
     118                   struct regval_blob *value)
    123119{
    124120        char *str_value = NULL;
     
    126122        ADS_STATUS status;
    127123
    128         if (value->type != REG_SZ)
     124        if (regval_type(value) != REG_SZ)
    129125                return false;
    130126
    131         if (value->size && *((smb_ucs2_t *) value->data_p)) {
     127        if (regval_size(value) && *((smb_ucs2_t *) regval_data_p(value))) {
    132128                if (!pull_ucs2_talloc(ctx, &str_value,
    133                                       (const smb_ucs2_t *) value->data_p,
     129                                      (const smb_ucs2_t *) regval_data_p(value),
    134130                                      &converted_size))
    135131                {
    136132                        return false;
    137133                }
    138                 status = ads_mod_str(ctx, mods, value->valuename, str_value);
     134                status = ads_mod_str(ctx, mods, regval_name(value), str_value);
    139135                return ADS_ERR_OK(status);
    140136        }
     
    147143*/
    148144static bool map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods,
    149                       const struct regval_blob *value)
     145                      struct regval_blob *value)
    150146{
    151147        char *str_value = NULL;
    152148        ADS_STATUS status;
    153149
    154         if (value->type != REG_DWORD)
    155                 return False;
    156         str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
     150        if (regval_type(value) != REG_DWORD)
     151                return False;
     152        str_value = talloc_asprintf(ctx, "%d", *((uint32 *) regval_data_p(value)));
    157153        if (!str_value) {
    158154                return False;
    159155        }
    160         status = ads_mod_str(ctx, mods, value->valuename, str_value);
     156        status = ads_mod_str(ctx, mods, regval_name(value), str_value);
    161157        return ADS_ERR_OK(status);
    162158}
     
    166162*/
    167163static bool map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
    168                      const struct regval_blob *value)
     164                     struct regval_blob *value)
    169165{
    170166        char *str_value;
    171167        ADS_STATUS status;
    172168
    173         if ((value->type != REG_BINARY) || (value->size != 1))
     169        if ((regval_type(value) != REG_BINARY) || (regval_size(value) != 1))
    174170                return False;
    175171        str_value =  talloc_asprintf(ctx, "%s",
    176                                      *(value->data_p) ? "TRUE" : "FALSE");
     172                                     *(regval_data_p(value)) ? "TRUE" : "FALSE");
    177173        if (!str_value) {
    178174                return False;
    179175        }
    180         status = ads_mod_str(ctx, mods, value->valuename, str_value);
     176        status = ads_mod_str(ctx, mods, regval_name(value), str_value);
    181177        return ADS_ERR_OK(status);
    182178}
     
    186182*/
    187183static bool map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
    188                          const struct regval_blob *value)
     184                         struct regval_blob *value)
    189185{
    190186        char **str_values = NULL;
    191187        size_t converted_size;
    192         smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
     188        smb_ucs2_t *cur_str = (smb_ucs2_t *) regval_data_p(value);
    193189        uint32 size = 0, num_vals = 0, i=0;
    194190        ADS_STATUS status;
    195191
    196         if (value->type != REG_MULTI_SZ)
    197                 return False;
    198 
    199         while(cur_str && *cur_str && (size < value->size)) {           
     192        if (regval_type(value) != REG_MULTI_SZ)
     193                return False;
     194
     195        while(cur_str && *cur_str && (size < regval_size(value))) {
    200196                size += 2 * (strlen_w(cur_str) + 1);
    201197                cur_str += strlen_w(cur_str) + 1;
     
    211207                       (num_vals + 1) * sizeof(char *));
    212208
    213                 cur_str = (smb_ucs2_t *) value->data_p;
     209                cur_str = (smb_ucs2_t *) regval_data_p(value);
    214210                for (i=0; i < num_vals; i++) {
    215211                        cur_str += pull_ucs2_talloc(ctx, &str_values[i],
     
    218214                }
    219215
    220                 status = ads_mod_strlist(ctx, mods, value->valuename,
     216                status = ads_mod_strlist(ctx, mods, regval_name(value),
    221217                                         (const char **) str_values);
    222218                return ADS_ERR_OK(status);
     
    227223struct valmap_to_ads {
    228224        const char *valname;
    229         bool (*fn)(TALLOC_CTX *, ADS_MODLIST *, const struct regval_blob *);
     225        bool (*fn)(TALLOC_CTX *, ADS_MODLIST *, struct regval_blob *);
    230226};
    231227
     
    294290
    295291        for (i=0; map[i].valname; i++) {
    296                 if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
     292                if (StrCaseCmp(map[i].valname, regval_name(value)) == 0) {
    297293                        if (!map[i].fn(ctx, mods, value)) {
    298                                 DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
     294                                DEBUG(5, ("Add of value %s to modlist failed\n", regval_name(value)));
    299295                        } else {
    300                                 DEBUG(7, ("Mapped value %s\n", value->valuename));
     296                                DEBUG(7, ("Mapped value %s\n", regval_name(value)));
    301297                        }
    302298                       
     
    311307                                          const char *printer)
    312308{
     309        struct dcerpc_binding_handle *b = cli->binding_handle;
    313310        WERROR result;
    314311        char *printername;
     
    317314        uint32 i;
    318315        struct policy_handle pol;
     316        WERROR werr;
    319317
    320318        if ((asprintf(&printername, "%s\\%s", cli->srv_name_slash, printer) == -1)) {
     
    346344                /* Have the data we need now, so start building */
    347345                for (i=0; i < count; i++) {
    348                         struct regval_blob v;
    349 
    350                         fstrcpy(v.valuename, info[i].value_name);
    351                         v.type = info[i].type;
    352                         v.data_p = info[i].data->data;
    353                         v.size = info[i].data->length;
    354 
    355                         map_regval_to_ads(mem_ctx, mods, &v);
     346                        struct regval_blob *v;
     347
     348                        v = regval_compose(mem_ctx, info[i].value_name,
     349                                           info[i].type,
     350                                           info[i].data->data,
     351                                           info[i].data->length);
     352                        if (v == NULL) {
     353                                return WERR_NOMEM;
     354                        }
     355
     356                        map_regval_to_ads(mem_ctx, mods, v);
     357                        talloc_free(v);
    356358                }
    357359        }
     
    367369        } else {
    368370                for (i=0; i < count; i++) {
    369                         struct regval_blob v;
    370 
    371                         fstrcpy(v.valuename, info[i].value_name);
    372                         v.type = info[i].type;
    373                         v.data_p = info[i].data->data;
    374                         v.size = info[i].data->length;
    375 
    376                         map_regval_to_ads(mem_ctx, mods, &v);
     371                        struct regval_blob *v;
     372
     373                        v = regval_compose(mem_ctx, info[i].value_name,
     374                                           info[i].type,
     375                                           info[i].data->data,
     376                                           info[i].data->length);
     377                        if (v == NULL) {
     378                                return WERR_NOMEM;
     379                        }
     380
     381                        map_regval_to_ads(mem_ctx, mods, v);
     382                        talloc_free(v);
    377383                }
    378384        }
     
    380386        ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
    381387
    382         rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
     388        dcerpc_spoolss_ClosePrinter(b, mem_ctx, &pol, &werr);
    383389        SAFE_FREE(printername);
    384390
     
    386392}
    387393
    388 bool get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
    389                                        ADS_MODLIST *mods,
    390                                        NT_PRINTER_DATA *data)
    391 {
    392         uint32 key,val;
    393 
    394         for (key=0; key < data->num_keys; key++) {
    395                 struct regval_ctr *ctr = data->keys[key].values;
    396                 for (val=0; val < ctr->num_values; val++)
    397                         map_regval_to_ads(mem_ctx, mods, ctr->values[val]);
    398         }
    399         return True;
    400 }
    401 
    402394#endif
  • vendor/current/source3/libads/ldap_schema.c

    r414 r740  
    2020
    2121#include "includes.h"
     22#include "ads.h"
     23#include "libads/ldap_schema.h"
     24#include "../libcli/ldap/ldap_ndr.h"
    2225
    2326#ifdef HAVE_LDAP
    2427
    25 ADS_STATUS ads_get_attrnames_by_oids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
    26                                      const char *schema_path,
    27                                      const char **OIDs, size_t num_OIDs,
    28                                      char ***OIDs_out, char ***names, size_t *count)
     28static ADS_STATUS ads_get_attrnames_by_oids(ADS_STRUCT *ads,
     29                                            TALLOC_CTX *mem_ctx,
     30                                            const char *schema_path,
     31                                            const char **OIDs,
     32                                            size_t num_OIDs,
     33                                            char ***OIDs_out, char ***names,
     34                                            size_t *count)
    2935{
    3036        ADS_STATUS status;
     
    123129        }
    124130
    125         guid_bin = guid_binstring(mem_ctx, schema_guid);
     131        guid_bin = ldap_encode_ndr_GUID(mem_ctx, schema_guid);
    126132        if (!guid_bin) {
    127133                goto done;
     
    152158}
    153159
    154 const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, const char *schema_path, TALLOC_CTX *mem_ctx, const char * OID)
    155 {
    156         ADS_STATUS rc;
    157         int count = 0;
    158         LDAPMessage *res = NULL;
    159         char *expr = NULL;
    160         const char *attrs[] = { "lDAPDisplayName", NULL };
    161         char *result;
    162 
    163         if (ads == NULL || mem_ctx == NULL || OID == NULL) {
    164                 goto failed;
    165         }
    166 
    167         expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID);
    168         if (expr == NULL) {
    169                 goto failed;
    170         }
    171 
    172         rc = ads_do_search_retry(ads, schema_path, LDAP_SCOPE_SUBTREE,
    173                 expr, attrs, &res);
    174         if (!ADS_ERR_OK(rc)) {
    175                 goto failed;
    176         }
    177 
    178         count = ads_count_replies(ads, res);
    179         if (count == 0 || !res) {
    180                 goto failed;
    181         }
    182 
    183         result = ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName");
    184         ads_msgfree(ads, res);
    185 
    186         return result;
    187        
    188 failed:
    189         DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n",
    190                 OID));
    191        
    192         ads_msgfree(ads, res);
    193         return NULL;
    194 }
    195160/*********************************************************************
    196161*********************************************************************/
  • vendor/current/source3/libads/ldap_user.c

    r414 r740  
    1919
    2020#include "includes.h"
     21#include "ads.h"
     22#include "../libds/common/flags.h"
    2123
    2224#ifdef HAVE_ADS
  • vendor/current/source3/libads/ldap_utils.c

    r414 r740  
    66   Copyright (C) Andrew Tridgell 2001
    77   Copyright (C) Guenther Deschner 2006,2007
    8    
     8
    99   This program is free software; you can redistribute it and/or modify
    1010   it under the terms of the GNU General Public License as published by
    1111   the Free Software Foundation; either version 3 of the License, or
    1212   (at your option) any later version.
    13    
     13
    1414   This program is distributed in the hope that it will be useful,
    1515   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1616   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1717   GNU General Public License for more details.
    18    
     18
    1919   You should have received a copy of the GNU General Public License
    2020   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2222
    2323#include "includes.h"
     24#include "ads.h"
    2425
    2526#ifdef HAVE_LDAP
     27
     28static ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads,
     29                                             TALLOC_CTX *mem_ctx,
     30                                             int scope,
     31                                             const char *base,
     32                                             const char *filter,
     33                                             const char **attrs,
     34                                             void *args,
     35                                             const char *range_attr,
     36                                             char ***strings,
     37                                             size_t *num_strings,
     38                                             uint32 *first_usn,
     39                                             int *num_retries,
     40                                             bool *more_values);
     41
    2642/*
    2743  a wrapper around ldap_search_s that retries depending on the error code
     
    4056
    4157        if (!ads->ldap.ld &&
    42             time(NULL) - ads->ldap.last_attempt < ADS_RECONNECT_TIME) {
     58            time_mono(NULL) - ads->ldap.last_attempt < ADS_RECONNECT_TIME) {
    4359                return ADS_ERROR(LDAP_SERVER_DOWN);
    4460        }
     
    7288                        ads_msgfree(ads, *res);
    7389                *res = NULL;
    74                
     90
    7591                DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n",
    7692                         ads->config.realm, ads_errstr(status)));
    77                          
     93
    7894                ads_disconnect(ads);
    7995                status = ads_connect(ads);
    80                
     96
    8197                if (!ADS_ERR_OK(status)) {
    8298                        DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n",
     
    121137}
    122138
    123  ADS_STATUS ads_do_search_retry_args(ADS_STRUCT *ads, const char *bind_path,
    124                                      int scope, const char *expr,
    125                                      const char **attrs, void *args,
    126                                      LDAPMessage **res)
     139static ADS_STATUS ads_do_search_retry_args(ADS_STRUCT *ads, const char *bind_path,
     140                                           int scope, const char *expr,
     141                                           const char **attrs, void *args,
     142                                           LDAPMessage **res)
    127143{
    128144        return ads_do_search_retry_internal(ads, bind_path, scope, expr, attrs, args, res);
     
    143159        return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE,
    144160                                   "(objectclass=*)", attrs, res);
    145 }
    146 
    147  ADS_STATUS ads_search_retry_extended_dn(ADS_STRUCT *ads, LDAPMessage **res,
    148                                          const char *dn,
    149                                          const char **attrs,
    150                                          enum ads_extended_dn_flags flags)
    151 {
    152         ads_control args;
    153 
    154         args.control = ADS_EXTENDED_DN_OID;
    155         args.val = flags;
    156         args.critical = True;
    157 
    158         return ads_do_search_retry_args(ads, dn, LDAP_SCOPE_BASE,
    159                                         "(objectclass=*)", attrs, &args, res);
    160161}
    161162
     
    200201
    201202 ADS_STATUS ads_search_retry_sid(ADS_STRUCT *ads, LDAPMessage **res,
    202                                  const DOM_SID *sid,
     203                                 const struct dom_sid *sid,
    203204                                 const char **attrs)
    204205{
    205206        char *dn, *sid_string;
    206207        ADS_STATUS status;
    207        
     208
    208209        sid_string = sid_binstring_hex(sid);
    209210        if (sid_string == NULL) {
     
    278279}
    279280
    280 ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads,
     281static ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads,
    281282                                      TALLOC_CTX *mem_ctx,
    282283                                      int scope,
     
    308309                return status;
    309310        }
    310        
     311
    311312        if (!res) {
    312313                return ADS_ERROR(LDAP_NO_MEMORY);
  • vendor/current/source3/libads/ndr.c

    r414 r740  
    2121
    2222#include "includes.h"
     23#include "ads.h"
     24#include "../librpc/gen_ndr/ndr_netlogon.h"
     25#include "librpc/ndr/util.h"
    2326
    24 void ndr_print_ads_auth_flags(struct ndr_print *ndr, const char *name, uint32_t r)
     27static void ndr_print_ads_auth_flags(struct ndr_print *ndr, const char *name, uint32_t r)
    2528{
    2629        ndr_print_uint32(ndr, name, r);
     
    3942void ndr_print_ads_struct(struct ndr_print *ndr, const char *name, const struct ads_struct *r)
    4043{
    41         if (!r) { return; }
    42 
    4344        ndr_print_struct(ndr, name, "ads_struct");
    4445        ndr->depth++;
  • vendor/current/source3/libads/sasl.c

    r597 r740  
    2020#include "includes.h"
    2121#include "../libcli/auth/spnego.h"
     22#include "../libcli/auth/ntlmssp.h"
     23#include "ads.h"
     24#include "smb_krb5.h"
    2225
    2326#ifdef HAVE_LDAP
     
    3033        NTSTATUS nt_status;
    3134        DATA_BLOB sig;
     35        TALLOC_CTX *frame;
    3236        uint8 *dptr = ads->ldap.out.buf + (4 + NTLMSSP_SIG_SIZE);
    3337
     38        frame = talloc_stackframe();
    3439        /* copy the data to the right location */
    3540        memcpy(dptr, buf, len);
     
    3843        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
    3944                nt_status = ntlmssp_seal_packet(ntlmssp_state,
     45                                                frame,
    4046                                                dptr, len,
    4147                                                dptr, len,
     
    4349        } else {
    4450                nt_status = ntlmssp_sign_packet(ntlmssp_state,
     51                                                frame,
    4552                                                dptr, len,
    4653                                                dptr, len,
     
    5461               sig.data, NTLMSSP_SIG_SIZE);
    5562
    56         data_blob_free(&sig);
     63        TALLOC_FREE(frame);
    5764
    5865        /* set how many bytes must be written to the underlying socket */
     
    102109                (struct ntlmssp_state *)ads->ldap.wrap_private_data;
    103110
    104         ntlmssp_end(&ntlmssp_state);
     111        TALLOC_FREE(ntlmssp_state);
    105112
    106113        ads->ldap.wrap_ops = NULL;
     
    134141        struct ntlmssp_state *ntlmssp_state;
    135142
    136         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
     143        nt_status = ntlmssp_client_start(NULL,
     144                                         global_myname(),
     145                                         lp_workgroup(),
     146                                         lp_client_ntlmv2_auth(),
     147                                         &ntlmssp_state);
     148        if (!NT_STATUS_IS_OK(nt_status)) {
    137149                return ADS_ERROR_NT(nt_status);
    138150        }
     
    181193                    && blob_out.length) {
    182194                        if (turn == 1) {
     195                                const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
    183196                                /* and wrap it in a SPNEGO wrapper */
    184                                 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
     197                                msg1 = spnego_gen_negTokenInit(talloc_tos(),
     198                                                OIDs_ntlm, &blob_out, NULL);
    185199                        } else {
    186200                                /* wrap it in SPNEGO */
    187                                 msg1 = spnego_gen_auth(blob_out);
     201                                msg1 = spnego_gen_auth(talloc_tos(), blob_out);
    188202                        }
    189203
     
    200214                                }
    201215
    202                                 ntlmssp_end(&ntlmssp_state);
     216                                TALLOC_FREE(ntlmssp_state);
    203217                                return ADS_ERROR(rc);
    204218                        }
     
    212226                } else {
    213227
    214                         ntlmssp_end(&ntlmssp_state);
     228                        TALLOC_FREE(ntlmssp_state);
    215229                        data_blob_free(&blob_out);
    216230                        return ADS_ERROR_NT(nt_status);
     
    221235                        DATA_BLOB tmp_blob = data_blob_null;
    222236                        /* the server might give us back two challenges */
    223                         if (!spnego_parse_challenge(blob, &blob_in,
     237                        if (!spnego_parse_challenge(talloc_tos(), blob, &blob_in,
    224238                                                    &tmp_blob)) {
    225239
    226                                 ntlmssp_end(&ntlmssp_state);
     240                                TALLOC_FREE(ntlmssp_state);
    227241                                data_blob_free(&blob);
    228242                                DEBUG(3,("Failed to parse challenges\n"));
     
    231245                        data_blob_free(&tmp_blob);
    232246                } else if (rc == LDAP_SASL_BIND_IN_PROGRESS) {
    233                         if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP,
     247                        if (!spnego_parse_auth_response(talloc_tos(), blob, nt_status, OID_NTLMSSP,
    234248                                                        &blob_in)) {
    235249
    236                                 ntlmssp_end(&ntlmssp_state);
     250                                TALLOC_FREE(ntlmssp_state);
    237251                                data_blob_free(&blob);
    238252                                DEBUG(3,("Failed to parse auth response\n"));
     
    257271                        DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n",
    258272                                ads_errstr(status)));
    259                         ntlmssp_end(&ntlmssp_state);
     273                        TALLOC_FREE(ntlmssp_state);
    260274                        return status;
    261275                }
    262276        } else {
    263                 ntlmssp_end(&ntlmssp_state);
     277                TALLOC_FREE(ntlmssp_state);
    264278        }
    265279
     
    498512        /* and wrap that in a shiny SPNEGO wrapper */
    499513        unwrapped = data_blob_const(output_token.value, output_token.length);
    500         wrapped = gen_negTokenTarg(spnego_mechs, unwrapped);
     514        wrapped = spnego_gen_negTokenInit(talloc_tos(),
     515                        spnego_mechs, &unwrapped, NULL);
    501516        gss_release_buffer(&minor_status, &output_token);
    502517        if (unwrapped.length > wrapped.length) {
     
    522537        }
    523538
    524         ok = spnego_parse_auth_response(wrapped, NT_STATUS_OK,
     539        ok = spnego_parse_auth_response(talloc_tos(), wrapped, NT_STATUS_OK,
    525540                                        OID_KERBEROS5_OLD,
    526541                                        &unwrapped);
     
    630645}
    631646
     647
     648static ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads,
     649                                              char **returned_principal)
     650{
     651        char *princ = NULL;
     652
     653        if (ads->server.realm && ads->server.ldap_server) {
     654                char *server, *server_realm;
     655
     656                server = SMB_STRDUP(ads->server.ldap_server);
     657                server_realm = SMB_STRDUP(ads->server.realm);
     658
     659                if (!server || !server_realm) {
     660                        SAFE_FREE(server);
     661                        SAFE_FREE(server_realm);
     662                        return ADS_ERROR(LDAP_NO_MEMORY);
     663                }
     664
     665                strlower_m(server);
     666                strupper_m(server_realm);
     667                if (asprintf(&princ, "ldap/%s@%s", server, server_realm) == -1) {
     668                        SAFE_FREE(server);
     669                        SAFE_FREE(server_realm);
     670                        return ADS_ERROR(LDAP_NO_MEMORY);
     671                }
     672
     673                SAFE_FREE(server);
     674                SAFE_FREE(server_realm);
     675
     676                if (!princ) {
     677                        return ADS_ERROR(LDAP_NO_MEMORY);
     678                }
     679        } else if (ads->config.realm && ads->config.ldap_server_name) {
     680                char *server, *server_realm;
     681
     682                server = SMB_STRDUP(ads->config.ldap_server_name);
     683                server_realm = SMB_STRDUP(ads->config.realm);
     684
     685                if (!server || !server_realm) {
     686                        SAFE_FREE(server);
     687                        SAFE_FREE(server_realm);
     688                        return ADS_ERROR(LDAP_NO_MEMORY);
     689                }
     690
     691                strlower_m(server);
     692                strupper_m(server_realm);
     693                if (asprintf(&princ, "ldap/%s@%s", server, server_realm) == -1) {
     694                        SAFE_FREE(server);
     695                        SAFE_FREE(server_realm);
     696                        return ADS_ERROR(LDAP_NO_MEMORY);
     697                }
     698
     699                SAFE_FREE(server);
     700                SAFE_FREE(server_realm);
     701
     702                if (!princ) {
     703                        return ADS_ERROR(LDAP_NO_MEMORY);
     704                }
     705        }
     706
     707        if (!princ) {
     708                return ADS_ERROR(LDAP_PARAM_ERROR);
     709        }
     710
     711        *returned_principal = princ;
     712
     713        return ADS_SUCCESS;
     714}
     715
    632716static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads,
    633717                                                 const char *given_principal,
     
    697781        }
    698782
    699         rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0,
     783        rc = spnego_gen_krb5_negTokenInit(talloc_tos(), principal,
     784                                     ads->auth.time_offset, &blob, &session_key, 0,
    700785                                     &ads->auth.tgs_expire);
    701786
     
    772857        /* the server sent us the first part of the SPNEGO exchange in the negprot
    773858           reply */
    774         if (!spnego_parse_negTokenInit(blob, OIDs, &given_principal) ||
     859        if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &given_principal, NULL) ||
    775860                        OIDs[0] == NULL) {
    776861                data_blob_free(&blob);
     
    9751060        output_token.length = 4;
    9761061        output_token.value = SMB_MALLOC(output_token.length);
     1062        if (!output_token.value) {
     1063                output_token.length = 0;
     1064                status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
     1065                goto failed;
     1066        }
    9771067        p = (uint8 *)output_token.value;
    9781068
     
    9901080
    9911081        gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
    992                           &output_token, &conf_state,
    993                           &input_token);
     1082                        &output_token, /* used as *input* here. */
     1083                        &conf_state,
     1084                        &input_token); /* Used as *output* here. */
    9941085        if (gss_rc) {
    9951086                status = ADS_ERROR_GSS(gss_rc, minor_status);
    996                 goto failed;
    997         }
    998 
    999         free(output_token.value);
     1087                output_token.length = 0;
     1088                SAFE_FREE(output_token.value);
     1089                goto failed;
     1090        }
     1091
     1092        /* We've finished with output_token. */
     1093        SAFE_FREE(output_token.value);
     1094        output_token.length = 0;
    10001095
    10011096        cred.bv_val = (char *)input_token.value;
     
    11151210                        if (strcmp(values[j], sasl_mechanisms[i].name) == 0) {
    11161211                                DEBUG(4,("Found SASL mechanism %s\n", values[j]));
     1212retry:
    11171213                                status = sasl_mechanisms[i].fn(ads);
     1214                                if (status.error_type == ENUM_ADS_ERROR_LDAP &&
     1215                                    status.err.rc == LDAP_STRONG_AUTH_REQUIRED &&
     1216                                    ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_PLAIN)
     1217                                {
     1218                                        DEBUG(3,("SASL bin got LDAP_STRONG_AUTH_REQUIRED "
     1219                                                 "retrying with signing enabled\n"));
     1220                                        ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN;
     1221                                        goto retry;
     1222                                }
    11181223                                ldap_value_free(values);
    11191224                                ldap_msgfree(res);
  • vendor/current/source3/libads/sasl_wrapping.c

    r414 r740  
    1919
    2020#include "includes.h"
     21#include "ads.h"
    2122
    2223#ifdef HAVE_LDAP_SASL_WRAPPING
  • vendor/current/source3/libads/util.c

    r414 r740  
    1919
    2020#include "includes.h"
     21#include "ads.h"
     22#include "secrets.h"
    2123
    2224#ifdef HAVE_KRB5
     
    5254        return ret;
    5355}
    54 
    55 ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads,
    56                                        char **returned_principal)
    57 {
    58         char *princ = NULL;
    59 
    60         if (ads->server.realm && ads->server.ldap_server) {
    61                 char *server, *server_realm;
    62 
    63                 server = SMB_STRDUP(ads->server.ldap_server);
    64                 server_realm = SMB_STRDUP(ads->server.realm);
    65 
    66                 if (!server || !server_realm) {
    67                         SAFE_FREE(server);
    68                         SAFE_FREE(server_realm);
    69                         return ADS_ERROR(LDAP_NO_MEMORY);
    70                 }
    71 
    72                 strlower_m(server);
    73                 strupper_m(server_realm);
    74                 if (asprintf(&princ, "ldap/%s@%s", server, server_realm) == -1) {
    75                         SAFE_FREE(server);
    76                         SAFE_FREE(server_realm);
    77                         return ADS_ERROR(LDAP_NO_MEMORY);
    78                 }
    79 
    80                 SAFE_FREE(server);
    81                 SAFE_FREE(server_realm);
    82 
    83                 if (!princ) {
    84                         return ADS_ERROR(LDAP_NO_MEMORY);
    85                 }
    86         } else if (ads->config.realm && ads->config.ldap_server_name) {
    87                 char *server, *server_realm;
    88 
    89                 server = SMB_STRDUP(ads->config.ldap_server_name);
    90                 server_realm = SMB_STRDUP(ads->config.realm);
    91 
    92                 if (!server || !server_realm) {
    93                         SAFE_FREE(server);
    94                         SAFE_FREE(server_realm);
    95                         return ADS_ERROR(LDAP_NO_MEMORY);
    96                 }
    97 
    98                 strlower_m(server);
    99                 strupper_m(server_realm);
    100                 if (asprintf(&princ, "ldap/%s@%s", server, server_realm) == -1) {
    101                         SAFE_FREE(server);
    102                         SAFE_FREE(server_realm);
    103                         return ADS_ERROR(LDAP_NO_MEMORY);
    104                 }
    105 
    106                 SAFE_FREE(server);
    107                 SAFE_FREE(server_realm);
    108 
    109                 if (!princ) {
    110                         return ADS_ERROR(LDAP_NO_MEMORY);
    111                 }
    112         }
    113 
    114         if (!princ) {
    115                 return ADS_ERROR(LDAP_PARAM_ERROR);
    116         }
    117 
    118         *returned_principal = princ;
    119 
    120         return ADS_SUCCESS;
    121 }
    122 
    12356#endif
Note: See TracChangeset for help on using the changeset viewer.