Line data Source code
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 363229 : void sdb_key_free(struct sdb_key *k)
31 : {
32 363229 : if (k == NULL) {
33 0 : return;
34 : }
35 :
36 : /*
37 : * Passing NULL as the Kerberos context is intentional here, as
38 : * both Heimdal and MIT libraries don't use the context when
39 : * clearing the keyblocks.
40 : */
41 363229 : krb5_free_keyblock_contents(NULL, &k->key);
42 :
43 363229 : if (k->salt) {
44 261630 : smb_krb5_free_data_contents(NULL, &k->salt->salt);
45 261630 : SAFE_FREE(k->salt);
46 : }
47 :
48 363229 : ZERO_STRUCTP(k);
49 : }
50 :
51 671979 : void sdb_keys_free(struct sdb_keys *keys)
52 : {
53 : unsigned int i;
54 :
55 671979 : if (keys == NULL) {
56 0 : return;
57 : }
58 :
59 1035208 : for (i=0; i < keys->len; i++) {
60 363229 : sdb_key_free(&keys->val[i]);
61 : }
62 :
63 671979 : SAFE_FREE(keys->val);
64 671979 : ZERO_STRUCTP(keys);
65 : }
66 :
67 223993 : void sdb_entry_free(struct sdb_entry *s)
68 : {
69 223993 : if (s->skdc_entry != NULL) {
70 208340 : s->skdc_entry->db_entry = NULL;
71 208340 : TALLOC_FREE(s->skdc_entry);
72 : }
73 :
74 : /*
75 : * Passing NULL as the Kerberos context is intentional here, as both
76 : * Heimdal and MIT libraries don't use the context when clearing the
77 : * principals.
78 : */
79 223993 : krb5_free_principal(NULL, s->principal);
80 :
81 223993 : sdb_keys_free(&s->keys);
82 223993 : sdb_keys_free(&s->old_keys);
83 223993 : sdb_keys_free(&s->older_keys);
84 223993 : krb5_free_principal(NULL, s->created_by.principal);
85 223993 : if (s->modified_by) {
86 53 : krb5_free_principal(NULL, s->modified_by->principal);
87 : }
88 223993 : SAFE_FREE(s->valid_start);
89 223993 : SAFE_FREE(s->valid_end);
90 223993 : SAFE_FREE(s->pw_end);
91 :
92 223993 : ZERO_STRUCTP(s);
93 223993 : }
94 :
95 210014 : struct SDBFlags int2SDBFlags(unsigned n)
96 : {
97 : struct SDBFlags flags;
98 :
99 210014 : memset(&flags, 0, sizeof(flags));
100 :
101 210014 : flags.initial = (n >> 0) & 1;
102 210014 : flags.forwardable = (n >> 1) & 1;
103 210014 : flags.proxiable = (n >> 2) & 1;
104 210014 : flags.renewable = (n >> 3) & 1;
105 210014 : flags.postdate = (n >> 4) & 1;
106 210014 : flags.server = (n >> 5) & 1;
107 210014 : flags.client = (n >> 6) & 1;
108 210014 : flags.invalid = (n >> 7) & 1;
109 210014 : flags.require_preauth = (n >> 8) & 1;
110 210014 : flags.change_pw = (n >> 9) & 1;
111 210014 : flags.require_hwauth = (n >> 10) & 1;
112 210014 : flags.ok_as_delegate = (n >> 11) & 1;
113 210014 : flags.user_to_user = (n >> 12) & 1;
114 210014 : flags.immutable = (n >> 13) & 1;
115 210014 : flags.trusted_for_delegation = (n >> 14) & 1;
116 210014 : flags.allow_kerberos4 = (n >> 15) & 1;
117 210014 : flags.allow_digest = (n >> 16) & 1;
118 210014 : flags.locked_out = (n >> 17) & 1;
119 210014 : flags.do_not_store = (n >> 31) & 1;
120 210014 : return flags;
121 : }
122 :
123 : /* Set the etypes of an sdb_entry based on its available current keys. */
124 209342 : krb5_error_code sdb_entry_set_etypes(struct sdb_entry *s)
125 : {
126 209342 : if (s->keys.val != NULL) {
127 : unsigned i;
128 :
129 209342 : s->etypes = malloc(sizeof(*s->etypes));
130 209342 : if (s->etypes == NULL) {
131 0 : return ENOMEM;
132 : }
133 :
134 209342 : s->etypes->len = s->keys.len;
135 :
136 209342 : s->etypes->val = calloc(s->etypes->len, sizeof(*s->etypes->val));
137 209342 : if (s->etypes->val == NULL) {
138 0 : return ENOMEM;
139 : }
140 :
141 783937 : for (i = 0; i < s->etypes->len; i++) {
142 574595 : const struct sdb_key *k = &s->keys.val[i];
143 :
144 574595 : s->etypes->val[i] = KRB5_KEY_TYPE(&(k->key));
145 : }
146 : }
147 :
148 209342 : return 0;
149 : }
150 :
151 : /*
152 : * Set the session etypes of a server sdb_entry based on its etypes, forcing in
153 : * strong etypes as desired.
154 : */
155 155099 : krb5_error_code sdb_entry_set_session_etypes(struct sdb_entry *s,
156 : bool add_aes256,
157 : bool add_aes128,
158 : bool add_rc4)
159 : {
160 155099 : unsigned len = 0;
161 :
162 155099 : if (add_aes256) {
163 : /* Reserve space for AES256 */
164 143075 : len += 1;
165 : }
166 :
167 155099 : if (add_aes128) {
168 : /* Reserve space for AES128 */
169 142045 : len += 1;
170 : }
171 :
172 155099 : if (add_rc4) {
173 : /* Reserve space for RC4. */
174 154046 : len += 1;
175 : }
176 :
177 155099 : if (len != 0) {
178 155099 : unsigned j = 0;
179 :
180 155099 : s->session_etypes = malloc(sizeof(*s->session_etypes));
181 155099 : if (s->session_etypes == NULL) {
182 0 : return ENOMEM;
183 : }
184 :
185 : /* session_etypes must be sorted in order of strength, with preferred etype first. */
186 :
187 155099 : s->session_etypes->val = calloc(len, sizeof(*s->session_etypes->val));
188 155099 : if (s->session_etypes->val == NULL) {
189 0 : SAFE_FREE(s->session_etypes);
190 0 : return ENOMEM;
191 : }
192 :
193 155099 : if (add_aes256) {
194 : /* Add AES256 */
195 143075 : s->session_etypes->val[j++] = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
196 : }
197 :
198 155099 : if (add_aes128) {
199 : /* Add AES128. */
200 142045 : s->session_etypes->val[j++] = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
201 : }
202 :
203 155099 : if (add_rc4) {
204 : /* Add RC4. */
205 154046 : s->session_etypes->val[j++] = ENCTYPE_ARCFOUR_HMAC;
206 : }
207 :
208 155099 : s->session_etypes->len = j;
209 : }
210 :
211 155099 : return 0;
212 : }
|