summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in3
-rw-r--r--source3/include/secrets.h14
-rw-r--r--source3/passdb/pdb_interface.c14
-rw-r--r--source3/passdb/secrets_lsa.c234
-rwxr-xr-xsource3/wscript_build2
5 files changed, 262 insertions, 5 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index f0718cef6b..ff2d433f82 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -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 \
diff --git a/source3/include/secrets.h b/source3/include/secrets.h
index 01e635c580..4c23335b58 100644
--- a/source3/include/secrets.h
+++ b/source3/include/secrets.h
@@ -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 */
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index 11c186a398..c92b22ae99 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -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
index 0000000000..a40942cf7b
--- /dev/null
+++ b/source3/passdb/secrets_lsa.c
@@ -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;
+}
diff --git a/source3/wscript_build b/source3/wscript_build
index 296e6b97f7..3be15ea02c 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -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