summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/rpcclient/samsync.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/source3/rpcclient/samsync.c b/source3/rpcclient/samsync.c
new file mode 100644
index 0000000000..866a3f1418
--- /dev/null
+++ b/source3/rpcclient/samsync.c
@@ -0,0 +1,270 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.2
+ RPC pipe client
+
+ Copyright (C) Tim Potter 2001
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/* Synchronise sam database */
+
+static int sam_sync(struct cli_state *cli, unsigned char trust_passwd[16])
+{
+ TALLOC_CTX *mem_ctx;
+ SAM_DELTA_HDR *hdr_deltas;
+ SAM_DELTA_CTR *deltas;
+ uint32 database_id = 0, num_deltas, result;
+
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(0,("talloc_init failed\n"));
+ return result;
+ }
+
+ if (!cli_nt_session_open (cli, PIPE_NETLOGON)) {
+ DEBUG(0, ("Could not initialize netlogon pipe!\n"));
+ goto done;
+ }
+
+ if ((result = cli_netlogon_sam_sync(cli, mem_ctx, database_id,
+ &num_deltas, &hdr_deltas, &deltas))
+ != NT_STATUS_NOPROBLEMO) {
+ goto done;
+ }
+
+ done:
+ cli_nt_session_close(cli);
+ talloc_destroy(mem_ctx);
+
+ return result;
+}
+
+/* Replicate sam deltas */
+
+static int sam_repl(struct cli_state *cli, unsigned char trust_passwde[16],
+ uint32 low_serial)
+{
+ uint32 result;
+
+ return 0;
+}
+
+/* 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("\n");
+}
+
+/* Initialise client credentials for authenticated pipe access */
+
+void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
+ char* domain, char* password)
+{
+ ZERO_STRUCTP(creds);
+
+ if (lp_encrypted_passwords()) {
+ pwd_make_lm_nt_16(&creds->pwd, password);
+ } else {
+ pwd_set_cleartext(&creds->pwd, password);
+ }
+
+ fstrcpy(creds->user_name, username);
+ fstrcpy(creds->domain, domain);
+
+ if (! *username) {
+ creds->pwd.null_pwd = True;
+ }
+}
+
+/* Connect to primary domain controller */
+
+static struct cli_state *init_connection(struct cli_state *cli)
+{
+ struct ntuser_creds creds;
+ extern pstring global_myname;
+ struct in_addr *dest_ip;
+ struct nmb_name calling, called;
+ int count;
+ fstring dest_host;
+
+ /* Initialise cli_state information */
+
+ ZERO_STRUCTP(cli);
+
+ if (!cli_initialise(cli)) {
+ return NULL;
+ }
+
+ init_rpcclient_creds(&creds, "Administrator", "FOO", "samba");
+ cli_init_creds(cli, &creds);
+
+ /* Look up name of PDC controller */
+
+ if (!get_dc_list(True, lp_workgroup(), &dest_ip, &count)) {
+ DEBUG(0, ("Cannot find domain controller for domain %s\n",
+ lp_workgroup()));
+ return NULL;
+ }
+
+ if (!lookup_pdc_name(global_myname, lp_workgroup(), dest_ip,
+ dest_host)) {
+ DEBUG(0, ("Could not lookup up PDC name for domain %s\n",
+ lp_workgroup()));
+ return NULL;
+ }
+
+ get_myname((*global_myname)?NULL:global_myname);
+ strupper(global_myname);
+
+ make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
+ make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
+
+ /* Establish a SMB connection */
+
+ if (!cli_establish_connection(cli, dest_host, dest_ip, &calling,
+ &called, "IPC$", "IPC", False, True)) {
+ return NULL;
+ }
+
+ return cli;
+}
+
+/* Main function */
+
+ int main(int argc, char **argv)
+{
+ BOOL do_sam_sync = False, do_sam_repl = False;
+ pstring servicesf = CONFIGFILE;
+ struct cli_state cli;
+ int result = 0, opt;
+ extern pstring debugf;
+ BOOL interactive = False;
+ uint32 low_serial = 0;
+ unsigned char trust_passwd[16];
+
+ if (argc == 1) {
+ usage();
+ return 1;
+ }
+
+ /* Parse command line options */
+
+ while((opt = getopt(argc, argv, "s:d:SR:hi")) != EOF) {
+ switch (opt) {
+ case 's':
+ pstrcpy(servicesf, 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 'h':
+ default:
+ usage();
+ exit(1);
+ }
+ }
+
+ argc -= optind;
+
+ if (argc > 0) {
+ usage();
+ return 1;
+ }
+
+ /* Initialise samba */
+
+ slprintf(debugf, sizeof(debugf) - 1, "%s/log.%s", LOGFILEBASE,
+ "samsync");
+
+ setup_logging("samsync", interactive);
+
+ if (!interactive)
+ reopen_logs();
+
+ if (!lp_load(servicesf, True, False, False)) {
+ fprintf(stderr, "Can't load %s\n", servicesf);
+ }
+
+ load_interfaces();
+
+ TimeInit();
+
+ /* Check arguments make sense */
+
+ if (do_sam_sync && do_sam_repl) {
+ fprintf(stderr, "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");
+ return 1;
+ }
+
+ if (do_sam_repl && low_serial == 0) {
+ fprintf(stderr, "serial number must be positive\n");
+ return 1;
+ }
+
+ /* BDC operations require the machine account password */
+
+ if (!secrets_init()) {
+ DEBUG(0, ("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"));
+ return 1;
+ }
+
+ /* Perform sync or replication */
+
+ if (!init_connection(&cli))
+ return 1;
+
+ if (do_sam_sync)
+ result = sam_sync(&cli, trust_passwd);
+
+ if (do_sam_repl)
+ result = sam_repl(&cli, trust_passwd, low_serial);
+
+ return result;
+}