CVE-2022-37966 s4:kdc: announce PA-SUPPORTED-ETYPES like windows.
[samba.git] / source4 / kdc / sdb.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Database Glue between Samba and the KDC
5
6    Copyright (C) Guenther Deschner <gd@samba.org> 2014
7    Copyright (C) Andreas Schneider <asn@samba.org> 2014
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "system/kerberos.h"
26 #include "sdb.h"
27 #include "samba_kdc.h"
28 #include "lib/krb5_wrap/krb5_samba.h"
29
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_KERBEROS
32
33 void sdb_key_free(struct sdb_key *k)
34 {
35         if (k == NULL) {
36                 return;
37         }
38
39         /*
40          * Passing NULL as the Kerberos context is intentional here, as
41          * both Heimdal and MIT libraries don't use the context when
42          * clearing the keyblocks.
43          */
44         krb5_free_keyblock_contents(NULL, &k->key);
45
46         if (k->salt) {
47                 smb_krb5_free_data_contents(NULL, &k->salt->salt);
48                 SAFE_FREE(k->salt);
49         }
50
51         ZERO_STRUCTP(k);
52 }
53
54 void sdb_keys_free(struct sdb_keys *keys)
55 {
56         unsigned int i;
57
58         if (keys == NULL) {
59                 return;
60         }
61
62         for (i=0; i < keys->len; i++) {
63                 sdb_key_free(&keys->val[i]);
64         }
65
66         SAFE_FREE(keys->val);
67         ZERO_STRUCTP(keys);
68 }
69
70 void sdb_entry_free(struct sdb_entry *s)
71 {
72         if (s->skdc_entry != NULL) {
73                 s->skdc_entry->db_entry = NULL;
74                 TALLOC_FREE(s->skdc_entry);
75         }
76
77         /*
78          * Passing NULL as the Kerberos context is intentional here, as both
79          * Heimdal and MIT libraries don't use the context when clearing the
80          * principals.
81          */
82         krb5_free_principal(NULL, s->principal);
83
84         sdb_keys_free(&s->keys);
85         sdb_keys_free(&s->old_keys);
86         sdb_keys_free(&s->older_keys);
87         krb5_free_principal(NULL, s->created_by.principal);
88         if (s->modified_by) {
89                 krb5_free_principal(NULL, s->modified_by->principal);
90         }
91         SAFE_FREE(s->valid_start);
92         SAFE_FREE(s->valid_end);
93         SAFE_FREE(s->pw_end);
94
95         ZERO_STRUCTP(s);
96 }
97
98 struct SDBFlags int2SDBFlags(unsigned n)
99 {
100         struct SDBFlags flags;
101
102         memset(&flags, 0, sizeof(flags));
103
104         flags.initial = (n >> 0) & 1;
105         flags.forwardable = (n >> 1) & 1;
106         flags.proxiable = (n >> 2) & 1;
107         flags.renewable = (n >> 3) & 1;
108         flags.postdate = (n >> 4) & 1;
109         flags.server = (n >> 5) & 1;
110         flags.client = (n >> 6) & 1;
111         flags.invalid = (n >> 7) & 1;
112         flags.require_preauth = (n >> 8) & 1;
113         flags.change_pw = (n >> 9) & 1;
114         flags.require_hwauth = (n >> 10) & 1;
115         flags.ok_as_delegate = (n >> 11) & 1;
116         flags.user_to_user = (n >> 12) & 1;
117         flags.immutable = (n >> 13) & 1;
118         flags.trusted_for_delegation = (n >> 14) & 1;
119         flags.allow_kerberos4 = (n >> 15) & 1;
120         flags.allow_digest = (n >> 16) & 1;
121         flags.locked_out = (n >> 17) & 1;
122         flags.do_not_store = (n >> 31) & 1;
123         return flags;
124 }
125
126 /* Set the etypes of an sdb_entry based on its available current keys. */
127 krb5_error_code sdb_entry_set_etypes(struct sdb_entry *s)
128 {
129         if (s->keys.val != NULL) {
130                 unsigned i;
131
132                 s->etypes = malloc(sizeof(*s->etypes));
133                 if (s->etypes == NULL) {
134                         return ENOMEM;
135                 }
136
137                 s->etypes->len = s->keys.len;
138
139                 s->etypes->val = calloc(s->etypes->len, sizeof(*s->etypes->val));
140                 if (s->etypes->val == NULL) {
141                         return ENOMEM;
142                 }
143
144                 for (i = 0; i < s->etypes->len; i++) {
145                         const struct sdb_key *k = &s->keys.val[i];
146
147                         s->etypes->val[i] = KRB5_KEY_TYPE(&(k->key));
148                 }
149         }
150
151         return 0;
152 }
153
154 /*
155  * Set the session etypes of a server sdb_entry based on its etypes, forcing in
156  * strong etypes as desired.
157  */
158 krb5_error_code sdb_entry_set_session_etypes(struct sdb_entry *s,
159                                              bool add_aes256,
160                                              bool add_aes128,
161                                              bool add_rc4)
162 {
163         unsigned len = 0;
164
165         if (add_aes256) {
166                 /* Reserve space for AES256 */
167                 len += 1;
168         }
169
170         if (add_aes128) {
171                 /* Reserve space for AES128 */
172                 len += 1;
173         }
174
175         if (add_rc4) {
176                 /* Reserve space for RC4. */
177                 len += 1;
178         }
179
180         if (len != 0) {
181                 unsigned j = 0;
182
183                 s->session_etypes = malloc(sizeof(*s->session_etypes));
184                 if (s->session_etypes == NULL) {
185                         return ENOMEM;
186                 }
187
188                 /* session_etypes must be sorted in order of strength, with preferred etype first. */
189
190                 s->session_etypes->val = calloc(len, sizeof(*s->session_etypes->val));
191                 if (s->session_etypes->val == NULL) {
192                         SAFE_FREE(s->session_etypes);
193                         return ENOMEM;
194                 }
195
196                 if (add_aes256) {
197                         /* Add AES256 */
198                         s->session_etypes->val[j++] = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
199                 }
200
201                 if (add_aes128) {
202                         /* Add AES128. */
203                         s->session_etypes->val[j++] = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
204                 }
205
206                 if (add_rc4) {
207                         /* Add RC4. */
208                         s->session_etypes->val[j++] = ENCTYPE_ARCFOUR_HMAC;
209                 }
210
211                 s->session_etypes->len = j;
212         }
213
214         return 0;
215 }