[PATCH] net cache samlogon list|show|ndrdump|delete (was: RFC: net cache samlogon list|show|delete)

Alexander Bokovoy ab at samba.org
Mon Jul 3 13:41:48 UTC 2017


On ma, 03 heinä 2017, Ralph Böhme via samba-technical wrote:
> On Mon, Jul 03, 2017 at 02:15:35PM +0200, Ralph Böhme via samba-technical wrote:
> > On Mon, Jul 03, 2017 at 01:42:21PM +0200, Ralph Böhme via samba-technical wrote:
> > > On Wed, Jun 28, 2017 at 09:14:44AM +0200, Ralph Böhme wrote:
> > > > On Wed, Jun 28, 2017 at 09:11:40AM +0200, Stefan Metzmacher wrote:
> > > > > Hi Ralph,
> > > > > 
> > > > > >> I'm working on an enhancement to net that will allow the user to work on the
> > > > > >> samlogon cache (netsamlogon_cache.tdb).
> > > > > >>
> > > > > >> I added this as a subcommand to the existing net cache commands. Any better
> > > > > >> suggestions?
> > > > > >>
> > > > > >> Here's what I already have:
> > > > > >>
> > > > > >> $ sudo ./bin/net cache samlogon 
> > > > > >> Invalid command: net cache samlogon 
> > > > > >> Usage:
> > > > > >> net cache samlogon list            List samlogon cache
> > > > > >> net cache samlogon show            Show samlogon cache entry
> > > > > >> net cache samlogon delete          Delete samlogon cache entry
> > > > > >>
> > > > > >> $ sudo ./bin/net cache samlogon list
> > > > > >> SID                                                Name                                     When cached
> > > > > >> ----------------------------------------------------------------------------------------------------------------------------
> > > > > >> S-1-5-21-364438107-531279461-249741216-1000        SLOWSERVER\slow                          Sun Mar 27 12:26:55 PM 2016 CEST
> > > > > >>
> > > > > >> $ sudo ./bin/net cache samlogon show S-1-5-21-364438107-531279461-249741216-1000
> > > > > >> Name: SLOWSERVER\slow
> > > > > >> SID  0: S-1-5-21-364438107-531279461-249741216-1000
> > > > > >> SID  1: S-1-5-21-364438107-531279461-249741216-513
> > > > > > 
> > > > > > fwiw, this lists all groups of the user... Better example:
> > > > > > 
> > > > > > $ sudo ./bin/net cache samlogon show S-1-5-21-364438107-531279461-249741216-1003
> > > > > > Name: SLOWSERVER\slow
> > > > > > SID  0: S-1-5-21-364438107-531279461-249741216-1003
> > > > > > SID  1: S-1-5-21-364438107-531279461-249741216-513
> > > > > > SID  2: S-1-5-21-364438107-531279461-249741216-1010
> > > > > > SID  3: S-1-5-21-364438107-531279461-249741216-1011
> > > > > 
> > > > > A mode that dump the whole cache entry with ndr_print
> > > > > whould be useful, similar to "net primarytrust dumpinfo",
> > > > > see https://git.samba.org/?p=samba.git;a=commitdiff;h=c7c17d9f503d6037aa
> > > > 
> > > > yup, though about that as well. Will add it...
> > > 
> > > patch attached.
> > 
> > here it is.
> 
> attached is an updated version where I removed an overlooked if(0) {...}.
Looks good to me. Missing documentation can be added for RC2.

> 
> Cheerio!
> -slow

