[SCM] Samba Shared Repository - branch v3-2-stable updated - release-3-2-1-20-g2525fd9

Karolin Seeger kseeger at samba.org
Mon Aug 11 14:52:00 GMT 2008


The branch, v3-2-stable has been updated
       via  2525fd971e650de009cc10b4cedd4c49c1a43ed0 (commit)
       via  a606ff9a23f96a1da98794b0b481f0c5fa2584cf (commit)
       via  c59725892da965d09aa25e867c75c6aa3bfedf1d (commit)
       via  f2e3f755b19c7ebec54204b2d46048d4af1a8d51 (commit)
       via  fd7df1959afe7009c4c9b0e890f93cfd9f12281a (commit)
       via  62c92221761ce6cc6d0e9916e77475b351611147 (commit)
       via  1a23e2b51ff907efedebab38bdc5bab2cff04c2f (commit)
       via  b08c910471a69a588379999a4f080f5aa9b224f7 (commit)
       via  476693767c89a97834c3afdb2d2e194d91f9854c (commit)
       via  53151468ccc775498e6944242f1822d5a482bc00 (commit)
       via  ceceb7bded185479aadad2700450591854a383f4 (commit)
       via  648fb541542bcd9f0e76d6f5f8b5589f9f02feb7 (commit)
       via  4b25a10a4d02c91ca3c5a2365e4e04d3f2c93f83 (commit)
       via  75a27ea6047d69d419ff8485a4df36f5f2b2a07e (commit)
       via  f0bcef0aaa87ad14cf071acfa7984ddfa6302959 (commit)
       via  b63ddc53f2ee74ca2295554838ca7a40272dcf2f (commit)
      from  b89ce09ad4b2b15a3882f653f3e8d19696452330 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-stable


- Log -----------------------------------------------------------------
commit 2525fd971e650de009cc10b4cedd4c49c1a43ed0
Author: Karolin Seeger <kseeger at samba.org>
Date:   Mon Aug 11 16:46:15 2008 +0200

    WHATSNEW: Update changes since 3.2.1.
    
    Karolin
    (cherry picked from commit 0099cb0741c159db7f389bcca52a3cc6a3762771)

commit a606ff9a23f96a1da98794b0b481f0c5fa2584cf
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Aug 10 17:53:35 2008 +0200

    fix smb_len calculation for chained requests
    
    I think chain_reply() is one of the most tricky parts of Samba. This recursion
    needs to go away, we need to sequentially walk the chain list.
    (cherry picked from commit 34b56cb54e06f9b38d2bb0a626ec7b04030fc4fa)

commit c59725892da965d09aa25e867c75c6aa3bfedf1d
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Aug 10 17:37:08 2008 +0200

    Fix andx offset calculation for more than 2 chained requests
    
    Untested code is broken code.... Test follows later, it's quite an intrusive
    change to libsmb/
    (cherry picked from commit 2abeea64e15f0e8e8c413744de9194bdcedd6f16)

commit f2e3f755b19c7ebec54204b2d46048d4af1a8d51
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Aug 8 16:08:36 2008 -0700

    One more build fix. Ensure we have KRB5_AUTH_CONTEXT_USE_SUBKEY defined before we compile the new code.
    Jeremy.
    (cherry picked from commit fc309e41a45079d58c03dc6fb0c35ceb4517f0ae)

commit fd7df1959afe7009c4c9b0e890f93cfd9f12281a
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Aug 8 15:16:04 2008 -0700

    Try and fix the build for systems that don't have krb5_auth_con_set_req_cksumtype().
    Jeremy.
    (cherry picked from commit 02862653724355b32e0c6e38e0ebcbb1a9954759)

commit 62c92221761ce6cc6d0e9916e77475b351611147
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Aug 8 14:33:00 2008 -0700

    Add Derrick Schommer's <dschommer at F5.com> kerberos delegation patch. Some
    work by me and advice by Love.
    Jeremy.
    (cherry picked from commit 5f419135ba1acae6bc37692fa77ae1162b62e0e3)

commit 1a23e2b51ff907efedebab38bdc5bab2cff04c2f
Author: Yannick Bergeron <yaberger at ca.ibm.com>
Date:   Fri Aug 8 13:32:15 2008 -0400

    using NGROUPS_MAX instead of 32 for the max group value in rep_initgroups() subroutine in lib/replace/replace.c
    (cherry picked from commit 6d6b205e444154e1bd2993d964eff4cf532bacd8)

