[PATCH] net cache samlogon list|show|ndrdump|delete (was: RFC: net cache samlogon list|show|delete)
Ralph Böhme
slow at samba.org
Mon Jul 3 12:34:00 UTC 2017
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) {...}.
Cheerio!
-slow
-------------- next part --------------
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
More information about the samba-technical
mailing list