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

Update source to 3.0.28a

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.