From d5c9172adadb83283e437578be7bad4368ad9f20 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 28 Aug 2001 06:43:43 +0000 Subject: Merge of sam sync code from TNG. Reverse-engineered the sam replication protocol from staring at hex dumps for a while. It's pretty similar to the sam sync protocol with a couple of different delta header types. I wasn't able to figure out the format of the privilege stuff - needs more time and a whiteboard. (-: The impressive bit is that the sam sync stuff from tng basically just worked thanks mainly to Luke Leighton's efforts in this area. (This used to be commit 3a60cb44f22d5f3f8c78a56ed8f5ea4794cd7ab3) --- source3/rpcclient/cmd_netlogon.c | 220 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 217 insertions(+), 3 deletions(-) (limited to 'source3/rpcclient/cmd_netlogon.c') diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 410fd7fb0a..1b49387558 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -81,7 +81,7 @@ static uint32 cmd_netlogon_logon_ctrl(struct cli_state *cli, int argc, /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_NETLOGON)) { - DEBUG(0, ("Could not initialize srvsvc pipe!\n")); + DEBUG(0, ("Could not initialize netlogon pipe!\n")); goto done; } @@ -98,14 +98,228 @@ static uint32 cmd_netlogon_logon_ctrl(struct cli_state *cli, int argc, return result; } +/* Display sam synchronisation information */ + +static void display_sam_sync(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas, + SAM_DELTA_CTR *deltas) +{ + fstring name; + uint32 i, j; + + for (i = 0; i < num_deltas; i++) { + switch (hdr_deltas[i].type) { + case SAM_DELTA_DOMAIN_INFO: + unistr2_to_ascii(name, + &deltas[i].domain_info.uni_dom_name, + sizeof(name) - 1); + DEBUG(0, ("Domain: %s\n", name)); + break; + case SAM_DELTA_GROUP_INFO: + unistr2_to_ascii(name, + &deltas[i].group_info.uni_grp_name, + sizeof(name) - 1); + DEBUG(0, ("Group: %s\n", name)); + break; + case SAM_DELTA_ACCOUNT_INFO: + unistr2_to_ascii(name, + &deltas[i].account_info.uni_acct_name, + sizeof(name) - 1); + DEBUG(0, ("Account: %s\n", name)); + break; + case SAM_DELTA_ALIAS_INFO: + unistr2_to_ascii(name, + &deltas[i].alias_info.uni_als_name, + sizeof(name) - 1); + DEBUG(0, ("Alias: %s\n", name)); + break; + case SAM_DELTA_ALIAS_MEM: { + SAM_ALIAS_MEM_INFO *alias = &deltas[i].als_mem_info; + + for (j = 0; j < alias->num_members; j++) { + fstring sid_str; + + sid_to_string(sid_str, &alias->sids[j].sid); + + DEBUG(0, ("%s\n", sid_str)); + } + break; + } + case SAM_DELTA_GROUP_MEM: { + SAM_GROUP_MEM_INFO *group = &deltas[i].grp_mem_info; + + for (j = 0; j < group->num_members; j++) + DEBUG(0, ("rid 0x%x, attrib 0x%08x\n", + group->rids[j], group->attribs[j])); + break; + } + case SAM_DELTA_SAM_STAMP: { + SAM_DELTA_STAMP *stamp = &deltas[i].stamp; + + DEBUG(0, ("sam sequence update: 0x%04x\n", + stamp->seqnum)); + break; + } + default: + DEBUG(0, ("unknown delta type 0x%02x\n", + hdr_deltas[i].type)); + break; + } + } +} + +/* Perform sam synchronisation */ + +static uint32 cmd_netlogon_sam_sync(struct cli_state *cli, int argc, + char **argv) +{ + uint32 result = NT_STATUS_UNSUCCESSFUL; + unsigned char trust_passwd[16]; + TALLOC_CTX *mem_ctx; + uint32 database_id = 0, num_deltas; + SAM_DELTA_HDR *hdr_deltas; + SAM_DELTA_CTR *deltas; + + if (argc > 2) { + printf("Usage: %s [database_id]\n", argv[0]); + return 0; + } + + if (argc == 2) + database_id = atoi(argv[1]); + + if (!secrets_init()) { + DEBUG(0, ("Unable to initialise secrets database\n")); + return result; + } + + if (!(mem_ctx = talloc_init())) { + DEBUG(0,("talloc_init failed\n")); + return result; + } + + /* Initialise RPC connection */ + + if (!cli_nt_session_open (cli, PIPE_NETLOGON)) { + DEBUG(0, ("Could not initialize netlogon pipe!\n")); + goto done; + } + + /* Initialise session credentials */ + + if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, + NULL)) { + DEBUG(0, ("could not fetch trust account password\n")); + goto done; + } + + if (!cli_nt_setup_creds(cli, trust_passwd)) { + DEBUG(0, ("Error initialising session creds\n")); + goto done; + } + + /* Synchronise sam database */ + + if ((result = cli_netlogon_sam_sync(cli, mem_ctx, database_id, + &num_deltas, &hdr_deltas, &deltas)) + != NT_STATUS_OK) { + goto done; + } + + /* Display results */ + + display_sam_sync(num_deltas, hdr_deltas, deltas); + + done: + cli_nt_session_close(cli); + talloc_destroy(mem_ctx); + + return result; +} + +/* Perform sam delta synchronisation */ + +static uint32 cmd_netlogon_sam_deltas(struct cli_state *cli, int argc, + char **argv) +{ + uint32 result = NT_STATUS_UNSUCCESSFUL; + unsigned char trust_passwd[16]; + TALLOC_CTX *mem_ctx = NULL; + uint32 database_id, num_deltas, tmp; + SAM_DELTA_HDR *hdr_deltas; + SAM_DELTA_CTR *deltas; + UINT64_S seqnum; + + if (argc != 3) { + printf("Usage: %s database_id seqnum\n", argv[0]); + return 0; + } + + database_id = atoi(argv[1]); + tmp = atoi(argv[2]); + + seqnum.low = tmp & 0xffff; + seqnum.high = 0; + + if (!secrets_init()) { + DEBUG(0, ("Unable to initialise secrets database\n")); + goto done; + } + + if (!(mem_ctx = talloc_init())) { + DEBUG(0,("talloc_init failed\n")); + goto done; + } + + /* Initialise RPC connection */ + + if (!cli_nt_session_open (cli, PIPE_NETLOGON)) { + DEBUG(0, ("Could not initialize netlogon pipe!\n")); + goto done; + } + + /* Initialise session credentials */ + + if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, + NULL)) { + DEBUG(0, ("could not fetch trust account password\n")); + goto done; + } + + if (!cli_nt_setup_creds(cli, trust_passwd)) { + DEBUG(0, ("Error initialising session creds\n")); + goto done; + } + + /* Synchronise sam database */ + + if ((result = cli_netlogon_sam_deltas(cli, mem_ctx, database_id, + seqnum, &num_deltas, + &hdr_deltas, &deltas)) + != NT_STATUS_OK) { + goto done; + } + + /* Display results */ + + display_sam_sync(num_deltas, hdr_deltas, deltas); + + done: + cli_nt_session_close(cli); + talloc_destroy(mem_ctx); + + return result; +} + /* List of commands exported by this module */ struct cmd_set netlogon_commands[] = { { "NETLOGON" }, - { "logonctrl2", cmd_netlogon_logon_ctrl2, "Logon Control 2", "" }, - { "logonctrl", cmd_netlogon_logon_ctrl, "Logon Control", "" }, + { "logonctrl2", cmd_netlogon_logon_ctrl2, "Logon Control 2", "" }, + { "logonctrl", cmd_netlogon_logon_ctrl, "Logon Control", "" }, + { "samsync", cmd_netlogon_sam_sync, "Sam Synchronisation", "" }, + { "samdeltas", cmd_netlogon_sam_deltas, "Query Sam Deltas", "" }, { NULL } }; -- cgit