server.c revision 178826
1139734Simp/* 2139734Simp * Copyright (c) 1997 - 2005 Kungliga Tekniska H�gskolan 317773Swosch * (Royal Institute of Technology, Stockholm, Sweden). 417773Swosch * All rights reserved. 517773Swosch * 617773Swosch * Redistribution and use in source and binary forms, with or without 717773Swosch * modification, are permitted provided that the following conditions 817773Swosch * are met: 917773Swosch * 1017773Swosch * 1. Redistributions of source code must retain the above copyright 1117773Swosch * notice, this list of conditions and the following disclaimer. 1217773Swosch * 1317773Swosch * 2. Redistributions in binary form must reproduce the above copyright 1417773Swosch * notice, this list of conditions and the following disclaimer in the 1517773Swosch * documentation and/or other materials provided with the distribution. 1617773Swosch * 1717773Swosch * 3. Neither the name of the Institute nor the names of its contributors 1817773Swosch * may be used to endorse or promote products derived from this software 1917773Swosch * without specific prior written permission. 2017773Swosch * 2117773Swosch * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2217773Swosch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2317773Swosch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2417773Swosch * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2517773Swosch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26146319Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27141580Sru * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28141580Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29217087Strasz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3012823Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3179538Sru * SUCH DAMAGE. 3212823Sphk */ 3314003Smpp 3475670Sru#include "kadmin_locl.h" 3512823Sphk#include <krb5-private.h> 3626192Speter 3768716SruRCSID("$Id: server.c 17611 2006-06-02 22:10:21Z lha $"); 3887529Sru 3987774Simpstatic kadm5_ret_t 4087773Simpkadmind_dispatch(void *kadm_handle, krb5_boolean initial, 4187773Simp krb5_data *in, krb5_data *out) 4287858Sru{ 4387773Simp kadm5_ret_t ret; 4471895Sru int32_t cmd, mask, tmp; 4512823Sphk kadm5_server_context *context = kadm_handle; 4675820Sobrien char client[128], name[128], name2[128]; 4775820Sobrien char *op = ""; 4875820Sobrien krb5_principal princ, princ2; 4975820Sobrien kadm5_principal_ent_rec ent; 5012823Sphk char *password, *expression; 5112823Sphk krb5_keyblock *new_keys; 5212823Sphk int n_keys; 5312823Sphk char **princs; 5412823Sphk int n_princs; 5512823Sphk krb5_storage *sp; 5612823Sphk 5712823Sphk krb5_unparse_name_fixed(context->context, context->caller, 5812823Sphk client, sizeof(client)); 5912951Sphk 6012951Sphk sp = krb5_storage_from_data(in); 6112823Sphk 6214966Sjoerg krb5_ret_int32(sp, &cmd); 6314966Sjoerg switch(cmd){ 64139947Skeramida case kadm_get:{ 65139725Simp op = "GET"; 66139725Simp ret = krb5_ret_principal(sp, &princ); 67139725Simp if(ret) 68166323Sjoel goto fail; 69166323Sjoel ret = krb5_ret_int32(sp, &mask); 70139725Simp if(ret){ 71175108Sgrog krb5_free_principal(context->context, princ); 72139725Simp goto fail; 73139725Simp } 74139947Skeramida krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); 75139734Simp krb5_warnx(context->context, "%s: %s %s", client, op, name); 76139734Simp ret = _kadm5_acl_check_permission(context, KADM5_PRIV_GET, princ); 77139734Simp if(ret){ 78139734Simp krb5_free_principal(context->context, princ); 79140173Sru goto fail; 80139734Simp } 81139734Simp ret = kadm5_get_principal(kadm_handle, princ, &ent, mask); 82139734Simp krb5_storage_free(sp); 83146307Skeramida sp = krb5_storage_emem(); 84139734Simp krb5_store_int32(sp, ret); 85139725Simp if(ret == 0){ 8675820Sobrien kadm5_store_principal_ent(sp, &ent); 87146319Sru kadm5_free_principal_ent(kadm_handle, &ent); 88146323Sobrien } 8975820Sobrien krb5_free_principal(context->context, princ); 9090018Sbde break; 9183041Sgrog } 9283041Sgrog case kadm_delete:{ 9390018Sbde op = "DELETE"; 9483041Sgrog ret = krb5_ret_principal(sp, &princ); 9576708Sobrien if(ret) 9690042Sobrien goto fail; 9792569Sru krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); 9892569Sru krb5_warnx(context->context, "%s: %s %s", client, op, name); 9990018Sbde ret = _kadm5_acl_check_permission(context, KADM5_PRIV_DELETE, princ); 10090018Sbde if(ret){ 10190018Sbde krb5_free_principal(context->context, princ); 10290018Sbde goto fail; 10390018Sbde } 10490018Sbde ret = kadm5_delete_principal(kadm_handle, princ); 10590018Sbde krb5_free_principal(context->context, princ); 10675820Sobrien krb5_storage_free(sp); 10790018Sbde sp = krb5_storage_emem(); 10890018Sbde krb5_store_int32(sp, ret); 10990018Sbde break; 110112629Sjhb } 11190018Sbde case kadm_create:{ 112131132Sbde op = "CREATE"; 11383517Sobrien ret = kadm5_ret_principal_ent(sp, &ent); 11484307Sru if(ret) 11575820Sobrien goto fail; 11675820Sobrien ret = krb5_ret_int32(sp, &mask); 11783041Sgrog if(ret){ 11875820Sobrien kadm5_free_principal_ent(context->context, &ent); 11987529Sru goto fail; 12087529Sru } 12187529Sru ret = krb5_ret_string(sp, &password); 122119893Sru if(ret){ 12387529Sru kadm5_free_principal_ent(context->context, &ent); 124119893Sru goto fail; 12587529Sru } 126119893Sru krb5_unparse_name_fixed(context->context, ent.principal, 12787529Sru name, sizeof(name)); 128119893Sru krb5_warnx(context->context, "%s: %s %s", client, op, name); 12987529Sru ret = _kadm5_acl_check_permission(context, KADM5_PRIV_ADD, 13071895Sru ent.principal); 13163324Sben if(ret){ 13214966Sjoerg kadm5_free_principal_ent(context->context, &ent); 13314966Sjoerg memset(password, 0, strlen(password)); 13483041Sgrog free(password); 13571895Sru goto fail; 13612823Sphk } 13712823Sphk ret = kadm5_create_principal(kadm_handle, &ent, 13812823Sphk mask, password); 13912823Sphk kadm5_free_principal_ent(kadm_handle, &ent); 14012823Sphk memset(password, 0, strlen(password)); 14114966Sjoerg free(password); 14214966Sjoerg krb5_storage_free(sp); 14387773Simp sp = krb5_storage_emem(); 14487773Simp krb5_store_int32(sp, ret); 14587773Simp break; 14687773Simp } 14787529Sru case kadm_modify:{ 148130582Sru op = "MODIFY"; 149120530Simp ret = kadm5_ret_principal_ent(sp, &ent); 15083041Sgrog if(ret) 15171895Sru goto fail; 15212823Sphk ret = krb5_ret_int32(sp, &mask); 15314966Sjoerg if(ret){ 15414966Sjoerg kadm5_free_principal_ent(context, &ent); 15587529Sru goto fail; 156119893Sru } 15787529Sru krb5_unparse_name_fixed(context->context, ent.principal, 15887529Sru name, sizeof(name)); 15987529Sru krb5_warnx(context->context, "%s: %s %s", client, op, name); 16087529Sru ret = _kadm5_acl_check_permission(context, KADM5_PRIV_MODIFY, 16171895Sru ent.principal); 16212823Sphk if(ret){ 16314966Sjoerg kadm5_free_principal_ent(context, &ent); 16414966Sjoerg goto fail; 16583041Sgrog } 16671895Sru ret = kadm5_modify_principal(kadm_handle, &ent, mask); 16712951Sphk kadm5_free_principal_ent(kadm_handle, &ent); 16814966Sjoerg krb5_storage_free(sp); 16914966Sjoerg sp = krb5_storage_emem(); 17087529Sru krb5_store_int32(sp, ret); 17187529Sru break; 17287529Sru } 17364395Ssheldonh case kadm_rename:{ 17464395Ssheldonh op = "RENAME"; 17564395Ssheldonh ret = krb5_ret_principal(sp, &princ); 17686725Sru if(ret) 17764395Ssheldonh goto fail; 17864395Ssheldonh ret = krb5_ret_principal(sp, &princ2); 17964395Ssheldonh if(ret){ 18064395Ssheldonh krb5_free_principal(context->context, princ); 18179727Sschweikh goto fail; 18287529Sru } 18379727Sschweikh krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); 18464395Ssheldonh krb5_unparse_name_fixed(context->context, princ2, name2, sizeof(name2)); 18564395Ssheldonh krb5_warnx(context->context, "%s: %s %s -> %s", 18664395Ssheldonh client, op, name, name2); 18764395Ssheldonh ret = _kadm5_acl_check_permission(context, 18864395Ssheldonh KADM5_PRIV_ADD, 18964395Ssheldonh princ2) 19063427Sben || _kadm5_acl_check_permission(context, 19149363Shoek KADM5_PRIV_DELETE, 19231613Swollman princ); 19387529Sru if(ret){ 19431613Swollman krb5_free_principal(context->context, princ); 19579727Sschweikh krb5_free_principal(context->context, princ2); 19687529Sru goto fail; 19731613Swollman } 19831614Swollman ret = kadm5_rename_principal(kadm_handle, princ, princ2); 19931613Swollman krb5_free_principal(context->context, princ); 20031613Swollman krb5_free_principal(context->context, princ2); 20171895Sru krb5_storage_free(sp); 20231613Swollman sp = krb5_storage_emem(); 20312951Sphk krb5_store_int32(sp, ret); 20412951Sphk break; 20591436Simp } 20614966Sjoerg case kadm_chpass:{ 20714966Sjoerg op = "CHPASS"; 208106302Srwatson ret = krb5_ret_principal(sp, &princ); 209106092Srwatson if(ret) 210106092Srwatson goto fail; 211106092Srwatson ret = krb5_ret_string(sp, &password); 212106092Srwatson if(ret){ 213106092Srwatson krb5_free_principal(context->context, princ); 214106092Srwatson goto fail; 215106092Srwatson } 216106302Srwatson krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); 217106092Srwatson krb5_warnx(context->context, "%s: %s %s", client, op, name); 218106092Srwatson 219106092Srwatson /* 220106092Srwatson * The change is allowed if at least one of: 221106092Srwatson 222106302Srwatson * a) it's for the principal him/herself and this was an 223107383Sru * initial ticket, but then, check with the password quality 224107383Sru * function. 225107383Sru * b) the user is on the CPW ACL. 226106302Srwatson */ 227106092Srwatson 228106092Srwatson if (initial 229106092Srwatson && krb5_principal_compare (context->context, context->caller, 230106092Srwatson princ)) 231106302Srwatson { 232106092Srwatson krb5_data pwd_data; 233106092Srwatson const char *pwd_reason; 234106092Srwatson 235106092Srwatson pwd_data.data = password; 236106302Srwatson pwd_data.length = strlen(password); 237106092Srwatson 238106092Srwatson pwd_reason = kadm5_check_password_quality (context->context, 239106092Srwatson princ, &pwd_data); 240106092Srwatson if (pwd_reason != NULL) 241106092Srwatson ret = KADM5_PASS_Q_DICT; 242106302Srwatson else 243106302Srwatson ret = 0; 244106302Srwatson } else 245106092Srwatson ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW, princ); 246106302Srwatson 247106302Srwatson if(ret) { 248106302Srwatson krb5_free_principal(context->context, princ); 249106092Srwatson memset(password, 0, strlen(password)); 250106092Srwatson free(password); 251106092Srwatson goto fail; 252106092Srwatson } 253106092Srwatson ret = kadm5_chpass_principal(kadm_handle, princ, password); 254106092Srwatson krb5_free_principal(context->context, princ); 255106092Srwatson memset(password, 0, strlen(password)); 256106092Srwatson free(password); 257106092Srwatson krb5_storage_free(sp); 258106092Srwatson sp = krb5_storage_emem(); 259106092Srwatson krb5_store_int32(sp, ret); 260106092Srwatson break; 261106092Srwatson } 262106092Srwatson case kadm_chpass_with_key:{ 263106302Srwatson int i; 264106092Srwatson krb5_key_data *key_data; 265106092Srwatson int n_key_data; 266106092Srwatson 267106092Srwatson op = "CHPASS_WITH_KEY"; 268106092Srwatson ret = krb5_ret_principal(sp, &princ); 269106302Srwatson if(ret) 270106092Srwatson goto fail; 271106092Srwatson ret = krb5_ret_int32(sp, &n_key_data); 272130432Sle if (ret) { 273106092Srwatson krb5_free_principal(context->context, princ); 274106092Srwatson goto fail; 275130582Sru } 276130582Sru /* n_key_data will be squeezed into an int16_t below. */ 277120530Simp if (n_key_data < 0 || n_key_data >= 1 << 16 || 278130582Sru n_key_data > UINT_MAX/sizeof(*key_data)) { 279130582Sru ret = ERANGE; 280130582Sru krb5_free_principal(context->context, princ); 281130582Sru goto fail; 282130582Sru } 283120530Simp 284120530Simp key_data = malloc (n_key_data * sizeof(*key_data)); 285130582Sru if (key_data == NULL) { 286130582Sru ret = ENOMEM; 287120530Simp krb5_free_principal(context->context, princ); 288130582Sru goto fail; 289120530Simp } 290120530Simp 29131613Swollman for (i = 0; i < n_key_data; ++i) { 29271895Sru ret = kadm5_ret_key_data (sp, &key_data[i]); 29312823Sphk if (ret) { 29414966Sjoerg int16_t dummy = i; 29514966Sjoerg 296209546Scperciva kadm5_free_key_data (context, &dummy, key_data); 297209546Scperciva free (key_data); 298209546Scperciva krb5_free_principal(context->context, princ); 299103189Srobert goto fail; 300103189Srobert } 301107383Sru } 302107383Sru 303107383Sru krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); 304107383Sru krb5_warnx(context->context, "%s: %s %s", client, op, name); 305107383Sru 306108317Sschweikh /* 307103189Srobert * The change is only allowed if the user is on the CPW ACL, 30814966Sjoerg * this it to force password quality check on the user. 309138327Sdds */ 31087529Sru 31187529Sru ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW, princ); 31285367Sjulian if(ret) { 31385445Sjulian int16_t dummy = n_key_data; 31485480Sbde 31599240Simp kadm5_free_key_data (context, &dummy, key_data); 31699240Simp free (key_data); 31785445Sjulian krb5_free_principal(context->context, princ); 31885480Sbde goto fail; 31914966Sjoerg } 32014966Sjoerg ret = kadm5_chpass_principal_with_key(kadm_handle, princ, 32149363Shoek n_key_data, key_data); 32287529Sru { 32387529Sru int16_t dummy = n_key_data; 32487529Sru kadm5_free_key_data (context, &dummy, key_data); 32587529Sru } 32687529Sru free (key_data); 32771895Sru krb5_free_principal(context->context, princ); 32812823Sphk krb5_storage_free(sp); 32985445Sjulian sp = krb5_storage_emem(); 33085445Sjulian krb5_store_int32(sp, ret); 33185445Sjulian break; 33285445Sjulian } 33312823Sphk case kadm_randkey:{ 33485445Sjulian op = "RANDKEY"; 33531612Swollman ret = krb5_ret_principal(sp, &princ); 33631613Swollman if(ret) 33731612Swollman goto fail; 33831612Swollman krb5_unparse_name_fixed(context->context, princ, name, sizeof(name)); 33987529Sru krb5_warnx(context->context, "%s: %s %s", client, op, name); 34087529Sru /* 34131612Swollman * The change is allowed if at least one of: 34271895Sru * a) it's for the principal him/herself and this was an initial ticket 34331612Swollman * b) the user is on the CPW ACL. 34487529Sru */ 34582952Sobrien 34685480Sbde if (initial 34785445Sjulian && krb5_principal_compare (context->context, context->caller, 34885445Sjulian princ)) 34985445Sjulian ret = 0; 35031612Swollman else 35185445Sjulian ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW, princ); 35231612Swollman 35331612Swollman if(ret) { 35487529Sru krb5_free_principal(context->context, princ); 355122424Sfanf goto fail; 356122424Sfanf } 357122424Sfanf ret = kadm5_randkey_principal(kadm_handle, princ, 358122424Sfanf &new_keys, &n_keys); 359122424Sfanf krb5_free_principal(context->context, princ); 360122424Sfanf krb5_storage_free(sp); 361122424Sfanf sp = krb5_storage_emem(); 362122554Sfanf krb5_store_int32(sp, ret); 363122424Sfanf if(ret == 0){ 364122424Sfanf int i; 365122424Sfanf krb5_store_int32(sp, n_keys); 366122424Sfanf for(i = 0; i < n_keys; i++){ 36787529Sru krb5_store_keyblock(sp, new_keys[i]); 36887529Sru krb5_free_keyblock_contents(context->context, &new_keys[i]); 36987529Sru } 37087529Sru } 37187529Sru break; 372107282Sru } 373107282Sru case kadm_get_privs:{ 37471895Sru uint32_t privs; 37512823Sphk ret = kadm5_get_privs(kadm_handle, &privs); 37687569Sobrien krb5_storage_free(sp); 37712951Sphk sp = krb5_storage_emem(); 37812823Sphk krb5_store_int32(sp, ret); 37987569Sobrien if(ret == 0) 38087569Sobrien krb5_store_uint32(sp, privs); 38114966Sjoerg break; 38214966Sjoerg } 38314966Sjoerg case kadm_get_princs:{ 38414966Sjoerg op = "LIST"; 385131530Sru ret = krb5_ret_int32(sp, &tmp); 38687529Sru if(ret) 38787529Sru goto fail; 38814966Sjoerg if(tmp){ 38987529Sru ret = krb5_ret_string(sp, &expression); 39014966Sjoerg if(ret) 39114966Sjoerg goto fail; 39214966Sjoerg }else 393102212Simp expression = NULL; 394103011Srobert krb5_warnx(context->context, "%s: %s %s", client, op, 395102212Simp expression ? expression : "*"); 39614966Sjoerg ret = _kadm5_acl_check_permission(context, KADM5_PRIV_LIST, NULL); 39714966Sjoerg if(ret){ 39881449Sru free(expression); 39987529Sru goto fail; 40014966Sjoerg } 40190043Simp ret = kadm5_get_principals(kadm_handle, expression, &princs, &n_princs); 40287529Sru free(expression); 40390043Simp krb5_storage_free(sp); 40414966Sjoerg sp = krb5_storage_emem(); 40526192Speter krb5_store_int32(sp, ret); 40687529Sru if(ret == 0){ 40787529Sru int i; 40887529Sru krb5_store_int32(sp, n_princs); 40987529Sru for(i = 0; i < n_princs; i++) 41087529Sru krb5_store_string(sp, princs[i]); 41187529Sru kadm5_free_name_list(kadm_handle, princs, &n_princs); 41226192Speter } 41326192Speter break; 41414966Sjoerg } 41571895Sru default: 41626192Speter krb5_warnx(context->context, "%s: UNKNOWN OP %d", client, cmd); 41714966Sjoerg krb5_storage_free(sp); 41814966Sjoerg sp = krb5_storage_emem(); 41949363Shoek krb5_store_int32(sp, KADM5_FAILURE); 42084408Sobrien break; 42186725Sru } 42287529Sru krb5_storage_to_data(sp, out); 42387529Sru krb5_storage_free(sp); 42484408Sobrien return 0; 42581449Srufail: 42671895Sru krb5_warn(context->context, ret, "%s", op); 42726192Speter krb5_storage_seek(sp, 0, SEEK_SET); 42826192Speter krb5_store_int32(sp, ret); 42926192Speter krb5_storage_to_data(sp, out); 43026192Speter krb5_storage_free(sp); 43171895Sru return 0; 43226192Speter} 43326192Speter 43426192Speterstatic void 43526192Speterv5_loop (krb5_context context, 43626192Speter krb5_auth_context ac, 43771895Sru krb5_boolean initial, 43826192Speter void *kadm_handle, 43975819Sobrien int fd) 44026192Speter{ 44112951Sphk krb5_error_code ret; 44212823Sphk krb5_data in, out; 44312823Sphk 44412823Sphk for (;;) { 44512823Sphk doing_useful_work = 0; 44612823Sphk if(term_flag) 44712823Sphk exit(0); 44826192Speter ret = krb5_read_priv_message(context, ac, &fd, &in); 44912823Sphk if(ret == HEIM_ERR_EOF) 45093107Sobrien exit(0); 45112951Sphk if(ret) 45212951Sphk krb5_err(context, 1, ret, "krb5_read_priv_message"); 45314966Sjoerg doing_useful_work = 1; 45414966Sjoerg kadmind_dispatch(kadm_handle, initial, &in, &out); 45587529Sru krb5_data_free(&in); 45687529Sru ret = krb5_write_priv_message(context, ac, &fd, &out); 45787529Sru if(ret) 45887529Sru krb5_err(context, 1, ret, "krb5_write_priv_message"); 45987529Sru } 46087529Sru} 46187529Sru 46287529Srustatic krb5_boolean 46387529Srumatch_appl_version(const void *data, const char *appl_version) 46487529Sru{ 46587529Sru unsigned minor; 46687529Sru if(sscanf(appl_version, "KADM0.%u", &minor) != 1) 46787529Sru return 0; 46887529Sru *(unsigned*)data = minor; 46987529Sru return 1; 47087529Sru} 47187529Sru 47287529Srustatic void 473217087Straszhandle_v5(krb5_context context, 474217087Strasz krb5_auth_context ac, 475217087Strasz krb5_keytab keytab, 47671895Sru int len, 477131127Sobrien int fd) 47812951Sphk{ 47912951Sphk krb5_error_code ret; 480164639Sobrien u_char version[sizeof(KRB5_SENDAUTH_VERSION)]; 48112951Sphk krb5_ticket *ticket; 48212951Sphk char *server_name; 48312951Sphk char *client; 48412951Sphk void *kadm_handle; 485131127Sobrien ssize_t n; 486131127Sobrien krb5_boolean initial; 487131127Sobrien 48812951Sphk unsigned kadm_version; 48912951Sphk kadm5_config_params realm_params; 49049361Shoek 49149361Shoek if (len != sizeof(KRB5_SENDAUTH_VERSION)) 49249361Shoek krb5_errx(context, 1, "bad sendauth len %d", len); 49349361Shoek n = krb5_net_read(context, &fd, version, len); 49449361Shoek if (n < 0) 49512951Sphk krb5_err (context, 1, errno, "reading sendauth version"); 49617812Swosch if (n == 0) 49712951Sphk krb5_errx (context, 1, "EOF reading sendauth version"); 49812951Sphk if(memcmp(version, KRB5_SENDAUTH_VERSION, len) != 0) 49912951Sphk krb5_errx(context, 1, "bad sendauth version %.8s", version); 50012951Sphk 50112951Sphk ret = krb5_recvauth_match_version(context, &ac, &fd, 50214966Sjoerg match_appl_version, &kadm_version, 50314966Sjoerg NULL, KRB5_RECVAUTH_IGNORE_VERSION, 50487529Sru keytab, &ticket); 50587529Sru if(ret == KRB5_KT_NOTFOUND) 506103179Sfanf krb5_errx(context, 1, "krb5_recvauth: key not found"); 507103179Sfanf if(ret) 508103179Sfanf krb5_err(context, 1, ret, "krb5_recvauth"); 509103179Sfanf 510103179Sfanf ret = krb5_unparse_name (context, ticket->server, &server_name); 51143406Sjulian if (ret) 51243406Sjulian krb5_err (context, 1, ret, "krb5_unparse_name"); 51387529Sru 51487529Sru if (strncmp (server_name, KADM5_ADMIN_SERVICE, 51587529Sru strlen(KADM5_ADMIN_SERVICE)) != 0) 51687529Sru krb5_errx (context, 1, "ticket for strange principal (%s)", 51771895Sru server_name); 51826192Speter 51926192Speter free (server_name); 52012951Sphk 52112951Sphk memset(&realm_params, 0, sizeof(realm_params)); 52243406Sjulian 52343406Sjulian if(kadm_version == 1) { 52494682Sasmodai krb5_data params; 52543406Sjulian ret = krb5_read_priv_message(context, ac, &fd, ¶ms); 52643406Sjulian if(ret) 52743406Sjulian krb5_err(context, 1, ret, "krb5_read_priv_message"); 52843406Sjulian _kadm5_unmarshal_params(context, ¶ms, &realm_params); 52943406Sjulian } 53043406Sjulian 53126192Speter initial = ticket->ticket.flags.initial; 53226192Speter ret = krb5_unparse_name(context, ticket->client, &client); 53314966Sjoerg if (ret) 53414966Sjoerg krb5_err (context, 1, ret, "krb5_unparse_name"); 53587529Sru krb5_free_ticket (context, ticket); 53687529Sru ret = kadm5_init_with_password_ctx(context, 53787529Sru client, 53887529Sru NULL, 53914966Sjoerg KADM5_ADMIN_SERVICE, 54071895Sru &realm_params, 54112951Sphk 0, 0, 54212951Sphk &kadm_handle); 54312951Sphk if(ret) 54412951Sphk krb5_err (context, 1, ret, "kadm5_init_with_password_ctx"); 54514966Sjoerg v5_loop (context, ac, initial, kadm_handle, fd); 54614966Sjoerg} 54726192Speter 54814966Sjoergkrb5_error_code 54980139Sddkadmind_loop(krb5_context context, 55080139Sdd krb5_auth_context ac, 55171895Sru krb5_keytab keytab, 55294682Sasmodai int fd) 55380139Sdd{ 55415095Smpp unsigned char tmp[4]; 55594682Sasmodai ssize_t n; 55678432Sdd unsigned long len; 55714966Sjoerg 55814966Sjoerg n = krb5_net_read(context, &fd, tmp, 4); 55949363Shoek if(n == 0) 56049363Shoek exit(0); 56187529Sru if(n < 0) 56287529Sru krb5_err(context, 1, errno, "read"); 56326192Speter _krb5_get_int(tmp, &len, 4); 56426192Speter /* this v4 test could probably also go away */ 56587529Sru if(len > 0xffff && (len & 0xffff) == ('K' << 8) + 'A') { 56687529Sru unsigned char v4reply[] = { 56787529Sru 0x00, 0x0c, 56871895Sru 'K', 'Y', 'O', 'U', 'L', 'O', 'S', 'E', 56912951Sphk 0x95, 0xb7, 0xa7, 0x08 /* KADM_BAD_VER */ 57012951Sphk }; 57112951Sphk krb5_net_write(context, &fd, v4reply, sizeof(v4reply)); 57212951Sphk krb5_errx(context, 1, "packet appears to be version 4"); 57312951Sphk } else { 57412951Sphk handle_v5(context, ac, keytab, len, fd); 57512951Sphk } 57614966Sjoerg return 0; 57714966Sjoerg} 57887529Sru