Start of samsync program invoked by smbd to perform sam synchronisation and
authorTim Potter <tpot@samba.org>
Tue, 28 Aug 2001 06:44:54 +0000 (06:44 +0000)
committerTim Potter <tpot@samba.org>
Tue, 28 Aug 2001 06:44:54 +0000 (06:44 +0000)
sam replication.  It doesn't work yet.  (-:
(This used to be commit c96aae613dfe97808dedffc836c5d4cc9ae52185)

source3/rpcclient/samsync.c [new file with mode: 0644]

diff --git a/source3/rpcclient/samsync.c b/source3/rpcclient/samsync.c
new file mode 100644 (file)
index 0000000..866a3f1
--- /dev/null
@@ -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;
+}