Ignore:
Timestamp:
Jul 1, 2011, 8:40:10 AM (14 years ago)
Author:
Herwig Bauernfeind
Message:

Samba 3.5: Update trunk to 3.5.6

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/server/source3/libsmb/clikrb5.c

    r414 r590  
    2929#define GSSAPI_CHECKSUM      0x8003             /* Checksum type value for Kerberos */
    3030#define GSSAPI_BNDLENGTH     16                 /* Bind Length (rfc-1964 pg.3) */
    31 #define GSSAPI_CHECKSUM_SIZE (12+GSSAPI_BNDLENGTH)
    32 
    33 #if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY)
    34 static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context,
    35                                          krb5_auth_context *auth_context,
    36                                          krb5_creds *credsp,
    37                                          krb5_ccache ccache,
    38                                          krb5_data *authenticator);
     31#define GSSAPI_CHECKSUM_SIZE (4+GSSAPI_BNDLENGTH+4) /* Length of bind length,
     32                                                        bind field, flags field. */
     33
     34/* MIT krb5 1.7beta3 (in Ubuntu Karmic) is missing the prototype,
     35   but still has the symbol */
     36#if !HAVE_DECL_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE
     37krb5_error_code krb5_auth_con_set_req_cksumtype( 
     38        krb5_context     context,
     39        krb5_auth_context      auth_context, 
     40        krb5_cksumtype     cksumtype);
    3941#endif
    4042
     
    646648}
    647649
     650/* Allocate and setup the auth context into the state we need. */
     651
     652static krb5_error_code setup_auth_context(krb5_context context,
     653                        krb5_auth_context *auth_context)
     654{
     655        krb5_error_code retval;
     656
     657        retval = krb5_auth_con_init(context, auth_context );
     658        if (retval) {
     659                DEBUG(1,("krb5_auth_con_init failed (%s)\n",
     660                        error_message(retval)));
     661                return retval;
     662        }
     663
     664        /* Ensure this is an addressless ticket. */
     665        retval = krb5_auth_con_setaddrs(context, *auth_context, NULL, NULL);
     666        if (retval) {
     667                DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n",
     668                        error_message(retval)));
     669        }
     670
     671        return retval;
     672}
     673
     674static krb5_error_code create_gss_checksum(krb5_data *in_data, /* [inout] */
     675                                                uint32_t gss_flags)
     676{
     677        unsigned int orig_length = in_data->length;
     678        unsigned int base_cksum_size = GSSAPI_CHECKSUM_SIZE;
     679        char *gss_cksum = NULL;
     680
     681        if (orig_length) {
     682                /* Extra length field for delgated ticket. */
     683                base_cksum_size += 4;
     684        }
     685
     686        if ((unsigned int)base_cksum_size + orig_length <
     687                        (unsigned int)base_cksum_size) {
     688                return EINVAL;
     689        }
     690
     691        gss_cksum = (char *)SMB_MALLOC(base_cksum_size + orig_length);
     692        if (gss_cksum == NULL) {
     693                return ENOMEM;
     694        }
     695
     696        memset(gss_cksum, '\0', base_cksum_size + orig_length);
     697        SIVAL(gss_cksum, 0, GSSAPI_BNDLENGTH);
     698
     699        /* Precalculated MD5sum of NULL channel bindings (20 bytes) */
     700        /* Channel bindings are: (all ints encoded as little endian)
     701
     702                [4 bytes] initiator_addrtype (255 for null bindings)
     703                [4 bytes] initiator_address length
     704                        [n bytes] .. initiator_address data - not present
     705                                     in null bindings.
     706                [4 bytes] acceptor_addrtype (255 for null bindings)
     707                [4 bytes] acceptor_address length
     708                        [n bytes] .. acceptor_address data - not present
     709                                     in null bindings.
     710                [4 bytes] application_data length
     711                        [n bytes] .. application_ data - not present
     712                                     in null bindings.
     713                MD5 of this is ""\x14\x8f\x0c\xf7\xb1u\xdey*J\x9a%\xdfV\xc5\x18"
     714        */
     715
     716        memcpy(&gss_cksum[4],
     717                "\x14\x8f\x0c\xf7\xb1u\xdey*J\x9a%\xdfV\xc5\x18",
     718                GSSAPI_BNDLENGTH);
     719
     720        SIVAL(gss_cksum, 20, gss_flags);
     721
     722        if (orig_length) {
     723                SSVAL(gss_cksum, 24, 1); /* The Delegation Option identifier */
     724                SSVAL(gss_cksum, 26, orig_length);
     725                /* Copy the kerberos KRB_CRED data */
     726                memcpy(gss_cksum + 28, in_data->data, orig_length);
     727                free(in_data->data);
     728                in_data->data = NULL;
     729                in_data->length = 0;
     730        }
     731        in_data->data = gss_cksum;
     732        in_data->length = base_cksum_size + orig_length;
     733        return 0;
     734}
     735
    648736/*
    649737  we can't use krb5_mk_req because w2k wants the service to be in a particular format
     
    666754        bool creds_ready = False;
    667755        int i = 0, maxtries = 3;
    668        
     756        uint32_t gss_flags = 0;
     757
    669758        ZERO_STRUCT(in_data);
    670759
     
    736825        }
    737826
    738 #if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY)
     827        /* Allocate the auth_context. */
     828        retval = setup_auth_context(context, auth_context);
     829        if (retval) {
     830                DEBUG(1,("setup_auth_context failed (%s)\n",
     831                        error_message(retval)));
     832                goto cleanup_creds;
     833        }
     834
     835#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY)
    739836        if( credsp->ticket_flags & TKT_FLG_OK_AS_DELEGATE ) {
    740837                /* Fetch a forwarded TGT from the KDC so that we can hand off a 2nd ticket
     
    743840                DEBUG( 3, ("ads_krb5_mk_req: server marked as OK to delegate to, building forwardable TGT\n")  );
    744841
    745                 if( *auth_context == NULL ) {
    746                         /* Allocate if it has not yet been allocated. */
    747                         retval = krb5_auth_con_init( context, auth_context );
    748                         if (retval) {
    749                                 DEBUG(1,("ads_krb5_mk_req: krb5_auth_con_init failed (%s)\n",
    750                                         error_message(retval)));
    751                                 goto cleanup_creds;
    752                         }
    753                 }
    754 
    755                 retval = krb5_auth_con_setuseruserkey( context, *auth_context, &credsp->keyblock );
     842                retval = krb5_auth_con_setuseruserkey(context,
     843                                        *auth_context,
     844                                        &credsp->keyblock );
    756845                if (retval) {
    757                         DEBUG(1,("ads_krb5_mk_req: krb5_auth_con_setuseruserkey failed (%s)\n",
     846                        DEBUG(1,("krb5_auth_con_setuseruserkey failed (%s)\n",
    758847                                error_message(retval)));
    759848                        goto cleanup_creds;
     
    761850
    762851                /* Must use a subkey for forwarded tickets. */
    763                 retval = krb5_auth_con_setflags( context, *auth_context, KRB5_AUTH_CONTEXT_USE_SUBKEY);
     852                retval = krb5_auth_con_setflags(context,
     853                                *auth_context,
     854                                KRB5_AUTH_CONTEXT_USE_SUBKEY);
    764855                if (retval) {
    765                         DEBUG(1,("ads_krb5_mk_req: krb5_auth_con_setflags failed (%s)\n",
     856                        DEBUG(1,("krb5_auth_con_setflags failed (%s)\n",
    766857                                error_message(retval)));
    767858                        goto cleanup_creds;
    768859                }
    769860
    770                 retval = ads_krb5_get_fwd_ticket( context,
    771                                                 auth_context,
    772                                                 credsp,
    773                                                 ccache,
    774                                                 &in_data );
     861                retval = krb5_fwd_tgt_creds(context,/* Krb5 context [in] */
     862                                *auth_context,  /* Authentication context [in] */
     863                                CONST_DISCARD(char *, KRB5_TGS_NAME),  /* Ticket service name ("krbtgt") [in] */
     864                                credsp->client, /* Client principal for the tgt [in] */
     865                                credsp->server, /* Server principal for the tgt [in] */
     866                                ccache,         /* Credential cache to use for storage [in] */
     867                                1,              /* Turn on for "Forwardable ticket" [in] */
     868                                &in_data );     /* Resulting response [out] */
     869
    775870                if (retval) {
    776                         DEBUG( 3, ("ads_krb5_get_fwd_ticket failed (%s)\n",
     871                        DEBUG( 3, ("krb5_fwd_tgt_creds failed (%s)\n",
    777872                                   error_message( retval ) ) );
    778873
     
    789884                        krb5_auth_con_free(context, *auth_context);
    790885                        *auth_context = NULL;
    791                 }
     886                        retval = setup_auth_context(context, auth_context);
     887                        if (retval) {
     888                                DEBUG(1,("setup_auth_context failed (%s)\n",
     889                                        error_message(retval)));
     890                                goto cleanup_creds;
     891                        }
     892                } else {
     893                        /* We got a delegated ticket. */
     894                        gss_flags |= GSS_C_DELEG_FLAG;
     895                }
     896        }
     897#endif
     898
     899        /* Frees and reallocates in_data into a GSS checksum blob. */
     900        retval = create_gss_checksum(&in_data, gss_flags);
     901        if (retval) {
     902                goto cleanup_data;
     903        }
     904
     905#if defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE)
     906        /* We always want GSS-checksum types. */
     907        retval = krb5_auth_con_set_req_cksumtype(context, *auth_context, GSSAPI_CHECKSUM );
     908        if (retval) {
     909                DEBUG(1,("krb5_auth_con_set_req_cksumtype failed (%s)\n",
     910                        error_message(retval)));
     911                goto cleanup_data;
    792912        }
    793913#endif
     
    800920        }
    801921
     922cleanup_data:
    802923        if (in_data.data) {
    803924                free( in_data.data );
     
    18461967        return ret;
    18471968}
    1848 
    1849 #if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY)
    1850 /**************************************************************
    1851 Routine: ads_krb5_get_fwd_ticket
    1852  Description:
    1853     When a service ticket is flagged as trusted
    1854     for delegation we should provide a forwardable
    1855     ticket so that the remote host can act on our
    1856     behalf.  This is done by taking the 2nd forwardable
    1857     TGT and storing it in the GSS-API authenticator
    1858     "checksum".  This routine will populate
    1859     the krb5_data authenticator with this TGT.
    1860  Parameters:
    1861     krb5_context context: The kerberos context for this authentication.
    1862     krb5_auth_context:    The authentication context.
    1863     krb5_creds *credsp:   The ticket credentials (AS-REP).
    1864     krb5_ccache ccache:   The credentials cache.
    1865     krb5_data &authenticator: The checksum field that will store the TGT, and
    1866      authenticator.data must be freed by the caller.
    1867 
    1868  Returns:
    1869     krb5_error_code: 0 if no errors, otherwise set.
    1870 **************************************************************/
    1871 
    1872 static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context,
    1873                                          krb5_auth_context *auth_context,
    1874                                          krb5_creds *credsp,
    1875                                          krb5_ccache ccache,
    1876                                          krb5_data *authenticator)
    1877 {
    1878         krb5_data fwdData;
    1879         krb5_error_code retval = 0;
    1880         char *pChksum = NULL;
    1881         char *p = NULL;
    1882 
    1883 /* MIT krb5 1.7beta3 (in Ubuntu Karmic) is missing the prototype,
    1884    but still has the symbol */
    1885 #if !HAVE_DECL_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE
    1886 krb5_error_code krb5_auth_con_set_req_cksumtype( 
    1887         krb5_context     context,
    1888         krb5_auth_context      auth_context, 
    1889         krb5_cksumtype     cksumtype);
    1890 #endif
    1891 
    1892         ZERO_STRUCT(fwdData);
    1893         ZERO_STRUCTP(authenticator);
    1894 
    1895         retval = krb5_fwd_tgt_creds(context,/* Krb5 context [in] */
    1896                                 *auth_context,  /* Authentication context [in] */
    1897                                 CONST_DISCARD(char *, KRB5_TGS_NAME),  /* Ticket service name ("krbtgt") [in] */
    1898                                 credsp->client, /* Client principal for the tgt [in] */
    1899                                 credsp->server, /* Server principal for the tgt [in] */
    1900                                 ccache,         /* Credential cache to use for storage [in] */
    1901                                 1,              /* Turn on for "Forwardable ticket" [in] */
    1902                                 &fwdData );     /* Resulting response [out] */
    1903 
    1904 
    1905         if (retval) {
    1906                 DEBUG(1,("ads_krb5_get_fwd_ticket: krb5_fwd_tgt_creds failed (%s)\n",
    1907                         error_message(retval)));
    1908                 goto out;
    1909         }
    1910 
    1911         if ((unsigned int)GSSAPI_CHECKSUM_SIZE + (unsigned int)fwdData.length <
    1912                 (unsigned int)GSSAPI_CHECKSUM_SIZE) {
    1913                 retval = EINVAL;
    1914                 goto out;
    1915         }
    1916 
    1917         /* We're going to allocate a gssChecksum structure with a little
    1918            extra data the length of the kerberos credentials length
    1919            (APPLICATION 22) so that we can pack it on the end of the structure.
    1920         */
    1921 
    1922         pChksum = (char *)SMB_MALLOC(GSSAPI_CHECKSUM_SIZE + fwdData.length );
    1923         if (!pChksum) {
    1924                 retval = ENOMEM;
    1925                 goto out;
    1926         }
    1927 
    1928         p = pChksum;
    1929 
    1930         SIVAL(p, 0, GSSAPI_BNDLENGTH);
    1931         p += 4;
    1932 
    1933         /* Zero out the bindings fields */
    1934         memset(p, '\0', GSSAPI_BNDLENGTH );
    1935         p += GSSAPI_BNDLENGTH;
    1936 
    1937         SIVAL(p, 0, GSS_C_DELEG_FLAG );
    1938         p += 4;
    1939         SSVAL(p, 0, 1 );
    1940         p += 2;
    1941         SSVAL(p, 0, fwdData.length );
    1942         p += 2;
    1943 
    1944         /* Migrate the kerberos KRB_CRED data to the checksum delegation */
    1945         memcpy(p, fwdData.data, fwdData.length );
    1946         p += fwdData.length;
    1947 
    1948         /* We need to do this in order to allow our GSS-API  */
    1949         retval = krb5_auth_con_set_req_cksumtype( context, *auth_context, GSSAPI_CHECKSUM );
    1950         if (retval) {
    1951                 goto out;
    1952         }
    1953 
    1954         /* We now have a service ticket, now turn it into an AP-REQ. */
    1955         authenticator->length = fwdData.length + GSSAPI_CHECKSUM_SIZE;
    1956 
    1957         /* Caller should call free() when they're done with this. */
    1958         authenticator->data = (char *)pChksum;
    1959 
    1960   out:
    1961 
    1962         /* Remove that input data, we never needed it anyway. */
    1963         if (fwdData.length > 0) {
    1964                 krb5_free_data_contents( context, &fwdData );
    1965         }
    1966 
    1967         return retval;
    1968 }
    1969 #endif
    19701969
    19711970#if defined(HAVE_KRB5_GET_CREDS_OPT_SET_IMPERSONATE) && \
Note: See TracChangeset for help on using the changeset viewer.