kadm5/kadmin: Add read-only mode
Now we can have read-only kadmind instances.
This commit is contained in:
@@ -149,12 +149,12 @@ void start_server(krb5_context, const char*);
|
|||||||
/* server.c */
|
/* server.c */
|
||||||
|
|
||||||
krb5_error_code
|
krb5_error_code
|
||||||
kadmind_loop (krb5_context, krb5_keytab, int);
|
kadmind_loop (krb5_context, krb5_keytab, int, int);
|
||||||
|
|
||||||
/* rpc.c */
|
/* rpc.c */
|
||||||
|
|
||||||
int
|
int
|
||||||
handle_mit(krb5_context, void *, size_t, int);
|
handle_mit(krb5_context, void *, size_t, int, int);
|
||||||
|
|
||||||
/* mod.c */
|
/* mod.c */
|
||||||
|
|
||||||
|
@@ -42,6 +42,7 @@ static char *keytab_str = sHDB;
|
|||||||
static int help_flag;
|
static int help_flag;
|
||||||
static int version_flag;
|
static int version_flag;
|
||||||
static int debug_flag;
|
static int debug_flag;
|
||||||
|
static int readonly_flag;
|
||||||
static char *port_str;
|
static char *port_str;
|
||||||
char *realm;
|
char *realm;
|
||||||
|
|
||||||
@@ -81,6 +82,8 @@ static struct getargs args[] = {
|
|||||||
},
|
},
|
||||||
{ "ports", 'p', arg_string, &port_str,
|
{ "ports", 'p', arg_string, &port_str,
|
||||||
"ports to listen to", "port" },
|
"ports to listen to", "port" },
|
||||||
|
{ "read-only", 0, arg_flag, &readonly_flag,
|
||||||
|
"read-only operations", NULL },
|
||||||
{ "help", 'h', arg_flag, &help_flag, NULL, NULL },
|
{ "help", 'h', arg_flag, &help_flag, NULL, NULL },
|
||||||
{ "version", 'v', arg_flag, &version_flag, NULL, NULL }
|
{ "version", 'v', arg_flag, &version_flag, NULL, NULL }
|
||||||
};
|
};
|
||||||
@@ -211,7 +214,7 @@ main(int argc, char **argv)
|
|||||||
if(realm)
|
if(realm)
|
||||||
krb5_set_default_realm(context, realm); /* XXX */
|
krb5_set_default_realm(context, realm); /* XXX */
|
||||||
|
|
||||||
kadmind_loop(context, keytab, sfd);
|
kadmind_loop(context, keytab, sfd, readonly_flag);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
51
kadmin/rpc.c
51
kadmin/rpc.c
@@ -689,7 +689,7 @@ proc_init(kadm5_server_context *contextp,
|
|||||||
struct krb5_proc {
|
struct krb5_proc {
|
||||||
const char *name;
|
const char *name;
|
||||||
void (*func)(kadm5_server_context *, krb5_storage *, krb5_storage *);
|
void (*func)(kadm5_server_context *, krb5_storage *, krb5_storage *);
|
||||||
} procs[] = {
|
} rwprocs[] = {
|
||||||
{ "NULL", NULL },
|
{ "NULL", NULL },
|
||||||
{ "create principal", proc_create_principal },
|
{ "create principal", proc_create_principal },
|
||||||
{ "delete principal", proc_delete_principal },
|
{ "delete principal", proc_delete_principal },
|
||||||
@@ -712,6 +712,29 @@ struct krb5_proc {
|
|||||||
{ "chpass principal v3", NULL },
|
{ "chpass principal v3", NULL },
|
||||||
{ "chrand principal v3", NULL },
|
{ "chrand principal v3", NULL },
|
||||||
{ "setkey principal v3", NULL }
|
{ "setkey principal v3", NULL }
|
||||||
|
}, roprocs[] = {
|
||||||
|
{ "NULL", NULL },
|
||||||
|
{ "create principal", NULL },
|
||||||
|
{ "delete principal", NULL },
|
||||||
|
{ "modify principal", NULL },
|
||||||
|
{ "rename principal", NULL },
|
||||||
|
{ "get principal", proc_get_principal },
|
||||||
|
{ "chpass principal", NULL },
|
||||||
|
{ "chrand principal", NULL },
|
||||||
|
{ "create policy", NULL },
|
||||||
|
{ "delete policy", NULL },
|
||||||
|
{ "modify policy", NULL },
|
||||||
|
{ "get policy", NULL },
|
||||||
|
{ "get privs", NULL },
|
||||||
|
{ "init", NULL },
|
||||||
|
{ "get principals", NULL },
|
||||||
|
{ "get polices", NULL },
|
||||||
|
{ "setkey principal", NULL },
|
||||||
|
{ "setkey principal v4", NULL },
|
||||||
|
{ "create principal v3", NULL },
|
||||||
|
{ "chpass principal v3", NULL },
|
||||||
|
{ "chrand principal v3", NULL },
|
||||||
|
{ "setkey principal v3", NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
@@ -742,8 +765,10 @@ struct gctx {
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
process_stream(krb5_context contextp,
|
process_stream(krb5_context contextp,
|
||||||
unsigned char *buf, size_t ilen,
|
unsigned char *buf,
|
||||||
krb5_storage *sp)
|
size_t ilen,
|
||||||
|
krb5_storage *sp,
|
||||||
|
int readonly)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_storage *msg, *reply, *dreply;
|
krb5_storage *msg, *reply, *dreply;
|
||||||
@@ -884,6 +909,7 @@ process_stream(krb5_context contextp,
|
|||||||
int conf_state;
|
int conf_state;
|
||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
krb5_storage *sp1;
|
krb5_storage *sp1;
|
||||||
|
struct krb5_proc *procs = readonly ? roprocs : rwprocs;
|
||||||
|
|
||||||
INSIST(gcred.service == rpg_privacy);
|
INSIST(gcred.service == rpg_privacy);
|
||||||
|
|
||||||
@@ -921,11 +947,16 @@ process_stream(krb5_context contextp,
|
|||||||
*/
|
*/
|
||||||
CHECK(krb5_store_uint32(dreply, gctx.seq_num));
|
CHECK(krb5_store_uint32(dreply, gctx.seq_num));
|
||||||
|
|
||||||
if (chdr.proc >= sizeof(procs)/sizeof(procs[0])) {
|
if (chdr.proc >= sizeof(rwprocs)/sizeof(rwprocs[0])) {
|
||||||
krb5_warnx(contextp, "proc number out of array");
|
krb5_warnx(contextp, "proc number out of array");
|
||||||
} else if (procs[chdr.proc].func == NULL) {
|
} else if (procs[chdr.proc].func == NULL) {
|
||||||
krb5_warnx(contextp, "proc '%s' never implemented",
|
if (readonly && rwprocs[chdr.proc].func)
|
||||||
procs[chdr.proc].name);
|
krb5_warnx(contextp,
|
||||||
|
"proc '%s' not allowed (readonly mode)",
|
||||||
|
procs[chdr.proc].name);
|
||||||
|
else
|
||||||
|
krb5_warnx(contextp, "proc '%s' never implemented",
|
||||||
|
procs[chdr.proc].name);
|
||||||
} else {
|
} else {
|
||||||
krb5_warnx(contextp, "proc %s", procs[chdr.proc].name);
|
krb5_warnx(contextp, "proc %s", procs[chdr.proc].name);
|
||||||
INSIST(server_handle != NULL);
|
INSIST(server_handle != NULL);
|
||||||
@@ -1101,7 +1132,11 @@ process_stream(krb5_context contextp,
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
handle_mit(krb5_context contextp, void *buf, size_t len, krb5_socket_t sock)
|
handle_mit(krb5_context contextp,
|
||||||
|
void *buf,
|
||||||
|
size_t len,
|
||||||
|
krb5_socket_t sock,
|
||||||
|
int readonly)
|
||||||
{
|
{
|
||||||
krb5_storage *sp;
|
krb5_storage *sp;
|
||||||
|
|
||||||
@@ -1110,7 +1145,7 @@ handle_mit(krb5_context contextp, void *buf, size_t len, krb5_socket_t sock)
|
|||||||
sp = krb5_storage_from_socket(sock);
|
sp = krb5_storage_from_socket(sock);
|
||||||
INSIST(sp != NULL);
|
INSIST(sp != NULL);
|
||||||
|
|
||||||
process_stream(contextp, buf, len, sp);
|
process_stream(contextp, buf, len, sp, readonly);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,7 @@ static kadm5_ret_t check_aliases(kadm5_server_context *,
|
|||||||
|
|
||||||
static kadm5_ret_t
|
static kadm5_ret_t
|
||||||
kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||||
krb5_data *in, krb5_data *out)
|
krb5_data *in, krb5_data *out, int readonly)
|
||||||
{
|
{
|
||||||
kadm5_ret_t ret;
|
kadm5_ret_t ret;
|
||||||
int32_t cmd, mask, kvno, tmp;
|
int32_t cmd, mask, kvno, tmp;
|
||||||
@@ -139,8 +139,12 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
|||||||
}
|
}
|
||||||
case kadm_delete:{
|
case kadm_delete:{
|
||||||
op = "DELETE";
|
op = "DELETE";
|
||||||
|
if (readonly) {
|
||||||
|
ret = KADM5_READ_ONLY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
ret = krb5_ret_principal(sp, &princ);
|
ret = krb5_ret_principal(sp, &princ);
|
||||||
if(ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name));
|
krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name));
|
||||||
krb5_warnx(contextp->context, "%s: %s %s", client, op, name);
|
krb5_warnx(contextp->context, "%s: %s %s", client, op, name);
|
||||||
@@ -165,6 +169,10 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
|||||||
}
|
}
|
||||||
case kadm_create:{
|
case kadm_create:{
|
||||||
op = "CREATE";
|
op = "CREATE";
|
||||||
|
if (readonly) {
|
||||||
|
ret = KADM5_READ_ONLY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
ret = kadm5_ret_principal_ent(sp, &ent);
|
ret = kadm5_ret_principal_ent(sp, &ent);
|
||||||
if(ret)
|
if(ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -212,6 +220,10 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
|||||||
}
|
}
|
||||||
case kadm_modify:{
|
case kadm_modify:{
|
||||||
op = "MODIFY";
|
op = "MODIFY";
|
||||||
|
if (readonly) {
|
||||||
|
ret = KADM5_READ_ONLY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
ret = kadm5_ret_principal_ent(sp, &ent);
|
ret = kadm5_ret_principal_ent(sp, &ent);
|
||||||
if(ret)
|
if(ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -261,6 +273,10 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
|||||||
}
|
}
|
||||||
case kadm_prune:{
|
case kadm_prune:{
|
||||||
op = "PRUNE";
|
op = "PRUNE";
|
||||||
|
if (readonly) {
|
||||||
|
ret = KADM5_READ_ONLY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
ret = krb5_ret_principal(sp, &princ);
|
ret = krb5_ret_principal(sp, &princ);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -288,6 +304,10 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
|||||||
}
|
}
|
||||||
case kadm_rename:{
|
case kadm_rename:{
|
||||||
op = "RENAME";
|
op = "RENAME";
|
||||||
|
if (readonly) {
|
||||||
|
ret = KADM5_READ_ONLY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
ret = krb5_ret_principal(sp, &princ);
|
ret = krb5_ret_principal(sp, &princ);
|
||||||
if(ret)
|
if(ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -335,6 +355,10 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
|||||||
krb5_boolean is_self_cpw, allow_self_cpw;
|
krb5_boolean is_self_cpw, allow_self_cpw;
|
||||||
|
|
||||||
op = "CHPASS";
|
op = "CHPASS";
|
||||||
|
if (readonly) {
|
||||||
|
ret = KADM5_READ_ONLY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
ret = krb5_ret_principal(sp, &princ);
|
ret = krb5_ret_principal(sp, &princ);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -382,6 +406,10 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
|||||||
int n_key_data;
|
int n_key_data;
|
||||||
|
|
||||||
op = "CHPASS_WITH_KEY";
|
op = "CHPASS_WITH_KEY";
|
||||||
|
if (readonly) {
|
||||||
|
ret = KADM5_READ_ONLY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
ret = krb5_ret_principal(sp, &princ);
|
ret = krb5_ret_principal(sp, &princ);
|
||||||
if(ret)
|
if(ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -453,6 +481,10 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
|||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
op = "RANDKEY";
|
op = "RANDKEY";
|
||||||
|
if (readonly) {
|
||||||
|
ret = KADM5_READ_ONLY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
ret = krb5_ret_principal(sp, &princ);
|
ret = krb5_ret_principal(sp, &princ);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -758,7 +790,8 @@ v5_loop (krb5_context contextp,
|
|||||||
krb5_auth_context ac,
|
krb5_auth_context ac,
|
||||||
krb5_boolean initial,
|
krb5_boolean initial,
|
||||||
void *kadm_handlep,
|
void *kadm_handlep,
|
||||||
krb5_socket_t fd)
|
krb5_socket_t fd,
|
||||||
|
int readonly)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_data in, out;
|
krb5_data in, out;
|
||||||
@@ -773,7 +806,7 @@ v5_loop (krb5_context contextp,
|
|||||||
if(ret)
|
if(ret)
|
||||||
krb5_err(contextp, 1, ret, "krb5_read_priv_message");
|
krb5_err(contextp, 1, ret, "krb5_read_priv_message");
|
||||||
doing_useful_work = 1;
|
doing_useful_work = 1;
|
||||||
ret = kadmind_dispatch(kadm_handlep, initial, &in, &out);
|
ret = kadmind_dispatch(kadm_handlep, initial, &in, &out, readonly);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(contextp, 1, ret, "kadmind_dispatch");
|
krb5_err(contextp, 1, ret, "kadmind_dispatch");
|
||||||
krb5_data_free(&in);
|
krb5_data_free(&in);
|
||||||
@@ -798,7 +831,8 @@ match_appl_version(const void *data, const char *appl_version)
|
|||||||
static void
|
static void
|
||||||
handle_v5(krb5_context contextp,
|
handle_v5(krb5_context contextp,
|
||||||
krb5_keytab keytab,
|
krb5_keytab keytab,
|
||||||
krb5_socket_t fd)
|
krb5_socket_t fd,
|
||||||
|
int readonly)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_ticket *ticket;
|
krb5_ticket *ticket;
|
||||||
@@ -853,13 +887,14 @@ handle_v5(krb5_context contextp,
|
|||||||
&kadm_handlep);
|
&kadm_handlep);
|
||||||
if(ret)
|
if(ret)
|
||||||
krb5_err (contextp, 1, ret, "kadm5_init_with_password_ctx");
|
krb5_err (contextp, 1, ret, "kadm5_init_with_password_ctx");
|
||||||
v5_loop (contextp, ac, initial, kadm_handlep, fd);
|
v5_loop (contextp, ac, initial, kadm_handlep, fd, readonly);
|
||||||
}
|
}
|
||||||
|
|
||||||
krb5_error_code
|
krb5_error_code
|
||||||
kadmind_loop(krb5_context contextp,
|
kadmind_loop(krb5_context contextp,
|
||||||
krb5_keytab keytab,
|
krb5_keytab keytab,
|
||||||
krb5_socket_t sock)
|
krb5_socket_t sock,
|
||||||
|
int readonly)
|
||||||
{
|
{
|
||||||
u_char buf[sizeof(KRB5_SENDAUTH_VERSION) + 4];
|
u_char buf[sizeof(KRB5_SENDAUTH_VERSION) + 4];
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
@@ -881,14 +916,14 @@ kadmind_loop(krb5_context contextp,
|
|||||||
krb5_errx (contextp, 1, "EOF reading sendauth version");
|
krb5_errx (contextp, 1, "EOF reading sendauth version");
|
||||||
|
|
||||||
if(memcmp(buf + 4, KRB5_SENDAUTH_VERSION, len) == 0) {
|
if(memcmp(buf + 4, KRB5_SENDAUTH_VERSION, len) == 0) {
|
||||||
handle_v5(contextp, keytab, sock);
|
handle_v5(contextp, keytab, sock, readonly);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
len += 4;
|
len += 4;
|
||||||
} else
|
} else
|
||||||
len = 4;
|
len = 4;
|
||||||
|
|
||||||
handle_mit(contextp, buf, len, sock);
|
handle_mit(contextp, buf, len, sock, readonly);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -204,6 +204,8 @@ typedef struct _kadm5_policy_ent_t {
|
|||||||
#define KADM5_CONFIG_EXPIRATION (1 << 16)
|
#define KADM5_CONFIG_EXPIRATION (1 << 16)
|
||||||
#define KADM5_CONFIG_FLAGS (1 << 17)
|
#define KADM5_CONFIG_FLAGS (1 << 17)
|
||||||
#define KADM5_CONFIG_ENCTYPES (1 << 18)
|
#define KADM5_CONFIG_ENCTYPES (1 << 18)
|
||||||
|
#define KADM5_CONFIG_READONLY_ADMIN_SERVER (1 << 19)
|
||||||
|
#define KADM5_CONFIG_READONLY_KADMIN_PORT (1 << 20)
|
||||||
|
|
||||||
#define KADM5_PRIV_GET (1 << 0)
|
#define KADM5_PRIV_GET (1 << 0)
|
||||||
#define KADM5_PRIV_ADD (1 << 1)
|
#define KADM5_PRIV_ADD (1 << 1)
|
||||||
@@ -218,6 +220,10 @@ typedef struct _kadm5_policy_ent_t {
|
|||||||
|
|
||||||
#define KADM5_BOGUS_KEY_DATA "\xe5\xe5\xe5\xe5"
|
#define KADM5_BOGUS_KEY_DATA "\xe5\xe5\xe5\xe5"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ABI NOTE: We can add fields at the end of this provided that we define new
|
||||||
|
* mask bits that must be set in the mask field when setting the new fields.
|
||||||
|
*/
|
||||||
typedef struct _kadm5_config_params {
|
typedef struct _kadm5_config_params {
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
|
|
||||||
@@ -234,6 +240,10 @@ typedef struct _kadm5_config_params {
|
|||||||
|
|
||||||
/* server library (database) fields */
|
/* server library (database) fields */
|
||||||
char *stash_file;
|
char *stash_file;
|
||||||
|
|
||||||
|
/* read-only kadmin server */
|
||||||
|
char *readonly_admin_server;
|
||||||
|
int readonly_kadmind_port;
|
||||||
} kadm5_config_params;
|
} kadm5_config_params;
|
||||||
|
|
||||||
typedef krb5_error_code kadm5_ret_t;
|
typedef krb5_error_code kadm5_ret_t;
|
||||||
|
@@ -58,7 +58,7 @@ kadm5_c_chpass_principal(void *server_handle,
|
|||||||
if (n_ks_tuple > 0)
|
if (n_ks_tuple > 0)
|
||||||
return KADM5_KS_TUPLE_NOSUPP;
|
return KADM5_KS_TUPLE_NOSUPP;
|
||||||
|
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 1 /* want_write */);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ kadm5_c_chpass_principal_with_key(void *server_handle,
|
|||||||
krb5_data reply;
|
krb5_data reply;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 1 /* want_write */);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@@ -64,7 +64,7 @@ kadm5_c_create_principal(void *server_handle,
|
|||||||
if (n_ks_tuple > 0)
|
if (n_ks_tuple > 0)
|
||||||
return KADM5_KS_TUPLE_NOSUPP;
|
return KADM5_KS_TUPLE_NOSUPP;
|
||||||
|
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 1 /* want_write */);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@@ -45,7 +45,7 @@ kadm5_c_delete_principal(void *server_handle, krb5_principal princ)
|
|||||||
int32_t tmp;
|
int32_t tmp;
|
||||||
krb5_data reply;
|
krb5_data reply;
|
||||||
|
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 1 /* want_write */);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@@ -41,6 +41,7 @@ kadm5_c_destroy(void *server_handle)
|
|||||||
kadm5_client_context *context = server_handle;
|
kadm5_client_context *context = server_handle;
|
||||||
|
|
||||||
free(context->realm);
|
free(context->realm);
|
||||||
|
free(context->readonly_admin_server);
|
||||||
free(context->admin_server);
|
free(context->admin_server);
|
||||||
rk_closesocket(context->sock);
|
rk_closesocket(context->sock);
|
||||||
if (context->client_name)
|
if (context->client_name)
|
||||||
|
@@ -48,7 +48,7 @@ kadm5_c_get_principal(void *server_handle,
|
|||||||
int32_t tmp;
|
int32_t tmp;
|
||||||
krb5_data reply;
|
krb5_data reply;
|
||||||
|
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 0 /* want_write */);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@@ -52,7 +52,7 @@ kadm5_c_get_principals(void *server_handle,
|
|||||||
*count = 0;
|
*count = 0;
|
||||||
*princs = NULL;
|
*princs = NULL;
|
||||||
|
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 0 /* want_write */);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@@ -89,13 +89,13 @@ _kadm5_c_init_context(kadm5_client_context **ctx,
|
|||||||
char *colon;
|
char *colon;
|
||||||
|
|
||||||
*ctx = malloc(sizeof(**ctx));
|
*ctx = malloc(sizeof(**ctx));
|
||||||
if(*ctx == NULL)
|
if (*ctx == NULL)
|
||||||
return krb5_enomem(context);
|
return krb5_enomem(context);
|
||||||
memset(*ctx, 0, sizeof(**ctx));
|
memset(*ctx, 0, sizeof(**ctx));
|
||||||
krb5_add_et_list (context, initialize_kadm5_error_table_r);
|
krb5_add_et_list(context, initialize_kadm5_error_table_r);
|
||||||
set_funcs(*ctx);
|
set_funcs(*ctx);
|
||||||
(*ctx)->context = context;
|
(*ctx)->context = context;
|
||||||
if(params->mask & KADM5_CONFIG_REALM) {
|
if (params->mask & KADM5_CONFIG_REALM) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
(*ctx)->realm = strdup(params->realm);
|
(*ctx)->realm = strdup(params->realm);
|
||||||
if ((*ctx)->realm == NULL)
|
if ((*ctx)->realm == NULL)
|
||||||
@@ -106,19 +106,24 @@ _kadm5_c_init_context(kadm5_client_context **ctx,
|
|||||||
free(*ctx);
|
free(*ctx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if(params->mask & KADM5_CONFIG_ADMIN_SERVER)
|
|
||||||
|
/*
|
||||||
|
* FIXME: If we have a hostlist, we should use the hostlist so that if we
|
||||||
|
* can't reach one server we try another.
|
||||||
|
*/
|
||||||
|
if (params->mask & KADM5_CONFIG_ADMIN_SERVER)
|
||||||
(*ctx)->admin_server = strdup(params->admin_server);
|
(*ctx)->admin_server = strdup(params->admin_server);
|
||||||
else {
|
else {
|
||||||
char **hostlist;
|
char **hostlist;
|
||||||
|
|
||||||
ret = krb5_get_krb_admin_hst (context, &(*ctx)->realm, &hostlist);
|
ret = krb5_get_krb_admin_hst(context, &(*ctx)->realm, &hostlist);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
free((*ctx)->realm);
|
free((*ctx)->realm);
|
||||||
free(*ctx);
|
free(*ctx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
(*ctx)->admin_server = strdup(*hostlist);
|
(*ctx)->admin_server = strdup(*hostlist);
|
||||||
krb5_free_krbhst (context, hostlist);
|
krb5_free_krbhst(context, hostlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*ctx)->admin_server == NULL) {
|
if ((*ctx)->admin_server == NULL) {
|
||||||
@@ -126,22 +131,64 @@ _kadm5_c_init_context(kadm5_client_context **ctx,
|
|||||||
free(*ctx);
|
free(*ctx);
|
||||||
return krb5_enomem(context);
|
return krb5_enomem(context);
|
||||||
}
|
}
|
||||||
colon = strchr ((*ctx)->admin_server, ':');
|
colon = strchr((*ctx)->admin_server, ':');
|
||||||
if (colon != NULL)
|
if (colon != NULL)
|
||||||
*colon++ = '\0';
|
*colon++ = '\0';
|
||||||
|
|
||||||
(*ctx)->kadmind_port = 0;
|
(*ctx)->kadmind_port = 0;
|
||||||
|
|
||||||
if(params->mask & KADM5_CONFIG_KADMIND_PORT)
|
if (params->mask & KADM5_CONFIG_KADMIND_PORT)
|
||||||
(*ctx)->kadmind_port = params->kadmind_port;
|
(*ctx)->kadmind_port = params->kadmind_port;
|
||||||
else if (colon != NULL) {
|
else if (colon != NULL) {
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
(*ctx)->kadmind_port = htons(strtol (colon, &end, 0));
|
(*ctx)->kadmind_port = htons(strtol(colon, &end, 0));
|
||||||
}
|
}
|
||||||
if ((*ctx)->kadmind_port == 0)
|
if ((*ctx)->kadmind_port == 0)
|
||||||
(*ctx)->kadmind_port = krb5_getportbyname (context, "kerberos-adm",
|
(*ctx)->kadmind_port = krb5_getportbyname(context, "kerberos-adm",
|
||||||
"tcp", 749);
|
"tcp", 749);
|
||||||
|
|
||||||
|
if (params->mask & KADM5_CONFIG_READONLY_ADMIN_SERVER) {
|
||||||
|
(*ctx)->readonly_admin_server = strdup(params->readonly_admin_server);
|
||||||
|
if ((*ctx)->readonly_admin_server == NULL) {
|
||||||
|
free((*ctx)->realm);
|
||||||
|
free(*ctx);
|
||||||
|
return krb5_enomem(context);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
char **hostlist;
|
||||||
|
|
||||||
|
ret = krb5_get_krb_readonly_admin_hst(context, &(*ctx)->realm,
|
||||||
|
&hostlist);
|
||||||
|
if (ret == 0) {
|
||||||
|
(*ctx)->readonly_admin_server = strdup(*hostlist);
|
||||||
|
krb5_free_krbhst(context, hostlist);
|
||||||
|
if ((*ctx)->readonly_admin_server == NULL) {
|
||||||
|
free((*ctx)->realm);
|
||||||
|
free(*ctx);
|
||||||
|
return krb5_enomem(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((*ctx)->readonly_admin_server) {
|
||||||
|
colon = strchr((*ctx)->readonly_admin_server, ':');
|
||||||
|
if (colon != NULL)
|
||||||
|
*colon++ = '\0';
|
||||||
|
|
||||||
|
} else {
|
||||||
|
colon = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*ctx)->readonly_kadmind_port = 0;
|
||||||
|
if (params->mask & KADM5_CONFIG_READONLY_KADMIN_PORT)
|
||||||
|
(*ctx)->readonly_kadmind_port = params->readonly_kadmind_port;
|
||||||
|
else if (colon != NULL) {
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
(*ctx)->readonly_kadmind_port = htons(strtol(colon, &end, 0));
|
||||||
|
}
|
||||||
|
if ((*ctx)->readonly_kadmind_port == 0)
|
||||||
|
(*ctx)->readonly_kadmind_port = (*ctx)->kadmind_port;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,10 +481,24 @@ kadm_connect(kadm5_client_context *ctx)
|
|||||||
struct addrinfo *ai, *a;
|
struct addrinfo *ai, *a;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
int error;
|
int error;
|
||||||
|
int kadmin_port = 0;
|
||||||
|
const char *admin_server = NULL;
|
||||||
char portstr[NI_MAXSERV];
|
char portstr[NI_MAXSERV];
|
||||||
char *hostname, *slash;
|
char *hostname, *slash;
|
||||||
char *service_name;
|
char *service_name;
|
||||||
krb5_context context = ctx->context;
|
krb5_context context = ctx->context;
|
||||||
|
int writable = 0;
|
||||||
|
|
||||||
|
if (!ctx->want_write) {
|
||||||
|
admin_server = ctx->readonly_admin_server;
|
||||||
|
kadmin_port = ctx->readonly_kadmind_port;
|
||||||
|
}
|
||||||
|
if (admin_server == NULL) {
|
||||||
|
admin_server = ctx->admin_server;
|
||||||
|
writable = 1;
|
||||||
|
}
|
||||||
|
if (kadmin_port < 1)
|
||||||
|
kadmin_port = ctx->kadmind_port;
|
||||||
|
|
||||||
memset (&hints, 0, sizeof(hints));
|
memset (&hints, 0, sizeof(hints));
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
@@ -563,14 +624,31 @@ kadm_connect(kadm5_client_context *ctx)
|
|||||||
krb5_cc_close(context, cc);
|
krb5_cc_close(context, cc);
|
||||||
ctx->sock = s;
|
ctx->sock = s;
|
||||||
|
|
||||||
|
ctx->connected_to_writable = !!writable;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
kadm5_ret_t
|
kadm5_ret_t
|
||||||
_kadm5_connect(void *handle)
|
_kadm5_connect(void *handle, int want_write)
|
||||||
{
|
{
|
||||||
kadm5_client_context *ctx = handle;
|
kadm5_client_context *ctx = handle;
|
||||||
if(ctx->sock == -1)
|
|
||||||
|
/*
|
||||||
|
* Reconnect? Note that we don't reconnect to read-only kadmin servers if
|
||||||
|
* we're already connected to a writable kadmin server because we sometimes
|
||||||
|
* get a principal record after writing it. We really need the application
|
||||||
|
* upstairs to tell us when to stop hogging writable kadmin servers.
|
||||||
|
*
|
||||||
|
* FIXME: Add an API for marking a kadm5_client_context as not needing to
|
||||||
|
* connect to writable kadmin servers.
|
||||||
|
*/
|
||||||
|
ctx->want_write = !!want_write;
|
||||||
|
if (ctx->sock != rk_INVALID_SOCKET && want_write &&
|
||||||
|
!ctx->connected_to_writable) {
|
||||||
|
rk_closesocket(ctx->sock);
|
||||||
|
ctx->sock = rk_INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
if (ctx->sock == rk_INVALID_SOCKET)
|
||||||
return kadm_connect(ctx);
|
return kadm_connect(ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -71,3 +71,4 @@ error_code BAD_SERVER_HOOK, "Bad KADM5 server hook"
|
|||||||
error_code SERVER_HOOK_NOT_FOUND, "Cannot find KADM5 server hook"
|
error_code SERVER_HOOK_NOT_FOUND, "Cannot find KADM5 server hook"
|
||||||
error_code OLD_SERVER_HOOK_VERSION, "KADM5 server hook is too old for this version of Heimdal"
|
error_code OLD_SERVER_HOOK_VERSION, "KADM5 server hook is too old for this version of Heimdal"
|
||||||
error_code NEW_SERVER_HOOK_VERSION, "KADM5 server hook is too new for this version of Heimdal"
|
error_code NEW_SERVER_HOOK_VERSION, "KADM5 server hook is too new for this version of Heimdal"
|
||||||
|
error_code READ_ONLY, "Database is read-only; try primary server"
|
||||||
|
@@ -47,7 +47,7 @@ kadm5_c_modify_principal(void *server_handle,
|
|||||||
int32_t tmp;
|
int32_t tmp;
|
||||||
krb5_data reply;
|
krb5_data reply;
|
||||||
|
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 1 /* want_write */);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@@ -137,6 +137,10 @@ typedef struct kadm5_client_context {
|
|||||||
const char *keytab;
|
const char *keytab;
|
||||||
krb5_ccache ccache;
|
krb5_ccache ccache;
|
||||||
kadm5_config_params *realm_params;
|
kadm5_config_params *realm_params;
|
||||||
|
char *readonly_admin_server;
|
||||||
|
int readonly_kadmind_port;
|
||||||
|
unsigned int want_write:1;
|
||||||
|
unsigned int connected_to_writable:1;
|
||||||
} kadm5_client_context;
|
} kadm5_client_context;
|
||||||
|
|
||||||
typedef struct kadm5_ad_context {
|
typedef struct kadm5_ad_context {
|
||||||
|
@@ -47,7 +47,7 @@ kadm5_c_get_privs(void *server_handle, uint32_t *privs)
|
|||||||
|
|
||||||
*privs = 0;
|
*privs = 0;
|
||||||
|
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 0 /* want_write */);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ kadm5_c_prune_principal(void *server_handle, krb5_principal princ, int kvno)
|
|||||||
krb5_data reply;
|
krb5_data reply;
|
||||||
|
|
||||||
krb5_data_zero(&reply);
|
krb5_data_zero(&reply);
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 1 /* want_write */);
|
||||||
if (ret == 0 && (sp = krb5_storage_from_mem(buf, sizeof(buf))) == NULL)
|
if (ret == 0 && (sp = krb5_storage_from_mem(buf, sizeof(buf))) == NULL)
|
||||||
ret = krb5_enomem(context->context);
|
ret = krb5_enomem(context->context);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
|
@@ -53,7 +53,7 @@ kadm5_c_randkey_principal(void *server_handle,
|
|||||||
krb5_data reply;
|
krb5_data reply;
|
||||||
krb5_keyblock *k;
|
krb5_keyblock *k;
|
||||||
|
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 1 /* want_write */);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@@ -47,7 +47,7 @@ kadm5_c_rename_principal(void *server_handle,
|
|||||||
int32_t tmp;
|
int32_t tmp;
|
||||||
krb5_data reply;
|
krb5_data reply;
|
||||||
|
|
||||||
ret = _kadm5_connect(server_handle);
|
ret = _kadm5_connect(server_handle, 1 /* want_write */);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@@ -833,11 +833,12 @@ typedef struct krb5_verify_opt {
|
|||||||
struct krb5_krbhst_data;
|
struct krb5_krbhst_data;
|
||||||
typedef struct krb5_krbhst_data *krb5_krbhst_handle;
|
typedef struct krb5_krbhst_data *krb5_krbhst_handle;
|
||||||
|
|
||||||
#define KRB5_KRBHST_KDC 1
|
#define KRB5_KRBHST_KDC 1
|
||||||
#define KRB5_KRBHST_ADMIN 2
|
#define KRB5_KRBHST_ADMIN 2
|
||||||
#define KRB5_KRBHST_CHANGEPW 3
|
#define KRB5_KRBHST_CHANGEPW 3
|
||||||
#define KRB5_KRBHST_KRB524 4
|
#define KRB5_KRBHST_KRB524 4
|
||||||
#define KRB5_KRBHST_KCA 5
|
#define KRB5_KRBHST_KCA 5
|
||||||
|
#define KRB5_KRBHST_READONLY_ADMIN 6
|
||||||
|
|
||||||
typedef struct krb5_krbhst_info {
|
typedef struct krb5_krbhst_info {
|
||||||
enum { KRB5_KRBHST_UDP,
|
enum { KRB5_KRBHST_UDP,
|
||||||
|
@@ -163,6 +163,8 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
|
|||||||
|
|
||||||
|
|
||||||
struct krb5_krbhst_data {
|
struct krb5_krbhst_data {
|
||||||
|
const char *config_param;
|
||||||
|
const char *srv_label;
|
||||||
char *realm;
|
char *realm;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int def_port;
|
int def_port;
|
||||||
@@ -739,7 +741,7 @@ kdc_get_next(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((kd->flags & KD_CONFIG) == 0) {
|
if((kd->flags & KD_CONFIG) == 0) {
|
||||||
config_get_hosts(context, kd, "kdc");
|
config_get_hosts(context, kd, kd->config_param);
|
||||||
kd->flags |= KD_CONFIG;
|
kd->flags |= KD_CONFIG;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -754,20 +756,20 @@ kdc_get_next(krb5_context context,
|
|||||||
|
|
||||||
if(context->srv_lookup) {
|
if(context->srv_lookup) {
|
||||||
if((kd->flags & KD_SRV_UDP) == 0 && (kd->flags & KD_LARGE_MSG) == 0) {
|
if((kd->flags & KD_SRV_UDP) == 0 && (kd->flags & KD_LARGE_MSG) == 0) {
|
||||||
srv_get_hosts(context, kd, "udp", "kerberos");
|
srv_get_hosts(context, kd, "udp", kd->srv_label);
|
||||||
kd->flags |= KD_SRV_UDP;
|
kd->flags |= KD_SRV_UDP;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((kd->flags & KD_SRV_TCP) == 0) {
|
if((kd->flags & KD_SRV_TCP) == 0) {
|
||||||
srv_get_hosts(context, kd, "tcp", "kerberos");
|
srv_get_hosts(context, kd, "tcp", kd->srv_label);
|
||||||
kd->flags |= KD_SRV_TCP;
|
kd->flags |= KD_SRV_TCP;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if((kd->flags & KD_SRV_HTTP) == 0) {
|
if((kd->flags & KD_SRV_HTTP) == 0) {
|
||||||
srv_get_hosts(context, kd, "http", "kerberos");
|
srv_get_hosts(context, kd, "http", kd->srv_label);
|
||||||
kd->flags |= KD_SRV_HTTP;
|
kd->flags |= KD_SRV_HTTP;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -804,7 +806,7 @@ admin_get_next(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((kd->flags & KD_CONFIG) == 0) {
|
if((kd->flags & KD_CONFIG) == 0) {
|
||||||
config_get_hosts(context, kd, "admin_server");
|
config_get_hosts(context, kd, kd->config_param);
|
||||||
kd->flags |= KD_CONFIG;
|
kd->flags |= KD_CONFIG;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -819,7 +821,7 @@ admin_get_next(krb5_context context,
|
|||||||
|
|
||||||
if(context->srv_lookup) {
|
if(context->srv_lookup) {
|
||||||
if((kd->flags & KD_SRV_TCP) == 0) {
|
if((kd->flags & KD_SRV_TCP) == 0) {
|
||||||
srv_get_hosts(context, kd, "tcp", "kerberos-adm");
|
srv_get_hosts(context, kd, "tcp", kd->srv_label);
|
||||||
kd->flags |= KD_SRV_TCP;
|
kd->flags |= KD_SRV_TCP;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -858,7 +860,7 @@ kpasswd_get_next(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((kd->flags & KD_CONFIG) == 0) {
|
if((kd->flags & KD_CONFIG) == 0) {
|
||||||
config_get_hosts(context, kd, "kpasswd_server");
|
config_get_hosts(context, kd, kd->config_param);
|
||||||
kd->flags |= KD_CONFIG;
|
kd->flags |= KD_CONFIG;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -873,13 +875,13 @@ kpasswd_get_next(krb5_context context,
|
|||||||
|
|
||||||
if(context->srv_lookup) {
|
if(context->srv_lookup) {
|
||||||
if((kd->flags & KD_SRV_UDP) == 0) {
|
if((kd->flags & KD_SRV_UDP) == 0) {
|
||||||
srv_get_hosts(context, kd, "udp", "kpasswd");
|
srv_get_hosts(context, kd, "udp", kd->srv_label);
|
||||||
kd->flags |= KD_SRV_UDP;
|
kd->flags |= KD_SRV_UDP;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if((kd->flags & KD_SRV_TCP) == 0) {
|
if((kd->flags & KD_SRV_TCP) == 0) {
|
||||||
srv_get_hosts(context, kd, "tcp", "kpasswd");
|
srv_get_hosts(context, kd, "tcp", kd->srv_label);
|
||||||
kd->flags |= KD_SRV_TCP;
|
kd->flags |= KD_SRV_TCP;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -921,6 +923,8 @@ krbhost_dealloc(void *ptr)
|
|||||||
|
|
||||||
static struct krb5_krbhst_data*
|
static struct krb5_krbhst_data*
|
||||||
common_init(krb5_context context,
|
common_init(krb5_context context,
|
||||||
|
const char *config_param,
|
||||||
|
const char *srv_label,
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *realm,
|
const char *realm,
|
||||||
int flags)
|
int flags)
|
||||||
@@ -935,6 +939,9 @@ common_init(krb5_context context,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kd->config_param = config_param;
|
||||||
|
kd->srv_label = srv_label;
|
||||||
|
|
||||||
_krb5_debug(context, 2, "Trying to find service %s for realm %s flags %x",
|
_krb5_debug(context, 2, "Trying to find service %s for realm %s flags %x",
|
||||||
service, realm, flags);
|
service, realm, flags);
|
||||||
|
|
||||||
@@ -972,6 +979,8 @@ krb5_krbhst_init_flags(krb5_context context,
|
|||||||
krb5_error_code (*next)(krb5_context, struct krb5_krbhst_data *,
|
krb5_error_code (*next)(krb5_context, struct krb5_krbhst_data *,
|
||||||
krb5_krbhst_info **);
|
krb5_krbhst_info **);
|
||||||
int def_port;
|
int def_port;
|
||||||
|
const char *config_param;
|
||||||
|
const char *srv_label;
|
||||||
const char *service;
|
const char *service;
|
||||||
|
|
||||||
*handle = NULL;
|
*handle = NULL;
|
||||||
@@ -979,19 +988,33 @@ krb5_krbhst_init_flags(krb5_context context,
|
|||||||
switch(type) {
|
switch(type) {
|
||||||
case KRB5_KRBHST_KDC:
|
case KRB5_KRBHST_KDC:
|
||||||
next = kdc_get_next;
|
next = kdc_get_next;
|
||||||
def_port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88));
|
def_port = ntohs(krb5_getportbyname(context, "kerberos", "udp", 88));
|
||||||
|
config_param = "kdc";
|
||||||
|
srv_label = "kerberos";
|
||||||
service = "kdc";
|
service = "kdc";
|
||||||
break;
|
break;
|
||||||
case KRB5_KRBHST_ADMIN:
|
case KRB5_KRBHST_ADMIN:
|
||||||
next = admin_get_next;
|
next = admin_get_next;
|
||||||
def_port = ntohs(krb5_getportbyname (context, "kerberos-adm",
|
def_port = ntohs(krb5_getportbyname(context, "kerberos-adm",
|
||||||
"tcp", 749));
|
"tcp", 749));
|
||||||
|
config_param = "admin_server";
|
||||||
|
srv_label = "kerberos-adm";
|
||||||
|
service = "admin";
|
||||||
|
break;
|
||||||
|
case KRB5_KRBHST_READONLY_ADMIN:
|
||||||
|
next = admin_get_next;
|
||||||
|
def_port = ntohs(krb5_getportbyname(context, "kerberos-adm",
|
||||||
|
"tcp", 749));
|
||||||
|
config_param = "readonly_admin_server";
|
||||||
|
srv_label = "kerberos-adm-readonly";
|
||||||
service = "admin";
|
service = "admin";
|
||||||
break;
|
break;
|
||||||
case KRB5_KRBHST_CHANGEPW:
|
case KRB5_KRBHST_CHANGEPW:
|
||||||
next = kpasswd_get_next;
|
next = kpasswd_get_next;
|
||||||
def_port = ntohs(krb5_getportbyname (context, "kpasswd", "udp",
|
def_port = ntohs(krb5_getportbyname(context, "kpasswd", "udp",
|
||||||
KPASSWD_PORT));
|
KPASSWD_PORT));
|
||||||
|
config_param = "kpasswd_server";
|
||||||
|
srv_label = "kpasswd";
|
||||||
service = "change_password";
|
service = "change_password";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -999,7 +1022,8 @@ krb5_krbhst_init_flags(krb5_context context,
|
|||||||
N_("unknown krbhst type (%u)", ""), type);
|
N_("unknown krbhst type (%u)", ""), type);
|
||||||
return ENOTTY;
|
return ENOTTY;
|
||||||
}
|
}
|
||||||
if((kd = common_init(context, service, realm, flags)) == NULL)
|
if((kd = common_init(context, config_param, srv_label, service, realm,
|
||||||
|
flags)) == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
kd->get_next = next;
|
kd->get_next = next;
|
||||||
kd->def_port = def_port;
|
kd->def_port = def_port;
|
||||||
@@ -1118,17 +1142,29 @@ gethostlist(krb5_context context, const char *realm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* return an malloced list of kadmin-hosts for `realm' in `hostlist'
|
* Return a malloced list of kadmin-hosts for `realm' in `hostlist'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||||
krb5_get_krb_admin_hst (krb5_context context,
|
krb5_get_krb_admin_hst(krb5_context context,
|
||||||
const krb5_realm *realm,
|
const krb5_realm *realm,
|
||||||
char ***hostlist)
|
char ***hostlist)
|
||||||
{
|
{
|
||||||
return gethostlist(context, *realm, KRB5_KRBHST_ADMIN, hostlist);
|
return gethostlist(context, *realm, KRB5_KRBHST_ADMIN, hostlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a malloced list of writable kadmin-hosts for `realm' in `hostlist'
|
||||||
|
*/
|
||||||
|
|
||||||
|
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||||
|
krb5_get_krb_readonly_admin_hst(krb5_context context,
|
||||||
|
const krb5_realm *realm,
|
||||||
|
char ***hostlist)
|
||||||
|
{
|
||||||
|
return gethostlist(context, *realm, KRB5_KRBHST_READONLY_ADMIN, hostlist);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* return an malloced list of changepw-hosts for `realm' in `hostlist'
|
* return an malloced list of changepw-hosts for `realm' in `hostlist'
|
||||||
*/
|
*/
|
||||||
|
@@ -378,6 +378,7 @@ EXPORTS
|
|||||||
krb5_get_krb524hst
|
krb5_get_krb524hst
|
||||||
krb5_get_krb_admin_hst
|
krb5_get_krb_admin_hst
|
||||||
krb5_get_krb_changepw_hst
|
krb5_get_krb_changepw_hst
|
||||||
|
krb5_get_krb_readonly_admin_hst
|
||||||
krb5_get_krbhst
|
krb5_get_krbhst
|
||||||
krb5_get_max_time_skew
|
krb5_get_max_time_skew
|
||||||
krb5_get_pw_salt
|
krb5_get_pw_salt
|
||||||
|
@@ -374,6 +374,7 @@ HEIMDAL_KRB5_2.0 {
|
|||||||
krb5_get_krb524hst;
|
krb5_get_krb524hst;
|
||||||
krb5_get_krb_admin_hst;
|
krb5_get_krb_admin_hst;
|
||||||
krb5_get_krb_changepw_hst;
|
krb5_get_krb_changepw_hst;
|
||||||
|
krb5_get_krb_readonly_admin_hst;
|
||||||
krb5_get_krbhst;
|
krb5_get_krbhst;
|
||||||
krb5_get_max_time_skew;
|
krb5_get_max_time_skew;
|
||||||
krb5_get_pw_salt;
|
krb5_get_pw_salt;
|
||||||
|
Reference in New Issue
Block a user