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 <hdb.h> 26 : #include "sdb.h" 27 : #include "sdb_hdb.h" 28 : #include "lib/krb5_wrap/krb5_samba.h" 29 : #include "librpc/gen_ndr/security.h" 30 : #include "kdc/samba_kdc.h" 31 : 32 : #undef DBGC_CLASS 33 : #define DBGC_CLASS DBGC_KERBEROS 34 : 35 210261 : static void sdb_flags_to_hdb_flags(const struct SDBFlags *s, 36 : HDBFlags *h) 37 : { 38 : SMB_ASSERT(sizeof(struct SDBFlags) == sizeof(HDBFlags)); 39 : 40 210261 : h->initial = s->initial; 41 210261 : h->forwardable = s->forwardable; 42 210261 : h->proxiable = s->proxiable; 43 210261 : h->renewable = s->renewable; 44 210261 : h->postdate = s->postdate; 45 210261 : h->server = s->server; 46 210261 : h->client = s->client; 47 210261 : h->invalid = s->invalid; 48 210261 : h->require_preauth = s->require_preauth; 49 210261 : h->change_pw = s->change_pw; 50 210261 : h->require_hwauth = s->require_hwauth; 51 210261 : h->ok_as_delegate = s->ok_as_delegate; 52 210261 : h->user_to_user = s->user_to_user; 53 210261 : h->immutable = s->immutable; 54 210261 : h->trusted_for_delegation = s->trusted_for_delegation; 55 210261 : h->allow_kerberos4 = s->allow_kerberos4; 56 210261 : h->allow_digest = s->allow_digest; 57 210261 : h->locked_out = s->locked_out; 58 210261 : h->require_pwchange = s->require_pwchange; 59 210261 : h->materialize = s->materialize; 60 210261 : h->virtual_keys = s->virtual_keys; 61 210261 : h->virtual = s->virtual; 62 210261 : h->synthetic = s->synthetic; 63 210261 : h->no_auth_data_reqd = s->no_auth_data_reqd; 64 210261 : h->_unused24 = s->_unused24; 65 210261 : h->_unused25 = s->_unused25; 66 210261 : h->_unused26 = s->_unused26; 67 210261 : h->_unused27 = s->_unused27; 68 210261 : h->_unused28 = s->_unused28; 69 210261 : h->_unused29 = s->_unused29; 70 210261 : h->force_canonicalize = s->force_canonicalize; 71 210261 : h->do_not_store = s->do_not_store; 72 210261 : } 73 : 74 257179 : static int sdb_salt_to_Salt(const struct sdb_salt *s, Salt *h) 75 : { 76 : int ret; 77 : 78 257179 : h->type = s->type; 79 257179 : ret = smb_krb5_copy_data_contents(&h->salt, s->salt.data, s->salt.length); 80 257179 : if (ret != 0) { 81 0 : free_Salt(h); 82 0 : return ENOMEM; 83 : } 84 257179 : h->opaque = NULL; 85 : 86 257179 : return 0; 87 : } 88 : 89 357155 : static int sdb_key_to_Key(const struct sdb_key *s, Key *h) 90 : { 91 : int rc; 92 : 93 357155 : ZERO_STRUCTP(h); 94 : 95 357155 : h->key.keytype = s->key.keytype; 96 357155 : rc = smb_krb5_copy_data_contents(&h->key.keyvalue, 97 357155 : s->key.keyvalue.data, 98 357155 : s->key.keyvalue.length); 99 357155 : if (rc != 0) { 100 0 : goto error_nomem; 101 : } 102 : 103 357155 : if (s->salt != NULL) { 104 257179 : h->salt = malloc(sizeof(Salt)); 105 257179 : if (h->salt == NULL) { 106 0 : goto error_nomem; 107 : } 108 : 109 257179 : rc = sdb_salt_to_Salt(s->salt, 110 : h->salt); 111 257179 : if (rc != 0) { 112 0 : goto error_nomem; 113 : } 114 : } else { 115 99976 : h->salt = NULL; 116 : } 117 : 118 357155 : return 0; 119 : 120 0 : error_nomem: 121 0 : free_Key(h); 122 0 : return ENOMEM; 123 : } 124 : 125 210261 : static int sdb_keys_to_Keys(const struct sdb_keys *s, Keys *h) 126 : { 127 : int ret, i; 128 : 129 210261 : h->len = s->len; 130 210261 : if (s->val != NULL) { 131 209402 : h->val = malloc(h->len * sizeof(Key)); 132 209402 : if (h->val == NULL) { 133 0 : return ENOMEM; 134 : } 135 566557 : for (i = 0; i < h->len; i++) { 136 357155 : ret = sdb_key_to_Key(&s->val[i], 137 357155 : &h->val[i]); 138 357155 : if (ret != 0) { 139 0 : free_Keys(h); 140 0 : return ENOMEM; 141 : } 142 : } 143 : } else { 144 859 : h->val = NULL; 145 : } 146 : 147 210261 : return 0; 148 : } 149 : 150 210261 : static int sdb_event_to_Event(krb5_context context, 151 : const struct sdb_event *s, Event *h) 152 : { 153 : int ret; 154 : 155 210261 : if (s->principal != NULL) { 156 1147 : ret = krb5_copy_principal(context, 157 1147 : s->principal, 158 1147 : &h->principal); 159 1147 : if (ret != 0) { 160 0 : free_Event(h); 161 0 : return ret; 162 : } 163 : } else { 164 209114 : h->principal = NULL; 165 : } 166 210261 : h->time = s->time; 167 : 168 210261 : return 0; 169 : } 170 : 171 210261 : int sdb_entry_to_hdb_entry(krb5_context context, 172 : const struct sdb_entry *s, 173 : hdb_entry *h) 174 : { 175 210261 : struct samba_kdc_entry *ske = s->skdc_entry; 176 : unsigned int i; 177 : int rc; 178 : 179 210261 : ZERO_STRUCTP(h); 180 : 181 210261 : rc = krb5_copy_principal(context, 182 210261 : s->principal, 183 210261 : &h->principal); 184 210261 : if (rc != 0) { 185 0 : return rc; 186 : } 187 : 188 210261 : h->kvno = s->kvno; 189 : 190 210261 : rc = sdb_keys_to_Keys(&s->keys, &h->keys); 191 210261 : if (rc != 0) { 192 0 : goto error; 193 : } 194 : 195 210261 : rc = sdb_event_to_Event(context, 196 : &s->created_by, 197 : &h->created_by); 198 210261 : if (rc != 0) { 199 0 : goto error; 200 : } 201 : 202 210261 : if (s->modified_by) { 203 0 : h->modified_by = malloc(sizeof(Event)); 204 0 : if (h->modified_by == NULL) { 205 0 : rc = ENOMEM; 206 0 : goto error; 207 : } 208 : 209 0 : rc = sdb_event_to_Event(context, 210 0 : s->modified_by, 211 : h->modified_by); 212 0 : if (rc != 0) { 213 0 : goto error; 214 : } 215 : } else { 216 210261 : h->modified_by = NULL; 217 : } 218 : 219 210261 : if (s->valid_start != NULL) { 220 0 : h->valid_start = malloc(sizeof(KerberosTime)); 221 0 : if (h->valid_start == NULL) { 222 0 : rc = ENOMEM; 223 0 : goto error; 224 : } 225 0 : *h->valid_start = *s->valid_start; 226 : } else { 227 210261 : h->valid_start = NULL; 228 : } 229 : 230 210261 : if (s->valid_end != NULL) { 231 0 : h->valid_end = malloc(sizeof(KerberosTime)); 232 0 : if (h->valid_end == NULL) { 233 0 : rc = ENOMEM; 234 0 : goto error; 235 : } 236 0 : *h->valid_end = *s->valid_end; 237 : } else { 238 210261 : h->valid_end = NULL; 239 : } 240 : 241 210261 : if (s->pw_end != NULL) { 242 55433 : h->pw_end = malloc(sizeof(KerberosTime)); 243 55433 : if (h->pw_end == NULL) { 244 0 : rc = ENOMEM; 245 0 : goto error; 246 : } 247 55433 : *h->pw_end = *s->pw_end; 248 : } else { 249 154828 : h->pw_end = NULL; 250 : } 251 : 252 210261 : if (s->max_life != NULL) { 253 207181 : h->max_life = malloc(sizeof(unsigned int)); 254 207181 : if (h->max_life == NULL) { 255 0 : rc = ENOMEM; 256 0 : goto error; 257 : } 258 207181 : *h->max_life = *s->max_life; 259 : } else { 260 3080 : h->max_life = NULL; 261 : } 262 : 263 210261 : if (s->max_renew != NULL) { 264 207181 : h->max_renew = malloc(sizeof(unsigned int)); 265 207181 : if (h->max_renew == NULL) { 266 0 : rc = ENOMEM; 267 0 : goto error; 268 : } 269 207181 : *h->max_renew = *s->max_renew; 270 : } else { 271 3080 : h->max_renew = NULL; 272 : } 273 : 274 210261 : sdb_flags_to_hdb_flags(&s->flags, &h->flags); 275 : 276 210261 : h->etypes = NULL; 277 210261 : if (s->etypes != NULL) { 278 208328 : h->etypes = malloc(sizeof(*h->etypes)); 279 208328 : if (h->etypes == NULL) { 280 0 : rc = ENOMEM; 281 0 : goto error; 282 : } 283 : 284 208328 : h->etypes->len = s->etypes->len; 285 : 286 208328 : h->etypes->val = calloc(h->etypes->len, sizeof(int)); 287 208328 : if (h->etypes->val == NULL) { 288 0 : rc = ENOMEM; 289 0 : goto error; 290 : } 291 : 292 562261 : for (i = 0; i < h->etypes->len; i++) { 293 353933 : h->etypes->val[i] = s->etypes->val[i]; 294 : } 295 : } 296 : 297 210261 : h->session_etypes = NULL; 298 210261 : if (s->session_etypes != NULL) { 299 155347 : h->session_etypes = malloc(sizeof(*h->session_etypes)); 300 155347 : if (h->session_etypes == NULL) { 301 0 : rc = ENOMEM; 302 0 : goto error; 303 : } 304 : 305 155347 : h->session_etypes->len = s->session_etypes->len; 306 : 307 155347 : h->session_etypes->val = calloc(h->session_etypes->len, sizeof(*h->session_etypes->val)); 308 155347 : if (h->session_etypes->val == NULL) { 309 0 : rc = ENOMEM; 310 0 : goto error; 311 : } 312 : 313 594899 : for (i = 0; i < h->session_etypes->len; ++i) { 314 439552 : h->session_etypes->val[i] = s->session_etypes->val[i]; 315 : } 316 : } 317 : 318 210261 : h->context = ske; 319 210261 : if (ske != NULL) { 320 208328 : ske->kdc_entry = h; 321 : } 322 210261 : return 0; 323 0 : error: 324 0 : free_hdb_entry(h); 325 0 : return rc; 326 : }