source: vendor/current/source3/passdb/secrets_lsa.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 6.0 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Copyright (C) Guenther Deschner 2009
4
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.
9
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.
14
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/>.
17*/
18
19#include "includes.h"
20#include "librpc/gen_ndr/ndr_secrets.h"
21#include "secrets.h"
22
23/******************************************************************************
24*******************************************************************************/
25
26static char *lsa_secret_key(TALLOC_CTX *mem_ctx,
27 const char *secret_name)
28{
29 return talloc_asprintf_strupper_m(mem_ctx, "SECRETS/LSA/%s",
30 secret_name);
31}
32
33/******************************************************************************
34*******************************************************************************/
35
36static NTSTATUS lsa_secret_get_common(TALLOC_CTX *mem_ctx,
37 const char *secret_name,
38 struct lsa_secret *secret)
39{
40 char *key;
41 DATA_BLOB blob;
42 enum ndr_err_code ndr_err;
43
44 ZERO_STRUCTP(secret);
45
46 key = lsa_secret_key(mem_ctx, secret_name);
47 if (!key) {
48 return NT_STATUS_NO_MEMORY;
49 }
50
51 blob.data = (uint8_t *)secrets_fetch(key, &blob.length);
52 talloc_free(key);
53
54 if (!blob.data) {
55 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
56 }
57
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);
63 }
64
65 SAFE_FREE(blob.data);
66
67 return NT_STATUS_OK;
68}
69
70/******************************************************************************
71*******************************************************************************/
72
73NTSTATUS lsa_secret_get(TALLOC_CTX *mem_ctx,
74 const char *secret_name,
75 DATA_BLOB *secret_current,
76 NTTIME *secret_current_lastchange,
77 DATA_BLOB *secret_old,
78 NTTIME *secret_old_lastchange,
79 struct security_descriptor **sd)
80{
81 NTSTATUS status;
82 struct lsa_secret secret;
83
84 status = lsa_secret_get_common(mem_ctx, secret_name, &secret);
85 if (!NT_STATUS_IS_OK(status)) {
86 return status;
87 }
88
89 if (secret_current) {
90 *secret_current = data_blob_null;
91 if (secret.secret_current) {
92 *secret_current = *secret.secret_current;
93 }
94 }
95 if (secret_current_lastchange) {
96 *secret_current_lastchange = secret.secret_current_lastchange;
97 }
98 if (secret_old) {
99 *secret_old = data_blob_null;
100 if (secret.secret_old) {
101 *secret_old = *secret.secret_old;
102 }
103 }
104 if (secret_old_lastchange) {
105 *secret_old_lastchange = secret.secret_old_lastchange;
106 }
107 if (sd) {
108 *sd = secret.sd;
109 }
110
111 return NT_STATUS_OK;
112}
113
114/******************************************************************************
115*******************************************************************************/
116
117static NTSTATUS lsa_secret_set_common(TALLOC_CTX *mem_ctx,
118 const char *key,
119 struct lsa_secret *secret,
120 DATA_BLOB *secret_current,
121 DATA_BLOB *secret_old,
122 struct security_descriptor *sd)
123{
124 enum ndr_err_code ndr_err;
125 DATA_BLOB blob;
126 struct timeval now = timeval_current();
127
128 if (!secret) {
129 secret = talloc_zero(mem_ctx, struct lsa_secret);
130 }
131
132 if (!secret) {
133 return NT_STATUS_NO_MEMORY;
134 }
135
136 if (secret_old) {
137 secret->secret_old = secret_old;
138 secret->secret_old_lastchange = timeval_to_nttime(&now);
139 } else {
140 if (secret->secret_current) {
141 secret->secret_old = secret->secret_current;
142 secret->secret_old_lastchange = secret->secret_current_lastchange;
143 } else {
144 secret->secret_old = NULL;
145 secret->secret_old_lastchange = timeval_to_nttime(&now);
146 }
147 }
148 if (secret_current) {
149 secret->secret_current = secret_current;
150 secret->secret_current_lastchange = timeval_to_nttime(&now);
151 } else {
152 secret->secret_current = NULL;
153 secret->secret_current_lastchange = timeval_to_nttime(&now);
154 }
155 if (sd) {
156 secret->sd = sd;
157 }
158
159 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, secret,
160 (ndr_push_flags_fn_t)ndr_push_lsa_secret);
161 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
162 return ndr_map_error2ntstatus(ndr_err);
163 }
164
165 if (!secrets_store(key, blob.data, blob.length)) {
166 return NT_STATUS_ACCESS_DENIED;
167 }
168
169 return NT_STATUS_OK;
170}
171
172/******************************************************************************
173*******************************************************************************/
174
175NTSTATUS lsa_secret_set(const char *secret_name,
176 DATA_BLOB *secret_current,
177 DATA_BLOB *secret_old,
178 struct security_descriptor *sd)
179{
180 char *key;
181 struct lsa_secret secret;
182 NTSTATUS status;
183
184 key = lsa_secret_key(talloc_tos(), secret_name);
185 if (!key) {
186 return NT_STATUS_NO_MEMORY;
187 }
188
189 status = lsa_secret_get_common(talloc_tos(), secret_name, &secret);
190 if (!NT_STATUS_IS_OK(status) &&
191 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
192 talloc_free(key);
193 return status;
194 }
195
196 status = lsa_secret_set_common(talloc_tos(), key,
197 &secret,
198 secret_current,
199 secret_old,
200 sd);
201 talloc_free(key);
202
203 return status;
204}
205
206/******************************************************************************
207*******************************************************************************/
208
209NTSTATUS lsa_secret_delete(const char *secret_name)
210{
211 char *key;
212 struct lsa_secret secret;
213 NTSTATUS status;
214
215 key = lsa_secret_key(talloc_tos(), secret_name);
216 if (!key) {
217 return NT_STATUS_NO_MEMORY;
218 }
219
220 status = lsa_secret_get_common(talloc_tos(), secret_name, &secret);
221 if (!NT_STATUS_IS_OK(status)) {
222 talloc_free(key);
223 return status;
224 }
225
226 if (!secrets_delete(key)) {
227 talloc_free(key);
228 return NT_STATUS_ACCESS_DENIED;
229 }
230
231 talloc_free(key);
232
233 return NT_STATUS_OK;
234}
Note: See TracBrowser for help on using the repository browser.