diff options
Diffstat (limited to 'crypto/heimdal/kadmin/server.c')
-rw-r--r-- | crypto/heimdal/kadmin/server.c | 369 |
1 files changed, 183 insertions, 186 deletions
diff --git a/crypto/heimdal/kadmin/server.c b/crypto/heimdal/kadmin/server.c index 07dd9a5ad7b0..256c2bac89b7 100644 --- a/crypto/heimdal/kadmin/server.c +++ b/crypto/heimdal/kadmin/server.c @@ -1,50 +1,48 @@ /* - * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include "kadmin_locl.h" #include <krb5-private.h> -RCSID("$Id: server.c 17611 2006-06-02 22:10:21Z lha $"); - static kadm5_ret_t -kadmind_dispatch(void *kadm_handle, krb5_boolean initial, +kadmind_dispatch(void *kadm_handlep, krb5_boolean initial, krb5_data *in, krb5_data *out) { kadm5_ret_t ret; int32_t cmd, mask, tmp; - kadm5_server_context *context = kadm_handle; + kadm5_server_context *contextp = kadm_handlep; char client[128], name[128], name2[128]; - char *op = ""; + const char *op = ""; krb5_principal princ, princ2; kadm5_principal_ent_rec ent; char *password, *expression; @@ -53,11 +51,13 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, char **princs; int n_princs; krb5_storage *sp; - - krb5_unparse_name_fixed(context->context, context->caller, + + krb5_unparse_name_fixed(contextp->context, contextp->caller, client, sizeof(client)); - + sp = krb5_storage_from_data(in); + if (sp == NULL) + krb5_errx(contextp->context, 1, "out of memory"); krb5_ret_int32(sp, &cmd); switch(cmd){ @@ -68,25 +68,26 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, goto fail; ret = krb5_ret_int32(sp, &mask); if(ret){ - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } - krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); - krb5_warnx(context->context, "%s: %s %s", client, op, name); - ret = _kadm5_acl_check_permission(context, KADM5_PRIV_GET, princ); + mask |= KADM5_PRINCIPAL; + krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name)); + krb5_warnx(contextp->context, "%s: %s %s", client, op, name); + ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_GET, princ); if(ret){ - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } - ret = kadm5_get_principal(kadm_handle, princ, &ent, mask); + ret = kadm5_get_principal(kadm_handlep, princ, &ent, mask); krb5_storage_free(sp); sp = krb5_storage_emem(); krb5_store_int32(sp, ret); if(ret == 0){ kadm5_store_principal_ent(sp, &ent); - kadm5_free_principal_ent(kadm_handle, &ent); + kadm5_free_principal_ent(kadm_handlep, &ent); } - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); break; } case kadm_delete:{ @@ -94,15 +95,15 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, ret = krb5_ret_principal(sp, &princ); if(ret) goto fail; - krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); - krb5_warnx(context->context, "%s: %s %s", client, op, name); - ret = _kadm5_acl_check_permission(context, KADM5_PRIV_DELETE, princ); + krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name)); + krb5_warnx(contextp->context, "%s: %s %s", client, op, name); + ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_DELETE, princ); if(ret){ - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } - ret = kadm5_delete_principal(kadm_handle, princ); - krb5_free_principal(context->context, princ); + ret = kadm5_delete_principal(kadm_handlep, princ); + krb5_free_principal(contextp->context, princ); krb5_storage_free(sp); sp = krb5_storage_emem(); krb5_store_int32(sp, ret); @@ -115,28 +116,28 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, goto fail; ret = krb5_ret_int32(sp, &mask); if(ret){ - kadm5_free_principal_ent(context->context, &ent); + kadm5_free_principal_ent(contextp->context, &ent); goto fail; } ret = krb5_ret_string(sp, &password); if(ret){ - kadm5_free_principal_ent(context->context, &ent); + kadm5_free_principal_ent(contextp->context, &ent); goto fail; } - krb5_unparse_name_fixed(context->context, ent.principal, + krb5_unparse_name_fixed(contextp->context, ent.principal, name, sizeof(name)); - krb5_warnx(context->context, "%s: %s %s", client, op, name); - ret = _kadm5_acl_check_permission(context, KADM5_PRIV_ADD, + krb5_warnx(contextp->context, "%s: %s %s", client, op, name); + ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_ADD, ent.principal); if(ret){ - kadm5_free_principal_ent(context->context, &ent); + kadm5_free_principal_ent(contextp->context, &ent); memset(password, 0, strlen(password)); free(password); goto fail; } - ret = kadm5_create_principal(kadm_handle, &ent, + ret = kadm5_create_principal(kadm_handlep, &ent, mask, password); - kadm5_free_principal_ent(kadm_handle, &ent); + kadm5_free_principal_ent(kadm_handlep, &ent); memset(password, 0, strlen(password)); free(password); krb5_storage_free(sp); @@ -151,20 +152,20 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, goto fail; ret = krb5_ret_int32(sp, &mask); if(ret){ - kadm5_free_principal_ent(context, &ent); + kadm5_free_principal_ent(contextp, &ent); goto fail; } - krb5_unparse_name_fixed(context->context, ent.principal, + krb5_unparse_name_fixed(contextp->context, ent.principal, name, sizeof(name)); - krb5_warnx(context->context, "%s: %s %s", client, op, name); - ret = _kadm5_acl_check_permission(context, KADM5_PRIV_MODIFY, + krb5_warnx(contextp->context, "%s: %s %s", client, op, name); + ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_MODIFY, ent.principal); if(ret){ - kadm5_free_principal_ent(context, &ent); + kadm5_free_principal_ent(contextp, &ent); goto fail; } - ret = kadm5_modify_principal(kadm_handle, &ent, mask); - kadm5_free_principal_ent(kadm_handle, &ent); + ret = kadm5_modify_principal(kadm_handlep, &ent, mask); + kadm5_free_principal_ent(kadm_handlep, &ent); krb5_storage_free(sp); sp = krb5_storage_emem(); krb5_store_int32(sp, ret); @@ -177,27 +178,27 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, goto fail; ret = krb5_ret_principal(sp, &princ2); if(ret){ - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } - krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); - krb5_unparse_name_fixed(context->context, princ2, name2, sizeof(name2)); - krb5_warnx(context->context, "%s: %s %s -> %s", + krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name)); + krb5_unparse_name_fixed(contextp->context, princ2, name2, sizeof(name2)); + krb5_warnx(contextp->context, "%s: %s %s -> %s", client, op, name, name2); - ret = _kadm5_acl_check_permission(context, + ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_ADD, princ2) - || _kadm5_acl_check_permission(context, + || _kadm5_acl_check_permission(contextp, KADM5_PRIV_DELETE, princ); if(ret){ - krb5_free_principal(context->context, princ); - krb5_free_principal(context->context, princ2); + krb5_free_principal(contextp->context, princ); + krb5_free_principal(contextp->context, princ2); goto fail; } - ret = kadm5_rename_principal(kadm_handle, princ, princ2); - krb5_free_principal(context->context, princ); - krb5_free_principal(context->context, princ2); + ret = kadm5_rename_principal(kadm_handlep, princ, princ2); + krb5_free_principal(contextp->context, princ); + krb5_free_principal(contextp->context, princ2); krb5_storage_free(sp); sp = krb5_storage_emem(); krb5_store_int32(sp, ret); @@ -210,23 +211,26 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, goto fail; ret = krb5_ret_string(sp, &password); if(ret){ - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } - krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); - krb5_warnx(context->context, "%s: %s %s", client, op, name); + krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name)); + krb5_warnx(contextp->context, "%s: %s %s", client, op, name); /* * The change is allowed if at least one of: - - * a) it's for the principal him/herself and this was an + * + * a) allowed by sysadmin + * b) it's for the principal him/herself and this was an * initial ticket, but then, check with the password quality * function. - * b) the user is on the CPW ACL. + * c) the user is on the CPW ACL. */ - if (initial - && krb5_principal_compare (context->context, context->caller, + if (krb5_config_get_bool_default(contextp->context, NULL, TRUE, + "kadmin", "allow_self_change_password", NULL) + && initial + && krb5_principal_compare (contextp->context, contextp->caller, princ)) { krb5_data pwd_data; @@ -235,23 +239,23 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, pwd_data.data = password; pwd_data.length = strlen(password); - pwd_reason = kadm5_check_password_quality (context->context, + pwd_reason = kadm5_check_password_quality (contextp->context, princ, &pwd_data); if (pwd_reason != NULL) ret = KADM5_PASS_Q_DICT; else ret = 0; } else - ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW, princ); + ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_CPW, princ); if(ret) { - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); memset(password, 0, strlen(password)); free(password); goto fail; } - ret = kadm5_chpass_principal(kadm_handle, princ, password); - krb5_free_principal(context->context, princ); + ret = kadm5_chpass_principal(kadm_handlep, princ, password); + krb5_free_principal(contextp->context, princ); memset(password, 0, strlen(password)); free(password); krb5_storage_free(sp); @@ -270,21 +274,21 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, goto fail; ret = krb5_ret_int32(sp, &n_key_data); if (ret) { - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } /* n_key_data will be squeezed into an int16_t below. */ if (n_key_data < 0 || n_key_data >= 1 << 16 || - n_key_data > UINT_MAX/sizeof(*key_data)) { + (size_t)n_key_data > UINT_MAX/sizeof(*key_data)) { ret = ERANGE; - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } key_data = malloc (n_key_data * sizeof(*key_data)); - if (key_data == NULL) { + if (key_data == NULL && n_key_data != 0) { ret = ENOMEM; - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } @@ -293,38 +297,38 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, if (ret) { int16_t dummy = i; - kadm5_free_key_data (context, &dummy, key_data); + kadm5_free_key_data (contextp, &dummy, key_data); free (key_data); - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } } - krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); - krb5_warnx(context->context, "%s: %s %s", client, op, name); + krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name)); + krb5_warnx(contextp->context, "%s: %s %s", client, op, name); /* * The change is only allowed if the user is on the CPW ACL, * this it to force password quality check on the user. */ - ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW, princ); + ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_CPW, princ); if(ret) { int16_t dummy = n_key_data; - kadm5_free_key_data (context, &dummy, key_data); + kadm5_free_key_data (contextp, &dummy, key_data); free (key_data); - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } - ret = kadm5_chpass_principal_with_key(kadm_handle, princ, + ret = kadm5_chpass_principal_with_key(kadm_handlep, princ, n_key_data, key_data); { int16_t dummy = n_key_data; - kadm5_free_key_data (context, &dummy, key_data); + kadm5_free_key_data (contextp, &dummy, key_data); } free (key_data); - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); krb5_storage_free(sp); sp = krb5_storage_emem(); krb5_store_int32(sp, ret); @@ -335,8 +339,8 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, ret = krb5_ret_principal(sp, &princ); if(ret) goto fail; - krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); - krb5_warnx(context->context, "%s: %s %s", client, op, name); + krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name)); + krb5_warnx(contextp->context, "%s: %s %s", client, op, name); /* * The change is allowed if at least one of: * a) it's for the principal him/herself and this was an initial ticket @@ -344,19 +348,19 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, */ if (initial - && krb5_principal_compare (context->context, context->caller, + && krb5_principal_compare (contextp->context, contextp->caller, princ)) ret = 0; else - ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW, princ); + ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_CPW, princ); if(ret) { - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); goto fail; } - ret = kadm5_randkey_principal(kadm_handle, princ, + ret = kadm5_randkey_principal(kadm_handlep, princ, &new_keys, &n_keys); - krb5_free_principal(context->context, princ); + krb5_free_principal(contextp->context, princ); krb5_storage_free(sp); sp = krb5_storage_emem(); krb5_store_int32(sp, ret); @@ -365,14 +369,15 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, krb5_store_int32(sp, n_keys); for(i = 0; i < n_keys; i++){ krb5_store_keyblock(sp, new_keys[i]); - krb5_free_keyblock_contents(context->context, &new_keys[i]); + krb5_free_keyblock_contents(contextp->context, &new_keys[i]); } + free(new_keys); } break; } case kadm_get_privs:{ uint32_t privs; - ret = kadm5_get_privs(kadm_handle, &privs); + ret = kadm5_get_privs(kadm_handlep, &privs); krb5_storage_free(sp); sp = krb5_storage_emem(); krb5_store_int32(sp, ret); @@ -391,14 +396,14 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, goto fail; }else expression = NULL; - krb5_warnx(context->context, "%s: %s %s", client, op, + krb5_warnx(contextp->context, "%s: %s %s", client, op, expression ? expression : "*"); - ret = _kadm5_acl_check_permission(context, KADM5_PRIV_LIST, NULL); + ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_LIST, NULL); if(ret){ free(expression); goto fail; } - ret = kadm5_get_principals(kadm_handle, expression, &princs, &n_princs); + ret = kadm5_get_principals(kadm_handlep, expression, &princs, &n_princs); free(expression); krb5_storage_free(sp); sp = krb5_storage_emem(); @@ -408,12 +413,12 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, krb5_store_int32(sp, n_princs); for(i = 0; i < n_princs; i++) krb5_store_string(sp, princs[i]); - kadm5_free_name_list(kadm_handle, princs, &n_princs); + kadm5_free_name_list(kadm_handlep, princs, &n_princs); } break; } default: - krb5_warnx(context->context, "%s: UNKNOWN OP %d", client, cmd); + krb5_warnx(contextp->context, "%s: UNKNOWN OP %d", client, cmd); krb5_storage_free(sp); sp = krb5_storage_emem(); krb5_store_int32(sp, KADM5_FAILURE); @@ -423,7 +428,7 @@ kadmind_dispatch(void *kadm_handle, krb5_boolean initial, krb5_storage_free(sp); return 0; fail: - krb5_warn(context->context, ret, "%s", op); + krb5_warn(contextp->context, ret, "%s", op); krb5_storage_seek(sp, 0, SEEK_SET); krb5_store_int32(sp, ret); krb5_storage_to_data(sp, out); @@ -432,11 +437,11 @@ fail: } static void -v5_loop (krb5_context context, +v5_loop (krb5_context contextp, krb5_auth_context ac, krb5_boolean initial, - void *kadm_handle, - int fd) + void *kadm_handlep, + krb5_socket_t fd) { krb5_error_code ret; krb5_data in, out; @@ -445,17 +450,17 @@ v5_loop (krb5_context context, doing_useful_work = 0; if(term_flag) exit(0); - ret = krb5_read_priv_message(context, ac, &fd, &in); + ret = krb5_read_priv_message(contextp, ac, &fd, &in); if(ret == HEIM_ERR_EOF) exit(0); if(ret) - krb5_err(context, 1, ret, "krb5_read_priv_message"); + krb5_err(contextp, 1, ret, "krb5_read_priv_message"); doing_useful_work = 1; - kadmind_dispatch(kadm_handle, initial, &in, &out); + kadmind_dispatch(kadm_handlep, initial, &in, &out); krb5_data_free(&in); - ret = krb5_write_priv_message(context, ac, &fd, &out); + ret = krb5_write_priv_message(contextp, ac, &fd, &out); if(ret) - krb5_err(context, 1, ret, "krb5_write_priv_message"); + krb5_err(contextp, 1, ret, "krb5_write_priv_message"); } } @@ -465,55 +470,41 @@ match_appl_version(const void *data, const char *appl_version) unsigned minor; if(sscanf(appl_version, "KADM0.%u", &minor) != 1) return 0; - *(unsigned*)data = minor; + /*XXX*/ + *(unsigned*)(intptr_t)data = minor; return 1; } static void -handle_v5(krb5_context context, - krb5_auth_context ac, +handle_v5(krb5_context contextp, krb5_keytab keytab, - int len, - int fd) + krb5_socket_t fd) { krb5_error_code ret; - u_char version[sizeof(KRB5_SENDAUTH_VERSION)]; krb5_ticket *ticket; char *server_name; char *client; - void *kadm_handle; - ssize_t n; + void *kadm_handlep; krb5_boolean initial; + krb5_auth_context ac = NULL; unsigned kadm_version; kadm5_config_params realm_params; - if (len != sizeof(KRB5_SENDAUTH_VERSION)) - krb5_errx(context, 1, "bad sendauth len %d", len); - n = krb5_net_read(context, &fd, version, len); - if (n < 0) - krb5_err (context, 1, errno, "reading sendauth version"); - if (n == 0) - krb5_errx (context, 1, "EOF reading sendauth version"); - if(memcmp(version, KRB5_SENDAUTH_VERSION, len) != 0) - krb5_errx(context, 1, "bad sendauth version %.8s", version); - - ret = krb5_recvauth_match_version(context, &ac, &fd, + ret = krb5_recvauth_match_version(contextp, &ac, &fd, match_appl_version, &kadm_version, - NULL, KRB5_RECVAUTH_IGNORE_VERSION, + NULL, KRB5_RECVAUTH_IGNORE_VERSION, keytab, &ticket); - if(ret == KRB5_KT_NOTFOUND) - krb5_errx(context, 1, "krb5_recvauth: key not found"); - if(ret) - krb5_err(context, 1, ret, "krb5_recvauth"); + if (ret) + krb5_err(contextp, 1, ret, "krb5_recvauth"); - ret = krb5_unparse_name (context, ticket->server, &server_name); + ret = krb5_unparse_name (contextp, ticket->server, &server_name); if (ret) - krb5_err (context, 1, ret, "krb5_unparse_name"); + krb5_err (contextp, 1, ret, "krb5_unparse_name"); if (strncmp (server_name, KADM5_ADMIN_SERVICE, strlen(KADM5_ADMIN_SERVICE)) != 0) - krb5_errx (context, 1, "ticket for strange principal (%s)", + krb5_errx (contextp, 1, "ticket for strange principal (%s)", server_name); free (server_name); @@ -522,56 +513,62 @@ handle_v5(krb5_context context, if(kadm_version == 1) { krb5_data params; - ret = krb5_read_priv_message(context, ac, &fd, ¶ms); + ret = krb5_read_priv_message(contextp, ac, &fd, ¶ms); if(ret) - krb5_err(context, 1, ret, "krb5_read_priv_message"); - _kadm5_unmarshal_params(context, ¶ms, &realm_params); + krb5_err(contextp, 1, ret, "krb5_read_priv_message"); + _kadm5_unmarshal_params(contextp, ¶ms, &realm_params); } initial = ticket->ticket.flags.initial; - ret = krb5_unparse_name(context, ticket->client, &client); + ret = krb5_unparse_name(contextp, ticket->client, &client); if (ret) - krb5_err (context, 1, ret, "krb5_unparse_name"); - krb5_free_ticket (context, ticket); - ret = kadm5_init_with_password_ctx(context, - client, - NULL, - KADM5_ADMIN_SERVICE, - &realm_params, - 0, 0, - &kadm_handle); + krb5_err (contextp, 1, ret, "krb5_unparse_name"); + krb5_free_ticket (contextp, ticket); + ret = kadm5_s_init_with_password_ctx(contextp, + client, + NULL, + KADM5_ADMIN_SERVICE, + &realm_params, + 0, 0, + &kadm_handlep); if(ret) - krb5_err (context, 1, ret, "kadm5_init_with_password_ctx"); - v5_loop (context, ac, initial, kadm_handle, fd); + krb5_err (contextp, 1, ret, "kadm5_init_with_password_ctx"); + v5_loop (contextp, ac, initial, kadm_handlep, fd); } krb5_error_code -kadmind_loop(krb5_context context, - krb5_auth_context ac, - krb5_keytab keytab, - int fd) +kadmind_loop(krb5_context contextp, + krb5_keytab keytab, + krb5_socket_t sock) { - unsigned char tmp[4]; + u_char buf[sizeof(KRB5_SENDAUTH_VERSION) + 4]; ssize_t n; unsigned long len; - n = krb5_net_read(context, &fd, tmp, 4); + n = krb5_net_read(contextp, &sock, buf, 4); if(n == 0) exit(0); if(n < 0) - krb5_err(context, 1, errno, "read"); - _krb5_get_int(tmp, &len, 4); - /* this v4 test could probably also go away */ - if(len > 0xffff && (len & 0xffff) == ('K' << 8) + 'A') { - unsigned char v4reply[] = { - 0x00, 0x0c, - 'K', 'Y', 'O', 'U', 'L', 'O', 'S', 'E', - 0x95, 0xb7, 0xa7, 0x08 /* KADM_BAD_VER */ - }; - krb5_net_write(context, &fd, v4reply, sizeof(v4reply)); - krb5_errx(context, 1, "packet appears to be version 4"); - } else { - handle_v5(context, ac, keytab, len, fd); - } + krb5_err(contextp, 1, errno, "read"); + _krb5_get_int(buf, &len, 4); + + if (len == sizeof(KRB5_SENDAUTH_VERSION)) { + + n = krb5_net_read(contextp, &sock, buf + 4, len); + if (n < 0) + krb5_err (contextp, 1, errno, "reading sendauth version"); + if (n == 0) + krb5_errx (contextp, 1, "EOF reading sendauth version"); + + if(memcmp(buf + 4, KRB5_SENDAUTH_VERSION, len) == 0) { + handle_v5(contextp, keytab, sock); + return 0; + } + len += 4; + } else + len = 4; + + handle_mit(contextp, buf, len, sock); + return 0; } |