diff options
Diffstat (limited to 'source3/rpcclient')
-rw-r--r-- | source3/rpcclient/cmd_lsarpc.c | 67 | ||||
-rw-r--r-- | source3/rpcclient/cmd_netlogon.c | 6 | ||||
-rw-r--r-- | source3/rpcclient/cmd_samr.c | 75 | ||||
-rw-r--r-- | source3/rpcclient/cmd_spoolss.c | 80 | ||||
-rw-r--r-- | source3/rpcclient/cmd_srvsvc.c | 2 | ||||
-rw-r--r-- | source3/rpcclient/rpcclient.c | 10 | ||||
-rw-r--r-- | source3/rpcclient/samsync.c | 411 |
7 files changed, 477 insertions, 174 deletions
diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 067325c06e..194e498122 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -32,7 +32,8 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID dom_sid; - fstring sid_str, domain_name; + GUID dom_guid; + fstring sid_str, domain_name="", dns_name="", forest_name=""; uint32 info_class = 3; if (argc > 2) { @@ -43,17 +44,31 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, if (argc == 2) info_class = atoi(argv[1]); - result = cli_lsa_open_policy(cli, mem_ctx, True, + /* Lookup info policy */ + switch (info_class) { + case 12: + result = cli_lsa_open_policy2(cli, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + result = cli_lsa_query_info_policy2(cli, mem_ctx, &pol, + info_class, domain_name, + dns_name, forest_name, + &dom_guid, &dom_sid); + break; + default: + result = cli_lsa_open_policy(cli, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); - if (!NT_STATUS_IS_OK(result)) - goto done; - - /* Lookup info policy */ - - result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, - domain_name, &dom_sid); + if (!NT_STATUS_IS_OK(result)) + goto done; + result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, + info_class, domain_name, + &dom_sid); + } if (!NT_STATUS_IS_OK(result)) goto done; @@ -65,6 +80,22 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, else printf("could not query info for level %d\n", info_class); + if (dns_name[0]) + printf("domain dns name is %s\n", dns_name); + if (forest_name[0]) + printf("forest name is %s\n", forest_name); + + if (info_class == 12) { + int i; + uint32 *data1 = (uint32 *) dom_guid.info; + uint16 *data2 = (uint16 *) &dom_guid.info[4]; + uint16 *data3 = (uint16 *) &dom_guid.info[6]; + printf("domain GUID is %08x-%04x-%04x", *data1,*data2,*data3); + printf("-%02x%02x-", dom_guid.info[8], dom_guid.info[9]); + for (i=10;i<GUID_SIZE;i++) + printf("%02x", dom_guid.info[i]); + printf("\n"); + } done: return result; } @@ -191,23 +222,15 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli, /* defaults, but may be changed using params */ uint32 enum_ctx = 0; - uint32 preferred_maxnum = 5; uint32 num_domains = 0; int i; - if (argc > 3) { - printf("Usage: %s [preferred max number (%d)] [enum context (0)]\n", - argv[0], preferred_maxnum); + if (argc > 2) { + printf("Usage: %s [enum context (0)]\n", argv[0]); return NT_STATUS_OK; } - /* enumeration context */ - if (argc >= 2 && argv[1]) { - preferred_maxnum = atoi(argv[1]); - } - - /* preferred maximum number */ - if (argc == 3 && argv[2]) { + if (argc == 2 && argv[1]) { enum_ctx = atoi(argv[2]); } @@ -221,8 +244,8 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli, /* Lookup list of trusted domains */ result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx, - &preferred_maxnum, &num_domains, - &domain_names, &domain_sids); + &num_domains, + &domain_names, &domain_sids); if (!NT_STATUS_IS_OK(result) && !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 2e89572660..c3bc9e5e13 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -174,7 +174,7 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli, goto done; } - result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd); if (!NT_STATUS_IS_OK(result)) { @@ -238,7 +238,7 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli, goto done; } - result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd); if (!NT_STATUS_IS_OK(result)) { @@ -301,7 +301,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli, goto done; } - result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd); if (!NT_STATUS_IS_OK(result)) { diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index eae24683d2..d9251f90bd 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -243,6 +243,22 @@ static void display_sam_info_5(SAM_ENTRY5 *e5, SAM_STR5 *s5) } +/**************************************************************************** + Try samr_connect4 first, then samr_conenct if it fails + ****************************************************************************/ +static NTSTATUS try_samr_connects(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 access_mask, POLICY_HND *connect_pol) +{ + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + result = cli_samr_connect4(cli, mem_ctx, access_mask, connect_pol); + if (!NT_STATUS_IS_OK(result)) { + result = cli_samr_connect(cli, mem_ctx, access_mask, + connect_pol); + } + return result; +} + /********************************************************************** * Query user information */ @@ -275,8 +291,8 @@ static NTSTATUS cmd_samr_query_user(struct cli_state *cli, slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -383,8 +399,8 @@ static NTSTATUS cmd_samr_query_group(struct cli_state *cli, slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -447,8 +463,8 @@ static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli, slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -513,8 +529,8 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli, slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -576,8 +592,8 @@ static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli, slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -635,8 +651,8 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct cli_state *cli, /* Get sam policy handle */ - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -711,8 +727,8 @@ static NTSTATUS cmd_samr_enum_als_groups(struct cli_state *cli, /* Get sam policy handle */ - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -794,8 +810,8 @@ static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli, /* Open SAMR handle */ - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -878,7 +894,8 @@ static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli, /* Get sam policy handle */ - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -983,8 +1000,8 @@ static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli, /* Get sam policy handle */ - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -1053,8 +1070,8 @@ static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli, /* Get sam policy handle */ - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -1109,8 +1126,8 @@ static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli, /* Get sam policy and domain handles */ - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -1174,8 +1191,8 @@ static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli, /* Get sam policy and domain handles */ - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -1231,8 +1248,8 @@ static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli, /* Get sam policy and domain handles */ - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -1312,8 +1329,8 @@ static NTSTATUS cmd_samr_query_sec_obj(struct cli_state *cli, slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 47e3f123ba..22e2db41f3 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1796,6 +1796,85 @@ done: return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } +static NTSTATUS cmd_spoolss_rffpcnex(struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, + char **argv) +{ + fstring servername, printername; + POLICY_HND hnd; + BOOL got_hnd = False; + WERROR result; + SPOOL_NOTIFY_OPTION option; + + if (argc != 2) { + printf("Usage: %s printername\n", argv[0]); + result = WERR_OK; + goto done; + } + + /* Open printer */ + + slprintf(servername, sizeof(fstring) - 1, "\\\\%s", cli->desthost); + strupper(servername); + + slprintf(printername, sizeof(fstring) - 1, "\\\\%s\\%s", cli->desthost, + argv[1]); + strupper(printername); + + result = cli_spoolss_open_printer_ex( + cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, + servername, cli->user_name, &hnd); + + if (!W_ERROR_IS_OK(result)) { + printf("Error opening %s\n", argv[1]); + goto done; + } + + got_hnd = True; + + /* Create spool options */ + + ZERO_STRUCT(option); + + option.version = 2; + option.option_type_ptr = 1; + option.count = option.ctr.count = 2; + + option.ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)talloc( + mem_ctx, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * 2); + + ZERO_STRUCT(option.ctr.type[0]); + option.ctr.type[0].type = PRINTER_NOTIFY_TYPE; + option.ctr.type[0].count = option.ctr.type[0].count2 = 1; + option.ctr.type[0].fields_ptr = 1; + option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME; + + ZERO_STRUCT(option.ctr.type[1]); + option.ctr.type[1].type = JOB_NOTIFY_TYPE; + option.ctr.type[1].count = option.ctr.type[1].count2 = 1; + option.ctr.type[1].fields_ptr = 1; + option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME; + + /* Send rffpcnex */ + + slprintf(servername, sizeof(fstring) - 1, "\\\\%s", myhostname()); + strupper(servername); + + result = cli_spoolss_rffpcnex( + cli, mem_ctx, &hnd, 0, 0, servername, 123, &option); + + if (!W_ERROR_IS_OK(result)) { + printf("Error rffpcnex %s\n", argv[1]); + goto done; + } + +done: + if (got_hnd) + cli_spoolss_close_printer(cli, mem_ctx, &hnd); + + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + /* List of commands exported by this module */ struct cmd_set spoolss_commands[] = { @@ -1824,6 +1903,7 @@ struct cmd_set spoolss_commands[] = { { "enumforms", cmd_spoolss_enum_forms, PIPE_SPOOLSS, "Enumerate forms", "" }, { "setprinter", cmd_spoolss_setprinter, PIPE_SPOOLSS, "Set printer comment", "" }, { "setprinterdata", cmd_spoolss_setprinterdata, PIPE_SPOOLSS, "Set REG_SZ printer data", "" }, + { "rffpcnex", cmd_spoolss_rffpcnex, PIPE_SPOOLSS, "Rffpcnex test", "" }, { NULL } }; diff --git a/source3/rpcclient/cmd_srvsvc.c b/source3/rpcclient/cmd_srvsvc.c index 43bfb25048..8d416f8db0 100644 --- a/source3/rpcclient/cmd_srvsvc.c +++ b/source3/rpcclient/cmd_srvsvc.c @@ -270,7 +270,7 @@ static NTSTATUS cmd_srvsvc_net_share_enum(struct cli_state *cli, result = cli_srvsvc_net_share_enum( cli, mem_ctx, info_level, &ctr, preferred_len, &hnd); - if (!W_ERROR_IS_OK(result)) + if (!W_ERROR_IS_OK(result) || !ctr.num_entries) goto done; /* Display results */ diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index a62c3d8365..2d86fb1d3d 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -612,7 +612,6 @@ static void usage(void) *opt_configfile=NULL, *opt_logfile=NULL, *opt_ipaddr=NULL; - static int opt_debuglevel; pstring logfile; struct cmd_set **cmd_set; struct in_addr server_ip; @@ -626,14 +625,13 @@ static void usage(void) {"authfile", 'A', POPT_ARG_STRING, &opt_authfile, 'A'}, {"conf", 's', POPT_ARG_STRING, &opt_configfile, 's'}, {"nopass", 'N', POPT_ARG_NONE, &got_pass}, - {"debug", 'd', POPT_ARG_INT, &opt_debuglevel, 'd'}, - {"debuglevel", 'd', POPT_ARG_INT, &opt_debuglevel, 'd'}, {"user", 'U', POPT_ARG_STRING, &opt_username, 'U'}, {"workgroup", 'W', POPT_ARG_STRING, &opt_domain, 'W'}, {"command", 'c', POPT_ARG_STRING, &cmdstr}, {"logfile", 'l', POPT_ARG_STRING, &opt_logfile, 'l'}, {"help", 'h', POPT_ARG_NONE, 0, 'h'}, {"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I'}, + { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug }, { NULL } }; @@ -673,10 +671,6 @@ static void usage(void) pstrcpy(dyn_CONFIGFILE, opt_configfile); break; - case 'd': - DEBUGLEVEL = opt_debuglevel; - break; - case 'U': { char *lp; @@ -768,7 +762,7 @@ static void usage(void) password, 0); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(1,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status))); + DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status))); return 1; } diff --git a/source3/rpcclient/samsync.c b/source3/rpcclient/samsync.c index 5b64cbc47d..3694eb47df 100644 --- a/source3/rpcclient/samsync.c +++ b/source3/rpcclient/samsync.c @@ -1,8 +1,8 @@ /* Unix SMB/CIFS implementation. - RPC pipe client + SAM synchronisation and replication - Copyright (C) Tim Potter 2001 + Copyright (C) Tim Potter 2001,2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +21,8 @@ #include "includes.h" +DOM_SID domain_sid; + static void decode_domain_info(SAM_DOMAIN_INFO *a) { fstring temp; @@ -252,20 +254,124 @@ static void decode_sam_deltas(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas, SAM_ } } +/* Convert a SAM_ACCOUNT_DELTA to a SAM_ACCOUNT. */ + +static void sam_account_from_delta(SAM_ACCOUNT *account, + SAM_ACCOUNT_INFO *delta) +{ + DOM_SID sid; + fstring s; + + /* Username, fullname, home dir, dir drive, logon script, acct + desc, workstations, profile. */ + + unistr2_to_ascii(s, &delta->uni_acct_name, sizeof(s) - 1); + pdb_set_nt_username(account, s); + + /* Unix username is the same - for sainity */ + pdb_set_username(account, s); + + unistr2_to_ascii(s, &delta->uni_full_name, sizeof(s) - 1); + pdb_set_fullname(account, s); + + unistr2_to_ascii(s, &delta->uni_home_dir, sizeof(s) - 1); + pdb_set_homedir(account, s, True); + + unistr2_to_ascii(s, &delta->uni_dir_drive, sizeof(s) - 1); + pdb_set_dir_drive(account, s, True); + + unistr2_to_ascii(s, &delta->uni_logon_script, sizeof(s) - 1); + pdb_set_logon_script(account, s, True); + + unistr2_to_ascii(s, &delta->uni_acct_desc, sizeof(s) - 1); + pdb_set_acct_desc(account, s); + + unistr2_to_ascii(s, &delta->uni_workstations, sizeof(s) - 1); + pdb_set_workstations(account, s); + + unistr2_to_ascii(s, &delta->uni_profile, sizeof(s) - 1); + pdb_set_profile_path(account, s, True); + + /* User and group sid */ + + sid_copy(&sid, &domain_sid); + sid_append_rid(&sid, delta->user_rid); + pdb_set_user_sid(account, &sid); + + sid_copy(&sid, &domain_sid); + sid_append_rid(&sid, delta->group_rid); + pdb_set_group_sid(account, &sid); + + /* Logon and password information */ + + pdb_set_logon_time(account, nt_time_to_unix(&delta->logon_time), True); + pdb_set_logoff_time(account, nt_time_to_unix(&delta->logoff_time), + True); + + pdb_set_logon_divs(account, delta->logon_divs); + + /* TODO: logon hours */ + /* TODO: bad password count */ + /* TODO: logon count */ + + pdb_set_pass_last_set_time( + account, nt_time_to_unix(&delta->pwd_last_set_time)); + + /* TODO: account expiry time */ + + pdb_set_acct_ctrl(account, delta->acb_info); +} + +static void apply_account_info(SAM_ACCOUNT_INFO *sam_acct_delta) +{ + SAM_ACCOUNT sam_acct; + BOOL result; + + ZERO_STRUCT(sam_acct); + + pdb_init_sam(&sam_acct); + + sam_account_from_delta(&sam_acct, sam_acct_delta); + result = pdb_add_sam_account(&sam_acct); +} + +/* Apply an array of deltas to the SAM database */ + +static void apply_deltas(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas, + SAM_DELTA_CTR *deltas) +{ + uint32 i; + + for (i = 0; i < num_deltas; i++) { + switch(hdr_deltas[i].type) { + case SAM_DELTA_ACCOUNT_INFO: + apply_account_info(&deltas[i].account_info); + break; + } + } +} + /* Synchronise sam database */ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16], BOOL do_smbpasswd_output, BOOL verbose) { TALLOC_CTX *mem_ctx; - SAM_DELTA_HDR *hdr_deltas_0, *hdr_deltas_1, *hdr_deltas_2; - SAM_DELTA_CTR *deltas_0, *deltas_1, *deltas_2; - uint32 num_deltas_0, num_deltas_1, num_deltas_2; + SAM_DELTA_HDR *hdr_deltas_0, *hdr_deltas_2; + SAM_DELTA_CTR *deltas_0, *deltas_2; + uint32 num_deltas_0, num_deltas_2; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + struct pdb_context *in; DOM_CRED ret_creds; + /* Initialise */ + if (!NT_STATUS_IS_OK(make_pdb_context_list(&in, lp_passdb_backend()))){ + DEBUG(0, ("Can't initialize passdb backend.\n")); + return result; + } + if (!(mem_ctx = talloc_init())) { DEBUG(0,("talloc_init failed\n")); return result; @@ -278,7 +384,7 @@ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16], /* Request a challenge */ - if (!NT_STATUS_IS_OK(new_cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_passwd))) { + if (!NT_STATUS_IS_OK(cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_passwd))) { DEBUG(0, ("Error initialising session creds\n")); goto done; } @@ -288,14 +394,14 @@ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16], /* Do sam synchronisation on the SAM database*/ - result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, 0, &num_deltas_0, &hdr_deltas_0, &deltas_0); + result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, 0, + &num_deltas_0, &hdr_deltas_0, + &deltas_0); if (!NT_STATUS_IS_OK(result)) goto done; - /* verbose mode */ - if (verbose) - decode_sam_deltas(num_deltas_0, hdr_deltas_0, deltas_0); + apply_deltas(num_deltas_0, hdr_deltas_0, deltas_0); /* @@ -379,23 +485,6 @@ static NTSTATUS sam_repl(struct cli_state *cli, unsigned char trust_passwde[16], return result; } -/* Print usage information */ - -static void usage(void) -{ - printf("Usage: samsync [options]\n"); - - printf("\t-d debuglevel set the debuglevel\n"); - printf("\t-h Print this help message.\n"); - printf("\t-s configfile specify an alternative config file\n"); - printf("\t-S synchronise sam database\n"); - printf("\t-R replicate sam deltas\n"); - printf("\t-U username username and password\n"); - printf("\t-p produce smbpasswd output\n"); - printf("\t-V verbose output\n"); - printf("\n"); -} - /* Connect to primary domain controller */ static struct cli_state *init_connection(struct cli_state **cli, @@ -407,7 +496,16 @@ static struct cli_state *init_connection(struct cli_state **cli, int count; fstring dest_host; - /* Initialise cli_state information */ + /* Initialise myname */ + + if (!global_myname[0]) { + char *p; + + fstrcpy(global_myname, myhostname()); + p = strchr(global_myname, '.'); + if (p) + *p = 0; + } /* Look up name of PDC controller */ @@ -430,148 +528,239 @@ static struct cli_state *init_connection(struct cli_state **cli, username, domain, password, 0))) { return *cli; - } else { - return NULL; } + + return NULL; } /* Main function */ +static fstring popt_username, popt_domain, popt_password; +static BOOL popt_got_pass; + +static void user_callback(poptContext con, + enum poptCallbackReason reason, + const struct poptOption *opt, + const char *arg, const void *data) +{ + char *p, *ch; + + if (!arg) + return; + + switch(opt->val) { + + /* Check for [DOMAIN\\]username[%password]*/ + + case 'U': + + p = arg; + + if ((ch = strchr(p, '\\'))) { + fstrcpy(popt_domain, p); + popt_domain[ch - p] = 0; + } + + fstrcpy(popt_username, p); + + if ((ch = strchr(p, '%'))) { + popt_username[ch - p] = 0; + fstrcpy(popt_password, ch + 1); + popt_got_pass = True; + } + + break; + + case 'W': + fstrcpy(popt_domain, arg); + break; + } +} + +/* Return domain, username and password passed in from cmd line */ + +void popt_common_get_auth_info(char **domain, char **username, char **password, + BOOL *got_pass) +{ + *domain = popt_domain; + *username = popt_username; + *password = popt_password; + *got_pass = popt_got_pass; +} + +struct poptOption popt_common_auth_info[] = { + { NULL, 0, POPT_ARG_CALLBACK, user_callback }, + { "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set username", + "[DOMAIN\\]username[%password]" }, + { "domain", 'W', POPT_ARG_STRING, NULL, 'W', "Set domain name", + "DOMAIN"}, + { 0 } +}; + +static BOOL popt_interactive; + +BOOL popt_common_is_interactive(void) +{ + return popt_interactive; +} + +struct poptOption popt_common_interactive[] = { + { "interactive", 'i', POPT_ARG_NONE, &popt_interactive, 'i', + "Log to stdout" }, + { 0 } +}; + int main(int argc, char **argv) { BOOL do_sam_sync = False, do_sam_repl = False; struct cli_state *cli; NTSTATUS result; - int opt; pstring logfile; - BOOL interactive = False, do_smbpasswd_output = False; - BOOL verbose = False; - uint32 low_serial = 0; + BOOL do_smbpasswd_output = False; + BOOL verbose = True, got_pass = False; + uint32 serial = 0; unsigned char trust_passwd[16]; - fstring username, domain, password; + char *username, *domain, *password; + poptContext pc; + char c; + + struct poptOption popt_samsync_opts[] = { + { "synchronise", 'S', POPT_ARG_NONE, &do_sam_sync, 'S', + "Perform full SAM synchronisation" }, + { "replicate", 'R', POPT_ARG_NONE, &do_sam_repl, 'R', + "Replicate SAM changes" }, + { "serial", 0, POPT_ARG_INT, &serial, 0, "SAM serial number" }, + { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug }, + { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_auth_info }, + { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_interactive }, + POPT_AUTOHELP + { 0 } + }; + + /* Read command line options */ + + pc = poptGetContext("samsync", argc, (const char **)argv, + popt_samsync_opts, 0); + + if (argc == 1) { + poptPrintUsage(pc, stdout, 0); + return 1; + } - if (argc == 1) { - usage(); - return 1; - } + while ((c = poptGetNextOpt(pc)) != -1) { - ZERO_STRUCT(username); - ZERO_STRUCT(domain); - ZERO_STRUCT(password); - - /* Parse command line options */ - - while((opt = getopt(argc, argv, "s:d:SR:hiU:W:pV")) != EOF) { - switch (opt) { - case 's': - pstrcpy(dyn_CONFIGFILE, optarg); - break; - case 'd': - DEBUGLEVEL = atoi(optarg); - break; - case 'S': - do_sam_sync = 1; - break; - case 'R': - do_sam_repl = 1; - low_serial = atoi(optarg); - break; - case 'i': - interactive = True; - break; - case 'U': { - char *lp; - - fstrcpy(username,optarg); - if ((lp=strchr_m(username,'%'))) { - *lp = 0; - fstrcpy(password,lp+1); - memset(strchr_m(optarg, '%') + 1, 'X', - strlen(password)); - } - break; - } - case 'W': - pstrcpy(domain, optarg); - break; - case 'p': - do_smbpasswd_output = True; - break; - case 'V': - verbose = True; - break; - case 'h': - default: - usage(); - exit(1); - } - } + /* Argument processing error */ - argc -= optind; + if (c < -1) { + fprintf(stderr, "samsync: %s: %s\n", + poptBadOption(pc, POPT_BADOPTION_NOALIAS), + poptStrerror(c)); + return 1; + } - if (argc > 0) { - usage(); - return 1; - } + /* Handle arguments */ + + switch (c) { + case 'h': + poptPrintHelp(pc, stdout, 0); + return 1; + case 'u': + poptPrintUsage(pc, stdout, 0); + return 1; + } + } - /* Initialise samba */ + /* Bail out if any extra args were passed */ + + if (poptPeekArg(pc)) { + fprintf(stderr, "samsync: invalid argument %s\n", + poptPeekArg(pc)); + poptPrintUsage(pc, stdout, 0); + return 1; + } + + poptFreeContext(pc); + + /* Setup logging */ + + dbf = x_stdout; + + if (!lp_load(dyn_CONFIGFILE, True, False, False)) { + d_fprintf(stderr, "samsync: error opening config file %s. " + "Error was %s\n", dyn_CONFIGFILE, strerror(errno)); + return 1; + } slprintf(logfile, sizeof(logfile) - 1, "%s/log.%s", dyn_LOGFILEBASE, "samsync"); + lp_set_logfile(logfile); - setup_logging("samsync", interactive); + setup_logging("samsync", popt_common_is_interactive()); - if (!interactive) + if (!popt_common_is_interactive()) reopen_logs(); - if (!lp_load(dyn_CONFIGFILE, True, False, False)) { - fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE); - } - - load_interfaces(); + load_interfaces(); /* Check arguments make sense */ if (do_sam_sync && do_sam_repl) { - fprintf(stderr, "cannot specify both -S and -R\n"); + DEBUG(0, ("cannot specify both -S and -R\n")); return 1; } if (!do_sam_sync && !do_sam_repl) { - fprintf(stderr, "must specify either -S or -R\n"); + DEBUG(0, ("samsync: you must either --synchronise or " + "--replicate the SAM database\n")); return 1; } - if (do_sam_repl && low_serial == 0) { - fprintf(stderr, "serial number must be positive\n"); + if (do_sam_repl && serial == 0) { + DEBUG(0, ("samsync: must specify serial number\n")); return 1; } + if (do_sam_sync && serial != 0) { + DEBUG(0, ("samsync: you can't specify a serial number when " + "synchonising the SAM database\n")); + return 1; + } + /* BDC operations require the machine account password */ if (!secrets_init()) { - DEBUG(0, ("Unable to initialise secrets database\n")); + DEBUG(0, ("samsync: unable to initialise secrets database\n")); return 1; } if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, NULL)) { - DEBUG(0, ("could not fetch trust account password\n")); + DEBUG(0, ("samsync: could not fetch trust account password\n")); return 1; } + /* I wish the domain sid wasn't stored in secrets.tdb */ + + if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + DEBUG(0, ("samsync: could not retrieve domain sid\n")); + return 1; + } + /* Perform sync or replication */ + popt_common_get_auth_info(&domain, &username, &password, &got_pass); + if (!init_connection(&cli, username, domain, password)) return 1; if (do_sam_sync) - result = sam_sync(cli, trust_passwd, do_smbpasswd_output, verbose); + result = sam_sync(cli, trust_passwd, do_smbpasswd_output, + verbose); if (do_sam_repl) - result = sam_repl(cli, trust_passwd, low_serial); + result = sam_repl(cli, trust_passwd, serial); if (!NT_STATUS_IS_OK(result)) { DEBUG(0, ("%s\n", nt_errstr(result))); |