Replace several other functions with `kadmind_loop'.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@4693 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
209
kadmin/server.c
209
kadmin/server.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
|
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -40,98 +40,8 @@
|
|||||||
|
|
||||||
RCSID("$Id$");
|
RCSID("$Id$");
|
||||||
|
|
||||||
kadm5_ret_t
|
static kadm5_ret_t
|
||||||
kadm5_server_send_sp(krb5_context context, krb5_auth_context ac,
|
kadmind_dispatch(void *kadm_handle, krb5_data *in, krb5_data *out)
|
||||||
krb5_storage *sp, int fd)
|
|
||||||
{
|
|
||||||
unsigned char buf[1024];
|
|
||||||
size_t len;
|
|
||||||
krb5_data in;
|
|
||||||
|
|
||||||
len = sp->seek(sp, 0, SEEK_CUR);
|
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
|
||||||
if(len > sizeof(buf))
|
|
||||||
return ENOMEM;
|
|
||||||
sp->fetch(sp, buf, len);
|
|
||||||
in.data = buf;
|
|
||||||
in.length = len;
|
|
||||||
return kadm5_server_send(context, ac, &in, fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_server_send(krb5_context context, krb5_auth_context ac,
|
|
||||||
krb5_data *data, int fd)
|
|
||||||
{
|
|
||||||
unsigned char buf[4];
|
|
||||||
kadm5_ret_t ret;
|
|
||||||
krb5_data out;
|
|
||||||
|
|
||||||
ret = krb5_mk_priv(context, ac, data, &out, NULL);
|
|
||||||
if(ret)
|
|
||||||
return ret;
|
|
||||||
buf[0] = (out.length >> 24) & 0xff;
|
|
||||||
buf[1] = (out.length >> 16) & 0xff;
|
|
||||||
buf[2] = (out.length >> 8) & 0xff;
|
|
||||||
buf[3] = out.length & 0xff;
|
|
||||||
krb5_net_write(context, &fd, buf, 4);
|
|
||||||
krb5_net_write(context, &fd, out.data, out.length);
|
|
||||||
krb5_data_free(&out);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_server_recv(krb5_context context, krb5_auth_context ac,
|
|
||||||
krb5_data *out, int fd)
|
|
||||||
{
|
|
||||||
unsigned char buf[1024];
|
|
||||||
size_t len;
|
|
||||||
krb5_data in;
|
|
||||||
kadm5_ret_t ret;
|
|
||||||
|
|
||||||
ret = krb5_net_read(context, &fd, buf, 4);
|
|
||||||
if(ret == 0)
|
|
||||||
exit(1);
|
|
||||||
if(ret < 0)
|
|
||||||
krb5_err(context, 1, errno, "krb5_net_read");
|
|
||||||
if(ret != 4)
|
|
||||||
krb5_errx(context, 1, "krb5_net_read(4) = %d", ret);
|
|
||||||
len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
|
||||||
if(len > sizeof(buf))
|
|
||||||
return ENOMEM;
|
|
||||||
ret = krb5_net_read(context, &fd, buf, len);
|
|
||||||
if(ret < 0)
|
|
||||||
krb5_err(context, 1, errno, "krb5_net_read");
|
|
||||||
if(ret != len)
|
|
||||||
krb5_errx(context, 1, "krb5_net_read(%d) = %d", len, ret);
|
|
||||||
|
|
||||||
in.data = buf;
|
|
||||||
in.length = len;
|
|
||||||
ret = krb5_rd_priv(context, ac, &in, out, NULL);
|
|
||||||
if(ret)
|
|
||||||
return ret;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_server_recv_sp(krb5_context context, krb5_auth_context ac,
|
|
||||||
krb5_storage *sp, int fd)
|
|
||||||
{
|
|
||||||
kadm5_ret_t ret;
|
|
||||||
krb5_data data;
|
|
||||||
|
|
||||||
ret = kadm5_server_recv (context, ac, &data, fd);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
sp->store(sp, data.data, data.length);
|
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
|
||||||
krb5_data_free(&data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
kadm5_ret_t
|
|
||||||
kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|
||||||
{
|
{
|
||||||
kadm5_ret_t ret;
|
kadm5_ret_t ret;
|
||||||
int32_t cmd, mask, tmp;
|
int32_t cmd, mask, tmp;
|
||||||
@@ -145,10 +55,13 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
int n_keys;
|
int n_keys;
|
||||||
char **princs;
|
char **princs;
|
||||||
int n_princs;
|
int n_princs;
|
||||||
|
krb5_storage *sp;
|
||||||
|
|
||||||
krb5_unparse_name_fixed(context->context, context->caller,
|
krb5_unparse_name_fixed(context->context, context->caller,
|
||||||
client, sizeof(client));
|
client, sizeof(client));
|
||||||
|
|
||||||
|
sp = krb5_storage_from_data(in);
|
||||||
|
|
||||||
krb5_ret_int32(sp, &cmd);
|
krb5_ret_int32(sp, &cmd);
|
||||||
switch(cmd){
|
switch(cmd){
|
||||||
case kadm_get:{
|
case kadm_get:{
|
||||||
@@ -169,7 +82,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
ret = kadm5_get_principal(kadm_handle, princ, &ent, mask);
|
ret = kadm5_get_principal(kadm_handle, princ, &ent, mask);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
if(ret == 0){
|
if(ret == 0){
|
||||||
kadm5_store_principal_ent(sp, &ent);
|
kadm5_store_principal_ent(sp, &ent);
|
||||||
@@ -192,7 +106,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
}
|
}
|
||||||
ret = kadm5_delete_principal(kadm_handle, princ);
|
ret = kadm5_delete_principal(kadm_handle, princ);
|
||||||
krb5_free_principal(context->context, princ);
|
krb5_free_principal(context->context, princ);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -226,7 +141,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
kadm5_free_principal_ent(kadm_handle, &ent);
|
kadm5_free_principal_ent(kadm_handle, &ent);
|
||||||
memset(password, 0, strlen(password));
|
memset(password, 0, strlen(password));
|
||||||
free(password);
|
free(password);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -250,7 +166,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
}
|
}
|
||||||
ret = kadm5_modify_principal(kadm_handle, &ent, mask);
|
ret = kadm5_modify_principal(kadm_handle, &ent, mask);
|
||||||
kadm5_free_principal_ent(kadm_handle, &ent);
|
kadm5_free_principal_ent(kadm_handle, &ent);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -269,7 +186,7 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
krb5_warnx(context->context, "%s: %s %s -> %s",
|
krb5_warnx(context->context, "%s: %s %s -> %s",
|
||||||
client, op, name, name2);
|
client, op, name, name2);
|
||||||
ret = _kadm5_acl_check_permission(context,
|
ret = _kadm5_acl_check_permission(context,
|
||||||
KADM5_PRIV_ADD|KADM5_PRIV_DELETE);
|
KADM5_PRIV_ADD|KADM5_PRIV_DELETE);
|
||||||
if(ret){
|
if(ret){
|
||||||
krb5_free_principal(context->context, princ);
|
krb5_free_principal(context->context, princ);
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -277,7 +194,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
ret = kadm5_rename_principal(kadm_handle, princ, princ2);
|
ret = kadm5_rename_principal(kadm_handle, princ, princ2);
|
||||||
krb5_free_principal(context->context, princ);
|
krb5_free_principal(context->context, princ);
|
||||||
krb5_free_principal(context->context, princ2);
|
krb5_free_principal(context->context, princ2);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -310,7 +228,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
krb5_free_principal(context->context, princ);
|
krb5_free_principal(context->context, princ);
|
||||||
memset(password, 0, strlen(password));
|
memset(password, 0, strlen(password));
|
||||||
free(password);
|
free(password);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -337,7 +256,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
ret = kadm5_randkey_principal(kadm_handle, princ,
|
ret = kadm5_randkey_principal(kadm_handle, princ,
|
||||||
&new_keys, &n_keys);
|
&new_keys, &n_keys);
|
||||||
krb5_free_principal(context->context, princ);
|
krb5_free_principal(context->context, princ);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
if(ret == 0){
|
if(ret == 0){
|
||||||
int i;
|
int i;
|
||||||
@@ -351,7 +271,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
}
|
}
|
||||||
case kadm_get_privs:{
|
case kadm_get_privs:{
|
||||||
ret = kadm5_get_privs(kadm_handle, &mask);
|
ret = kadm5_get_privs(kadm_handle, &mask);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
if(ret == 0)
|
if(ret == 0)
|
||||||
krb5_store_int32(sp, mask);
|
krb5_store_int32(sp, mask);
|
||||||
@@ -376,7 +297,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
}
|
}
|
||||||
ret = kadm5_get_principals(kadm_handle, exp, &princs, &n_princs);
|
ret = kadm5_get_principals(kadm_handle, exp, &princs, &n_princs);
|
||||||
free(exp);
|
free(exp);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
if(ret == 0){
|
if(ret == 0){
|
||||||
int i;
|
int i;
|
||||||
@@ -389,14 +311,91 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
krb5_warnx(context->context, "%s: UNKNOWN OP %d", client, cmd);
|
krb5_warnx(context->context, "%s: UNKNOWN OP %d", client, cmd);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, KADM5_FAILURE);
|
krb5_store_int32(sp, KADM5_FAILURE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
krb5_storage_to_data(sp, out);
|
||||||
|
krb5_storage_free(sp);
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
krb5_warnx(context->context, "%s", op);
|
krb5_warn(context->context, ret, "%s", op);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
sp->seek(sp, 0, SEEK_SET);
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
|
krb5_storage_to_data(sp, out);
|
||||||
|
krb5_storage_free(sp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
krb5_error_code
|
||||||
|
kadmind_loop(krb5_context context,
|
||||||
|
krb5_auth_context ac,
|
||||||
|
const char *client,
|
||||||
|
int fd)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
void *kadm_handle;
|
||||||
|
ret = kadm5_init_with_password_ctx(context,
|
||||||
|
client,
|
||||||
|
"password",
|
||||||
|
"service",
|
||||||
|
NULL, 0, 0,
|
||||||
|
&kadm_handle);
|
||||||
|
if(ret) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
krb5_data in, out, msg, reply;
|
||||||
|
unsigned char tmp[4];
|
||||||
|
unsigned long len;
|
||||||
|
ssize_t n;
|
||||||
|
struct iovec iov[2];
|
||||||
|
krb5_boolean krb4_packet = 0;
|
||||||
|
|
||||||
|
n = krb5_net_read(context, &fd, tmp, 4);
|
||||||
|
if(n == 0)
|
||||||
|
exit(0);
|
||||||
|
if(n < 0)
|
||||||
|
krb5_errx(context, 1, "read error: %d", errno);
|
||||||
|
if(n < 4)
|
||||||
|
krb5_errx(context, 1, "short read (%ld)", (long int)n);
|
||||||
|
k_get_int(tmp, &len, 4);
|
||||||
|
if(len > 0xffff && (len & 0xffff) == ('K' << 8) + 'A') {
|
||||||
|
len = len << 16;
|
||||||
|
krb4_packet = 1;
|
||||||
|
krb5_errx(context, 1, "packet appears to be version 4");
|
||||||
|
}
|
||||||
|
in.length = len;
|
||||||
|
in.data = malloc(in.length);
|
||||||
|
n = krb5_net_read(context, &fd, in.data, in.length);
|
||||||
|
if(n < 0)
|
||||||
|
krb5_errx(context, 1, "read error: %d", errno);
|
||||||
|
if(n < in.length)
|
||||||
|
krb5_errx(context, 1, "short read (%ld)", (long int)n);
|
||||||
|
if(!krb4_packet) {
|
||||||
|
ret = krb5_rd_priv(context, ac, &in, &out, NULL);
|
||||||
|
krb5_data_free(&in);
|
||||||
|
kadmind_dispatch(kadm_handle, &out, &msg);
|
||||||
|
krb5_data_free(&out);
|
||||||
|
}
|
||||||
|
ret = krb5_mk_priv(context, ac, &msg, &reply, NULL);
|
||||||
|
krb5_data_free(&msg);
|
||||||
|
if(ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_mk_priv");
|
||||||
|
|
||||||
|
k_put_int(tmp, reply.length, 4);
|
||||||
|
|
||||||
|
iov[0].iov_base = tmp;
|
||||||
|
iov[0].iov_len = 4;
|
||||||
|
iov[1].iov_base = reply.data;
|
||||||
|
iov[1].iov_len = reply.length;
|
||||||
|
n = writev(fd, iov, 2);
|
||||||
|
krb5_data_free(&reply);
|
||||||
|
if(n < 0)
|
||||||
|
krb5_err(context, 1, errno, "writev");
|
||||||
|
if(n < iov[0].iov_len + iov[1].iov_len)
|
||||||
|
krb5_errx(context, 1, "short write");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
|
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -40,98 +40,8 @@
|
|||||||
|
|
||||||
RCSID("$Id$");
|
RCSID("$Id$");
|
||||||
|
|
||||||
kadm5_ret_t
|
static kadm5_ret_t
|
||||||
kadm5_server_send_sp(krb5_context context, krb5_auth_context ac,
|
kadmind_dispatch(void *kadm_handle, krb5_data *in, krb5_data *out)
|
||||||
krb5_storage *sp, int fd)
|
|
||||||
{
|
|
||||||
unsigned char buf[1024];
|
|
||||||
size_t len;
|
|
||||||
krb5_data in;
|
|
||||||
|
|
||||||
len = sp->seek(sp, 0, SEEK_CUR);
|
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
|
||||||
if(len > sizeof(buf))
|
|
||||||
return ENOMEM;
|
|
||||||
sp->fetch(sp, buf, len);
|
|
||||||
in.data = buf;
|
|
||||||
in.length = len;
|
|
||||||
return kadm5_server_send(context, ac, &in, fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_server_send(krb5_context context, krb5_auth_context ac,
|
|
||||||
krb5_data *data, int fd)
|
|
||||||
{
|
|
||||||
unsigned char buf[4];
|
|
||||||
kadm5_ret_t ret;
|
|
||||||
krb5_data out;
|
|
||||||
|
|
||||||
ret = krb5_mk_priv(context, ac, data, &out, NULL);
|
|
||||||
if(ret)
|
|
||||||
return ret;
|
|
||||||
buf[0] = (out.length >> 24) & 0xff;
|
|
||||||
buf[1] = (out.length >> 16) & 0xff;
|
|
||||||
buf[2] = (out.length >> 8) & 0xff;
|
|
||||||
buf[3] = out.length & 0xff;
|
|
||||||
krb5_net_write(context, &fd, buf, 4);
|
|
||||||
krb5_net_write(context, &fd, out.data, out.length);
|
|
||||||
krb5_data_free(&out);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_server_recv(krb5_context context, krb5_auth_context ac,
|
|
||||||
krb5_data *out, int fd)
|
|
||||||
{
|
|
||||||
unsigned char buf[1024];
|
|
||||||
size_t len;
|
|
||||||
krb5_data in;
|
|
||||||
kadm5_ret_t ret;
|
|
||||||
|
|
||||||
ret = krb5_net_read(context, &fd, buf, 4);
|
|
||||||
if(ret == 0)
|
|
||||||
exit(1);
|
|
||||||
if(ret < 0)
|
|
||||||
krb5_err(context, 1, errno, "krb5_net_read");
|
|
||||||
if(ret != 4)
|
|
||||||
krb5_errx(context, 1, "krb5_net_read(4) = %d", ret);
|
|
||||||
len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
|
||||||
if(len > sizeof(buf))
|
|
||||||
return ENOMEM;
|
|
||||||
ret = krb5_net_read(context, &fd, buf, len);
|
|
||||||
if(ret < 0)
|
|
||||||
krb5_err(context, 1, errno, "krb5_net_read");
|
|
||||||
if(ret != len)
|
|
||||||
krb5_errx(context, 1, "krb5_net_read(%d) = %d", len, ret);
|
|
||||||
|
|
||||||
in.data = buf;
|
|
||||||
in.length = len;
|
|
||||||
ret = krb5_rd_priv(context, ac, &in, out, NULL);
|
|
||||||
if(ret)
|
|
||||||
return ret;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
kadm5_ret_t
|
|
||||||
kadm5_server_recv_sp(krb5_context context, krb5_auth_context ac,
|
|
||||||
krb5_storage *sp, int fd)
|
|
||||||
{
|
|
||||||
kadm5_ret_t ret;
|
|
||||||
krb5_data data;
|
|
||||||
|
|
||||||
ret = kadm5_server_recv (context, ac, &data, fd);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
sp->store(sp, data.data, data.length);
|
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
|
||||||
krb5_data_free(&data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
kadm5_ret_t
|
|
||||||
kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|
||||||
{
|
{
|
||||||
kadm5_ret_t ret;
|
kadm5_ret_t ret;
|
||||||
int32_t cmd, mask, tmp;
|
int32_t cmd, mask, tmp;
|
||||||
@@ -145,10 +55,13 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
int n_keys;
|
int n_keys;
|
||||||
char **princs;
|
char **princs;
|
||||||
int n_princs;
|
int n_princs;
|
||||||
|
krb5_storage *sp;
|
||||||
|
|
||||||
krb5_unparse_name_fixed(context->context, context->caller,
|
krb5_unparse_name_fixed(context->context, context->caller,
|
||||||
client, sizeof(client));
|
client, sizeof(client));
|
||||||
|
|
||||||
|
sp = krb5_storage_from_data(in);
|
||||||
|
|
||||||
krb5_ret_int32(sp, &cmd);
|
krb5_ret_int32(sp, &cmd);
|
||||||
switch(cmd){
|
switch(cmd){
|
||||||
case kadm_get:{
|
case kadm_get:{
|
||||||
@@ -169,7 +82,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
ret = kadm5_get_principal(kadm_handle, princ, &ent, mask);
|
ret = kadm5_get_principal(kadm_handle, princ, &ent, mask);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
if(ret == 0){
|
if(ret == 0){
|
||||||
kadm5_store_principal_ent(sp, &ent);
|
kadm5_store_principal_ent(sp, &ent);
|
||||||
@@ -192,7 +106,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
}
|
}
|
||||||
ret = kadm5_delete_principal(kadm_handle, princ);
|
ret = kadm5_delete_principal(kadm_handle, princ);
|
||||||
krb5_free_principal(context->context, princ);
|
krb5_free_principal(context->context, princ);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -226,7 +141,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
kadm5_free_principal_ent(kadm_handle, &ent);
|
kadm5_free_principal_ent(kadm_handle, &ent);
|
||||||
memset(password, 0, strlen(password));
|
memset(password, 0, strlen(password));
|
||||||
free(password);
|
free(password);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -250,7 +166,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
}
|
}
|
||||||
ret = kadm5_modify_principal(kadm_handle, &ent, mask);
|
ret = kadm5_modify_principal(kadm_handle, &ent, mask);
|
||||||
kadm5_free_principal_ent(kadm_handle, &ent);
|
kadm5_free_principal_ent(kadm_handle, &ent);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -269,7 +186,7 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
krb5_warnx(context->context, "%s: %s %s -> %s",
|
krb5_warnx(context->context, "%s: %s %s -> %s",
|
||||||
client, op, name, name2);
|
client, op, name, name2);
|
||||||
ret = _kadm5_acl_check_permission(context,
|
ret = _kadm5_acl_check_permission(context,
|
||||||
KADM5_PRIV_ADD|KADM5_PRIV_DELETE);
|
KADM5_PRIV_ADD|KADM5_PRIV_DELETE);
|
||||||
if(ret){
|
if(ret){
|
||||||
krb5_free_principal(context->context, princ);
|
krb5_free_principal(context->context, princ);
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -277,7 +194,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
ret = kadm5_rename_principal(kadm_handle, princ, princ2);
|
ret = kadm5_rename_principal(kadm_handle, princ, princ2);
|
||||||
krb5_free_principal(context->context, princ);
|
krb5_free_principal(context->context, princ);
|
||||||
krb5_free_principal(context->context, princ2);
|
krb5_free_principal(context->context, princ2);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -310,7 +228,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
krb5_free_principal(context->context, princ);
|
krb5_free_principal(context->context, princ);
|
||||||
memset(password, 0, strlen(password));
|
memset(password, 0, strlen(password));
|
||||||
free(password);
|
free(password);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -337,7 +256,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
ret = kadm5_randkey_principal(kadm_handle, princ,
|
ret = kadm5_randkey_principal(kadm_handle, princ,
|
||||||
&new_keys, &n_keys);
|
&new_keys, &n_keys);
|
||||||
krb5_free_principal(context->context, princ);
|
krb5_free_principal(context->context, princ);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
if(ret == 0){
|
if(ret == 0){
|
||||||
int i;
|
int i;
|
||||||
@@ -351,7 +271,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
}
|
}
|
||||||
case kadm_get_privs:{
|
case kadm_get_privs:{
|
||||||
ret = kadm5_get_privs(kadm_handle, &mask);
|
ret = kadm5_get_privs(kadm_handle, &mask);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
if(ret == 0)
|
if(ret == 0)
|
||||||
krb5_store_int32(sp, mask);
|
krb5_store_int32(sp, mask);
|
||||||
@@ -376,7 +297,8 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
}
|
}
|
||||||
ret = kadm5_get_principals(kadm_handle, exp, &princs, &n_princs);
|
ret = kadm5_get_principals(kadm_handle, exp, &princs, &n_princs);
|
||||||
free(exp);
|
free(exp);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
if(ret == 0){
|
if(ret == 0){
|
||||||
int i;
|
int i;
|
||||||
@@ -389,14 +311,91 @@ kadmind_dispatch(void *kadm_handle, krb5_storage *sp)
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
krb5_warnx(context->context, "%s: UNKNOWN OP %d", client, cmd);
|
krb5_warnx(context->context, "%s: UNKNOWN OP %d", client, cmd);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
krb5_storage_free(sp);
|
||||||
|
sp = krb5_storage_emem();
|
||||||
krb5_store_int32(sp, KADM5_FAILURE);
|
krb5_store_int32(sp, KADM5_FAILURE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
krb5_storage_to_data(sp, out);
|
||||||
|
krb5_storage_free(sp);
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
krb5_warnx(context->context, "%s", op);
|
krb5_warn(context->context, ret, "%s", op);
|
||||||
sp->seek(sp, 0, SEEK_SET);
|
sp->seek(sp, 0, SEEK_SET);
|
||||||
krb5_store_int32(sp, ret);
|
krb5_store_int32(sp, ret);
|
||||||
|
krb5_storage_to_data(sp, out);
|
||||||
|
krb5_storage_free(sp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
krb5_error_code
|
||||||
|
kadmind_loop(krb5_context context,
|
||||||
|
krb5_auth_context ac,
|
||||||
|
const char *client,
|
||||||
|
int fd)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
void *kadm_handle;
|
||||||
|
ret = kadm5_init_with_password_ctx(context,
|
||||||
|
client,
|
||||||
|
"password",
|
||||||
|
"service",
|
||||||
|
NULL, 0, 0,
|
||||||
|
&kadm_handle);
|
||||||
|
if(ret) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
krb5_data in, out, msg, reply;
|
||||||
|
unsigned char tmp[4];
|
||||||
|
unsigned long len;
|
||||||
|
ssize_t n;
|
||||||
|
struct iovec iov[2];
|
||||||
|
krb5_boolean krb4_packet = 0;
|
||||||
|
|
||||||
|
n = krb5_net_read(context, &fd, tmp, 4);
|
||||||
|
if(n == 0)
|
||||||
|
exit(0);
|
||||||
|
if(n < 0)
|
||||||
|
krb5_errx(context, 1, "read error: %d", errno);
|
||||||
|
if(n < 4)
|
||||||
|
krb5_errx(context, 1, "short read (%ld)", (long int)n);
|
||||||
|
k_get_int(tmp, &len, 4);
|
||||||
|
if(len > 0xffff && (len & 0xffff) == ('K' << 8) + 'A') {
|
||||||
|
len = len << 16;
|
||||||
|
krb4_packet = 1;
|
||||||
|
krb5_errx(context, 1, "packet appears to be version 4");
|
||||||
|
}
|
||||||
|
in.length = len;
|
||||||
|
in.data = malloc(in.length);
|
||||||
|
n = krb5_net_read(context, &fd, in.data, in.length);
|
||||||
|
if(n < 0)
|
||||||
|
krb5_errx(context, 1, "read error: %d", errno);
|
||||||
|
if(n < in.length)
|
||||||
|
krb5_errx(context, 1, "short read (%ld)", (long int)n);
|
||||||
|
if(!krb4_packet) {
|
||||||
|
ret = krb5_rd_priv(context, ac, &in, &out, NULL);
|
||||||
|
krb5_data_free(&in);
|
||||||
|
kadmind_dispatch(kadm_handle, &out, &msg);
|
||||||
|
krb5_data_free(&out);
|
||||||
|
}
|
||||||
|
ret = krb5_mk_priv(context, ac, &msg, &reply, NULL);
|
||||||
|
krb5_data_free(&msg);
|
||||||
|
if(ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_mk_priv");
|
||||||
|
|
||||||
|
k_put_int(tmp, reply.length, 4);
|
||||||
|
|
||||||
|
iov[0].iov_base = tmp;
|
||||||
|
iov[0].iov_len = 4;
|
||||||
|
iov[1].iov_base = reply.data;
|
||||||
|
iov[1].iov_len = reply.length;
|
||||||
|
n = writev(fd, iov, 2);
|
||||||
|
krb5_data_free(&reply);
|
||||||
|
if(n < 0)
|
||||||
|
krb5_err(context, 1, errno, "writev");
|
||||||
|
if(n < iov[0].iov_len + iov[1].iov_len)
|
||||||
|
krb5_errx(context, 1, "short write");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user