commit b08c910471a69a588379999a4f080f5aa9b224f7
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Aug 7 17:56:50 2008 -0700

    Fix bug #5675 with a varient of Tim Waugh's patch,
    as proposed by James Peach.
    Jeremy.
    (cherry picked from commit 1ee1e8306f3578c19fe015145eb8da1013f7b820)

commit 476693767c89a97834c3afdb2d2e194d91f9854c
Author: Yannick Bergeron <yaberger at ca.ibm.com>
Date:   Wed Aug 6 13:23:00 2008 -0400

    Solve an IBM XL C/C++ compiler error encountered in get_exit_code() auth_errors array initialization in client/smbspool.c
    (cherry picked from commit f6ffc95a363d3ed8aa480ac25e440d2472551891)

commit 53151468ccc775498e6944242f1822d5a482bc00
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 6 16:35:43 2008 +1000

    fixed permissions on ctdb databases
    (cherry picked from commit 123fc3980a83d956bffaa689f3af81bbf81ce1c1)
    (cherry picked from commit 61274204b63cf077a826671a9e0d807bd17dfec3)

commit ceceb7bded185479aadad2700450591854a383f4
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 6 14:02:45 2008 +1000

    fixed a fd leak when trying to regain contact to a domain controller
    in winbind
    
    When a w2k3 DC is rebooted the 139/445 ports come up before the
    udp/389 cldap port. During this brief period, winbind manages to
    connect to 139/445 but not to udp 389. It then enters a tight loop
    where it leaks one fd each time. In a couple of seconds it runs out of
    file descriptors, and leaves winbind crippled after the DC does
    finally come up
    (cherry picked from commit 57187cafbcc053e75bb54750494df9feabe3a738)
    (cherry picked from commit 892e41d60469e1e8adccd2b1ff860210db58dcb0)

commit 648fb541542bcd9f0e76d6f5f8b5589f9f02feb7
Author: Michael Adam <obnox at samba.org>
Date:   Tue Aug 5 23:38:56 2008 +0200

    dbwrap: add comment describing behaviour of dbwrap_change_int32_atomic().
    
    Michael
    (cherry picked from commit f8f21c8e3922806230e240cb54205fc2db7a3619)
    (cherry picked from commit 0bdab793c1da9b56790d37ac7d064b67ec51e3a4)

commit 4b25a10a4d02c91ca3c5a2365e4e04d3f2c93f83
Author: Michael Adam <obnox at samba.org>
Date:   Tue Aug 5 23:14:05 2008 +0200

    secrets: fix replacemend random seed generator (security issue).
    
    This is a regression introduced by the change to dbwrap.
    The replacement dbwrap_change_int32_atomic() does not
    correctly mimic the behaviour of tdb_change_int32_atomic():
    The intended behaviour is to use *oldval  as an initial
    value when the entry does not yet exist in the db and to
    return the old value in *oldval.
    
    The effect was that:
    1. get_rand_seed() always returns sys_getpid() in *new_seed
       instead of the incremented seed from the secrets.tdb.
    2. the seed stored in the tdb is always starting at 0 instead
       of sys_getpid() + 1 and incremented in subsequent calls.
    
    In principle this is a security issue, but i think the danger is
    low, since this is only used as a fallback when there is no useable
    /dev/urandom, and this is at most called on startup or via
    reinit_after_fork.
    
    Michael
    (cherry picked from commit bfc5d34a196f667276ce1e173821db478d01258b)
    (cherry picked from commit c0e764d3878120e9612bbd847e581c6fd6c79532)

commit 75a27ea6047d69d419ff8485a4df36f5f2b2a07e
Author: Michael Adam <obnox at samba.org>
Date:   Tue Aug 5 23:13:06 2008 +0200

    dbwrap: add comment describing behaviour of dbwrap_change_uint32_atomic().
    
    Michael
    (cherry picked from commit 7edfb54c865ddcfd5cdcc8c2184b96aaac2d2ec0)
    (cherry picked from commit c601ad0d1c5b7f3568fef7592e501b8f6be9c469)

