TNG NTLMSP-related bug (affects XP, pwd change)

Luke Kenneth Casson Leighton lkcl at samba-tng.org
Wed Sep 5 18:26:17 GMT 2001


hi there,

for those people who were trying out XP with tng, for whom i recommended
'client schannel = auto
and server schannel = auto',
could you please try again>


i've discovered a bug in prs_create which had been
changed from a use-mem-passed-in to copy-mem-passed-in
semantics.

the effect that this had on the ntlmssp and netsec (schannel)
code was that packets were being decoded and thrown away instead
of decoded in-place!

diff is attached for those people who wish to review it.

all best,

luke
-------------- next part --------------
Index: include/rpc_creds.h
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/include/rpc_creds.h,v
retrieving revision 1.2
diff -u -r1.2 rpc_creds.h
--- include/rpc_creds.h	2001/08/22 22:39:08	1.2
+++ include/rpc_creds.h	2001/09/05 00:04:03
@@ -27,7 +27,8 @@
 	uint16 version;
 	uint16 command;
 
-	fstring name;
+	fstring pipename;
+	fstring hostname; /* client connecting hostname */
 
 	uint32 ptr_vuser;
 	user_struct *vuser;
Index: include/smb.h
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/include/smb.h,v
retrieving revision 1.13
diff -u -r1.13 smb.h
--- include/smb.h	2001/09/01 17:43:24	1.13
+++ include/smb.h	2001/09/05 00:04:25
@@ -1983,6 +1983,7 @@
 
 struct msrpc_local
 {
+	fstring srv_name;
 	fstring pipe_name;
 	struct ntdom_info nt;
 #if 0
Index: lib/msrpc-agent.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/lib/msrpc-agent.c,v
retrieving revision 1.2
diff -u -r1.2 msrpc-agent.c
--- lib/msrpc-agent.c	2000/10/10 19:24:23	1.2
+++ lib/msrpc-agent.c	2001/09/05 00:04:27
@@ -94,8 +94,6 @@
 		return NULL;
 	}
 
