Home | History | Annotate | Line # | Download | only in kadm5
      1  1.1     elric /*	$NetBSD: common_glue.c,v 1.2 2017/01/28 21:31:49 christos Exp $	*/
      2  1.1     elric 
      3  1.1     elric /*
      4  1.1     elric  * Copyright (c) 1997 - 2000 Kungliga Tekniska Hgskolan
      5  1.1     elric  * (Royal Institute of Technology, Stockholm, Sweden).
      6  1.1     elric  * All rights reserved.
      7  1.1     elric  *
      8  1.1     elric  * Redistribution and use in source and binary forms, with or without
      9  1.1     elric  * modification, are permitted provided that the following conditions
     10  1.1     elric  * are met:
     11  1.1     elric  *
     12  1.1     elric  * 1. Redistributions of source code must retain the above copyright
     13  1.1     elric  *    notice, this list of conditions and the following disclaimer.
     14  1.1     elric  *
     15  1.1     elric  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1     elric  *    notice, this list of conditions and the following disclaimer in the
     17  1.1     elric  *    documentation and/or other materials provided with the distribution.
     18  1.1     elric  *
     19  1.1     elric  * 3. Neither the name of the Institute nor the names of its contributors
     20  1.1     elric  *    may be used to endorse or promote products derived from this software
     21  1.1     elric  *    without specific prior written permission.
     22  1.1     elric  *
     23  1.1     elric  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
     24  1.1     elric  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  1.1     elric  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  1.1     elric  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
     27  1.1     elric  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  1.1     elric  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  1.1     elric  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  1.1     elric  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  1.1     elric  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  1.1     elric  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  1.1     elric  * SUCH DAMAGE.
     34  1.1     elric  */
     35  1.1     elric 
     36  1.1     elric #include "kadm5_locl.h"
     37  1.1     elric 
     38  1.1     elric __RCSID("$NetBSD: common_glue.c,v 1.2 2017/01/28 21:31:49 christos Exp $");
     39  1.1     elric 
     40  1.2  christos #define __CALL(F, P) (*((kadm5_common_context*)server_handle)->funcs.F)P
     41  1.2  christos #define __CALLABLE(F) (((kadm5_common_context*)server_handle)->funcs.F != 0)
     42  1.1     elric 
     43  1.1     elric kadm5_ret_t
     44  1.1     elric kadm5_chpass_principal(void *server_handle,
     45  1.1     elric 		       krb5_principal princ,
     46  1.1     elric 		       const char *password)
     47  1.1     elric {
     48  1.2  christos     return __CALL(chpass_principal, (server_handle, princ, 0,
     49  1.2  christos 		  0, NULL, password));
     50  1.2  christos }
     51  1.2  christos 
     52  1.2  christos kadm5_ret_t
     53  1.2  christos kadm5_chpass_principal_3(void *server_handle,
     54  1.2  christos 		         krb5_principal princ,
     55  1.2  christos 		         krb5_boolean keepold,
     56  1.2  christos 		         int n_ks_tuple,
     57  1.2  christos 		         krb5_key_salt_tuple *ks_tuple,
     58  1.2  christos 		         const char *password)
     59  1.2  christos {
     60  1.2  christos     return __CALL(chpass_principal, (server_handle, princ, keepold,
     61  1.2  christos 		  n_ks_tuple, ks_tuple, password));
     62  1.1     elric }
     63  1.1     elric 
     64  1.1     elric kadm5_ret_t
     65  1.1     elric kadm5_chpass_principal_with_key(void *server_handle,
     66  1.1     elric 				krb5_principal princ,
     67  1.1     elric 				int n_key_data,
     68  1.1     elric 				krb5_key_data *key_data)
     69  1.1     elric {
     70  1.1     elric     return __CALL(chpass_principal_with_key,
     71  1.2  christos 		  (server_handle, princ, 0, n_key_data, key_data));
     72  1.2  christos }
     73  1.2  christos 
     74  1.2  christos kadm5_ret_t
     75  1.2  christos kadm5_chpass_principal_with_key_3(void *server_handle,
     76  1.2  christos 				  krb5_principal princ,
     77  1.2  christos 				  int keepold,
     78  1.2  christos 				  int n_key_data,
     79  1.2  christos 				  krb5_key_data *key_data)
     80  1.2  christos {
     81  1.2  christos     return __CALL(chpass_principal_with_key,
     82  1.2  christos 		  (server_handle, princ, keepold, n_key_data, key_data));
     83  1.2  christos }
     84  1.2  christos 
     85  1.2  christos kadm5_ret_t
     86  1.2  christos kadm5_create_principal_3(void *server_handle,
     87  1.2  christos 			 kadm5_principal_ent_t princ,
     88  1.2  christos 			 uint32_t mask,
     89  1.2  christos 			 int n_ks_tuple,
     90  1.2  christos 			 krb5_key_salt_tuple *ks_tuple,
     91  1.2  christos 			 char *password)
     92  1.2  christos {
     93  1.2  christos     return __CALL(create_principal,
     94  1.2  christos 		  (server_handle, princ, mask, n_ks_tuple, ks_tuple, password));
     95  1.1     elric }
     96  1.1     elric 
     97  1.1     elric kadm5_ret_t
     98  1.1     elric kadm5_create_principal(void *server_handle,
     99  1.1     elric 		       kadm5_principal_ent_t princ,
    100  1.1     elric 		       uint32_t mask,
    101  1.1     elric 		       const char *password)
    102  1.1     elric {
    103  1.2  christos     return __CALL(create_principal,
    104  1.2  christos 		  (server_handle, princ, mask, 0, NULL, password));
    105  1.1     elric }
    106  1.1     elric 
    107  1.1     elric kadm5_ret_t
    108  1.1     elric kadm5_delete_principal(void *server_handle,
    109  1.1     elric 		       krb5_principal princ)
    110  1.1     elric {
    111  1.1     elric     return __CALL(delete_principal, (server_handle, princ));
    112  1.1     elric }
    113  1.1     elric 
    114  1.1     elric kadm5_ret_t
    115  1.1     elric kadm5_destroy (void *server_handle)
    116  1.1     elric {
    117  1.1     elric     return __CALL(destroy, (server_handle));
    118  1.1     elric }
    119  1.1     elric 
    120  1.1     elric kadm5_ret_t
    121  1.1     elric kadm5_flush (void *server_handle)
    122  1.1     elric {
    123  1.1     elric     return __CALL(flush, (server_handle));
    124  1.1     elric }
    125  1.1     elric 
    126  1.1     elric kadm5_ret_t
    127  1.1     elric kadm5_get_principal(void *server_handle,
    128  1.1     elric 		    krb5_principal princ,
    129  1.1     elric 		    kadm5_principal_ent_t out,
    130  1.1     elric 		    uint32_t mask)
    131  1.1     elric {
    132  1.1     elric     return __CALL(get_principal, (server_handle, princ, out, mask));
    133  1.1     elric }
    134  1.1     elric 
    135  1.2  christos /**
    136  1.2  christos  * Extract decrypted keys from kadm5_principal_ent_t object.  Mostly a
    137  1.2  christos  * no-op for Heimdal because we fetch the entry with decrypted keys.
    138  1.2  christos  * Sadly this is not fully a no-op, as we have to allocate a copy.
    139  1.2  christos  *
    140  1.2  christos  * @server_handle is the kadm5 handle
    141  1.2  christos  * @entry is the HDB entry for the principal in question
    142  1.2  christos  * @ktype is the enctype to get a key for, or -1 to get the first one
    143  1.2  christos  * @stype is the salttype to get a key for, or -1 to get the first match
    144  1.2  christos  * @kvno is the kvno to search for, or -1 to get the first match (highest kvno)
    145  1.2  christos  * @keyblock is where the key will be placed
    146  1.2  christos  * @keysalt, if not NULL, is where the salt will be placed
    147  1.2  christos  * @kvnop, if not NULL, is where the selected kvno will be placed
    148  1.2  christos  */
    149  1.2  christos kadm5_ret_t
    150  1.2  christos kadm5_decrypt_key(void *server_handle,
    151  1.2  christos                   kadm5_principal_ent_t entry,
    152  1.2  christos 		  int32_t ktype, int32_t stype,
    153  1.2  christos 		  int32_t kvno, krb5_keyblock *keyblock,
    154  1.2  christos                   krb5_keysalt *keysalt, int *kvnop)
    155  1.2  christos {
    156  1.2  christos     size_t i;
    157  1.2  christos 
    158  1.2  christos     if (kvno < 1 || stype != -1)
    159  1.2  christos 	return KADM5_DECRYPT_USAGE_NOSUPP;
    160  1.2  christos 
    161  1.2  christos     for (i = 0; i < entry->n_key_data; i++) {
    162  1.2  christos 	if (ktype != entry->key_data[i].key_data_kvno)
    163  1.2  christos 	    continue;
    164  1.2  christos 
    165  1.2  christos 	keyblock->keytype = ktype;
    166  1.2  christos 	keyblock->keyvalue.length = entry->key_data[i].key_data_length[0];
    167  1.2  christos 	keyblock->keyvalue.data = malloc(keyblock->keyvalue.length);
    168  1.2  christos 	if (keyblock->keyvalue.data == NULL)
    169  1.2  christos 	    return ENOMEM;
    170  1.2  christos 	memcpy(keyblock->keyvalue.data,
    171  1.2  christos 	       entry->key_data[i].key_data_contents[0],
    172  1.2  christos 	       keyblock->keyvalue.length);
    173  1.2  christos     }
    174  1.2  christos 
    175  1.2  christos     return 0;
    176  1.2  christos }
    177  1.2  christos 
    178  1.1     elric kadm5_ret_t
    179  1.1     elric kadm5_modify_principal(void *server_handle,
    180  1.1     elric 		       kadm5_principal_ent_t princ,
    181  1.1     elric 		       uint32_t mask)
    182  1.1     elric {
    183  1.1     elric     return __CALL(modify_principal, (server_handle, princ, mask));
    184  1.1     elric }
    185  1.1     elric 
    186  1.1     elric kadm5_ret_t
    187  1.1     elric kadm5_randkey_principal(void *server_handle,
    188  1.1     elric 			krb5_principal princ,
    189  1.1     elric 			krb5_keyblock **new_keys,
    190  1.1     elric 			int *n_keys)
    191  1.1     elric {
    192  1.2  christos     return __CALL(randkey_principal, (server_handle, princ, FALSE, 0, NULL,
    193  1.2  christos 		  new_keys, n_keys));
    194  1.2  christos }
    195  1.2  christos 
    196  1.2  christos kadm5_ret_t
    197  1.2  christos kadm5_randkey_principal_3(void *server_handle,
    198  1.2  christos 			  krb5_principal princ,
    199  1.2  christos 			  krb5_boolean keepold,
    200  1.2  christos 			  int n_ks_tuple,
    201  1.2  christos 			  krb5_key_salt_tuple *ks_tuple,
    202  1.2  christos 			  krb5_keyblock **new_keys,
    203  1.2  christos 			  int *n_keys)
    204  1.2  christos {
    205  1.2  christos     return __CALL(randkey_principal, (server_handle, princ, keepold,
    206  1.2  christos 				      n_ks_tuple, ks_tuple, new_keys, n_keys));
    207  1.1     elric }
    208  1.1     elric 
    209  1.1     elric kadm5_ret_t
    210  1.1     elric kadm5_rename_principal(void *server_handle,
    211  1.1     elric 		       krb5_principal source,
    212  1.1     elric 		       krb5_principal target)
    213  1.1     elric {
    214  1.1     elric     return __CALL(rename_principal, (server_handle, source, target));
    215  1.1     elric }
    216  1.1     elric 
    217  1.1     elric kadm5_ret_t
    218  1.1     elric kadm5_get_principals(void *server_handle,
    219  1.1     elric 		     const char *expression,
    220  1.1     elric 		     char ***princs,
    221  1.1     elric 		     int *count)
    222  1.1     elric {
    223  1.1     elric     return __CALL(get_principals, (server_handle, expression, princs, count));
    224  1.1     elric }
    225  1.1     elric 
    226  1.1     elric kadm5_ret_t
    227  1.1     elric kadm5_get_privs(void *server_handle,
    228  1.1     elric 		uint32_t *privs)
    229  1.1     elric {
    230  1.1     elric     return __CALL(get_privs, (server_handle, privs));
    231  1.1     elric }
    232  1.2  christos 
    233  1.2  christos 
    234  1.2  christos /**
    235  1.2  christos  * This function is allows the caller to set new keys for a principal.
    236  1.2  christos  * This is a trivial wrapper around kadm5_setkey_principal_3().
    237  1.2  christos  */
    238  1.2  christos kadm5_ret_t
    239  1.2  christos kadm5_setkey_principal(void *server_handle,
    240  1.2  christos                        krb5_principal princ,
    241  1.2  christos                        krb5_keyblock *new_keys,
    242  1.2  christos                        int n_keys)
    243  1.2  christos {
    244  1.2  christos     return kadm5_setkey_principal_3(server_handle, princ, 0, 0, NULL,
    245  1.2  christos 				    new_keys, n_keys);
    246  1.2  christos }
    247  1.2  christos 
    248  1.2  christos /**
    249  1.2  christos  * This function is allows the caller to set new keys for a principal.
    250  1.2  christos  * This is a simple wrapper around kadm5_get_principal() and
    251  1.2  christos  * kadm5_modify_principal().
    252  1.2  christos  */
    253  1.2  christos kadm5_ret_t
    254  1.2  christos kadm5_setkey_principal_3(void *server_handle,
    255  1.2  christos                          krb5_principal princ,
    256  1.2  christos                          krb5_boolean keepold,
    257  1.2  christos                          int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
    258  1.2  christos                          krb5_keyblock *keyblocks,
    259  1.2  christos                          int n_keys)
    260  1.2  christos {
    261  1.2  christos     kadm5_principal_ent_rec princ_ent;
    262  1.2  christos     kadm5_ret_t ret;
    263  1.2  christos     krb5_key_data *new_key_data = NULL;
    264  1.2  christos     size_t i;
    265  1.2  christos 
    266  1.2  christos     if (n_keys < 1)
    267  1.2  christos 	return EINVAL;
    268  1.2  christos     if (n_ks_tuple > 0 && n_ks_tuple != n_keys)
    269  1.2  christos 	return KADM5_SETKEY3_ETYPE_MISMATCH;
    270  1.2  christos 
    271  1.2  christos     /*
    272  1.2  christos      * If setkey_principal_3 is defined in the server handle, use that.
    273  1.2  christos      */
    274  1.2  christos     if (__CALLABLE(setkey_principal_3))
    275  1.2  christos 	return __CALL(setkey_principal_3,
    276  1.2  christos 		      (server_handle, princ, keepold, n_ks_tuple, ks_tuple,
    277  1.2  christos 		       keyblocks, n_keys));
    278  1.2  christos 
    279  1.2  christos     /*
    280  1.2  christos      * Otherwise, simulate it via a get, update, modify sequence.
    281  1.2  christos      */
    282  1.2  christos     ret = kadm5_get_principal(server_handle, princ, &princ_ent,
    283  1.2  christos                               KADM5_KVNO | KADM5_PRINCIPAL | KADM5_KEY_DATA);
    284  1.2  christos     if (ret)
    285  1.2  christos 	return ret;
    286  1.2  christos 
    287  1.2  christos     if (keepold) {
    288  1.2  christos         new_key_data = calloc((n_keys + princ_ent.n_key_data),
    289  1.2  christos                               sizeof(*new_key_data));
    290  1.2  christos 	if (new_key_data == NULL) {
    291  1.2  christos 	    ret = ENOMEM;
    292  1.2  christos 	    goto out;
    293  1.2  christos 	}
    294  1.2  christos 
    295  1.2  christos 	memcpy(&new_key_data[n_keys], &princ_ent.key_data[0],
    296  1.2  christos 		princ_ent.n_key_data * sizeof (princ_ent.key_data[0]));
    297  1.2  christos     } else {
    298  1.2  christos 	new_key_data = calloc(n_keys, sizeof(*new_key_data));
    299  1.2  christos 	if (new_key_data == NULL) {
    300  1.2  christos 	    ret = ENOMEM;
    301  1.2  christos 	    goto out;
    302  1.2  christos 	}
    303  1.2  christos     }
    304  1.2  christos 
    305  1.2  christos     princ_ent.kvno++;
    306  1.2  christos     for (i = 0; i < n_keys; i++) {
    307  1.2  christos 	new_key_data[i].key_data_ver = 2;
    308  1.2  christos 
    309  1.2  christos 	/* Key */
    310  1.2  christos 	new_key_data[i].key_data_kvno = princ_ent.kvno;
    311  1.2  christos 	new_key_data[i].key_data_type[0] = keyblocks[i].keytype;
    312  1.2  christos 	new_key_data[i].key_data_length[0] = keyblocks[i].keyvalue.length;
    313  1.2  christos 	new_key_data[i].key_data_contents[0] =
    314  1.2  christos 	    malloc(keyblocks[i].keyvalue.length);
    315  1.2  christos 	if (new_key_data[i].key_data_contents[0] == NULL) {
    316  1.2  christos 	    ret = ENOMEM;
    317  1.2  christos 	    goto out;
    318  1.2  christos 	}
    319  1.2  christos 	memcpy(new_key_data[i].key_data_contents[0],
    320  1.2  christos 	       keyblocks[i].keyvalue.data,
    321  1.2  christos 	       keyblocks[i].keyvalue.length);
    322  1.2  christos 
    323  1.2  christos 	/*
    324  1.2  christos 	 * Salt (but there's no salt, just salttype, which is kinda
    325  1.2  christos 	 * silly -- what's the point of setkey_3() then, besides
    326  1.2  christos 	 * keepold?!)
    327  1.2  christos 	 */
    328  1.2  christos 	new_key_data[i].key_data_type[1] = 0;
    329  1.2  christos 	if (n_ks_tuple > 0) {
    330  1.2  christos 	    if (ks_tuple[i].ks_enctype != keyblocks[i].keytype) {
    331  1.2  christos 		ret = KADM5_SETKEY3_ETYPE_MISMATCH;
    332  1.2  christos                 goto out;
    333  1.2  christos             }
    334  1.2  christos 	    new_key_data[i].key_data_type[1] = ks_tuple[i].ks_salttype;
    335  1.2  christos 	}
    336  1.2  christos 	new_key_data[i].key_data_length[1] = 0;
    337  1.2  christos 	new_key_data[i].key_data_contents[1] = NULL;
    338  1.2  christos     }
    339  1.2  christos 
    340  1.2  christos     /* Free old keys */
    341  1.2  christos     if (!keepold) {
    342  1.2  christos 	for (i = 0; i < princ_ent.n_key_data; i++) {
    343  1.2  christos 	    free(princ_ent.key_data[i].key_data_contents[0]);
    344  1.2  christos 	    free(princ_ent.key_data[i].key_data_contents[1]);
    345  1.2  christos 	}
    346  1.2  christos     }
    347  1.2  christos     free(princ_ent.key_data);
    348  1.2  christos     princ_ent.key_data = new_key_data;
    349  1.2  christos     princ_ent.n_key_data = n_keys + (keepold ? princ_ent.n_key_data : 0);
    350  1.2  christos     new_key_data = NULL;
    351  1.2  christos 
    352  1.2  christos     /* Modify the principal */
    353  1.2  christos     ret = kadm5_modify_principal(server_handle, &princ_ent, KADM5_KVNO | KADM5_KEY_DATA);
    354  1.2  christos 
    355  1.2  christos out:
    356  1.2  christos     if (new_key_data != NULL) {
    357  1.2  christos 	for (i = 0; i < n_keys; i++) {
    358  1.2  christos 	    free(new_key_data[i].key_data_contents[0]);
    359  1.2  christos 	    free(new_key_data[i].key_data_contents[1]);
    360  1.2  christos 	}
    361  1.2  christos 	free(new_key_data);
    362  1.2  christos     }
    363  1.2  christos     kadm5_free_principal_ent(server_handle, &princ_ent);
    364  1.2  christos     return ret;
    365  1.2  christos }
    366  1.2  christos 
    367  1.2  christos 
    368  1.2  christos kadm5_ret_t
    369  1.2  christos kadm5_lock(void *server_handle)
    370  1.2  christos {
    371  1.2  christos     return __CALL(lock, (server_handle));
    372  1.2  christos }
    373  1.2  christos 
    374  1.2  christos kadm5_ret_t
    375  1.2  christos kadm5_unlock(void *server_handle)
    376  1.2  christos {
    377  1.2  christos     return __CALL(unlock, (server_handle));
    378  1.2  christos }
    379  1.2  christos 
    380  1.2  christos 
    381  1.2  christos kadm5_ret_t
    382  1.2  christos kadm5_create_policy(void *server_handle,
    383  1.2  christos 	                         kadm5_policy_ent_t policy, long mask)
    384  1.2  christos {
    385  1.2  christos     return KADM5_POLICY_OP_NOSUPP;
    386  1.2  christos }
    387  1.2  christos 
    388  1.2  christos kadm5_ret_t
    389  1.2  christos kadm5_delete_policy(void *server_handle, char *name)
    390  1.2  christos {
    391  1.2  christos     return KADM5_POLICY_OP_NOSUPP;
    392  1.2  christos }
    393  1.2  christos 
    394  1.2  christos 
    395  1.2  christos kadm5_ret_t
    396  1.2  christos kadm5_modify_policy(void *server_handle, kadm5_policy_ent_t policy,
    397  1.2  christos 		    uint32_t mask)
    398  1.2  christos {
    399  1.2  christos     return KADM5_POLICY_OP_NOSUPP;
    400  1.2  christos }
    401  1.2  christos 
    402  1.2  christos kadm5_ret_t
    403  1.2  christos kadm5_get_policy(void *server_handle, char *policy, kadm5_policy_ent_t ent)
    404  1.2  christos {
    405  1.2  christos     memset(ent, 0, sizeof (*ent));
    406  1.2  christos     return KADM5_POLICY_OP_NOSUPP;
    407  1.2  christos }
    408  1.2  christos 
    409  1.2  christos 
    410  1.2  christos kadm5_ret_t
    411  1.2  christos kadm5_get_policies(void *server_handle, char *exp, char ***pols, int *count)
    412  1.2  christos {
    413  1.2  christos     *count = 0;
    414  1.2  christos     *pols = NULL;
    415  1.2  christos 
    416  1.2  christos     return KADM5_POLICY_OP_NOSUPP;
    417  1.2  christos }
    418  1.2  christos 
    419  1.2  christos kadm5_ret_t
    420  1.2  christos kadm5_free_policy_ent(kadm5_policy_ent_t ent)
    421  1.2  christos {
    422  1.2  christos     if (ent->policy)
    423  1.2  christos 	free(ent->policy);
    424  1.2  christos     /*
    425  1.2  christos      * Not clear if we should free ent or not.  It might be an automatic
    426  1.2  christos      * struct, so we don't free it for now, just in case.
    427  1.2  christos      */
    428  1.2  christos     return 0;
    429  1.2  christos }
    430  1.2  christos 
    431