[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