- 	prs_free_data(&ps);
-
 	if (ps.offset != rl)
 	{
 		DEBUG(0,("Buffer size %d %d!\n", ps.offset, rl));
Index: lib/msrpc-client.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/lib/msrpc-client.c,v
retrieving revision 1.3
diff -u -r1.3 msrpc-client.c
--- lib/msrpc-client.c	2001/08/22 22:39:10	1.3
+++ lib/msrpc-client.c	2001/09/05 00:04:31
@@ -145,7 +145,9 @@
 /****************************************************************************
 open the msrpcent sockets
 ****************************************************************************/
-static BOOL ncalrpc_l_connect(struct msrpc_local *msrpc, const char *pipe_name)
+static BOOL ncalrpc_l_connect(struct msrpc_local *msrpc,
+		const char *srv_name,
+		const char *pipe_name)
 {
 	fstring path;
 	fstring pname;
@@ -153,6 +155,7 @@
 	strlower(pname);
 	slprintf(path, sizeof(path) - 1, "%s/.msrpc/%s", LOCKDIR, pname);
 
+	fstrcpy(msrpc->srv_name, srv_name);
 	fstrcpy(msrpc->pipe_name, pipe_name);
 
 	msrpc->fd = open_pipe_sock(path);
@@ -192,7 +195,8 @@
 
 	vuser = get_valid_user_struct(msrpc->nt.vuid);
 
-	if (!create_user_creds(&ps, msrpc->pipe_name, 0x0, command, vuser))
+	if (!create_user_creds(&ps, msrpc->srv_name, msrpc->pipe_name,
+				0x0, command, vuser))
 	{
 		DEBUG(0, ("could not parse credentials\n"));
 		close(sock);
@@ -297,6 +301,7 @@
 establishes a connection right up to doing tconX, reading in a password.
 ****************************************************************************/
 BOOL ncalrpc_l_establish_connection(struct msrpc_local *msrpc,
+				    const char *srv_name,
 				    const char *pipe_name)
 {
 	if (strnequal("\\PIPE\\", pipe_name, 6))
@@ -304,8 +309,13 @@
 		pipe_name = &pipe_name[6];
 	}
 
-	DEBUG(5, ("ncalrpc_l_establish_connection: connecting to %s\n",
-		  pipe_name));
+	if (strnequal("\\\\", srv_name, 2))
+	{
+		pipe_name = &pipe_name[2];
+	}
+
+	DEBUG(5, ("ncalrpc_l_establish_connection: connecting to %s[%s]\n",
+		  srv_name, pipe_name));
 
 	/* establish connection */
 
@@ -316,7 +326,7 @@
 
 	if (msrpc->fd == -1)
 	{
-		if (!ncalrpc_l_connect(msrpc, pipe_name))
+		if (!ncalrpc_l_connect(msrpc, srv_name, pipe_name))
 		{
 			DEBUG(1,
 			      ("ncalrpc_l_establish_connection: failed %s)\n",
Index: msrpc/msrpcd_process.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/msrpc/msrpcd_process.c,v
retrieving revision 1.5
diff -u -r1.5 msrpcd_process.c
--- msrpc/msrpcd_process.c	2001/08/22 22:39:14	1.5
+++ msrpc/msrpcd_process.c	2001/09/05 00:04:34
@@ -228,6 +228,13 @@
 		}
 	}
 
+	/* set the client hostname from the connection */
+	if (!strequal(cmd.hostname, "."))
+	{
+		/* treat \\. - loopback - differently */
+		set_remote_machine (cmd.hostname);
+	}
+
 	/* obtain the remote process id and vuid */
 	if (cmd.vuser == NULL)
 	{
Index: passdb/ldapdb.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/passdb/ldapdb.c,v
retrieving revision 1.2
diff -u -r1.2 ldapdb.c
--- passdb/ldapdb.c	2000/10/11 18:01:11	1.2
+++ passdb/ldapdb.c	2001/09/05 00:04:52
@@ -1268,9 +1268,9 @@
 
 	/* True for reading */
 	prs_create (&ps, bv->bv_val, bv->bv_len, 4, True);
-	safe_free(bv->bv_val);
 
 	ret = smb_io_dom_sid ("berval_to_sid", sid, &ps, 0);
+	safe_free(bv->bv_val);
 
 	if (ret)
 	{
Index: rpc_client/cli_ncalrpc.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/rpc_client/cli_ncalrpc.c,v
retrieving revision 1.2
diff -u -r1.2 cli_ncalrpc.c
--- rpc_client/cli_ncalrpc.c	2001/08/22 22:39:18	1.2
+++ rpc_client/cli_ncalrpc.c	2001/09/05 00:04:55
@@ -28,7 +28,7 @@
 extern int DEBUGLEVEL;
 
 /* create new connection.  strictly speaking, one arg should be
- * full dce/rpc format: e.g "ncalrpc:\\server\pipe\pipename" */
+ * full dce/rpc format: e.g "ncalrpc:server[pipename]" */
 static cli_rpc_info *ncalrpc_connect_add(const char *pipe_name,
 			     uint16 vuid,
 			     const char *srv_name,
@@ -37,7 +37,7 @@
 {
 	cli_rpc_info *ret;
 	become_root(False);
-	ret = ncalrpc_l_use_add(pipe_name, vuid, reuse, is_new_connection);
+	ret = ncalrpc_l_use_add(srv_name, pipe_name, vuid, reuse, is_new_connection);
 	/*
 	 * XXX - this rebinds on the same pipe,
 	 * only necessary, when the loopback connection
Index: rpc_client/ncalrpc_l_use.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/rpc_client/ncalrpc_l_use.c,v
retrieving revision 1.5
diff -u -r1.5 ncalrpc_l_use.c
--- rpc_client/ncalrpc_l_use.c	2001/08/24 18:34:03	1.5
+++ rpc_client/ncalrpc_l_use.c	2001/09/05 00:04:58
@@ -107,7 +107,8 @@
 find client state.  server name, user name, vuid name and password must all
 match.
 ****************************************************************************/
-static struct ncalrpc_use *ncalrpc_l_find(const char *pipe_name,
+static struct ncalrpc_use *ncalrpc_l_find(const char *srv_name,
+					const char *pipe_name,
 					  uint16 vuid, BOOL reuse)
 {
 	int i;
@@ -117,6 +118,7 @@
 
 	for (i = 0; i < num_clis; i++)
 	{
+		char *cli_srvname = NULL;
 		char *cli_name = NULL;
 		struct ncalrpc_use *c = clis[i];
 
@@ -125,12 +127,17 @@
 			continue;
 		}
 
+		cli_srvname = c->cli->srv_name;
 		cli_name = c->cli->pipe_name;
 
-		DEBUG(10, ("ncalrpc_l_find[%d]: %s [%x]\n",
-			   i, cli_name,
+		DEBUG(10, ("ncalrpc_l_find[%d]: %s[%s] [%x]\n",
+			   i, cli_srvname, cli_name,
 			   c->cli->nt.vuid));
 
+		if (!strequal(cli_srvname, srv_name))
+		{
+			continue;
+		}
 		if (!strequal(cli_name, pipe_name))
 		{
 			continue;
@@ -151,8 +158,7 @@
 /****************************************************************************
 create a new client state from user credentials
 ****************************************************************************/
-static struct ncalrpc_use *ncalrpc_use_get(const char *pipe_name,
-					   uint16 vuid)
+static struct ncalrpc_use *ncalrpc_use_get(uint16 vuid)
 {
 	struct ncalrpc_use *cli = (struct ncalrpc_use *)malloc(sizeof(*cli));
 
@@ -176,7 +182,8 @@
 /****************************************************************************
 init client state
 ****************************************************************************/
-struct msrpc_local *ncalrpc_l_use_add(const char *pipe_name,
+struct msrpc_local *ncalrpc_l_use_add(const char *srv_name,
+					const char *pipe_name,
 				      uint16 vuid,
 				      BOOL reuse, BOOL *is_new)
 {
@@ -184,12 +191,17 @@
 
 	DEBUG(10, ("ncalrpc_l_use_add\n"));
 
+	if (strnequal("\\\\", srv_name, 2))
+	{
+		srv_name = &srv_name[6];
+	}
+
 	if (strnequal("\\PIPE\\", pipe_name, 6))
 	{
 		pipe_name = &pipe_name[6];
 	}
 
-	cli = ncalrpc_l_find(pipe_name, vuid, reuse);
+	cli = ncalrpc_l_find(srv_name, pipe_name, vuid, reuse);
 
 	if (cli != NULL)
 	{
@@ -204,13 +216,13 @@
 	 * allocate
 	 */
 
-	cli = ncalrpc_use_get(pipe_name, vuid);
+	cli = ncalrpc_use_get(vuid);
 
 	/*
 	 * connect
 	 */
 
-	if (!ncalrpc_l_establish_connection(cli->cli, pipe_name))
+	if (!ncalrpc_l_establish_connection(cli->cli, srv_name, pipe_name))
 	{
 		DEBUG(0, ("ncalrpc_l_use_add: connection failed\n"));
 		ncalrpc_use_free(cli);
Index: rpc_parse/parse_creds.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/rpc_parse/parse_creds.c,v
retrieving revision 1.3
diff -u -r1.3 parse_creds.c
--- rpc_parse/parse_creds.c	2001/08/22 22:39:19	1.3
+++ rpc_parse/parse_creds.c	2001/09/05 00:04:59
@@ -59,10 +59,11 @@
 
 	prs_align(ps);
 
-	prs_uint16("version", ps, depth, &(r_u->version));
-	prs_uint16("command", ps, depth, &(r_u->command));
+	prs_uint16("version ", ps, depth, &(r_u->version));
+	prs_uint16("command ", ps, depth, &(r_u->command));
 
-	prs_string("name   ", ps, depth,   r_u->name, strlen(r_u->name), sizeof(r_u->name));
+	prs_string("pipename", ps, depth,   r_u->pipename, strlen(r_u->pipename), sizeof(r_u->pipename));
+	prs_string("hostname", ps, depth,   r_u->hostname, strlen(r_u->hostname), sizeof(r_u->hostname));
 	prs_align(ps);
 	
 	prs_uint32("ptr_vuser", ps, depth, &(r_u->ptr_vuser));
@@ -83,7 +84,8 @@
 
 
 BOOL create_user_creds( prs_struct *ps,
-				const char* name, 
+				const char* pipe_name, 
+				const char* client_host_name, 
 				uint16 version, uint16 command,
 				const user_struct *usr)
 {
@@ -91,10 +93,11 @@
 
 	ZERO_STRUCT(cmd);
 
-	DEBUG(10,("create_user_creds: %s %d %d\n",
-		name, version, command));
+	DEBUG(10,("create_user_creds: ncacn_np:%s[%s] %d %d\n",
+		client_host_name, pipe_name, version, command));
 
-	fstrcpy(cmd.name, name);
+	fstrcpy(cmd.pipename, pipe_name);
+	fstrcpy(cmd.hostname, client_host_name);
 	cmd.version = version;
 	cmd.command = command;
 	cmd.ptr_vuser = usr != NULL ? 1 : 0;
Index: rpc_parse/parse_prs.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/rpc_parse/parse_prs.c,v
retrieving revision 1.6
diff -u -r1.6 parse_prs.c
--- rpc_parse/parse_prs.c	2001/08/21 19:00:12	1.6
+++ rpc_parse/parse_prs.c	2001/09/05 00:05:15
@@ -157,12 +157,9 @@
 		    data, size, align, BOOLSTR(io)));
 
 	prs_init(ps, 0, align, io);
-	prs_append_data(ps, data, size);
-	if (MARSHALLING(ps))
-	{
-		DEBUG(4, ("WARNING: prs_create initialised a buffer "
-			  "in marshalling-mode\n"));
-	}
+	ps->data = data;
+	ps->data_size = size;
+	ps->end = ps->start + size;
 
 	CHECK_STRUCT(ps);
 }
@@ -350,7 +347,7 @@
 	{
 		CHECK_STRUCT(ps);
 		/* delete data in this structure */
-		/* prs_sma_region should realy already be initialised */
+		/* prs_sma_region should really already be initialised */
 		sma_free(prs_sma_region, ps->data);
 		ps->data = NULL;
 	}
@@ -1649,8 +1646,8 @@
 
 	data = tdb_fetch(tdb, key);
 
-	prs_create(pd, data.dptr, data.dsize, 4, True);
-	safe_free(data.dptr);
+	prs_init(pd, 0, 4, True);
+	prs_append_data(pd, data.dptr, data.dsize);
 }
 
 
@@ -1677,8 +1674,8 @@
 	if (!dbuf.dptr) return -1;
 
 	ZERO_STRUCTP(ps);
-	prs_create(ps, dbuf.dptr, dbuf.dsize, 4, UNMARSHALL);
-	safe_free(dbuf.dptr);
+	prs_init(ps, 0, 4, UNMARSHALL);
+	prs_append_data(ps, dbuf.dptr, dbuf.dsize);
 
 	return 0;
 }
Index: rpc_server/srv_pipe_hnd.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/rpc_server/srv_pipe_hnd.c,v
retrieving revision 1.6
diff -u -r1.6 srv_pipe_hnd.c
--- rpc_server/srv_pipe_hnd.c	2001/08/22 22:39:20	1.6
+++ rpc_server/srv_pipe_hnd.c	2001/09/05 00:05:17
@@ -83,6 +83,7 @@
 	pipes_struct *p;
 	static int next_pipe;
 	struct msrpc_local *m = NULL;
+	extern fstring remote_machine;
 
 	DEBUG(4, ("Open pipe requested %s by [%x] (pipes_open=%d)\n",
 		  pipe_name, vuid, pipes_open));
@@ -120,7 +121,8 @@
 	{
 		BOOL is_new;
 		become_root(False);	/* to make pipe connection */
-		m = ncalrpc_l_use_add(pipe_name, vuid, False, &is_new);
+		m = ncalrpc_l_use_add(remote_machine, pipe_name,
+				vuid, False, &is_new);
 		unbecome_root(False);
 		if (m == NULL)
 		{
Index: samrd/srv_samr_dom_tdb.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/samrd/srv_samr_dom_tdb.c,v
retrieving revision 1.3
diff -u -r1.3 srv_samr_dom_tdb.c
--- samrd/srv_samr_dom_tdb.c	2001/07/26 16:38:48	1.3
+++ samrd/srv_samr_dom_tdb.c	2001/09/05 00:05:26
@@ -73,13 +73,13 @@
 	}
 
 	prs_create(&ps, dbuf.dptr, dbuf.dsize, 4, True);
-	safe_free(dbuf.dptr);
 
 	usr = &data->usr[data->num_sam_entries];
 	if (sam_io_user_info21("usr", usr, &ps, 0))
 	{
 		data->num_sam_entries++;
 	}
+	safe_free(dbuf.dptr);
 
 	return 0;
 }
Index: samrd/srv_samr_sam_tdb.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/samrd/srv_samr_sam_tdb.c,v
retrieving revision 1.4
diff -u -r1.4 srv_samr_sam_tdb.c
--- samrd/srv_samr_sam_tdb.c	2001/07/26 16:38:49	1.4
+++ samrd/srv_samr_sam_tdb.c	2001/09/05 00:05:29
@@ -83,7 +83,6 @@
 	ZERO_STRUCTP(str);
 
 	prs_create(&key, kbuf.dptr, kbuf.dsize, 4, True);
-	safe_free(kbuf.dptr);
 
 	if (smb_io_unistr2("dom", str, True, &key, 0))
 	{
@@ -92,6 +91,7 @@
 
 		data->num_sam_entries++;
 	}
+	safe_free(kbuf.dptr);
 
 	return 0;
 }
Index: smbd/ipc.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/smbd/ipc.c,v
retrieving revision 1.6
diff -u -r1.6 ipc.c
--- smbd/ipc.c	2001/07/26 16:06:42	1.6
+++ smbd/ipc.c	2001/09/05 00:05:35
@@ -196,11 +196,10 @@
 {
 	prs_struct ps;
 	prs_create(&ps, rdata, rlen, 0, UNMARSHALL);
-	safe_free(rdata);
 	prs_debug_out(&ps, "api_rpc_trans_reply", 200);
 	send_trans_reply(outbuf, &ps, NULL, NULL, 0, rlen,
 			 pipe_data_outstanding);
-	prs_free_data(&ps);
+	safe_free(rdata);
 }
 
 /****************************************************************************
Index: smbd/lanman.c
===================================================================
RCS file: /home/cvsroot/dcerpc/tng/source/smbd/lanman.c,v
retrieving revision 1.8
diff -u -r1.8 lanman.c
--- smbd/lanman.c	2001/08/22 22:39:22	1.8
+++ smbd/lanman.c	2001/09/05 00:06:09
@@ -3325,15 +3325,10 @@
 				&rdata, &rparam, &rdata_len, &rparam_len);
 
 	prs_create(&rdata_buf, rdata, rdata_len, 0, UNMARSHALL);
-	safe_free(rdata);
 	prs_create(&rparam_buf, rparam, rparam_len, 0, UNMARSHALL);
-	safe_free(rparam);
 
 	/* now send the reply */
 	send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0, False);
-
-	prs_free_data(&rdata_buf);
-	prs_free_data(&rparam_buf);
 
 	return -1;
 }


More information about the samba-technical mailing list