Ignore:
Timestamp:
Mar 12, 2008, 9:08:18 AM (17 years ago)
Author:
Paul Smedley
Message:

Update source to 3.0.28a

Location:
branches/samba-3.0/source/libads
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.0/source/libads/kerberos.c

    r71 r124  
    363363}
    364364
     365/************************************************************************
     366 Routine to get the default realm from the kerberos credentials cache.
     367 Caller must free if the return value is not NULL.
     368************************************************************************/
     369
     370char *kerberos_get_default_realm_from_ccache( void )
     371{
     372        char *realm = NULL;
     373        krb5_context ctx = NULL;
     374        krb5_ccache cc = NULL;
     375        krb5_principal princ = NULL;
     376
     377        initialize_krb5_error_table();
     378        if (krb5_init_context(&ctx)) {
     379                return NULL;
     380        }
     381
     382        DEBUG(5,("kerberos_get_default_realm_from_ccache: "
     383                "Trying to read krb5 cache: %s\n",
     384                krb5_cc_default_name(ctx)));
     385        if (krb5_cc_default(ctx, &cc)) {
     386                DEBUG(0,("kerberos_get_default_realm_from_ccache: "
     387                        "failed to read default cache\n"));
     388                goto out;
     389        }
     390        if (krb5_cc_get_principal(ctx, cc, &princ)) {
     391                DEBUG(0,("kerberos_get_default_realm_from_ccache: "
     392                        "failed to get default principal\n"));
     393                goto out;
     394        }
     395
     396#if defined(HAVE_KRB5_PRINCIPAL_GET_REALM)
     397        realm = SMB_STRDUP(krb5_principal_get_realm(ctx, princ));
     398#elif defined(HAVE_KRB5_PRINC_REALM)
     399        {
     400                krb5_data *realm_data = krb5_princ_realm(ctx, princ);
     401                realm = SMB_STRNDUP(realm_data->data, realm_data->length);
     402        }
     403#endif
     404
     405  out:
     406
     407        if (princ) {
     408                krb5_free_principal(ctx, princ);
     409        }
     410        if (cc) {
     411                krb5_cc_close(ctx, cc);
     412        }
     413        if (ctx) {
     414                krb5_free_context(ctx);
     415        }
     416
     417        return realm;
     418}
     419
    365420
    366421/************************************************************************
     
    622677                return False;
    623678        }
    624                
    625         file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n"
    626                                 "[realms]\n\t%s = {\n"
    627                                 "\t%s\t}\n",
    628                                 realm_upper, realm_upper, kdc_ip_string);
     679
     680        file_contents = talloc_asprintf(fname,
     681                                        "[libdefaults]\n\tdefault_realm = %s\n"
     682                                        "default_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
     683                                        "default_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
     684                                        "preferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n"
     685                                        "[realms]\n\t%s = {\n"
     686                                        "\t%s\t}\n",
     687                                        realm_upper, realm_upper, kdc_ip_string);
    629688
    630689        if (!file_contents) {
  • branches/samba-3.0/source/libads/sasl.c

    r26 r124  
    138138
    139139#ifdef HAVE_KRB5
     140struct ads_service_principal {
     141         char *string;
     142#ifdef HAVE_GSSAPI
     143         gss_name_t name;
     144#endif
     145};
     146
     147static void ads_free_service_principal(struct ads_service_principal *p)
     148{
     149        SAFE_FREE(p->string);
     150
     151#ifdef HAVE_GSSAPI
     152        if (p->name) {
     153                uint32 minor_status;
     154                gss_release_name(&minor_status, &p->name);
     155        }
     156#endif
     157        ZERO_STRUCTP(p);
     158}
     159
     160static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads,
     161                                                 const char *given_principal,
     162                                                 struct ads_service_principal *p)
     163{
     164        ADS_STATUS status;
     165#ifdef HAVE_GSSAPI
     166        gss_buffer_desc input_name;
     167        /* GSS_KRB5_NT_PRINCIPAL_NAME */
     168        gss_OID_desc nt_principal =
     169        {10, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01")};
     170        uint32 minor_status;
     171        int gss_rc;
     172#endif
     173
     174        ZERO_STRUCTP(p);
     175
     176        /* I've seen a child Windows 2000 domain not send
     177           the principal name back in the first round of
     178           the SASL bind reply.  So we guess based on server
     179           name and realm.  --jerry  */
     180        /* Also try best guess when we get the w2k8 ignore
     181           principal back - gd */
     182
     183        if (!given_principal ||
     184            strequal(given_principal, ADS_IGNORE_PRINCIPAL)) {
     185
     186                status = ads_guess_service_principal(ads, &p->string);
     187                if (!ADS_ERR_OK(status)) {
     188                        return status;
     189                }
     190        } else {
     191                p->string = SMB_STRDUP(given_principal);
     192                if (!p->string) {
     193                        return ADS_ERROR(LDAP_NO_MEMORY);
     194                }
     195        }
     196
     197#ifdef HAVE_GSSAPI
     198        input_name.value = p->string;
     199        input_name.length = strlen(p->string);
     200
     201        gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &p->name);
     202        if (gss_rc) {
     203                ads_free_service_principal(p);
     204                return ADS_ERROR_GSS(gss_rc, minor_status);
     205        }
     206#endif
     207
     208        return ADS_SUCCESS;
     209}
     210
    140211/*
    141212   perform a LDAP/SASL/SPNEGO/KRB5 bind
    142213*/
    143 static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal)
     214static ADS_STATUS ads_sasl_spnego_rawkrb5_bind(ADS_STRUCT *ads, const char *principal)
    144215{
    145216        DATA_BLOB blob = data_blob(NULL, 0);
     
    168239        return ADS_ERROR(rc);
    169240}
     241
     242static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads,
     243                                            struct ads_service_principal *p)
     244{
     245        return ads_sasl_spnego_rawkrb5_bind(ads, p->string);
     246}
     247
    170248#endif
    171249
     
    179257        ADS_STATUS status;
    180258        DATA_BLOB blob;
    181         char *principal = NULL;
     259        char *given_principal = NULL;
    182260        char *OIDs[ASN1_MAX_OIDS];
    183261#ifdef HAVE_KRB5
     
    202280        /* the server sent us the first part of the SPNEGO exchange in the negprot
    203281           reply */
    204         if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
     282        if (!spnego_parse_negTokenInit(blob, OIDs, &given_principal)) {
    205283                data_blob_free(&blob);
    206284                status = ADS_ERROR(LDAP_OPERATIONS_ERROR);
     
    220298                free(OIDs[i]);
    221299        }
    222         DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", principal));
     300        DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal));
    223301
    224302#ifdef HAVE_KRB5
     
    226304            got_kerberos_mechanism)
    227305        {
    228                 /* I've seen a child Windows 2000 domain not send
    229                    the principal name back in the first round of
    230                    the SASL bind reply.  So we guess based on server
    231                    name and realm.  --jerry  */
    232                 if ( !principal ) {
    233                         if ( ads->server.realm && ads->server.ldap_server ) {
    234                                 char *server, *server_realm;
    235                                
    236                                 server = SMB_STRDUP( ads->server.ldap_server );
    237                                 server_realm = SMB_STRDUP( ads->server.realm );
    238                                
    239                                 if ( !server || !server_realm )
    240                                         return ADS_ERROR(LDAP_NO_MEMORY);
    241 
    242                                 strlower_m( server );
    243                                 strupper_m( server_realm );                             
    244                                 asprintf( &principal, "ldap/%s@%s", server, server_realm );
    245 
    246                                 SAFE_FREE( server );
    247                                 SAFE_FREE( server_realm );
    248 
    249                                 if ( !principal )
    250                                         return ADS_ERROR(LDAP_NO_MEMORY);                               
    251                         }
    252                        
    253                 }
    254                
    255                 status = ads_sasl_spnego_krb5_bind(ads, principal);
     306                struct ads_service_principal p;
     307
     308                status = ads_generate_service_principal(ads, given_principal, &p);
     309                SAFE_FREE(given_principal);
     310                if (!ADS_ERR_OK(status)) {
     311                        return status;
     312                }
     313
     314                status = ads_sasl_spnego_krb5_bind(ads, &p);
    256315                if (ADS_ERR_OK(status)) {
    257                         SAFE_FREE(principal);
     316                        ads_free_service_principal(&p);
    258317                        return status;
    259318                }
     
    265324
    266325                if (ADS_ERR_OK(status)) {
    267                         status = ads_sasl_spnego_krb5_bind(ads, principal);
    268                 }
     326                        status = ads_sasl_spnego_krb5_bind(ads, &p);
     327                        if (!ADS_ERR_OK(status)) {
     328                                DEBUG(0,("kinit succeeded but "
     329                                        "ads_sasl_spnego_krb5_bind failed: %s\n",
     330                                        ads_errstr(status)));
     331                        }
     332                }
     333
     334                ads_free_service_principal(&p);
    269335
    270336                /* only fallback to NTLMSSP if allowed */
    271337                if (ADS_ERR_OK(status) ||
    272338                    !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
    273                         SAFE_FREE(principal);
    274339                        return status;
    275340                }
    276         }
    277 #endif
    278 
    279         SAFE_FREE(principal);
     341        } else
     342#endif
     343        {
     344                SAFE_FREE(given_principal);
     345        }
    280346
    281347        /* lets do NTLMSSP ... this has the big advantage that we don't need
  • branches/samba-3.0/source/libads/util.c

    r1 r124  
    5353        return ret;
    5454}
     55
     56ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads,
     57                                       char **returned_principal)
     58{
     59        char *princ = NULL;
     60
     61        if (ads->server.realm && ads->server.ldap_server) {
     62                char *server, *server_realm;
     63
     64                server = SMB_STRDUP(ads->server.ldap_server);
     65                server_realm = SMB_STRDUP(ads->server.realm);
     66
     67                if (!server || !server_realm) {
     68                        return ADS_ERROR(LDAP_NO_MEMORY);
     69                }
     70
     71                strlower_m(server);
     72                strupper_m(server_realm);
     73                asprintf(&princ, "ldap/%s@%s", server, server_realm);
     74
     75                SAFE_FREE(server);
     76                SAFE_FREE(server_realm);
     77
     78                if (!princ) {
     79                        return ADS_ERROR(LDAP_NO_MEMORY);
     80                }
     81        } else if (ads->config.realm && ads->config.ldap_server_name) {
     82                char *server, *server_realm;
     83
     84                server = SMB_STRDUP(ads->config.ldap_server_name);
     85                server_realm = SMB_STRDUP(ads->config.realm);
     86
     87                if (!server || !server_realm) {
     88                        return ADS_ERROR(LDAP_NO_MEMORY);
     89                }
     90
     91                strlower_m(server);
     92                strupper_m(server_realm);
     93                asprintf(&princ, "ldap/%s@%s", server, server_realm);
     94
     95                SAFE_FREE(server);
     96                SAFE_FREE(server_realm);
     97
     98                if (!princ) {
     99                        return ADS_ERROR(LDAP_NO_MEMORY);
     100                }
     101        }
     102
     103        if (!princ) {
     104                return ADS_ERROR(LDAP_PARAM_ERROR);
     105        }
     106
     107        *returned_principal = princ;
     108
     109        return ADS_SUCCESS;
     110}
     111
    55112#endif
Note: See TracChangeset for help on using the changeset viewer.