commit f0bcef0aaa87ad14cf071acfa7984ddfa6302959
Author: Michael Adam <obnox at samba.org>
Date:   Tue Aug 5 22:38:44 2008 +0200

    idmap_tdb2: fix a race condition in idmap_tdb2_allocate_id().
    
    The race is a regression introduced by the change to dbwrap.
    It might have led to two concurrent processes returning the same id.
    
    This fix is achieved by changing dbwrap_change_uint32_atomic() to
    match the original behaviour of tdb_change_uint32_atomic(), which
    is the following: *oldval is used as initial value when
    the value does not yet exist and that the old value should be
    returned in *oldval.
    
    dbwrap_change_uint32_atomic() is used (only) in idmap_tdb2.c,
    to get new ids.
    
    Michael
    (cherry picked from commit 72bd83fea7572a6202027b200d192c05023aa633)
    (cherry picked from commit f3cdf9e646180837a470e90f8a17d933f07b60c3)

commit b63ddc53f2ee74ca2295554838ca7a40272dcf2f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Jun 17 22:45:29 2008 +1000

    Without stdlib.h we don't get a prototype for free().
    
    This test fails if GCC emits any warnings (presumably to detect the
    function propertly), but unless we include this message then free()
    fail.  Why we need to call free in a configure test is probably
    something to blame on valgrind...
    
    Andrew Bartlett
    (cherry picked from commit d013f6fadc3e80fabb4a1784207dabc84f9b7dc2)
    (cherry picked from commit 91c17ecfd7b07ff948874c3eb7013eb79c5b66ab)

-----------------------------------------------------------------------

Summary of changes:
 WHATSNEW.txt                        |   30 ++++++
 source/client/smbspool.c            |    2 +-
 source/configure.in                 |    3 +
 source/include/client.h             |    1 +
 source/lib/dbwrap_ctdb.c            |    5 +
 source/lib/dbwrap_util.c            |   30 +++++-
 source/lib/replace/libreplace_cc.m4 |    3 +-
 source/lib/replace/replace.c        |    2 +-
 source/libsmb/cliconnect.c          |    5 +-
 source/libsmb/clifsinfo.c           |    2 +-
 source/libsmb/clikrb5.c             |  186 ++++++++++++++++++++++++++++++++++-
 source/smbd/process.c               |   16 +++-
 source/winbindd/winbindd_cm.c       |    1 +
 13 files changed, 269 insertions(+), 17 deletions(-)


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 984b097..163f7e2 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -18,6 +18,36 @@ Changes since 3.2.1
 -------------------
 
 
+o   Michael Adam <obnox at samba.org>
+    * Fix replacement of random seed generator.
+    * Fix a race condition in idmap_tdb2_allocate_id().
+
+
+o   Jeremy Allison <jra at samba.org>
+    * BUG 5675: Fix smbspool program assuming Kerberos authentication by
+      mistake.
+    * Several build fixes.
+
+
+o   Andrew Bartlett <abartlet at samba.org>
+    * Include stdlib.h to get a prototype for free().
+
+
+o   Yannick Bergeron <yaberger at ca.ibm.com>
+    * Solve an IBM XL C/C++ compiler error encountered in get_exit_code()
+      auth_errors array initialization in client/smbspool.c.
+    * Use NGROUPS_MAX instead of 32 for the max group value in
+      rep_initgroups().
+
+
+o   Volker Lendecke <vl at samba.org>
+    * Fix smb_len calculation for chained requests.
+
+
+o   Andrew Tridgell <tridge at samba.org>
+    * Fix a fd leak when trying to regain contact to a domain controller
+      in Winbind.
+    * Fix permissions on ctdb databases.
 
 
 ######################################################################
