summaryrefslogtreecommitdiffstats
path: root/source4/kdc/sdb.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
commit4f5791ebd03eaec1c7da0865a383175b05102712 (patch)
tree8ce7b00f7a76baa386372422adebbe64510812d4 /source4/kdc/sdb.c
parentInitial commit. (diff)
downloadsamba-upstream.tar.xz
samba-upstream.zip
Adding upstream version 2:4.17.12+dfsg.upstream/2%4.17.12+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--source4/kdc/sdb.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/source4/kdc/sdb.c b/source4/kdc/sdb.c
new file mode 100644
index 0000000..5fb1146
--- /dev/null
+++ b/source4/kdc/sdb.c
@@ -0,0 +1,212 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Database Glue between Samba and the KDC
+
+ Copyright (C) Guenther Deschner <gd@samba.org> 2014
+ Copyright (C) Andreas Schneider <asn@samba.org> 2014
+
+ 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 "system/kerberos.h"
+#include "sdb.h"
+#include "samba_kdc.h"
+#include "lib/krb5_wrap/krb5_samba.h"
+
+void sdb_key_free(struct sdb_key *k)
+{
+ if (k == NULL) {
+ return;
+ }
+
+ /*
+ * Passing NULL as the Kerberos context is intentional here, as
+ * both Heimdal and MIT libraries don't use the context when
+ * clearing the keyblocks.
+ */
+ krb5_free_keyblock_contents(NULL, &k->key);
+
+ if (k->salt) {
+ smb_krb5_free_data_contents(NULL, &k->salt->salt);
+ SAFE_FREE(k->salt);
+ }
+
+ ZERO_STRUCTP(k);
+}
+
+void sdb_keys_free(struct sdb_keys *keys)
+{
+ unsigned int i;
+
+ if (keys == NULL) {
+ return;
+ }
+
+ for (i=0; i < keys->len; i++) {
+ sdb_key_free(&keys->val[i]);
+ }
+
+ SAFE_FREE(keys->val);
+ ZERO_STRUCTP(keys);
+}
+
+void sdb_entry_free(struct sdb_entry *s)
+{
+ if (s->skdc_entry != NULL) {
+ s->skdc_entry->db_entry = NULL;
+ TALLOC_FREE(s->skdc_entry);
+ }
+
+ /*
+ * Passing NULL as the Kerberos context is intentional here, as both
+ * Heimdal and MIT libraries don't use the context when clearing the
+ * principals.
+ */
+ krb5_free_principal(NULL, s->principal);
+
+ sdb_keys_free(&s->keys);
+ sdb_keys_free(&s->old_keys);
+ sdb_keys_free(&s->older_keys);
+ krb5_free_principal(NULL, s->created_by.principal);
+ if (s->modified_by) {
+ krb5_free_principal(NULL, s->modified_by->principal);
+ }
+ SAFE_FREE(s->valid_start);
+ SAFE_FREE(s->valid_end);
+ SAFE_FREE(s->pw_end);
+
+ ZERO_STRUCTP(s);
+}
+
+struct SDBFlags int2SDBFlags(unsigned n)
+{
+ struct SDBFlags flags;
+
+ memset(&flags, 0, sizeof(flags));
+
+ flags.initial = (n >> 0) & 1;
+ flags.forwardable = (n >> 1) & 1;
+ flags.proxiable = (n >> 2) & 1;
+ flags.renewable = (n >> 3) & 1;
+ flags.postdate = (n >> 4) & 1;
+ flags.server = (n >> 5) & 1;
+ flags.client = (n >> 6) & 1;
+ flags.invalid = (n >> 7) & 1;
+ flags.require_preauth = (n >> 8) & 1;
+ flags.change_pw = (n >> 9) & 1;
+ flags.require_hwauth = (n >> 10) & 1;
+ flags.ok_as_delegate = (n >> 11) & 1;
+ flags.user_to_user = (n >> 12) & 1;
+ flags.immutable = (n >> 13) & 1;
+ flags.trusted_for_delegation = (n >> 14) & 1;
+ flags.allow_kerberos4 = (n >> 15) & 1;
+ flags.allow_digest = (n >> 16) & 1;
+ flags.locked_out = (n >> 17) & 1;
+ flags.do_not_store = (n >> 31) & 1;
+ return flags;
+}
+
+/* Set the etypes of an sdb_entry based on its available current keys. */
+krb5_error_code sdb_entry_set_etypes(struct sdb_entry *s)
+{
+ if (s->keys.val != NULL) {
+ unsigned i;
+
+ s->etypes = malloc(sizeof(*s->etypes));
+ if (s->etypes == NULL) {
+ return ENOMEM;
+ }
+
+ s->etypes->len = s->keys.len;
+
+ s->etypes->val = calloc(s->etypes->len, sizeof(*s->etypes->val));
+ if (s->etypes->val == NULL) {
+ return ENOMEM;
+ }
+
+ for (i = 0; i < s->etypes->len; i++) {
+ const struct sdb_key *k = &s->keys.val[i];
+
+ s->etypes->val[i] = KRB5_KEY_TYPE(&(k->key));
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Set the session etypes of a server sdb_entry based on its etypes, forcing in
+ * strong etypes as desired.
+ */
+krb5_error_code sdb_entry_set_session_etypes(struct sdb_entry *s,
+ bool add_aes256,
+ bool add_aes128,
+ bool add_rc4)
+{
+ unsigned len = 0;
+
+ if (add_aes256) {
+ /* Reserve space for AES256 */
+ len += 1;
+ }
+
+ if (add_aes128) {
+ /* Reserve space for AES128 */
+ len += 1;
+ }
+
+ if (add_rc4) {
+ /* Reserve space for RC4. */
+ len += 1;
+ }
+
+ if (len != 0) {
+ unsigned j = 0;
+
+ s->session_etypes = malloc(sizeof(*s->session_etypes));
+ if (s->session_etypes == NULL) {
+ return ENOMEM;
+ }
+
+ /* session_etypes must be sorted in order of strength, with preferred etype first. */
+
+ s->session_etypes->val = calloc(len, sizeof(*s->session_etypes->val));
+ if (s->session_etypes->val == NULL) {
+ SAFE_FREE(s->session_etypes);
+ return ENOMEM;
+ }
+
+ if (add_aes256) {
+ /* Add AES256 */
+ s->session_etypes->val[j++] = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
+ }
+
+ if (add_aes128) {
+ /* Add AES128. */
+ s->session_etypes->val[j++] = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
+ }
+
+ if (add_rc4) {
+ /* Add RC4. */
+ s->session_etypes->val[j++] = ENCTYPE_ARCFOUR_HMAC;
+ }
+
+ s->session_etypes->len = j;
+ }
+
+ return 0;
+}