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 541188 : void sdb_key_free(struct sdb_key *k) 34 : { 35 541188 : 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 541188 : krb5_free_keyblock_contents(NULL, &k->key); 45 : 46 541188 : if (k->salt) { 47 399869 : smb_krb5_free_data_contents(NULL, &k->salt->salt); 48 399869 : SAFE_FREE(k->salt); 49 : } 50 : 51 541188 : ZERO_STRUCTP(k); 52 : } 53 : 54 992205 : void sdb_keys_free(struct sdb_keys *keys) 55 : { 56 30843 : unsigned int i; 57 : 58 992205 : if (keys == NULL) { 59 0 : return; 60 : } 61 : 62 1533393 : for (i=0; i < keys->len; i++) { 63 541188 : sdb_key_free(&keys->val[i]); 64 : } 65 : 66 992205 : SAFE_FREE(keys->val); 67 992205 : ZERO_STRUCTP(keys); 68 : } 69 : 70 330735 : void sdb_entry_free(struct sdb_entry *s) 71 : { 72 330735 : if (s->skdc_entry != NULL) { 73 310239 : s->skdc_entry->db_entry = NULL; 74 310239 : 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 330735 : krb5_free_principal(NULL, s->principal); 83 : 84 330735 : sdb_keys_free(&s->keys); 85 330735 : SAFE_FREE(s->etypes); 86 330735 : sdb_keys_free(&s->old_keys); 87 330735 : sdb_keys_free(&s->older_keys); 88 330735 : if (s->session_etypes != NULL) { 89 225755 : SAFE_FREE(s->session_etypes->val); 90 : } 91 330735 : SAFE_FREE(s->session_etypes); 92 330735 : krb5_free_principal(NULL, s->created_by.principal); 93 330735 : if (s->modified_by) { 94 260 : krb5_free_principal(NULL, s->modified_by->principal); 95 : } 96 330735 : SAFE_FREE(s->valid_start); 97 330735 : SAFE_FREE(s->valid_end); 98 330735 : SAFE_FREE(s->pw_end); 99 330735 : SAFE_FREE(s->max_life); 100 330735 : SAFE_FREE(s->max_renew); 101 : 102 330735 : ZERO_STRUCTP(s); 103 330735 : } 104 : 105 : /* Set the etypes of an sdb_entry based on its available current keys. */ 106 309564 : krb5_error_code sdb_entry_set_etypes(struct sdb_entry *s) 107 : { 108 309564 : if (s->keys.val != NULL) { 109 10142 : unsigned i; 110 : 111 309564 : s->etypes = malloc(sizeof(*s->etypes)); 112 309564 : if (s->etypes == NULL) { 113 0 : return ENOMEM; 114 : } 115 : 116 309564 : s->etypes->len = s->keys.len; 117 : 118 309564 : s->etypes->val = calloc(s->etypes->len, sizeof(*s->etypes->val)); 119 309564 : if (s->etypes->val == NULL) { 120 0 : SAFE_FREE(s->etypes); 121 0 : return ENOMEM; 122 : } 123 : 124 1167995 : for (i = 0; i < s->etypes->len; i++) { 125 858431 : const struct sdb_key *k = &s->keys.val[i]; 126 : 127 858431 : s->etypes->val[i] = KRB5_KEY_TYPE(&(k->key)); 128 : } 129 : } 130 : 131 299422 : 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 225815 : 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 225815 : unsigned len = 0; 144 : 145 225815 : if (add_aes256) { 146 : /* Reserve space for AES256 */ 147 213136 : len += 1; 148 : } 149 : 150 225815 : if (add_aes128) { 151 : /* Reserve space for AES128 */ 152 210961 : len += 1; 153 : } 154 : 155 225815 : if (add_rc4) { 156 : /* Reserve space for RC4. */ 157 223318 : len += 1; 158 : } 159 : 160 225815 : if (len != 0) { 161 225755 : unsigned j = 0; 162 : 163 225755 : s->session_etypes = malloc(sizeof(*s->session_etypes)); 164 225755 : 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 225755 : s->session_etypes->val = calloc(len, sizeof(*s->session_etypes->val)); 171 225755 : if (s->session_etypes->val == NULL) { 172 0 : SAFE_FREE(s->session_etypes); 173 0 : return ENOMEM; 174 : } 175 : 176 225755 : if (add_aes256) { 177 : /* Add AES256 */ 178 213136 : s->session_etypes->val[j++] = ENCTYPE_AES256_CTS_HMAC_SHA1_96; 179 : } 180 : 181 225755 : if (add_aes128) { 182 : /* Add AES128. */ 183 210961 : s->session_etypes->val[j++] = ENCTYPE_AES128_CTS_HMAC_SHA1_96; 184 : } 185 : 186 225755 : if (add_rc4) { 187 : /* Add RC4. */ 188 223318 : s->session_etypes->val[j++] = ENCTYPE_ARCFOUR_HMAC; 189 : } 190 : 191 225755 : s->session_etypes->len = j; 192 : } 193 : 194 218483 : return 0; 195 : }