diff --git a/source/client/smbspool.c b/source/client/smbspool.c
index e567ef8..f35a9d3 100644
--- a/source/client/smbspool.c
+++ b/source/client/smbspool.c
@@ -347,7 +347,7 @@ get_exit_code(struct cli_state * cli,
 		}
 
 		if (cli) {
-			if (cli->use_kerberos || (cli->capabilities & CAP_EXTENDED_SECURITY))
+			if (cli->use_kerberos && cli->got_kerberos_mechanism)
 				fputs("ATTR: auth-info-required=negotiate\n", stderr);
 			else
 				fputs("ATTR: auth-info-required=username,password\n", stderr);
diff --git a/source/configure.in b/source/configure.in
index 9a230de..010c2e3 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -3367,6 +3367,8 @@ if test x"$with_ads_support" != x"no"; then
   AC_CHECK_FUNC_EXT(krb5_get_init_creds_opt_free, $KRB5_LIBS)
   AC_CHECK_FUNC_EXT(krb5_get_init_creds_opt_get_error, $KRB5_LIBS)
   AC_CHECK_FUNC_EXT(krb5_enctype_to_string, $KRB5_LIBS)
+  AC_CHECK_FUNC_EXT(krb5_fwd_tgt_creds, $KRB5_LIBS)
+  AC_CHECK_FUNC_EXT(krb5_auth_con_set_req_cksumtype, $KRB5_LIBS)
 
   LIBS="$KRB5_LIBS $LIBS"
 
@@ -3747,6 +3749,7 @@ if test x"$with_ads_support" != x"no"; then
     AC_CACHE_CHECK([for krb5_error_code krb5_enctype_to_string(krb5_context context, krb5_enctype enctype, char **str)],
         smb_krb5_cv_enctype_to_string_takes_krb5_context_arg,[
 	AC_TRY_RUN_STRICT([
+		#include <stdlib.h>
 		#include <krb5.h>
 		int main(void) {
 			krb5_context context = NULL;
diff --git a/source/include/client.h b/source/include/client.h
index 0e73745..833f4b4 100644
--- a/source/include/client.h
+++ b/source/include/client.h
@@ -184,6 +184,7 @@ struct cli_state {
 	bool use_kerberos;
 	bool fallback_after_kerberos;
 	bool use_spnego;
+	bool got_kerberos_mechanism; /* Server supports krb5 in SPNEGO. */
 
 	bool use_oplocks; /* should we use oplocks? */
 	bool use_level_II_oplocks; /* should we use level II oplocks? */
diff --git a/source/lib/dbwrap_ctdb.c b/source/lib/dbwrap_ctdb.c
index a66ea7c..cb4c573 100644
--- a/source/lib/dbwrap_ctdb.c
+++ b/source/lib/dbwrap_ctdb.c
@@ -488,6 +488,11 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
 	/* only pass through specific flags */
 	tdb_flags &= TDB_SEQNUM;
 
+	/* honor permissions if user has specified O_CREAT */
+	if (open_flags & O_CREAT) {
+		chmod(db_path, mode);
+	}
+
 	db_ctdb->wtdb = tdb_wrap_open(db_ctdb, db_path, hash_size, tdb_flags, O_RDWR, 0);
 	if (db_ctdb->wtdb == NULL) {
 		DEBUG(0, ("Could not open tdb %s: %s\n", db_path, strerror(errno)));
diff --git a/source/lib/dbwrap_util.c b/source/lib/dbwrap_util.c
index 07e5082..09e9071 100644
--- a/source/lib/dbwrap_util.c
+++ b/source/lib/dbwrap_util.c
@@ -98,6 +98,13 @@ bool dbwrap_store_uint32(struct db_context *db, const char *keystr, uint32_t v)
 	return NT_STATUS_IS_OK(status) ? 0 : -1;
 }
 
+/**
+ * Atomic unsigned integer change (addition):
+ *
+ * if value does not exist yet in the db, use *oldval as initial old value.
+ * return old value in *oldval.
+ * store *oldval + change_val to db.
+ */
 uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr,
 				     uint32_t *oldval, uint32_t change_val)
 {
@@ -110,9 +117,13 @@ uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr,
 		return -1;
 	}
 
-	if ((rec->value.dptr != NULL)
-	    && (rec->value.dsize == sizeof(val))) {
+	if (rec->value.dptr == NULL) {
+		val = *oldval;
+	} else if (rec->value.dsize == sizeof(val)) {
 		val = IVAL(rec->value.dptr, 0);
+		*oldval = val;
+	} else {
+		return -1;
 	}
 
 	val += change_val;
@@ -127,6 +138,13 @@ uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr,
 	return 0;
 }
 
+/**
+ * Atomic integer change (addition):
+ *
+ * if value does not exist yet in the db, use *oldval as initial old value.
+ * return old value in *oldval.
+ * store *oldval + change_val to db.
+ */
 int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr,
 				 int32 *oldval, int32 change_val)
 {
@@ -139,9 +157,13 @@ int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr,
 		return -1;
 	}
 
-	if ((rec->value.dptr != NULL)
-	    && (rec->value.dsize == sizeof(val))) {
+	if (rec->value.dptr == NULL) {
+		val = *oldval;
+	} else if (rec->value.dsize == sizeof(val)) {
 		val = IVAL(rec->value.dptr, 0);
+		*oldval = val;
+	} else {
+		return -1;
 	}
 
 	val += change_val;
diff --git a/source/lib/replace/libreplace_cc.m4 b/source/lib/replace/libreplace_cc.m4
index bed0558..30c63f2 100644
--- a/source/lib/replace/libreplace_cc.m4
+++ b/source/lib/replace/libreplace_cc.m4
@@ -167,7 +167,8 @@ AC_CACHE_CHECK([for immediate structures],libreplace_cv_immediate_structures,[
 			FOOBAR y; 
 		} f2[] = {
 			{FOO_ONE}
-		};   
+		};
+		static const FOOBAR f3[] = {FOO_ONE};
 	],
 	libreplace_cv_immediate_structures=yes,
 	libreplace_cv_immediate_structures=no,
diff --git a/source/lib/replace/replace.c b/source/lib/replace/replace.c
index 106c9df..98d799b 100644
--- a/source/lib/replace/replace.c
+++ b/source/lib/replace/replace.c
@@ -170,7 +170,7 @@ int rep_initgroups(char *name, gid_t id)
 #include <grp.h>
 
 	gid_t *grouplst = NULL;
-	int max_gr = 32;
+	int max_gr = NGROUPS_MAX;
 	int ret;
 	int    i,j;
 	struct group *g;
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 632d910..5993cd3 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -797,7 +797,6 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
 	char *principal = NULL;
 	char *OIDs[ASN1_MAX_OIDS];
 	int i;
-	bool got_kerberos_mechanism = False;
 	DATA_BLOB blob;
 	const char *p = NULL;
 	char *account = NULL;
@@ -832,7 +831,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
 		DEBUG(3,("got OID=%s\n", OIDs[i]));
 		if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
 		    strcmp(OIDs[i], OID_KERBEROS5) == 0) {
-			got_kerberos_mechanism = True;
+			cli->got_kerberos_mechanism = True;
 		}
 		free(OIDs[i]);
 	}
@@ -845,7 +844,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
 	/* If password is set we reauthenticate to kerberos server
 	 * and do not store results */
 
-	if (got_kerberos_mechanism && cli->use_kerberos) {
+	if (cli->got_kerberos_mechanism && cli->use_kerberos) {
 		ADS_STATUS rc;
 
 		if (pass && *pass) {
diff --git a/source/libsmb/clifsinfo.c b/source/libsmb/clifsinfo.c
index 0005c39..5e73b61 100644
--- a/source/libsmb/clifsinfo.c
+++ b/source/libsmb/clifsinfo.c
@@ -528,7 +528,7 @@ static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es,
 				&es->s.gss_state->gss_ctx,
 				srv_name,
 				GSS_C_NO_OID, /* default OID. */
-				GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG,
+				GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG,
 				GSS_C_INDEFINITE,	/* requested ticket lifetime. */
 				NULL,   /* no channel bindings */
 				p_tok_in,
diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c
index c289740..f207236 100644
--- a/source/libsmb/clikrb5.c
+++ b/source/libsmb/clikrb5.c
@@ -37,6 +37,18 @@
 #define KRB5_KEY_DATA(k)	((k)->contents)
 #endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
 
+#define GSSAPI_CHECKSUM      0x8003             /* Checksum type value for Kerberos */
+#define GSSAPI_BNDLENGTH     16                 /* Bind Length (rfc-1964 pg.3) */
+#define GSSAPI_CHECKSUM_SIZE (12+GSSAPI_BNDLENGTH)
+
+#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)
+static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context,
+                                         krb5_auth_context *auth_context,
+                                         krb5_creds *credsp,
+                                         krb5_ccache ccache,
+                                         krb5_data *authenticator);
+#endif
+
 /**************************************************************
  Wrappers around kerberos string functions that convert from
  utf8 -> unix charset and vica versa.
@@ -636,6 +648,8 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context,
 	bool creds_ready = False;
 	int i = 0, maxtries = 3;
 	
+	ZERO_STRUCT(in_data);
+
 	retval = smb_krb5_parse_name(context, principal, &server);
 	if (retval) {
 		DEBUG(1,("ads_krb5_mk_req: Failed to parse principal %s\n", principal));
@@ -691,14 +705,69 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context,
 		*expire_time = (time_t)credsp->times.endtime;
 	}
 
-	in_data.length = 0;
+#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)
+	if( credsp->ticket_flags & TKT_FLG_OK_AS_DELEGATE ) {
+		/* Fetch a forwarded TGT from the KDC so that we can hand off a 2nd ticket
+		 as part of the kerberos exchange. */
+
+		DEBUG( 3, ("ads_krb5_mk_req: server marked as OK to delegate to, building forwardable TGT\n")  );
+
+		if( *auth_context == NULL ) {
+			/* Allocate if it has not yet been allocated. */
+			retval = krb5_auth_con_init( context, auth_context );
+			if (retval) {
+				DEBUG(1,("ads_krb5_mk_req: krb5_auth_con_init failed (%s)\n",
+					error_message(retval)));
+				goto cleanup_creds;
+			}
+		}
+
+		retval = krb5_auth_con_setuseruserkey( context, *auth_context, &credsp->keyblock );
+		if (retval) {
+			DEBUG(1,("ads_krb5_mk_req: krb5_auth_con_setuseruserkey failed (%s)\n",
+				error_message(retval)));
+			goto cleanup_creds;
+		}
+
+		/* Must use a subkey for forwarded tickets. */
+		retval = krb5_auth_con_setflags( context, *auth_context, KRB5_AUTH_CONTEXT_USE_SUBKEY);
+		if (retval) {
+			DEBUG(1,("ads_krb5_mk_req: krb5_auth_con_setflags failed (%s)\n",
+				error_message(retval)));
+			goto cleanup_creds;
+		}
+
+		retval = ads_krb5_get_fwd_ticket( context,
+						auth_context,
+						credsp,
+						ccache,
+						&in_data );
+		if (retval) {
+			DEBUG( 1, ("ads_krb5_get_fwd_ticket failed (%s)\n", error_message( retval ) ) );
+			goto cleanup_creds;
+		}
+
+		if (retval) {
+			DEBUG( 1, ("krb5_auth_con_set_req_cksumtype failed (%s)\n",
+				error_message( retval ) ) );
+			goto cleanup_creds;
+		}
+
+	}
+#endif
+
 	retval = krb5_mk_req_extended(context, auth_context, ap_req_options, 
 				      &in_data, credsp, outbuf);
 	if (retval) {
 		DEBUG(1,("ads_krb5_mk_req: krb5_mk_req_extended failed (%s)\n", 
 			 error_message(retval)));
 	}
-	
+
+	if (in_data.data) {
+		free( in_data.data );
+		in_data.length = 0;
+	}
+
 	krb5_free_creds(context, credsp);
 
 cleanup_creds:
@@ -1704,6 +1773,119 @@ done:
  	return ret;
 }
 
+#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)
+/**************************************************************
+Routine: ads_krb5_get_fwd_ticket
+ Description:
+    When a service ticket is flagged as trusted
+    for delegation we should provide a forwardable
+    ticket so that the remote host can act on our
+    behalf.  This is done by taking the 2nd forwardable
+    TGT and storing it in the GSS-API authenticator
+    "checksum".  This routine will populate
+    the krb5_data authenticator with this TGT.
+ Parameters:
+    krb5_context context: The kerberos context for this authentication.
+    krb5_auth_context:    The authentication context.
+    krb5_creds *credsp:   The ticket credentials (AS-REP).
+    krb5_ccache ccache:   The credentials cache.
+    krb5_data &authenticator: The checksum field that will store the TGT, and
+     authenticator.data must be freed by the caller.
+
+ Returns:
+    krb5_error_code: 0 if no errors, otherwise set.
+**************************************************************/
+
+static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context,
+					 krb5_auth_context *auth_context,
+					 krb5_creds *credsp,
+					 krb5_ccache ccache,
+					 krb5_data *authenticator)
+{
+	krb5_data fwdData;
+	krb5_error_code retval = 0;
+	char *pChksum = NULL;
+	char *p = NULL;
+
+	ZERO_STRUCT(fwdData);
+	ZERO_STRUCTP(authenticator);
+
+	retval = krb5_fwd_tgt_creds(context,/* Krb5 context [in] */
+				*auth_context,  /* Authentication context [in] */
+				CONST_DISCARD(char *, KRB5_TGS_NAME),  /* Ticket service name ("krbtgt") [in] */
+				credsp->client, /* Client principal for the tgt [in] */
+				credsp->server, /* Server principal for the tgt [in] */
+				ccache,         /* Credential cache to use for storage [in] */
+				1,              /* Turn on for "Forwardable ticket" [in] */
+				&fwdData );     /* Resulting response [out] */
+
+
+	if (retval) {
+		DEBUG(1,("ads_krb5_get_fwd_ticket: krb5_fwd_tgt_creds failed (%s)\n", 
+			error_message(retval)));
+		goto out;
+	}
+
+	if ((unsigned int)GSSAPI_CHECKSUM_SIZE + (unsigned int)fwdData.length <
+		(unsigned int)GSSAPI_CHECKSUM_SIZE) {
+		retval = EINVAL;
+		goto out;
+	}
+
+	/* We're going to allocate a gssChecksum structure with a little
+	   extra data the length of the kerberos credentials length
+	   (APPLICATION 22) so that we can pack it on the end of the structure.
+	*/
+
+	pChksum	= SMB_MALLOC(GSSAPI_CHECKSUM_SIZE + fwdData.length );
+	if (!pChksum) {
+		retval = ENOMEM;
+		goto out;
+	}
+
+	p = pChksum;
+
+	SIVAL(p, 0, GSSAPI_BNDLENGTH);
+	p += 4;
+
+	/* Zero out the bindings fields */
+	memset(p, '\0', GSSAPI_BNDLENGTH );
+	p += GSSAPI_BNDLENGTH;
+
+	SIVAL(p, 0, GSS_C_DELEG_FLAG );
+	p += 4;
+	SSVAL(p, 0, 1 );
+	p += 2;
+	SSVAL(p, 0, fwdData.length );
+	p += 2;
+
+	/* Migrate the kerberos KRB_CRED data to the checksum delegation */
+	memcpy(p, fwdData.data, fwdData.length );
+	p += fwdData.length;
+
+	/* We need to do this in order to allow our GSS-API  */
+	retval = krb5_auth_con_set_req_cksumtype( context, *auth_context, GSSAPI_CHECKSUM );
+	if (retval) {
+		goto out;
+	}
+
+	/* We now have a service ticket, now turn it into an AP-REQ. */
+	authenticator->length = ntohs(fwdData.length + GSSAPI_CHECKSUM_SIZE);
+
+	/* Caller should call free() when they're done with this. */
+	authenticator->data = (char *)pChksum;
+
+  out:
+
+ 	/* Remove that input data, we never needed it anyway. */
+   	if (fwdData.length > 0) {
+  		krb5_free_data_contents( context, &fwdData );
+   	}
+
+	return retval;
+}
+#endif
+
 #else /* HAVE_KRB5 */
  /* this saves a few linking headaches */
  int cli_krb5_get_ticket(const char *principal, time_t time_offset, 
diff --git a/source/smbd/process.c b/source/smbd/process.c
index 1c28f68..4989c8f 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -1636,6 +1636,7 @@ void chain_reply(struct smb_request *req)
 	char *outbuf = (char *)req->outbuf;
 	size_t outsize = smb_len(outbuf) + 4;
 	size_t outsize_padded;
+	size_t padding;
 	size_t ofs, to_move;
 
 	struct smb_request *req2;
@@ -1674,12 +1675,13 @@ void chain_reply(struct smb_request *req)
 	 */
 
 	outsize_padded = (outsize + 3) & ~3;
+	padding = outsize_padded - outsize;
 
 	/*
 	 * remember how much the caller added to the chain, only counting
 	 * stuff after the parameter words
 	 */
-	chain_size += outsize_padded - smb_wct;
+	chain_size += (outsize_padded - smb_wct);
 
 	/*
 	 * work out pointers into the original packets. The
@@ -1787,17 +1789,17 @@ void chain_reply(struct smb_request *req)
 	SCVAL(outbuf, smb_vwv0, smb_com2);
 	SSVAL(outbuf, smb_vwv1, chain_size + smb_wct - 4);
 
-	if (outsize_padded > outsize) {
+	if (padding != 0) {
 
 		/*
 		 * Due to padding we have some uninitialized bytes after the
 		 * caller's output
 		 */
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list