s3-secrets: add lsa_secret passdb api.
authorGünther Deschner <gd@samba.org>
Thu, 17 Feb 2011 15:10:28 +0000 (16:10 +0100)
committerGünther Deschner <gd@samba.org>
Sun, 31 Jul 2011 20:37:26 +0000 (22:37 +0200)
Guenther

source3/Makefile.in
source3/include/secrets.h
source3/passdb/pdb_interface.c
source3/passdb/secrets_lsa.c [new file with mode: 0644]
source3/wscript_build

index f0718cef6b0b0bac12ff517d7d1cc2f01e94d5b1..ff2d433f823f077bc2f3cc033a1230d09d04bf96 100644 (file)
@@ -520,7 +520,8 @@ LIBADS_SERVER_OBJ = libads/kerberos_verify.o libads/authdata.o ../auth/kerberos/
 LIBADS_PRINTER_OBJ = libads/ldap_printer.o
 
 SECRETS_OBJ = passdb/secrets.o passdb/machine_account_secrets.o passdb/machine_sid.o \
-             librpc/gen_ndr/ndr_secrets.o
+             librpc/gen_ndr/ndr_secrets.o \
+             passdb/secrets_lsa.o
 
 LIBNBT_OBJ = ../libcli/nbt/nbtname.o \
             ../libcli/netlogon/netlogon.o \
