smbd: Don't talloc_zero where we assign the struct a line below
[samba4-gss.git] / source3 / passdb / secrets_lsa.c
blob7ff6d518caec17bfbd6c639b713b6394433df714
1 /*
2 Unix SMB/CIFS implementation.
3 Copyright (C) Guenther Deschner 2009
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "includes.h"
20 #include "librpc/gen_ndr/ndr_secrets.h"
21 #include "secrets.h"
23 /******************************************************************************
24 *******************************************************************************/
26 static char *lsa_secret_key(TALLOC_CTX *mem_ctx,
27 const char *secret_name)
29 return talloc_asprintf_strupper_m(mem_ctx, "SECRETS/LSA/%s",
30 secret_name);
33 /******************************************************************************
34 *******************************************************************************/
36 static NTSTATUS lsa_secret_get_common(TALLOC_CTX *mem_ctx,
37 const char *secret_name,
38 struct lsa_secret *secret)
40 char *key;
41 DATA_BLOB blob;
42 enum ndr_err_code ndr_err;
44 ZERO_STRUCTP(secret);
46 key = lsa_secret_key(mem_ctx, secret_name);
47 if (!key) {
48 return NT_STATUS_NO_MEMORY;
51 blob.data = (uint8_t *)secrets_fetch(key, &blob.length);
52 talloc_free(key);
54 if (!blob.data) {
55 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
58 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, secret,
59 (ndr_pull_flags_fn_t)ndr_pull_lsa_secret);
60 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
61 SAFE_FREE(blob.data);
62 return ndr_map_error2ntstatus(ndr_err);
65 /* This is NOT a talloc blob */
66 BURN_FREE(blob.data, blob.length);
68 if (secret->secret_current != NULL &&
69 secret->secret_current->data != NULL) {
70 talloc_keep_secret(secret->secret_current->data);
72 if (secret->secret_old != NULL && secret->secret_old->data != NULL) {
73 talloc_keep_secret(secret->secret_old->data);
76 return NT_STATUS_OK;
79 /******************************************************************************
80 *******************************************************************************/
82 NTSTATUS lsa_secret_get(TALLOC_CTX *mem_ctx,
83 const char *secret_name,
84 DATA_BLOB *secret_current,
85 NTTIME *secret_current_lastchange,
86 DATA_BLOB *secret_old,
87 NTTIME *secret_old_lastchange,
88 struct security_descriptor **sd)
90 NTSTATUS status;
91 struct lsa_secret secret;
93 status = lsa_secret_get_common(mem_ctx, secret_name, &secret);
94 if (!NT_STATUS_IS_OK(status)) {
95 return status;
98 if (secret_current) {
99 *secret_current = data_blob_null;
100 if (secret.secret_current) {
101 *secret_current = *secret.secret_current;
104 if (secret_current_lastchange) {
105 *secret_current_lastchange = secret.secret_current_lastchange;
107 if (secret_old) {
108 *secret_old = data_blob_null;
109 if (secret.secret_old) {
110 *secret_old = *secret.secret_old;
113 if (secret_old_lastchange) {
114 *secret_old_lastchange = secret.secret_old_lastchange;
116 if (sd) {
117 *sd = secret.sd;
120 return NT_STATUS_OK;
123 /******************************************************************************
124 *******************************************************************************/
126 static NTSTATUS lsa_secret_set_common(TALLOC_CTX *mem_ctx,
127 const char *key,
128 struct lsa_secret *secret,
129 DATA_BLOB *secret_current,
130 DATA_BLOB *secret_old,
131 struct security_descriptor *sd)
133 enum ndr_err_code ndr_err;
134 DATA_BLOB blob;
135 struct timeval now = timeval_current();
137 if (!secret) {
138 secret = talloc_zero(mem_ctx, struct lsa_secret);
141 if (!secret) {
142 return NT_STATUS_NO_MEMORY;
145 if (secret_old) {
146 secret->secret_old = secret_old;
147 secret->secret_old_lastchange = timeval_to_nttime(&now);
148 } else {
149 if (secret->secret_current) {
150 secret->secret_old = secret->secret_current;
151 secret->secret_old_lastchange = secret->secret_current_lastchange;
152 } else {
153 secret->secret_old = NULL;
154 secret->secret_old_lastchange = timeval_to_nttime(&now);
157 if (secret_current) {
158 secret->secret_current = secret_current;
159 secret->secret_current_lastchange = timeval_to_nttime(&now);
160 } else {
161 secret->secret_current = NULL;
162 secret->secret_current_lastchange = timeval_to_nttime(&now);
164 if (sd) {
165 secret->sd = sd;
168 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, secret,
169 (ndr_push_flags_fn_t)ndr_push_lsa_secret);
170 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
171 return ndr_map_error2ntstatus(ndr_err);
174 if (!secrets_store(key, blob.data, blob.length)) {
175 data_blob_clear(&blob);
176 return NT_STATUS_ACCESS_DENIED;
179 data_blob_clear(&blob);
180 return NT_STATUS_OK;
183 /******************************************************************************
184 *******************************************************************************/
186 NTSTATUS lsa_secret_set(const char *secret_name,
187 DATA_BLOB *secret_current,
188 DATA_BLOB *secret_old,
189 struct security_descriptor *sd)
191 char *key;
192 struct lsa_secret secret;
193 NTSTATUS status;
195 key = lsa_secret_key(talloc_tos(), secret_name);
196 if (!key) {
197 return NT_STATUS_NO_MEMORY;
200 status = lsa_secret_get_common(talloc_tos(), secret_name, &secret);
201 if (!NT_STATUS_IS_OK(status) &&
202 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
203 talloc_free(key);
204 return status;
207 status = lsa_secret_set_common(talloc_tos(), key,
208 &secret,
209 secret_current,
210 secret_old,
211 sd);
212 talloc_free(key);
214 return status;
217 /******************************************************************************
218 *******************************************************************************/
220 NTSTATUS lsa_secret_delete(const char *secret_name)
222 char *key;
223 struct lsa_secret secret;
224 NTSTATUS status;
226 key = lsa_secret_key(talloc_tos(), secret_name);
227 if (!key) {
228 return NT_STATUS_NO_MEMORY;
231 status = lsa_secret_get_common(talloc_tos(), secret_name, &secret);
232 if (!NT_STATUS_IS_OK(status)) {
233 talloc_free(key);
234 return status;
237 if (!secrets_delete_entry(key)) {
238 talloc_free(key);
239 return NT_STATUS_ACCESS_DENIED;
242 talloc_free(key);
244 return NT_STATUS_OK;