r6603: More work on the samdump puzzle. This implements a function pointer
authorAndrew Bartlett <abartlet@samba.org>
Tue, 3 May 2005 14:38:14 +0000 (14:38 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:16:29 +0000 (13:16 -0500)
callback interface, so we can start dumping into more than just stdout
soon.

Also use the enums instead of uint32 where possible and valid.

Andrew Bartlett

source/libnet/libnet_vampire.c
source/libnet/libnet_vampire.h
source/torture/rpc/samsync.c

index daf7bdfaed8a041b57bfe6130cd536b1469afed5..82209f336195c28494b0bd687f657d7f4b8fadee 100644 (file)
@@ -24,9 +24,9 @@
 #include "librpc/gen_ndr/ndr_netlogon.h"
 #include "librpc/gen_ndr/ndr_samr.h"
 
-static BOOL vampire_samdump_handle_user(TALLOC_CTX *mem_ctx,
-                                       struct creds_CredentialState *creds,
-                                       struct netr_DELTA_ENUM *delta) 
+static NTSTATUS vampire_samdump_handle_user(TALLOC_CTX *mem_ctx,
+                                           struct creds_CredentialState *creds,
+                                           struct netr_DELTA_ENUM *delta) 
 {
        uint32_t rid = delta->delta_id_union.rid;
        struct netr_DELTA_USER *user = delta->delta_union.user;
@@ -44,6 +44,7 @@ static BOOL vampire_samdump_handle_user(TALLOC_CTX *mem_ctx,
                sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0);
                lm_hash_p = &lm_hash;
        }
+
        if (user->nt_password_present) {
                sam_rid_crypt(rid, user->ntpassword.hash, nt_hash.hash, 0);
                nt_hash_p = &nt_hash;
@@ -66,9 +67,9 @@ static BOOL vampire_samdump_handle_user(TALLOC_CTX *mem_ctx,
                                nt_hash_p = &nt_hash;
                        }
                } else {
-                       printf("Failed to parse Sensitive Data for %s:\n", username);
+                       DEBUG(1, ("Failed to parse Sensitive Data for %s:\n", username));
                        dump_data(10, data.data, data.length);
-                       return False;
+                       return nt_status;
                }
        }
 
@@ -80,20 +81,47 @@ static BOOL vampire_samdump_handle_user(TALLOC_CTX *mem_ctx,
               smbpasswd_encode_acb_info(mem_ctx, user->acct_flags),
               (unsigned int)nt_time_to_unix(user->last_password_change));
 
-       return True;
+       return NT_STATUS_OK;
 }
 
+static NTSTATUS libnet_samdump_fn(TALLOC_CTX *mem_ctx,                 
+                                 void *private,                        
+                                 struct creds_CredentialState *creds,
+                                 enum netr_SamDatabaseID database,
+                                 struct netr_DELTA_ENUM *delta,
+                                 char **error_string)
+{
+       NTSTATUS nt_status = NT_STATUS_OK;
+       *error_string = NULL;
+       switch (database) {
+       case SAM_DATABASE_DOMAIN: 
+       {
+               switch (delta->delta_type) {
+               case NETR_DELTA_USER:
+               {
+                       nt_status = vampire_samdump_handle_user(mem_ctx, 
+                                                               creds,
+                                                               delta);
+                       break;
+               }
+               }
+               break;
+       }
+       }
+       return nt_status;
+}
 
-
-static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r)
+static NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamSync *r)
 {
-       NTSTATUS nt_status;
+       NTSTATUS nt_status, dbsync_nt_status;
        TALLOC_CTX *loop_ctx, *delta_ctx;
        struct creds_CredentialState *creds;
        struct netr_DatabaseSync dbsync;
        struct cli_credentials *machine_account;
        struct dcerpc_binding *b;
        struct dcerpc_pipe *p;
+       const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; 
+       int i;
 
        /* TODO: This is bogus */
        const char **bindings = lp_passwordserver();
@@ -120,8 +148,9 @@ static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX *
                r->netlogon.error_string
                        = talloc_asprintf(mem_ctx, 
                                          "Our join to domain %s is not as a BDC (%d), please rejoin as a BDC",
-                                         cli_credentials_get_secure_channel_type(machine_account),
-                                         cli_credentials_get_domain(machine_account));
+                                         
+                                         cli_credentials_get_domain(machine_account),
+                                         cli_credentials_get_secure_channel_type(machine_account));
                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
        }
 
@@ -147,10 +176,11 @@ static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX *
                return nt_status;
        }
 
-       /* call domain logon */
+       /* get NETLOGON credentails */
 
        nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds);
        if (!NT_STATUS_IS_OK(nt_status)) {
+               r->netlogon.error_string = talloc_strdup(mem_ctx, "Could not obtain NETLOGON credentials from DCERPC/GENSEC layer");
                return nt_status;
        }
 
@@ -159,45 +189,70 @@ static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX *
        dbsync.in.preferredmaximumlength = (uint32_t)-1;
        ZERO_STRUCT(dbsync.in.return_authenticator);
 
