s3-lib: Do not set an empty string in split_domain_user()
[samba.git] / source3 / libnet / libnet_samsync.c
index 0c00b8518aef668cb7f89297805c1de4a912e9a6..e7e1393fdc855d1d50cd35af92fb1007b1aba539 100644 (file)
 
 
 #include "includes.h"
-#include "libnet/libnet.h"
-
-/**
- * Decrypt and extract the user's passwords.
- *
- * The writes decrypted (no longer 'RID encrypted' or arcfour encrypted)
- * passwords back into the structure
- */
-
-static NTSTATUS fix_user(TALLOC_CTX *mem_ctx,
-                        DATA_BLOB *session_key,
-                        enum netr_SamDatabaseID database_id,
-                        struct netr_DELTA_ENUM *delta)
-{
-
-       uint32_t rid = delta->delta_id_union.rid;
-       struct netr_DELTA_USER *user = delta->delta_union.user;
-       struct samr_Password lm_hash;
-       struct samr_Password nt_hash;
-       unsigned char zero_buf[16];
-
-       memset(zero_buf, '\0', sizeof(zero_buf));
-
-       /* Note that win2000 may send us all zeros
-        * for the hashes if it doesn't
-        * think this channel is secure enough. */
-       if (user->lm_password_present) {
-               if (memcmp(user->lmpassword.hash, zero_buf, 16) != 0) {
-                       sam_pwd_hash(rid, user->lmpassword.hash, lm_hash.hash, 0);
-               } else {
-                       memset(lm_hash.hash, '\0', sizeof(lm_hash.hash));
-               }
-               user->lmpassword = lm_hash;
-       }
-
-       if (user->nt_password_present) {
-               if (memcmp(user->ntpassword.hash, zero_buf, 16) != 0) {
-                       sam_pwd_hash(rid, user->ntpassword.hash, nt_hash.hash, 0);
-               } else {
-                       memset(nt_hash.hash, '\0', sizeof(nt_hash.hash));
-               }
-               user->ntpassword = nt_hash;
-       }
-
-       if (user->user_private_info.SensitiveData) {
-               DATA_BLOB data;
-               struct netr_USER_KEYS keys;
-               enum ndr_err_code ndr_err;
-               data.data = user->user_private_info.SensitiveData;
-               data.length = user->user_private_info.DataLength;
-               SamOEMhashBlob(data.data, data.length, session_key);
-               user->user_private_info.SensitiveData = data.data;
-               user->user_private_info.DataLength = data.length;
-
-               ndr_err = ndr_pull_struct_blob(&data, mem_ctx, NULL, &keys,
-                       (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS);
-               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                       dump_data(10, data.data, data.length);
-                       return ndr_map_error2ntstatus(ndr_err);
-               }
-
-               /* Note that win2000 may send us all zeros
-                * for the hashes if it doesn't
-                * think this channel is secure enough. */
-               if (keys.keys.keys2.lmpassword.length == 16) {
-                       if (memcmp(keys.keys.keys2.lmpassword.pwd.hash,
-                                       zero_buf, 16) != 0) {
-                               sam_pwd_hash(rid,
-                                       keys.keys.keys2.lmpassword.pwd.hash,
-                                       lm_hash.hash, 0);
-                       } else {
-                               memset(lm_hash.hash, '\0', sizeof(lm_hash.hash));
-                       }
-                       user->lmpassword = lm_hash;
-                       user->lm_password_present = true;
-               }
-               if (keys.keys.keys2.ntpassword.length == 16) {
-                       if (memcmp(keys.keys.keys2.ntpassword.pwd.hash,
-                                               zero_buf, 16) != 0) {
-                               sam_pwd_hash(rid,
-                                       keys.keys.keys2.ntpassword.pwd.hash,
-                                       nt_hash.hash, 0);
-                       } else {
-                               memset(nt_hash.hash, '\0', sizeof(nt_hash.hash));
-                       }
-                       user->ntpassword = nt_hash;
-                       user->nt_password_present = true;
-               }
-               /* TODO: rid decrypt history fields */
-       }
-       return NT_STATUS_OK;
-}
-
-/**
- * Decrypt and extract the secrets
- *
- * The writes decrypted secrets back into the structure
- */
-static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx,
-                          DATA_BLOB *session_key,
-                          enum netr_SamDatabaseID database_id,
-                          struct netr_DELTA_ENUM *delta)
-{
-       struct netr_DELTA_SECRET *secret = delta->delta_union.secret;
-
-       SamOEMhashBlob(secret->current_cipher.cipher_data,
-                      secret->current_cipher.maxlen,
-                      session_key);
-
-       SamOEMhashBlob(secret->old_cipher.cipher_data,
-                      secret->old_cipher.maxlen,
-                      session_key);
-
-       return NT_STATUS_OK;
-}
-
-/**
- * Fix up the delta, dealing with encryption issues so that the final
- * callback need only do the printing or application logic
- */
-
-static NTSTATUS samsync_fix_delta(TALLOC_CTX *mem_ctx,
-                                 DATA_BLOB *session_key,
-                                 enum netr_SamDatabaseID database_id,
-                                 struct netr_DELTA_ENUM *delta)
-{
-       NTSTATUS status = NT_STATUS_OK;
-
-       switch (delta->delta_type) {
-               case NETR_DELTA_USER:
-
-                       status = fix_user(mem_ctx,
-                                         session_key,
-                                         database_id,
-                                         delta);
-                       break;
-               case NETR_DELTA_SECRET:
-
-                       status = fix_secret(mem_ctx,
-                                           session_key,
-                                           database_id,
-                                           delta);
-                       break;
-               default:
-                       break;
-       }
-
-       return status;
-}
+#include "libnet/libnet_samsync.h"
+#include "../libcli/samsync/samsync.h"
+#include "../libcli/auth/libcli_auth.h"
+#include "rpc_client/rpc_client.h"
+#include "../librpc/gen_ndr/ndr_netlogon.h"
+#include "../librpc/gen_ndr/ndr_netlogon_c.h"
+#include "../libcli/security/security.h"
+#include "messages.h"
+#include "../libcli/auth/netlogon_creds_cli.h"
 
 /**
  * Fix up the delta, dealing with encryption issues so that the final
@@ -178,7 +38,7 @@ static NTSTATUS samsync_fix_delta(TALLOC_CTX *mem_ctx,
  */
 
 static NTSTATUS samsync_fix_delta_array(TALLOC_CTX *mem_ctx,
-                                       DATA_BLOB *session_key,
+                                       struct netlogon_creds_CredentialState *creds,
                                        enum netr_SamDatabaseID database_id,
                                        struct netr_DELTA_ENUM_ARRAY *r)
 {
@@ -188,7 +48,7 @@ static NTSTATUS samsync_fix_delta_array(TALLOC_CTX *mem_ctx,
        for (i = 0; i < r->num_deltas; i++) {
 
                status = samsync_fix_delta(mem_ctx,
-                                          session_key,
+                                          creds,
                                           database_id,
                                           &r->delta_enum[i]);
                if (!NT_STATUS_IS_OK(status)) {
@@ -211,17 +71,20 @@ NTSTATUS libnet_samsync_init_context(TALLOC_CTX *mem_ctx,
 
        *ctx_p = NULL;
 
-       ctx = TALLOC_ZERO_P(mem_ctx, struct samsync_context);
+       ctx = talloc_zero(mem_ctx, struct samsync_context);
        NT_STATUS_HAVE_NO_MEMORY(ctx);
 
        if (domain_sid) {
-               ctx->domain_sid = sid_dup_talloc(mem_ctx, domain_sid);
+               ctx->domain_sid = dom_sid_dup(mem_ctx, domain_sid);
                NT_STATUS_HAVE_NO_MEMORY(ctx->domain_sid);
 
                ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid);
                NT_STATUS_HAVE_NO_MEMORY(ctx->domain_sid_str);
        }
 
+       ctx->msg_ctx = messaging_init(ctx, samba_tevent_context_init(ctx));
+       NT_STATUS_HAVE_NO_MEMORY(ctx->msg_ctx);
+
        *ctx_p = ctx;
 
        return NT_STATUS_OK;
@@ -337,36 +200,44 @@ static NTSTATUS libnet_samsync_delta(TALLOC_CTX *mem_ctx,
                                     struct samsync_context *ctx,
                                     struct netr_ChangeLogEntry *e)
 {
-       NTSTATUS result;
+       NTSTATUS result, status;
        NTSTATUS callback_status;
        const char *logon_server = ctx->cli->desthost;
-       const char *computername = global_myname();
+       const char *computername = lp_netbios_name();
        struct netr_Authenticator credential;
        struct netr_Authenticator return_authenticator;
        uint16_t restart_state = 0;
        uint32_t sync_context = 0;
-       DATA_BLOB session_key;
+       struct dcerpc_binding_handle *b = ctx->cli->binding_handle;
 
        ZERO_STRUCT(return_authenticator);
 
        do {
                struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
+               struct netlogon_creds_CredentialState *creds = NULL;
+
+               status = netlogon_creds_cli_lock(ctx->netlogon_creds,
+                                                mem_ctx, &creds);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
 
-               netlogon_creds_client_step(ctx->cli->dc, &credential);
+               netlogon_creds_client_authenticator(creds, &credential);
 
                if (ctx->single_object_replication &&
                    !ctx->force_full_replication) {
-                       result = rpccli_netr_DatabaseRedo(ctx->cli, mem_ctx,
+                       status = dcerpc_netr_DatabaseRedo(b, mem_ctx,
                                                          logon_server,
                                                          computername,
                                                          &credential,
                                                          &return_authenticator,
                                                          *e,
                                                          0,
-                                                         &delta_enum_array);
+                                                         &delta_enum_array,
+                                                         &result);
                } else if (!ctx->force_full_replication &&
                           sequence_num && (*sequence_num > 0)) {
-                       result = rpccli_netr_DatabaseDeltas(ctx->cli, mem_ctx,
+                       status = dcerpc_netr_DatabaseDeltas(b, mem_ctx,
                                                            logon_server,
                                                            computername,
                                                            &credential,
@@ -374,9 +245,10 @@ static NTSTATUS libnet_samsync_delta(TALLOC_CTX *mem_ctx,
                                                            database_id,
                                                            sequence_num,
                                                            &delta_enum_array,
-                                                           0xffff);
+                                                           0xffff,
+                                                           &result);
                } else {
-                       result = rpccli_netr_DatabaseSync2(ctx->cli, mem_ctx,
+                       status = dcerpc_netr_DatabaseSync2(b, mem_ctx,
                                                           logon_server,
                                                           computername,
                                                           &credential,
@@ -385,30 +257,38 @@ static NTSTATUS libnet_samsync_delta(TALLOC_CTX *mem_ctx,
                                                           restart_state,
                                                           &sync_context,
                                                           &delta_enum_array,
-                                                          0xffff);
+                                                          0xffff,
+                                                          &result);
                }
 
-               if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) {
-                       return result;
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(creds);
+                       return status;
                }
 
                /* Check returned credentials. */
-               if (!netlogon_creds_client_check(ctx->cli->dc,
+               if (!netlogon_creds_client_check(creds,
                                                 &return_authenticator.cred)) {
+                       TALLOC_FREE(creds);
                        DEBUG(0,("credentials chain check failed\n"));
                        return NT_STATUS_ACCESS_DENIED;
                }
 
+               if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) {
+                       TALLOC_FREE(creds);
+                       return result;
+               }
+
                if (NT_STATUS_IS_ERR(result)) {
+                       TALLOC_FREE(creds);
                        break;
                }
 
-               session_key = data_blob_const(ctx->cli->dc->sess_key, 16);
-
                samsync_fix_delta_array(mem_ctx,
-                                       &session_key,
+                                       creds,
                                        database_id,
                                        delta_enum_array);
+               TALLOC_FREE(creds);
 
                /* Process results */
                callback_status = ctx->ops->process_objects(mem_ctx, database_id,
@@ -536,14 +416,14 @@ NTSTATUS pull_netr_AcctLockStr(TALLOC_CTX *mem_ctx,
 
        *str_p = NULL;
 
-       str = TALLOC_ZERO_P(mem_ctx, struct netr_AcctLockStr);
+       str = talloc_zero(mem_ctx, struct netr_AcctLockStr);
        if (!str) {
                return NT_STATUS_NO_MEMORY;
        }
 
        blob = data_blob_const(r->array, r->length);
 
-       ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, str,
+       ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, str,
                       (ndr_pull_flags_fn_t)ndr_pull_netr_AcctLockStr);
 
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {