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
(This used to be commit f0c67a4a24dbd7fc32fc864d61a21eeee587178e)

source4/libnet/libnet_vampire.c
source4/libnet/libnet_vampire.h
source4/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;