> From 8e54f302db8739ca2bcee834c48b7629c16fd16c Mon Sep 17 00:00:00 2001
> From: Ralph Boehme <slow at samba.org>
> Date: Mon, 3 Jul 2017 12:38:22 +0200
> Subject: [PATCH 1/3] netlogon.idl: mark session keys with NDR_SECRET
> 
> Signed-off-by: Ralph Boehme <slow at samba.org>
> ---
>  librpc/idl/netlogon.idl | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/librpc/idl/netlogon.idl b/librpc/idl/netlogon.idl
> index 9a5159d..22f86b9 100644
> --- a/librpc/idl/netlogon.idl
> +++ b/librpc/idl/netlogon.idl
> @@ -231,11 +231,11 @@ interface netlogon
>  		uint32 primary_gid;
>  		samr_RidWithAttributeArray groups;
>  		netr_UserFlags user_flags;
> -		netr_UserSessionKey key;
> +		[flag(NDR_SECRET)] netr_UserSessionKey key;
>  		lsa_StringLarge logon_server;
>  		lsa_StringLarge logon_domain;
>  		dom_sid2 *domain_sid;
> -		netr_LMSessionKey LMSessKey;
> +		[flag(NDR_SECRET)] netr_LMSessionKey LMSessKey;
>  		samr_AcctFlags acct_flags;
>  		uint32 sub_auth_status;
>  		NTTIME last_successful_logon;
> -- 
> 2.9.4
> 
> 
> From 2707477e63bc6fd03f7ab00c01a714b129951f5b Mon Sep 17 00:00:00 2001
> From: Ralph Boehme <slow at samba.org>
> Date: Tue, 27 Jun 2017 17:34:34 +0200
> Subject: [PATCH 2/3] samlogon_cache: add netsamlog_cache_for_all()
> 
> Signed-off-by: Ralph Boehme <slow at samba.org>
> ---
>  source3/libsmb/samlogon_cache.c | 102 ++++++++++++++++++++++++++++++++++++++++
>  source3/libsmb/samlogon_cache.h |   5 ++
>  2 files changed, 107 insertions(+)
> 
> diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c
> index 5a16686..0a2890e 100644
> --- a/source3/libsmb/samlogon_cache.c
> +++ b/source3/libsmb/samlogon_cache.c
> @@ -291,3 +291,105 @@ bool netsamlogon_cache_have(const struct dom_sid *sid)
>  	ok = tdb_exists(netsamlogon_tdb, string_term_tdb_data(keystr));
>  	return ok;
>  }
> +
> +struct netsamlog_cache_forall_state {
> +	TALLOC_CTX *mem_ctx;
> +	int (*cb)(const char *sid_str,
> +		  time_t when_cached,
> +		  struct netr_SamInfo3 *,
> +		  void *private_data);
> +	void *private_data;
> +};
> +
> +static int netsamlog_cache_traverse_cb(struct tdb_context *tdb,
> +				       TDB_DATA key,
> +				       TDB_DATA data,
> +				       void *private_data)
> +{
> +	struct netsamlog_cache_forall_state *state =
> +		(struct netsamlog_cache_forall_state *)private_data;
> +	TALLOC_CTX *mem_ctx = NULL;
> +	DATA_BLOB blob;
> +	const char *sid_str = NULL;
> +	struct dom_sid sid;
> +	struct netsamlogoncache_entry r;
> +	enum ndr_err_code ndr_err;
> +	int ret;
> +	bool ok;
> +
> +	if (key.dsize == 0) {
> +		return 0;
> +	}
> +	if (key.dptr[key.dsize - 1] != '\0') {
> +		return 0;
> +	}
> +	if (data.dptr == NULL) {
> +		return 0;
> +	}
> +	sid_str = (char *)key.dptr;
> +
> +	ok = string_to_sid(&sid, sid_str);
> +	if (!ok) {
> +		DBG_ERR("String to SID failed for %s\n", sid_str);
> +		return -1;
> +	}
> +
> +	if (sid.num_auths != 5) {
> +		return 0;
> +	}
> +
> +	mem_ctx = talloc_new(state->mem_ctx);
> +	if (mem_ctx == NULL) {
> +		return -1;
> +	}
> +
> +	blob = data_blob_const(data.dptr, data.dsize);
> +
> +	ndr_err = ndr_pull_struct_blob(
> +		&blob, state->mem_ctx, &r,
> +		(ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry);
> +
> +	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
> +		DBG_ERR("failed to pull entry from cache\n");
> +		return -1;
> +	}
> +
> +	ret = state->cb(sid_str, r.timestamp, &r.info3, state->private_data);
> +
> +	TALLOC_FREE(mem_ctx);
> +	return ret;
> +}
> +
> +int netsamlog_cache_for_all(int (*cb)(const char *sid_str,
> +				      time_t when_cached,
> +				      struct netr_SamInfo3 *,
> +				      void *private_data),
> +			    void *private_data)
> +{
> +	int ret;
> +	TALLOC_CTX *mem_ctx = NULL;
> +	struct netsamlog_cache_forall_state state;
> +
> +	if (!netsamlogon_cache_init()) {
> +		DBG_ERR("Cannot open %s\n", NETSAMLOGON_TDB);
> +		return -1;
> +	}
> +
> +	mem_ctx = talloc_init("netsamlog_cache_for_all");
> +	if (mem_ctx == NULL) {
> +		return -1;
> +	}
> +
> +	state = (struct netsamlog_cache_forall_state) {
> +		.mem_ctx = mem_ctx,
> +		.cb = cb,
> +		.private_data = private_data,
> +	};
> +
> +	ret = tdb_traverse_read(netsamlogon_tdb,
> +				netsamlog_cache_traverse_cb,
> +				&state);
> +
> +	TALLOC_FREE(state.mem_ctx);
> +	return ret;
> +}
> diff --git a/source3/libsmb/samlogon_cache.h b/source3/libsmb/samlogon_cache.h
> index 221e67b..29e0cea 100644
> --- a/source3/libsmb/samlogon_cache.h
> +++ b/source3/libsmb/samlogon_cache.h
> @@ -37,5 +37,10 @@ bool netsamlogon_cache_store(const char *username,
>  struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx,
>  					    const struct dom_sid *user_sid);
>  bool netsamlogon_cache_have(const struct dom_sid *sid);
> +int netsamlog_cache_for_all(int (*cb)(const char *sid_str,
> +				      time_t when_cached,
> +				      struct netr_SamInfo3 *,
> +				      void *private_data),
> +			    void *private_data);
>  
>  #endif
> -- 
> 2.9.4
> 
> 
> From 0fc3b60f73a38ab48bf8aeb399081bf9f0aba732 Mon Sep 17 00:00:00 2001
> From: Ralph Boehme <slow at samba.org>
> Date: Wed, 28 Jun 2017 07:14:36 +0200
> Subject: [PATCH 3/3] net: add net cache samlogon list|show|delete
> 
> Signed-off-by: Ralph Boehme <slow at samba.org>
> ---
>  source3/utils/net_cache.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 227 insertions(+)
> 
> diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c
> index 4de3a6c..f02cf4d 100644
> --- a/source3/utils/net_cache.c
> +++ b/source3/utils/net_cache.c
> @@ -19,6 +19,10 @@
>  
>  #include "includes.h"
>  #include "net.h"
> +#include "libsmb/samlogon_cache.h"
> +#include "../librpc/gen_ndr/netlogon.h"
> +#include "../librpc/gen_ndr/ndr_netlogon.h"
> +#include "libcli/security/dom_sid.h"
>  
>  /**
>   * @file net_cache.c
> @@ -340,6 +344,221 @@ static int net_cache_stabilize(struct net_context *c, int argc,
>  	}
>  	return 0;
>  }
> +
> +static int netsamlog_cache_for_all_cb(const char *sid_str,
> +				      time_t when_cached,
> +				      struct netr_SamInfo3 *info3,
> +				      void *private_data)
> +{
> +	struct net_context *c = (struct net_context *)private_data;
> +	char *name = NULL;
> +
> +	name = talloc_asprintf(c, "%s\\%s",
> +			       info3->base.logon_domain.string,
> +			       info3->base.account_name.string);
> +	if (name == NULL) {
> +		return -1;
> +	}
> +
> +	d_printf("%-50s %-40s When cached\n", "SID", "Name");
> +	d_printf("------------------------------------------------------------"
> +		 "------------------------------------------------------------"
> +		 "----\n");
> +	d_printf("%-50s %-40s %s\n",
> +		 sid_str,
> +		 name,
> +		 timestring(c, when_cached));
> +
> +	return 0;
> +}
> +
> +static int net_cache_samlogon_list(struct net_context *c,
> +				   int argc,
> +				   const char **argv)
> +{
> +	return netsamlog_cache_for_all(netsamlog_cache_for_all_cb, c);
> +
> +	return 0;
> +}
> +
> +static int net_cache_samlogon_show(struct net_context *c,
> +				   int argc,
> +				   const char **argv)
> +{
> +	const char *sid_str = argv[0];
> +	struct dom_sid sid;
> +	struct dom_sid *user_sids = NULL;
> +	uint32_t num_user_sids;
> +	struct netr_SamInfo3 *info3 = NULL;
> +	char *name = NULL;
> +	uint32_t i;
> +	NTSTATUS status;
> +	bool ok;
> +
> +	if (argc != 1 || c->display_usage) {
> +		d_printf("%s\n"
> +			 "net cache samlogon show SID\n"
> +			 "    %s\n",
> +			 _("Usage:"),
> +			 _("Show samlogon cache entry for SID."));
> +		return 0;
> +	}
> +
> +	ok = string_to_sid(&sid, sid_str);
> +	if (!ok) {
> +		d_printf("String to SID failed for %s\n", sid_str);
> +		return -1;
> +	}
> +
> +	info3 = netsamlogon_cache_get(c, &sid);
> +	if (info3 == NULL) {
> +		d_printf("SID %s not found in samlogon cache\n", sid_str);
> +		return -1;
> +	}
> +
> +	name = talloc_asprintf(c, "%s\\%s",
> +			       info3->base.logon_domain.string,
> +			       info3->base.account_name.string);
> +	if (name == NULL) {
> +		return -1;
> +	}
> +
> +	d_printf("Name: %s\n", name);
> +
> +	status = sid_array_from_info3(c,
> +				      info3,
> +				      &user_sids,
> +				      &num_user_sids,
> +				      true);
> +	if (!NT_STATUS_IS_OK(status)) {
> +		d_printf("sid_array_from_info3 failed for %s\n", sid_str);
> +		return -1;
> +	}
> +
> +	for (i = 0; i < num_user_sids; i++) {
> +		d_printf("SID %2" PRIu32 ": %s\n",
> +			 i, sid_string_dbg(&user_sids[i]));
> +	}
> +
> +	return 0;
> +}
> +
> +static int net_cache_samlogon_ndrdump(struct net_context *c,
> +				      int argc,
> +				      const char **argv)
> +{
> +	const char *sid_str = NULL;
> +	struct dom_sid sid;
> +	struct netr_SamInfo3 *info3 = NULL;
> +	struct ndr_print *ndr_print = NULL;
> +	bool ok;
> +
> +	if (argc != 1 || c->display_usage) {
> +		d_printf(  "%s\n"
> +			   "net cache samlogon ndrdump SID\n"
> +			   "    %s\n",
> +			   _("Usage:"),
> +			   _("Show samlogon cache entry for SID."));
> +		return 0;
> +	}
> +
> +	sid_str = argv[0];
> +
> +	ok = string_to_sid(&sid, sid_str);
> +	if (!ok) {
> +		d_printf("String to SID failed for %s\n", sid_str);
> +		return -1;
> +	}
> +
> +	info3 = netsamlogon_cache_get(c, &sid);
> +	if (info3 == NULL) {
> +		d_printf("SID %s not found in samlogon cache\n", sid_str);
> +		return -1;
> +	}
> +
> +	ndr_print = talloc_zero(c, struct ndr_print);
> +	if (ndr_print == NULL) {
> +		d_printf("Could not allocate memory.\n");
> +		return -1;
> +	}
> +
> +	ndr_print->print = ndr_print_printf_helper;
> +	ndr_print->depth = 1;
> +	ndr_print_netr_SamInfo3(ndr_print, "netr_SamInfo3", info3);
> +	TALLOC_FREE(ndr_print);
> +
> +	return 0;
> +}
> +
> +static int net_cache_samlogon_delete(struct net_context *c,
> +				     int argc,
> +				     const char **argv)
> +{
> +	const char *sid_str = argv[0];
> +	struct dom_sid sid;
> +	bool ok;
> +
> +	if (argc != 1 || c->display_usage) {
> +		d_printf(  "%s\n"
> +			   "net cache samlogon delete SID\n"
> +			   "    %s\n",
> +			 _("Usage:"),
> +			 _("Delete samlogon cache entry for SID."));
> +		return 0;
> +	}
> +
> +	ok = string_to_sid(&sid, sid_str);
> +	if (!ok) {
> +		d_printf("String to SID failed for %s\n", sid_str);
> +		return -1;
> +	}
> +
> +	netsamlogon_clear_cached_user(&sid);
> +
> +	return 0;
> +}
> +
> +static int net_cache_samlogon(struct net_context *c, int argc, const char **argv)
> +{
> +	struct functable func[] = {
> +		{
> +			"list",
> +			net_cache_samlogon_list,
> +			NET_TRANSPORT_LOCAL,
> +			N_("List samlogon cache"),
> +			N_("net cache samlogon list\n"
> +			   "    List samlogon cachen\n")
> +		},
> +		{
> +			"show",
> +			net_cache_samlogon_show,
> +			NET_TRANSPORT_LOCAL,
> +			N_("Show samlogon cache entry"),
> +			N_("net cache samlogon show SID\n"
> +			   "    Show samlogon cache entry\n")
> +		},
> +		{
> +			"ndrdump",
> +			net_cache_samlogon_ndrdump,
> +			NET_TRANSPORT_LOCAL,
> +			N_("Dump the samlogon cache entry NDR blob"),
> +			N_("net cache samlogon ndrdump SID\n"
> +			   "    Dump the samlogon cache entry NDR blob\n")
> +		},
> +		{
> +			"delete",
> +			net_cache_samlogon_delete,
> +			NET_TRANSPORT_LOCAL,
> +			N_("Delete samlogon cache entry"),
> +			N_("net cache samlogon delete SID\n"
> +			   "    Delete samlogon cache entry\n")
> +		},
> +		{NULL, NULL, 0, NULL, NULL}
> +	};
> +
> +	return net_run_function(c, argc, argv, "net cache samlogon", func);
> +}
> +
>  /**
>   * Entry point to 'net cache' subfunctionality
>   *
> @@ -413,6 +632,14 @@ int net_cache(struct net_context *c, int argc, const char **argv)
>  			N_("net cache stabilize\n"
>  			   "  Move transient cache content to stable storage")
>  		},
> +		{
> +			"samlogon",
> +			net_cache_samlogon,
> +			NET_TRANSPORT_LOCAL,
> +			N_("List contents of the samlogon cache"),
> +			N_("net cache samlogon\n"
> +			   "  List contents of the samlogon cache")
> +		},
>  		{NULL, NULL, 0, NULL, NULL}
>  	};
>  
> -- 
> 2.9.4
> 


-- 
/ Alexander Bokovoy



More information about the samba-technical mailing list