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 : #undef DBGC_CLASS 31 : #define DBGC_CLASS DBGC_KERBEROS 32 : 33 526001 : void sdb_key_free(struct sdb_key *k) 34 : { 35 526001 : if (k == NULL) { 36 0 : 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 526001 : krb5_free_keyblock_contents(NULL, &k->key); 45 : 46 526001 : if (k->salt) { 47 388897 : smb_krb5_free_data_contents(NULL, &k->salt->salt); 48 388897 : SAFE_FREE(k->salt); 49 : } 50 : 51 526001 : ZERO_STRUCTP(k); 52 : } 53 : 54 965373 : void sdb_keys_free(struct sdb_keys *keys) 55 : { 56 30843 : unsigned int i; 57 : 58 965373 : if (keys == NULL) { 59 0 : return; 60 : } 61 : 62 1491374 : for (i=0; i < keys->len; i++) { 63 526001 : sdb_key_free(&keys->val[i]); 64 : } 65 : 66 965373 : SAFE_FREE(keys->val); 67 965373 : ZERO_STRUCTP(keys); 68 : } 69 : 70 321791 : void sdb_entry_free(struct sdb_entry *s) 71 : { 72 321791 : if (s->skdc_entry != NULL) { 73 302271 : s->skdc_entry->db_entry = NULL; 74 302271 : 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 321791 : krb5_free_principal(NULL, s->principal); 83 : 84 321791 : sdb_keys_free(&s->keys); 85 321791 : SAFE_FREE(s->etypes); 86 321791 : sdb_keys_free(&s->old_keys); 87 321791 : sdb_keys_free(&s->older_keys); 88 321791 : if (s->session_etypes != NULL) { 89 220268 : SAFE_FREE(s->session_etypes->val); 90 : } 91 321791 : SAFE_FREE(s->session_etypes); 92 321791 : krb5_free_principal(NULL, s->created_by.principal); 93 321791 : if (s->modified_by) { 94 160 : krb5_free_principal(NULL, s->modified_by->principal); 95 : } 96 321791 : SAFE_FREE(s->valid_start); 97 321791 : SAFE_FREE(s->valid_end); 98 321791 : SAFE_FREE(s->pw_end); 99 321791 : SAFE_FREE(s->max_life); 100 321791 : SAFE_FREE(s->max_renew); 101 : 102 321791 : ZERO_STRUCTP(s); 103 321791 : } 104 : 105 : /* Set the etypes of an sdb_entry based on its available current keys. */ 106 301596 : krb5_error_code sdb_entry_set_etypes(struct sdb_entry *s) 107 : { 108 301596 : if (s->keys.val != NULL) { 109 10142 : unsigned i; 110 : 111 301596 : s->etypes = malloc(sizeof(*s->etypes)); 112 301596 : if (s->etypes == NULL) { 113 0 : return ENOMEM; 114 : } 115 : 116 301596 : s->etypes->len = s->keys.len; 117 : 118 301596 : s->etypes->val = calloc(s->etypes->len, sizeof(*s->etypes->val)); 119 301596 : if (s->etypes->val == NULL) { 120 0 : SAFE_FREE(s->etypes); 121 0 : return ENOMEM; 122 : } 123 : 124 1138286 : for (i = 0; i < s->etypes->len; i++) { 125 836690 : const struct sdb_key *k = &s->keys.val[i]; 126 : 127 836690 : s->etypes->val[i] = KRB5_KEY_TYPE(&(k->key)); 128 : } 129 : } 130 : 131 291454 : return 0; 132 : } 133 : 134 : /* 135 : * Set the session etypes of a server sdb_entry based on its etypes, forcing in 136 : * strong etypes as desired. 137 : */ 138 220328 : krb5_error_code sdb_entry_set_session_etypes(struct sdb_entry *s, 139 : bool add_aes256, 140 : bool add_aes128, 141 : bool add_rc4) 142 : { 143 220328 : unsigned len = 0; 144 : 145 220328 : if (add_aes256) { 146 : /* Reserve space for AES256 */ 147 207649 : len += 1; 148 : } 149 : 150 220328 : if (add_aes128) { 151 : /* Reserve space for AES128 */ 152 206410 : len += 1; 153 : } 154 : 155 220328 : if (add_rc4) { 156 : /* Reserve space for RC4. */ 157 218771 : len += 1; 158 : } 159 : 160 220328 : if (len != 0) { 161 220268 : unsigned j = 0; 162 : 163 220268 : s->session_etypes = malloc(sizeof(*s->session_etypes)); 164 220268 : if (s->session_etypes == NULL) { 165 0 : return ENOMEM; 166 : } 167 : 168 : /* session_etypes must be sorted in order of strength, with preferred etype first. */ 169 : 170 220268 : s->session_etypes->val = calloc(len, sizeof(*s->session_etypes->val)); 171 220268 : if (s->session_etypes->val == NULL) { 172 0 : SAFE_FREE(s->session_etypes); 173 0 : return ENOMEM; 174 : } 175 : 176 220268 : if (add_aes256) { 177 : /* Add AES256 */ 178 207649 : s->session_etypes->val[j++] = ENCTYPE_AES256_CTS_HMAC_SHA1_96; 179 : } 180 : 181 220268 : if (add_aes128) { 182 : /* Add AES128. */ 183 206410 : s->session_etypes->val[j++] = ENCTYPE_AES128_CTS_HMAC_SHA1_96; 184 : } 185 : 186 220268 : if (add_rc4) { 187 : /* Add RC4. */ 188 218771 : s->session_etypes->val[j++] = ENCTYPE_ARCFOUR_HMAC; 189 : } 190 : 191 220268 : s->session_etypes->len = j; 192 : } 193 : 194 212996 : return 0; 195 : }