summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/pdb_interface.c14
-rw-r--r--source3/passdb/secrets_lsa.c234
2 files changed, 245 insertions, 3 deletions
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;
+}