libcli/auth: fix memory leak in schannel_creds_server_step_check_ldb()
[ira/wip.git] / libcli / auth / schannel_state_ldb.c
index 69d6bad22c2de123cacdcce15fa25ebd20e7cd51..ba3d96fcf7eab6e32a35bfa13d1e0402ad8d8974 100644 (file)
@@ -28,8 +28,7 @@
 #include "libcli/auth/libcli_auth.h"
 #include "auth/auth.h"
 #include "param/param.h"
-#include "auth/gensec/schannel_state.h"
-#include "../libcli/auth/schannel_state_proto.h"
+#include "../libcli/auth/schannel_state.h"
 
 static struct ldb_val *schannel_dom_sid_ldb_val(TALLOC_CTX *mem_ctx,
                                                struct dom_sid *sid)
@@ -96,7 +95,7 @@ NTSTATUS schannel_store_session_key_ldb(struct ldb_context *ldb,
                return NT_STATUS_NO_MEMORY;
        }
 
-       msg = ldb_msg_new(ldb);
+       msg = ldb_msg_new(mem_ctx);
        if (msg == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -271,10 +270,21 @@ NTSTATUS schannel_creds_server_step_check_ldb(struct ldb_context *ldb,
                                              struct netr_Authenticator *return_authenticator,
                                              struct netlogon_creds_CredentialState **creds_out)
 {
-       struct netlogon_creds_CredentialState *creds;
+       struct netlogon_creds_CredentialState *creds = NULL;
        NTSTATUS nt_status;
        int ret;
 
+       /* If we are flaged that schannel is required for a call, and
+        * it is not in use, then make this an error */
+
+       /* It would be good to make this mandetory once schannel is
+        * negoiated, but this is not what windows does */
+       if (schannel_required_for_call && !schannel_in_use) {
+               DEBUG(0,("schannel_creds_server_step_check: client %s not using schannel for netlogon, despite negotiating it\n",
+                       creds->computer_name ));
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
        ret = ldb_transaction_start(ldb);
        if (ret != 0) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -286,37 +296,39 @@ NTSTATUS schannel_creds_server_step_check_ldb(struct ldb_context *ldb,
 
        nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name,
                                                   &creds);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               ldb_transaction_cancel(ldb);
+               return nt_status;
+       }
 
-       /* If we are flaged that schannel is required for a call, and
-        * it is not in use, then make this an error */
-
-       /* It would be good to make this mandetory once schannel is
-        * negoiated, bu this is not what windows does */
-       if (schannel_required_for_call && !schannel_in_use) {
-               DEBUG(0,("schannel_creds_server_step_check: client %s not using schannel for netlogon, despite negotiating it\n",
-                       creds->computer_name ));
+       nt_status = netlogon_creds_server_step_check(creds,
+                                                    received_authenticator,
+                                                    return_authenticator);
+       if (!NT_STATUS_IS_OK(nt_status)) {
                ldb_transaction_cancel(ldb);
-               return NT_STATUS_ACCESS_DENIED;
+               talloc_free(creds);
+               return nt_status;
        }
 
-       if (NT_STATUS_IS_OK(nt_status)) {
-               nt_status = netlogon_creds_server_step_check(creds,
-                                                            received_authenticator,
-                                                            return_authenticator);
+       nt_status = schannel_store_session_key_ldb(ldb, mem_ctx, creds);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               ldb_transaction_cancel(ldb);
+               talloc_free(creds);
+               return nt_status;
        }
 
-       if (NT_STATUS_IS_OK(nt_status)) {
-               nt_status = schannel_store_session_key_ldb(ldb, mem_ctx, creds);
+       ldb_transaction_commit(ldb);
+       if (ret != 0) {
+               talloc_free(creds);
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
-       if (NT_STATUS_IS_OK(nt_status)) {
-               ldb_transaction_commit(ldb);
-               if (creds_out) {
-                       *creds_out = creds;
-                       talloc_steal(mem_ctx, creds);
-               }
+       if (creds_out) {
+               *creds_out = creds;
+               talloc_steal(mem_ctx, creds);
        } else {
-               ldb_transaction_cancel(ldb);
+               talloc_free(creds);
        }
-       return nt_status;
+
+       return NT_STATUS_OK;
 }