index 01e635c5803790ae6a46e1b9e60c8ec6fff6b544..4c23335b58f296e59b47035f9171f1c7d7bec21f 100644 (file)
@@ -125,4 +125,18 @@ bool secrets_store_generic(const char *owner, const char *key, const char *secre
 char *secrets_fetch_generic(const char *owner, const char *key);
 bool secrets_delete_generic(const char *owner, const char *key);
 
+/* The following definitions come from passdb/secrets_lsa.c  */
+NTSTATUS lsa_secret_get(TALLOC_CTX *mem_ctx,
+                       const char *secret_name,
+                       DATA_BLOB *secret_current,
+                       NTTIME *secret_current_lastchange,
+                       DATA_BLOB *secret_old,
+                       NTTIME *secret_old_lastchange,
+                       struct security_descriptor **sd);
+NTSTATUS lsa_secret_set(const char *secret_name,
+                       DATA_BLOB *secret_current,
+                       DATA_BLOB *secret_old,
+                       struct security_descriptor *sd);
+NTSTATUS lsa_secret_delete(const char *secret_name);
+
 #endif /* _SECRETS_H */
index 11c186a3988b50abcfd5a15ef0492746e9d186cf..c92b22ae992015f03ec285a633f693fd49673895 100644 (file)
@@ -2328,7 +2328,12 @@ static NTSTATUS pdb_default_get_secret(struct pdb_methods *methods,
                                       NTTIME *secret_old_lastchange,
                                       struct security_descriptor **sd)
 {
-       return NT_STATUS_NOT_SUPPORTED;
+       return lsa_secret_get(mem_ctx, secret_name,
+                             secret_current,
+                             secret_current_lastchange,
+                             secret_old,
+                             secret_old_lastchange,
+                             sd);
 }
 
 static NTSTATUS pdb_default_set_secret(struct pdb_methods *methods,
@@ -2337,13 +2342,16 @@ static NTSTATUS pdb_default_set_secret(struct pdb_methods *methods,
                                       DATA_BLOB *secret_old,
                                       struct security_descriptor *sd)
 {
-       return NT_STATUS_NOT_SUPPORTED;
+       return lsa_secret_set(secret_name,
+                             secret_current,
+                             secret_old,
+                             sd);
 }
 
 static NTSTATUS pdb_default_delete_secret(struct pdb_methods *methods,
                                          const char *secret_name)
 {
-       return NT_STATUS_NOT_SUPPORTED;
+       return lsa_secret_delete(secret_name);
 }
 
 /*******************************************************************
diff --git a/source3/passdb/secrets_lsa.c b/source3/passdb/secrets_lsa.c
new file mode 100644 (file)
index 0000000..a40942c
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+   Unix SMB/CIFS implementation.
+   Copyright (C) Guenther Deschner    2009
+
+   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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_secrets.h"
+#include "secrets.h"
+
+/******************************************************************************
+*******************************************************************************/
+
+static char *lsa_secret_key(TALLOC_CTX *mem_ctx,
+                           const char *secret_name)
+{
+       return talloc_asprintf_strupper_m(mem_ctx, "SECRETS/LSA/%s",
+                                         secret_name);
+}
+
+/******************************************************************************
+*******************************************************************************/
+
+static NTSTATUS lsa_secret_get_common(TALLOC_CTX *mem_ctx,
+                                     const char *secret_name,
+                                     struct lsa_secret *secret)
+{
+       char *key;
+       DATA_BLOB blob;
+       enum ndr_err_code ndr_err;
+
+       ZERO_STRUCTP(secret);
+
+       key = lsa_secret_key(mem_ctx, secret_name);
+       if (!key) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       blob.data = (uint8_t *)secrets_fetch(key, &blob.length);
+       talloc_free(key);
+
+       if (!blob.data) {
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, secret,
+                               (ndr_pull_flags_fn_t)ndr_pull_lsa_secret);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               SAFE_FREE(blob.data);
+               return ndr_map_error2ntstatus(ndr_err);
+       }
+
+       SAFE_FREE(blob.data);
+
+       return NT_STATUS_OK;
+}
+
+/******************************************************************************
+*******************************************************************************/
+
+NTSTATUS lsa_secret_get(TALLOC_CTX *mem_ctx,
+                       const char *secret_name,
+                       DATA_BLOB *secret_current,
+                       NTTIME *secret_current_lastchange,
+                       DATA_BLOB *secret_old,
+                       NTTIME *secret_old_lastchange,
+                       struct security_descriptor **sd)
+{
+       NTSTATUS status;
+       struct lsa_secret secret;
+
+       status = lsa_secret_get_common(mem_ctx, secret_name, &secret);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (secret_current) {
+               *secret_current = data_blob_null;
+               if (secret.secret_current) {
+                       *secret_current = *secret.secret_current;
+               }
+       }
+       if (secret_current_lastchange) {
+               *secret_current_lastchange = secret.secret_current_lastchange;
+       }
+       if (secret_old) {
+               *secret_old = data_blob_null;
+               if (secret.secret_old) {
+                       *secret_old = *secret.secret_old;
+               }
+       }
+       if (secret_old_lastchange) {
+               *secret_old_lastchange = secret.secret_old_lastchange;
+       }
+       if (sd) {
+               *sd = secret.sd;
+       }
+
+       return NT_STATUS_OK;
+}
+
+/******************************************************************************
+*******************************************************************************/
+
+static NTSTATUS lsa_secret_set_common(TALLOC_CTX *mem_ctx,
+                                     const char *key,
+                                     struct lsa_secret *secret,
+                                     DATA_BLOB *secret_current,
+                                     DATA_BLOB *secret_old,
+                                     struct security_descriptor *sd)
+{
+       enum ndr_err_code ndr_err;
+       DATA_BLOB blob;
+       struct timeval now = timeval_current();
+
+       if (!secret) {
+               secret = talloc_zero(mem_ctx, struct lsa_secret);
+       }
+
+       if (!secret) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (secret_old) {
+               secret->secret_old = secret_old;
+               secret->secret_old_lastchange = timeval_to_nttime(&now);
+       } else {
+               if (secret->secret_current) {
+                       secret->secret_old = secret->secret_current;
+                       secret->secret_old_lastchange = secret->secret_current_lastchange;
+               } else {
+                       secret->secret_old = NULL;
+                       secret->secret_old_lastchange = timeval_to_nttime(&now);
+               }
+       }
+       if (secret_current) {
+               secret->secret_current = secret_current;
+               secret->secret_current_lastchange = timeval_to_nttime(&now);
+       } else {
+               secret->secret_current = NULL;
+               secret->secret_current_lastchange = timeval_to_nttime(&now);
+       }
+       if (sd) {
+               secret->sd = sd;
+       }
+
+       ndr_err = ndr_push_struct_blob(&blob, mem_ctx, secret,
+                               (ndr_push_flags_fn_t)ndr_push_lsa_secret);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               return ndr_map_error2ntstatus(ndr_err);
+       }
+
+       if (!secrets_store(key, blob.data, blob.length)) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       return NT_STATUS_OK;
+}
+
+/******************************************************************************
+*******************************************************************************/
+
+NTSTATUS lsa_secret_set(const char *secret_name,
+                       DATA_BLOB *secret_current,
+                       DATA_BLOB *secret_old,
+                       struct security_descriptor *sd)
+{
+       char *key;
+       struct lsa_secret secret;
+       NTSTATUS status;
+
+       key = lsa_secret_key(talloc_tos(), secret_name);
+       if (!key) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = lsa_secret_get_common(talloc_tos(), secret_name, &secret);
+       if (!NT_STATUS_IS_OK(status) &&
+           !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+               talloc_free(key);
+               return status;
+       }
+
+       status = lsa_secret_set_common(talloc_tos(), key,
+                                      &secret,
+                                      secret_current,
+                                      secret_old,
+                                      sd);
+       talloc_free(key);
+
+       return status;
+}
+
+/******************************************************************************
+*******************************************************************************/
+
+NTSTATUS lsa_secret_delete(const char *secret_name)
+{
+       char *key;
+       struct lsa_secret secret;
+       NTSTATUS status;
+
+       key = lsa_secret_key(talloc_tos(), secret_name);
+       if (!key) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = lsa_secret_get_common(talloc_tos(), secret_name, &secret);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(key);
+               return status;
+       }
+
+       if (!secrets_delete(key)) {
+               talloc_free(key);
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       talloc_free(key);
+
+       return NT_STATUS_OK;
+}
index 296e6b97f7242ba33db5909a7433127918a4ad42..3be15ea02c9e3163094d902101f0550bba0a33ec 100755 (executable)
@@ -114,7 +114,7 @@ LIBADS_SERVER_SRC = '''libads/kerberos_verify.c libads/authdata.c'''
 LIBADS_PRINTER_SRC = '''libads/ldap_printer.c'''
 
 SECRETS_SRC = '''passdb/secrets.c passdb/machine_account_secrets.c
-                 passdb/machine_sid.c'''
+                 passdb/machine_sid.c passdb/secrets_lsa.c'''
 
 LIBNMB_SRC = '''libsmb/unexpected.c libsmb/namecache.c libsmb/nmblib.c
              libsmb/namequery.c libsmb/conncache.c