-       dbsync.in.sync_context = 0;
-       dbsync.in.database_id = SAM_DATABASE_DOMAIN;
-
-       do {
-               int d;
-               loop_ctx = talloc_named(mem_ctx, 0, "DatabaseSync loop context");
-               creds_client_authenticator(creds, &dbsync.in.credential);
-               
-               nt_status = dcerpc_netr_DatabaseSync(p, loop_ctx, &dbsync);
-               if (!NT_STATUS_IS_OK(nt_status) &&
-                   !NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)) {
-                       printf("DatabaseSync - %s\n", nt_errstr(nt_status));
-                       return nt_status;
-               }
-               
-               if (!creds_client_check(creds, &dbsync.out.return_authenticator.cred)) {
-                       printf("Credential chaining failed\n");
-               }
+       for (i=0;i< ARRAY_SIZE(database_ids); i++) { 
+               dbsync.in.sync_context = 0;
+               dbsync.in.database_id = database_ids[i]; 
                
-               dbsync.in.sync_context = dbsync.out.sync_context;
-               
-               for (d=0; d < dbsync.out.delta_enum_array->num_deltas; d++) {
-                       delta_ctx = talloc_named(loop_ctx, 0, "DatabaseSync delta context");
-                       switch (dbsync.out.delta_enum_array->delta_enum[d].delta_type) {
-                       case NETR_DELTA_USER:
-                               if (!vampire_samdump_handle_user(delta_ctx, 
+               do {
+                       int d;
+                       loop_ctx = talloc_named(mem_ctx, 0, "DatabaseSync loop context");
+                       creds_client_authenticator(creds, &dbsync.in.credential);
+                       
+                       dbsync_nt_status = dcerpc_netr_DatabaseSync(p, loop_ctx, &dbsync);
+                       if (!NT_STATUS_IS_OK(dbsync_nt_status) &&
+                           !NT_STATUS_EQUAL(dbsync_nt_status, STATUS_MORE_ENTRIES)) {
+                               r->netlogon.error_string = talloc_asprintf(mem_ctx, "DatabaseSync failed - %s", nt_errstr(nt_status));
+                               return nt_status;
+                       }
+                       
+                       if (!creds_client_check(creds, &dbsync.out.return_authenticator.cred)) {
+                               r->netlogon.error_string = talloc_strdup(mem_ctx, "Credential chaining failed");
+                               return NT_STATUS_ACCESS_DENIED;
+                       }
+                       
+                       dbsync.in.sync_context = dbsync.out.sync_context;
+                       
+                       for (d=0; d < dbsync.out.delta_enum_array->num_deltas; d++) {
+                               char *error_string = NULL;
+                               delta_ctx = talloc_named(loop_ctx, 0, "DatabaseSync delta context");
+                               nt_status = r->netlogon.delta_fn(delta_ctx, 
+                                                                r->netlogon.fn_ctx,
                                                                 creds,
-                                                                &dbsync.out.delta_enum_array->delta_enum[d])) {
-                                       return NT_STATUS_INVALID_PARAMETER;
+                                                                dbsync.in.database_id,
+                                                                &dbsync.out.delta_enum_array->delta_enum[d], 
+                                                                &error_string);
+                               if (!NT_STATUS_IS_OK(nt_status)) {
+                                       r->netlogon.error_string = talloc_steal(mem_ctx, error_string);
+                                       talloc_free(delta_ctx);
+                                       return nt_status;
                                }
-                               break;
+                               talloc_free(delta_ctx);
                        }
-                       talloc_free(delta_ctx);
-               }
-               talloc_free(loop_ctx);
-       } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
-       return NT_STATUS_OK;
+                       talloc_free(loop_ctx);
+               } while (NT_STATUS_EQUAL(dbsync_nt_status, STATUS_MORE_ENTRIES));
+               nt_status = dbsync_nt_status;
+       }
+       return nt_status;
+}
+
+NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r)
+{
+       NTSTATUS nt_status;
+       union libnet_SamSync r2;
+
+       r2.netlogon.level = LIBNET_SAMDUMP_NETLOGON;
+       r2.netlogon.error_string = NULL;
+       r2.netlogon.delta_fn = libnet_samdump_fn;
+       r2.netlogon.fn_ctx = NULL;
+       nt_status = libnet_SamSync_netlogon(ctx, mem_ctx, &r2);
+       r->generic.error_string = r2.netlogon.error_string;
+
+       
+       return nt_status;
 }
 
+
+
 NTSTATUS libnet_SamDump_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r)
 {
        NTSTATUS nt_status;
index 22ac1606bda8bd13a9d540b01df057928a335919..4777f51b0b54fb25cbd9011df2235c6ca18e51f7 100644 (file)
 #include "librpc/gen_ndr/ndr_netlogon.h"
 
 /* struct and enum for doing a remote domain join */
+enum libnet_SamSync_level {
+       LIBNET_SAMSYNC_GENERIC,
+       LIBNET_SAMSYNC_NETLOGON,
+};
+
+union libnet_SamSync {
+       struct {
+               enum libnet_SamSync_level level;
+               char *error_string;
+       } generic;
+
+       struct {
+               enum libnet_SamSync_level level;
+               NTSTATUS (*delta_fn)(TALLOC_CTX *mem_ctx,               
+                                    void *private,                     
+                                    struct creds_CredentialState *creds,
+                                    enum netr_SamDatabaseID database,
+                                    struct netr_DELTA_ENUM *delta,
+                                    char **error_string);
+               void *fn_ctx;
+               char *error_string;
+       } netlogon;
+};
+
 enum libnet_SamDump_level {
        LIBNET_SAMDUMP_GENERIC,
        LIBNET_SAMDUMP_NETLOGON,
index 6b8b28c06039e53c8d21ce96e932eab264493e52..4690b18ead841aa2d596f1a4cb100ea0b7f9cbf6 100644 (file)
@@ -1069,7 +1069,7 @@ static BOOL test_DatabaseSync(struct samsync_state *samsync_state,
        NTSTATUS status;
        TALLOC_CTX *loop_ctx, *delta_ctx, *trustdom_ctx;
        struct netr_DatabaseSync r;
-       const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; 
+       const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; 
        int i, d;
        BOOL ret = True;
        struct samsync_trusted_domain *t;