Beispiel #1
0
int
iprop_replay(struct replay_options *opt, int argc, char **argv)
{
    kadm5_server_context *server_context;
    krb5_error_code ret;

    server_context = get_kadmin_context(opt->config_file_string,
					opt->realm_string);

    ret = server_context->db->hdb_open(context,
				       server_context->db,
				       O_RDWR | O_CREAT, 0600);
    if (ret)
	krb5_err (context, 1, ret, "db->open");

    ret = kadm5_log_init (server_context);
    if (ret)
	krb5_err (context, 1, ret, "kadm5_log_init");

    ret = kadm5_log_foreach (server_context, apply_entry, opt);
    if(ret)
	krb5_warn(context, ret, "kadm5_log_foreach");
    ret = kadm5_log_end (server_context);
    if (ret)
	krb5_warn(context, ret, "kadm5_log_end");
    ret = server_context->db->hdb_close (context, server_context->db);
    if (ret)
	krb5_err (context, 1, ret, "db->close");

    return 0;
}
Beispiel #2
0
static int
iterate (krb5_context context,
	 const char *database_name,
	 HDB *db,
	 int type,
	 struct prop_data *pd)
{
    int ret;

    switch(type) {
    case HPROP_MIT_DUMP:
	ret = hdb_mit_dump(context, database_name, v5_prop, pd);
	if (ret)
	    krb5_warn(context, ret, "mit_prop_dump");
	break;
    case HPROP_HEIMDAL:
	ret = hdb_foreach(context, db, HDB_F_DECRYPT, v5_prop, pd);
	if(ret)
	    krb5_warn(context, ret, "hdb_foreach");
	break;
    default:
	krb5_errx(context, 1, "unknown prop type: %d", type);
    }
    return ret;
}
Beispiel #3
0
static int
connect_to_master (krb5_context context, const char *master,
		   const char *port_str)
{
    char port[NI_MAXSERV];
    struct addrinfo *ai, *a;
    struct addrinfo hints;
    int error;
    int one = 1;
    int s = -1;

    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;

    if (port_str == NULL) {
	snprintf(port, sizeof(port), "%u", IPROP_PORT);
	port_str = port;
    }

    error = getaddrinfo(master, port_str, &hints, &ai);
    if (error) {
	krb5_warnx(context, "Failed to get address of to %s: %s",
		   master, gai_strerror(error));
	return -1;
    }

    for (a = ai; a != NULL; a = a->ai_next) {
	char node[NI_MAXHOST];
	error = getnameinfo(a->ai_addr, a->ai_addrlen,
			    node, sizeof(node), NULL, 0, NI_NUMERICHOST);
	if (error)
	    strlcpy(node, "[unknown-addr]", sizeof(node));

	s = socket(a->ai_family, a->ai_socktype, a->ai_protocol);
	if (s < 0)
	    continue;
	if (connect(s, a->ai_addr, a->ai_addrlen) < 0) {
	    krb5_warn(context, errno, "connection failed to %s[%s]",
		      master, node);
	    close(s);
	    continue;
	}
	krb5_warnx(context, "connection successful "
		   "to master: %s[%s]", master, node);
	break;
    }
    freeaddrinfo(ai);

    if (a == NULL)
	return -1;

    if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)) < 0)
        krb5_warn(context, errno, "setsockopt(SO_KEEPALIVE) failed");

    return s;
}
Beispiel #4
0
int
kt_remove(struct remove_options *opt, int argc, char **argv)
{
    krb5_error_code ret = 0;
    krb5_keytab_entry entry;
    krb5_keytab keytab;
    krb5_principal principal = NULL;
    krb5_enctype enctype = 0;

    if(opt->principal_string) {
	ret = krb5_parse_name(context, opt->principal_string, &principal);
	if(ret) {
	    krb5_warn(context, ret, "%s", opt->principal_string);
	    return 1;
	}
    }
    if(opt->enctype_string) {
	ret = krb5_string_to_enctype(context, opt->enctype_string, &enctype);
	if(ret) {
	    int t;
	    if(sscanf(opt->enctype_string, "%d", &t) == 1)
		enctype = t;
	    else {
		krb5_warn(context, ret, "%s", opt->enctype_string);
		if(principal)
		    krb5_free_principal(context, principal);
		return 1;
	    }
	}
    }
    if (!principal && !enctype && !opt->kvno_integer) {
	krb5_warnx(context,
		   "You must give at least one of "
		   "principal, enctype or kvno.");
	ret = EINVAL;
	goto out;
    }

    if((keytab = ktutil_open_keytab()) == NULL) {
	ret = 1;
	goto out;
    }

    entry.principal = principal;
    entry.keyblock.keytype = enctype;
    entry.vno = opt->kvno_integer;
    ret = krb5_kt_remove_entry(context, keytab, &entry);
    krb5_kt_close(context, keytab);
    if(ret)
	krb5_warn(context, ret, "remove");
 out:
    if(principal)
	krb5_free_principal(context, principal);
    return ret != 0;
}
Beispiel #5
0
/*
 * Loop over all principals matching exp.  If any of calls to `func'
 * failes, the first error is returned when all principals are
 * processed.
 */
int
foreach_principal(const char *exp_str,
		  int (*func)(krb5_principal, void*),
		  const char *funcname,
		  void *data)
{
    char **princs = NULL;
    int num_princs = 0;
    int i;
    krb5_error_code saved_ret = 0, ret = 0;
    krb5_principal princ_ent;
    int is_expr;

    /* if this isn't an expression, there is no point in wading
       through the whole database looking for matches */
    is_expr = is_expression(exp_str);
    if(is_expr)
	ret = kadm5_get_principals(kadm_handle, exp_str, &princs, &num_princs);
    if(!is_expr || ret == KADM5_AUTH_LIST) {
	/* we might be able to perform the requested opreration even
           if we're not allowed to list principals */
	num_princs = 1;
	princs = malloc(sizeof(*princs));
	if(princs == NULL)
	    return ENOMEM;
	princs[0] = strdup(exp_str);
	if(princs[0] == NULL){
	    free(princs);
	    return ENOMEM;
	}
    } else if(ret) {
	krb5_warn(context, ret, "kadm5_get_principals");
	return ret;
    }
    for(i = 0; i < num_princs; i++) {
	ret = krb5_parse_name(context, princs[i], &princ_ent);
	if(ret){
	    krb5_warn(context, ret, "krb5_parse_name(%s)", princs[i]);
	    continue;
	}
	ret = (*func)(princ_ent, data);
	if(ret) {
	    krb5_clear_error_message(context);
	    krb5_warn(context, ret, "%s %s", funcname, princs[i]);
	    if (saved_ret == 0)
		saved_ret = ret;
	}
	krb5_free_principal(context, princ_ent);
    }
    if (ret == 0 && saved_ret != 0)
	ret = saved_ret;
    kadm5_free_name_list(kadm_handle, princs, &num_princs);
    return ret;
}
Beispiel #6
0
int
dump(struct dump_options *opt, int argc, char **argv)
{
    krb5_error_code ret;
    FILE *f;
    struct hdb_print_entry_arg parg;
    HDB *db = NULL;

    if (!local_flag) {
	krb5_warnx(context, "dump is only available in local (-l) mode");
	return 0;
    }

    db = _kadm5_s_get_db(kadm_handle);

    if (argc == 0)
	f = stdout;
    else
	f = fopen(argv[0], "w");

    if (f == NULL) {
	krb5_warn(context, errno, "open: %s", argv[0]);
	goto out;
    }
    ret = db->hdb_open(context, db, O_RDONLY, 0600);
    if (ret) {
	krb5_warn(context, ret, "hdb_open");
	goto out;
    }

    if (!opt->format_string || strcmp(opt->format_string, "Heimdal") == 0) {
        parg.fmt = HDB_DUMP_HEIMDAL;
    } else if (opt->format_string && strcmp(opt->format_string, "MIT") == 0) {
        parg.fmt = HDB_DUMP_MIT;
        fprintf(f, "kdb5_util load_dump version 5\n"); /* 5||6, either way */
    } else {
        krb5_errx(context, 1, "Supported dump formats: Heimdal and MIT");
    }
    parg.out = f;
    hdb_foreach(context, db, opt->decrypt_flag ? HDB_F_DECRYPT : 0,
		hdb_print_entry, &parg);

    db->hdb_close(context, db);
out:
    if(f && f != stdout)
	fclose(f);
    return 0;
}
Beispiel #7
0
int
ext_keytab(struct ext_keytab_options *opt, int argc, char **argv)
{
    krb5_error_code ret;
    int i;
    struct ext_keytab_data data;

    if (opt->keytab_string == NULL)
	ret = krb5_kt_default(context, &data.keytab);
    else
	ret = krb5_kt_resolve(context, opt->keytab_string, &data.keytab);

    if(ret){
	krb5_warn(context, ret, "krb5_kt_resolve");
	return 1;
    }

    for(i = 0; i < argc; i++) {
	ret = foreach_principal(argv[i], do_ext_keytab, "ext", &data);
	if (ret)
	    break;
    }

    krb5_kt_close(context, data.keytab);

    return ret != 0;
}
Beispiel #8
0
static int
send_are_you_there (krb5_context context, slave *s)
{
    krb5_storage *sp;
    krb5_data data;
    char buf[4];
    int ret;

    if (s->flags & (SLAVE_F_DEAD|SLAVE_F_AYT))
	return 0;

    s->flags |= SLAVE_F_AYT;

    data.data = buf;
    data.length = 4;

    sp = krb5_storage_from_mem (buf, 4);
    if (sp == NULL) {
	krb5_warnx (context, "are_you_there: krb5_data_alloc");
	slave_dead(s);
	return 1;
    }
    krb5_store_int32 (sp, ARE_YOU_THERE);
    krb5_storage_free (sp);

    ret = krb5_write_priv_message(context, s->ac, &s->fd, &data);

    if (ret) {
	krb5_warn (context, ret, "are_you_there: krb5_write_priv_message");
	slave_dead(s);
	return 1;
    }

    return 0;
}
Beispiel #9
0
static krb5_error_code
ihave(krb5_context context, krb5_auth_context auth_context,
      int fd, uint32_t version)
{
    int ret;
    u_char buf[8];
    krb5_storage *sp;
    krb5_data data;

    sp = krb5_storage_from_mem(buf, 8);
    ret = krb5_store_uint32(sp, I_HAVE);
    if (ret == 0)
        ret = krb5_store_uint32(sp, version);
    krb5_storage_free(sp);
    data.length = 8;
    data.data   = buf;

    if (ret == 0) {
        if (verbose)
            krb5_warnx(context, "telling master we are at %u", version);

        ret = krb5_write_priv_message(context, auth_context, &fd, &data);
        if (ret)
            krb5_warn(context, ret, "krb5_write_message");
    }
    return ret;
}
Beispiel #10
0
static void
apply_entry(kadm5_server_context *server_context,
	    uint32_t ver,
	    time_t timestamp,
	    enum kadm_ops op,
	    uint32_t len,
	    krb5_storage *sp,
	    void *ctx)
{
    struct replay_options *opt = ctx;
    krb5_error_code ret;

    if((opt->start_version_integer != -1 && ver < (uint32_t)opt->start_version_integer) ||
       (opt->end_version_integer != -1 && ver > (uint32_t)opt->end_version_integer)) {
	/* XXX skip this entry */
	krb5_storage_seek(sp, len, SEEK_CUR);
	return;
    }
    printf ("ver %u... ", ver);
    fflush (stdout);

    ret = kadm5_log_replay (server_context,
			    op, ver, len, sp);
    if (ret)
	krb5_warn (server_context->context, ret, "kadm5_log_replay");

    printf ("done\n");
}
Beispiel #11
0
int
last_version(struct last_version_options *opt, int argc, char **argv)
{
    kadm5_server_context *server_context;
    krb5_error_code ret;
    uint32_t version;

    server_context = get_kadmin_context(opt->config_file_string,
					opt->realm_string);

    ret = kadm5_log_init (server_context);
    if (ret)
	krb5_err (context, 1, ret, "kadm5_log_init");

    ret = kadm5_log_get_version (server_context, &version);
    if (ret)
	krb5_err (context, 1, ret, "kadm5_log_get_version");

    ret = kadm5_log_end (server_context);
    if (ret)
	krb5_warn(context, ret, "kadm5_log_end");

    printf("version: %lu\n", (unsigned long)version);

    return 0;
}
Beispiel #12
0
int
add_new_key(struct add_options *opt, int argc, char **argv)
{
    krb5_error_code ret = 0;
    int i;
    int num;
    krb5_key_data key_data[3];
    krb5_key_data *kdp = NULL;

    num = 0;
    if (opt->random_key_flag)
	++num;
    if (opt->random_password_flag)
	++num;
    if (opt->password_string)
	++num;
    if (opt->key_string)
	++num;

    if (num > 1) {
	fprintf (stderr, "give only one of "
		"--random-key, --random-password, --password, --key\n");
	return 1;
    }

    if (opt->key_string) {
	const char *error;

	if (parse_des_key (opt->key_string, key_data, &error)) {
	    fprintf (stderr, "failed parsing key \"%s\": %s\n",
		     opt->key_string, error);
	    return 1;
	}
	kdp = key_data;
    }

    for(i = 0; i < argc; i++) {
	ret = add_one_principal (argv[i],
				 opt->random_key_flag,
				 opt->random_password_flag,
				 opt->use_defaults_flag,
				 opt->password_string,
				 opt->policy_string,
				 kdp,
				 opt->max_ticket_life_string,
				 opt->max_renewable_life_string,
				 opt->attributes_string,
				 opt->expiration_time_string,
				 opt->pw_expiration_time_string);
	if (ret) {
	    krb5_warn (context, ret, "adding %s", argv[i]);
	    break;
	}
    }
    if (kdp) {
	int16_t dummy = 3;
	kadm5_free_key_data (kadm_handle, &dummy, key_data);
    }
    return ret != 0;
}
Beispiel #13
0
static int
krb_enc(krb5_context context,
	krb5_crypto crypto,
	unsigned usage,
	krb5_data *cipher,
	krb5_data *clear)
{
    krb5_data decrypt;
    krb5_error_code ret;

    krb5_data_zero(&decrypt);

    ret = krb5_decrypt(context,
		       crypto,
		       usage,
		       cipher->data,
		       cipher->length,
		       &decrypt);

    if (ret) {
	krb5_warn(context, ret, "krb5_decrypt");
	return ret;
    }

    if (decrypt.length != clear->length ||
	memcmp(decrypt.data, clear->data, decrypt.length) != 0) {
	krb5_warnx(context, "clear text not same");
	return EINVAL;
    }

    krb5_data_free(&decrypt);

    return 0;
}
Beispiel #14
0
static int
random_to_key(krb5_context context)
{
    krb5_error_code ret;
    krb5_keyblock key;

    ret = krb5_random_to_key(context,
			     ETYPE_DES3_CBC_SHA1,
			     "\x21\x39\x04\x58\x6A\xBD\x7F"
			     "\x21\x39\x04\x58\x6A\xBD\x7F"
			     "\x21\x39\x04\x58\x6A\xBD\x7F",
			     21,
			     &key);
    if (ret){
	krb5_warn(context, ret, "random_to_key");
	return 1;
    }
    if (key.keyvalue.length != 24)
	return 1;

    if (memcmp(key.keyvalue.data,
	       "\x20\x38\x04\x58\x6b\xbc\x7f\xc7"
	       "\x20\x38\x04\x58\x6b\xbc\x7f\xc7"
	       "\x20\x38\x04\x58\x6b\xbc\x7f\xc7",
	       24) != 0)
	return 1;

    krb5_free_keyblock_contents(context, &key);

    return 0;
}
Beispiel #15
0
kadm5_ret_t
kadm5_s_get_principals(void *server_handle,
		       const char *expression,
		       char ***princs,
		       int *count)
{
    struct foreach_data d;
    kadm5_server_context *context = server_handle;
    kadm5_ret_t ret;
    ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0);
    if(ret) {
	krb5_warn(context->context, ret, "opening database");
	return ret;
    }
    d.exp = expression;
    {
	krb5_realm r;
	krb5_get_default_realm(context->context, &r);
	asprintf(&d.exp2, "%s@%s", expression, r);
	free(r);
    }
    d.princs = NULL;
    d.count = 0;
    ret = hdb_foreach(context->context, context->db, HDB_F_ADMIN_DATA, foreach, &d);
    context->db->hdb_close(context->context, context->db);
    if(ret == 0)
	ret = add_princ(&d, NULL);
    if(ret == 0){
	*princs = d.princs;
	*count = d.count - 1;
    }else
	kadm5_free_name_list(context, d.princs, &d.count);
    free(d.exp2);
    return _kadm5_error_code(ret);
}
Beispiel #16
0
static krb5_error_code copy_one_entry(krb5_context context, 
				      krb5_keytab src_keytab, krb5_keytab dst_keytab, krb5_keytab_entry entry) 
{
    krb5_error_code ret;
    krb5_keytab_entry dummy;

    char *name_str;
    char *etype_str;
    ret = krb5_unparse_name (context, entry.principal, &name_str);
    if(ret) {
	krb5_set_error_message(context, ret, "krb5_unparse_name");
	name_str = NULL; /* XXX */
	return ret;
    }
    ret = krb5_enctype_to_string(context, entry.keyblock.keytype, &etype_str);
    if(ret) {
	krb5_set_error_message(context, ret, "krb5_enctype_to_string");
	etype_str = NULL; /* XXX */
	return ret;
    }
    ret = krb5_kt_get_entry(context, dst_keytab,
			    entry.principal,
			    entry.vno,
			    entry.keyblock.keytype,
			    &dummy);
    if(ret == 0) {
	/* this entry is already in the new keytab, so no need to
	   copy it; if the keyblocks are not the same, something
	   is weird, so complain about that */
	if(!compare_keyblock(&entry.keyblock, &dummy.keyblock)) {
		krb5_warn(context, 0, "entry with different keyvalue "
			  "already exists for %s, keytype %s, kvno %d",
			  name_str, etype_str, entry.vno);
	}
	krb5_kt_free_entry(context, &dummy);
	krb5_kt_free_entry (context, &entry);
	free(name_str);
	free(etype_str);
	return ret;
    } else if(ret != KRB5_KT_NOTFOUND) {
	krb5_set_error_message (context, ret, "fetching %s/%s/%u",
				name_str, etype_str, entry.vno);
	krb5_kt_free_entry (context, &entry);
	free(name_str);
	free(etype_str);
	return ret;
    } 
    ret = krb5_kt_add_entry (context, dst_keytab, &entry);
    krb5_kt_free_entry (context, &entry);
    if (ret) {
	krb5_set_error_message (context, ret, "adding %s/%s/%u",
				name_str, etype_str, entry.vno);
	free(name_str);
	free(etype_str);
	return ret;
    }
    free(name_str);
    free(etype_str);
    return ret;
}
Beispiel #17
0
static int
spawn_child(krb5_context contextp, int *socks,
	    unsigned int num_socks, int this_sock)
{
    int e;
    size_t i;
    struct sockaddr_storage __ss;
    struct sockaddr *sa = (struct sockaddr *)&__ss;
    socklen_t sa_size = sizeof(__ss);
    krb5_socket_t s;
    pid_t pid;
    krb5_address addr;
    char buf[128];
    size_t buf_len;

    s = accept(socks[this_sock], sa, &sa_size);
    if(rk_IS_BAD_SOCKET(s)) {
	krb5_warn(contextp, rk_SOCK_ERRNO, "accept");
	return 1;
    }
    e = krb5_sockaddr2address(contextp, sa, &addr);
    if(e)
	krb5_warn(contextp, e, "krb5_sockaddr2address");
    else {
	e = krb5_print_address (&addr, buf, sizeof(buf),
				&buf_len);
	if(e)
	    krb5_warn(contextp, e, "krb5_print_address");
	else
	    krb5_warnx(contextp, "connection from %s", buf);
	krb5_free_address(contextp, &addr);
    }

    pid = fork();
    if(pid == 0) {
	for(i = 0; i < num_socks; i++)
	    rk_closesocket(socks[i]);
	dup2(s, STDIN_FILENO);
	dup2(s, STDOUT_FILENO);
	if(s != STDIN_FILENO && s != STDOUT_FILENO)
	    rk_closesocket(s);
	return 0;
    } else {
	rk_closesocket(s);
    }
    return 1;
}
Beispiel #18
0
static krb5_error_code
copy_configs(krb5_context context,
	     krb5_ccache dst,
	     krb5_ccache src,
	     krb5_principal start_ticket_server)
{
    krb5_error_code ret;
    const char *cfg_names[] = {"realm-config", "FriendlyName", NULL};
    const char *cfg_names_w_pname[] = {"fast_avail", NULL};
    krb5_data cfg_data;
    size_t i;

    for (i = 0; cfg_names[i]; i++) {
	ret = krb5_cc_get_config(context, src, NULL, cfg_names[i], &cfg_data);
	if (ret == KRB5_CC_NOTFOUND || ret == KRB5_CC_END) {
	    continue;
	} else if (ret) {
	    krb5_warn(context, ret, "krb5_cc_get_config");
	    return ret;
	}
	ret = krb5_cc_set_config(context, dst, NULL, cfg_names[i], &cfg_data);
	if (ret)
	    krb5_warn(context, ret, "krb5_cc_set_config");
    }
    for (i = 0; start_ticket_server && cfg_names_w_pname[i]; i++) {
	ret = krb5_cc_get_config(context, src, start_ticket_server,
				 cfg_names_w_pname[i], &cfg_data);
	if (ret == KRB5_CC_NOTFOUND || ret == KRB5_CC_END) {
	    continue;
	} else if (ret) {
	    krb5_warn(context, ret, "krb5_cc_get_config");
	    return ret;
	}
	ret = krb5_cc_set_config(context, dst, start_ticket_server,
				 cfg_names_w_pname[i], &cfg_data);
	if (ret && ret != KRB5_CC_NOTFOUND)
	    krb5_warn(context, ret, "krb5_cc_set_config");
    }
    /*
     * We don't copy cc configs for any other principals though (mostly
     * those are per-target time offsets and the like, so it's bad to
     * lose them, but hardly the end of the world, and as they may not
     * expire anyways, it's good to let them go).
     */
    return 0;
}
Beispiel #19
0
static int
change_password(krb5_context context,
		krb5_principal principal,
		krb5_ccache id)
{
    krb5_data result_code_string, result_string;
    int result_code;
    krb5_error_code ret;
    char pwbuf[BUFSIZ];
    char *msg, *name;
    int aret;

    krb5_data_zero (&result_code_string);
    krb5_data_zero (&result_string);

    name = msg = NULL;
    if (principal == NULL)
	aret = asprintf(&msg, "New password: "******"krb5_unparse_name");

	aret = asprintf(&msg, "New password for %s: ", name);
    }

    if (aret == -1 || msg == NULL)
	krb5_errx (context, 1, "out of memory");

    ret = UI_UTIL_read_pw_string (pwbuf, sizeof(pwbuf), msg, 1);
    free(msg);
    if (name)
	free(name);
    if (ret != 0) {
	return 1;
    }

    ret = krb5_set_password_using_ccache (context, id, pwbuf,
					  principal,
					  &result_code,
					  &result_code_string,
					  &result_string);
    if (ret) {
	krb5_warn (context, ret, "krb5_set_password_using_ccache");
	return 1;
    }

    printf ("%s%s%.*s\n", krb5_passwd_result_to_string(context, result_code),
	    result_string.length > 0 ? " : " : "",
	    (int)result_string.length,
	    result_string.length > 0 ? (char *)result_string.data : "");

    krb5_data_free (&result_code_string);
    krb5_data_free (&result_string);

    return ret != 0;
}
Beispiel #20
0
static time_t
ticket_lifetime(krb5_context context, krb5_ccache cache, krb5_principal client,
		const char *server, time_t *renew)
{
    krb5_creds in_cred, *cred;
    krb5_error_code ret;
    time_t timeout;
    time_t curtime;

    memset(&in_cred, 0, sizeof(in_cred));

    ret = krb5_cc_get_principal(context, cache, &in_cred.client);
    if (ret) {
	krb5_warn(context, ret, "krb5_cc_get_principal");
	return 0;
    }
    ret = get_server(context, in_cred.client, server, &in_cred.server);
    if (ret) {
	krb5_free_principal(context, in_cred.client);
	krb5_warn(context, ret, "get_server");
	return 0;
    }

    ret = krb5_get_credentials(context, KRB5_GC_CACHED,
			       cache, &in_cred, &cred);
    krb5_free_principal(context, in_cred.client);
    krb5_free_principal(context, in_cred.server);
    if (ret) {
	krb5_warn(context, ret, "krb5_get_credentials");
	return 0;
    }
    curtime = time(NULL);
    timeout = cred->times.endtime - curtime;
    if (timeout < 0)
	timeout = 0;
    if (renew) {
	*renew = cred->times.renew_till - curtime;
	if (*renew < 0)
	    *renew = 0;
    }
    krb5_free_creds(context, cred);
    return timeout;
}
Beispiel #21
0
static krb5_error_code
do_524init(krb5_context context, krb5_ccache ccache,
	   krb5_creds *creds, const char *server)
{
    krb5_error_code ret;

    struct credentials c;
    krb5_creds in_creds, *real_creds;

    if(creds != NULL)
	real_creds = creds;
    else {
	krb5_principal client;
	krb5_cc_get_principal(context, ccache, &client);
	memset(&in_creds, 0, sizeof(in_creds));
	ret = get_server(context, client, server, &in_creds.server);
	if(ret) {
	    krb5_free_principal(context, client);
	    return ret;
	}
	in_creds.client = client;
	ret = krb5_get_credentials(context, 0, ccache, &in_creds, &real_creds);
	krb5_free_principal(context, client);
	krb5_free_principal(context, in_creds.server);
	if(ret)
	    return ret;
    }
    ret = krb524_convert_creds_kdc_ccache(context, ccache, real_creds, &c);
    if(ret)
	krb5_warn(context, ret, "converting creds");
    else {
	krb5_error_code tret = _krb5_krb_tf_setup(context, &c, NULL, 0);
	if(tret)
	    krb5_warn(context, tret, "saving v4 creds");
    }

    if(creds == NULL)
	krb5_free_creds(context, real_creds);
    memset(&c, 0, sizeof(c));

    return ret;
}
Beispiel #22
0
static int
wait_for_connection(krb5_context context,
		    int *socks, int num_socks)
{
    int i, e;
    fd_set orig_read_set, read_set;
    int max_fd = -1;
    
    FD_ZERO(&orig_read_set);
    
    for(i = 0; i < num_socks; i++) {
	if (socks[i] >= FD_SETSIZE)
	    errx (1, "fd too large");
	FD_SET(socks[i], &orig_read_set);
	max_fd = max(max_fd, socks[i]);
    }
    
    pgrp = getpid();

    if(setpgid(0, pgrp) < 0)
	err(1, "setpgid");

    signal(SIGTERM, terminate);
    signal(SIGINT, terminate);
    signal(SIGCHLD, sigchld);

    while (term_flag == 0) {
	read_set = orig_read_set;
	e = select(max_fd + 1, &read_set, NULL, NULL, NULL);
	if(e < 0) {
	    if(errno != EINTR)
		krb5_warn(context, errno, "select");
	} else if(e == 0)
	    krb5_warnx(context, "select returned 0");
	else {
	    for(i = 0; i < num_socks; i++) {
		if(FD_ISSET(socks[i], &read_set))
		    if(spawn_child(context, socks, num_socks, i) == 0)
			return 0;
	    }
	}
    }
    signal(SIGCHLD, SIG_IGN);
    while(1) {
	int status;
	pid_t pid;
	pid = waitpid(-1, &status, 0);
	if(pid == -1 && errno == ECHILD)
	    break;
    }
    exit(0);
}
Beispiel #23
0
static void
send_reply (int s,
            struct sockaddr *sa,
            int sa_size,
            krb5_data *ap_rep,
            krb5_data *rest)
{
    struct msghdr msghdr;
    struct iovec iov[3];
    uint16_t len, ap_rep_len;
    u_char header[6];
    u_char *p;

    if (ap_rep)
        ap_rep_len = ap_rep->length;
    else
        ap_rep_len = 0;

    len = 6 + ap_rep_len + rest->length;
    p = header;
    *p++ = (len >> 8) & 0xFF;
    *p++ = (len >> 0) & 0xFF;
    *p++ = 0;
    *p++ = 1;
    *p++ = (ap_rep_len >> 8) & 0xFF;
    *p++ = (ap_rep_len >> 0) & 0xFF;

    memset (&msghdr, 0, sizeof(msghdr));
    msghdr.msg_name       = (void *)sa;
    msghdr.msg_namelen    = sa_size;
    msghdr.msg_iov        = iov;
    msghdr.msg_iovlen     = sizeof(iov)/sizeof(*iov);
#if 0
    msghdr.msg_control    = NULL;
    msghdr.msg_controllen = 0;
#endif

    iov[0].iov_base       = (char *)header;
    iov[0].iov_len        = 6;
    if (ap_rep_len) {
        iov[1].iov_base   = ap_rep->data;
        iov[1].iov_len    = ap_rep->length;
    } else {
        iov[1].iov_base   = NULL;
        iov[1].iov_len    = 0;
    }
    iov[2].iov_base       = rest->data;
    iov[2].iov_len        = rest->length;

    if (sendmsg (s, &msghdr, 0) < 0)
        krb5_warn (context, errno, "sendmsg");
}
Beispiel #24
0
static void
wait_for_connection(krb5_context context,
		    krb5_socket_t *socks, unsigned int num_socks)
{
    unsigned int i;
    int e;
    fd_set orig_read_set, read_set;
    int status, max_fd = -1;

    FD_ZERO(&orig_read_set);

    for(i = 0; i < num_socks; i++) {
#ifdef FD_SETSIZE
	if (socks[i] >= FD_SETSIZE)
	    errx (1, "fd too large");
#endif
	FD_SET(socks[i], &orig_read_set);
	max_fd = max(max_fd, socks[i]);
    }

    pgrp = getpid();

    if(setpgid(0, pgrp) < 0)
	err(1, "setpgid");

    signal(SIGTERM, terminate);
    signal(SIGINT, terminate);
    signal(SIGCHLD, sigchld);

    while (term_flag == 0) {
	read_set = orig_read_set;
	e = select(max_fd + 1, &read_set, NULL, NULL, NULL);
	if(rk_IS_SOCKET_ERROR(e)) {
	    if(rk_SOCK_ERRNO != EINTR)
		krb5_warn(context, rk_SOCK_ERRNO, "select");
	} else if(e == 0)
	    krb5_warnx(context, "select returned 0");
	else {
	    for(i = 0; i < num_socks; i++) {
		if(FD_ISSET(socks[i], &read_set))
		    if(spawn_child(context, socks, num_socks, i) == 0)
			return;
	    }
	}
    }
    signal(SIGCHLD, SIG_IGN);

    while ((waitpid(-1, &status, WNOHANG)) > 0)
	;

    exit(0);
}
Beispiel #25
0
int
iprop_dump(struct dump_options *opt, int argc, char **argv)
{
    kadm5_server_context *server_context;
    krb5_error_code ret;

    server_context = get_kadmin_context(opt->config_file_string,
					opt->realm_string);

    ret = kadm5_log_init (server_context);
    if (ret)
	krb5_err (context, 1, ret, "kadm5_log_init");

    ret = kadm5_log_foreach (server_context, print_entry, NULL);
    if(ret)
	krb5_warn(context, ret, "kadm5_log_foreach");

    ret = kadm5_log_end (server_context);
    if (ret)
	krb5_warn(context, ret, "kadm5_log_end");
    return 0;
}
Beispiel #26
0
static int
process_msg (krb5_context context, slave *s, int log_fd,
	     const char *database, u_int32_t current_version)
{
    int ret = 0;
    krb5_data out;
    krb5_storage *sp;
    int32_t tmp;

    ret = krb5_read_priv_message(context, s->ac, &s->fd, &out);
    if(ret) {
	krb5_warn (context, ret, "error reading message from %s", s->name);
	return 1;
    }

    sp = krb5_storage_from_mem (out.data, out.length);
    if (sp == NULL) {
	krb5_warnx (context, "process_msg: no memory");
	krb5_data_free (&out);
	return 1;
    }
    if (krb5_ret_int32 (sp, &tmp) != 0) {
	krb5_warnx (context, "process_msg: client send too short command");
	krb5_data_free (&out);
	return 1;
    }
    switch (tmp) {
    case I_HAVE :
	ret = krb5_ret_int32 (sp, &tmp);
	if (ret != 0) {
	    krb5_warnx (context, "process_msg: client send too I_HAVE data");
	    break;
	}
	s->version = tmp;
	ret = send_diffs (context, s, log_fd, database, current_version);
	break;
    case I_AM_HERE :
	break;
    case ARE_YOU_THERE:
    case FOR_YOU :
    default :
	krb5_warnx (context, "Ignoring command %d", tmp);
	break;
    }

    krb5_data_free (&out);

    slave_seen(s);

    return ret;
}
Beispiel #27
0
static void
reply_priv (krb5_auth_context auth_context,
            int s,
            struct sockaddr *sa,
            int sa_size,
            uint16_t result_code,
            const char *expl)
{
    krb5_error_code ret;
    krb5_data krb_priv_data;
    krb5_data ap_rep_data;
    krb5_data e_data;

    ret = krb5_mk_rep (context,
                       auth_context,
                       &ap_rep_data);
    if (ret) {
        krb5_warn (context, ret, "Could not even generate error reply");
        return;
    }

    if (make_result(&e_data, result_code, expl))
        return;

    ret = krb5_mk_priv (context,
                        auth_context,
                        &e_data,
                        &krb_priv_data,
                        NULL);
    krb5_data_free (&e_data);
    if (ret) {
        krb5_warn (context, ret, "Could not even generate error reply");
        return;
    }
    send_reply (s, sa, sa_size, &ap_rep_data, &krb_priv_data);
    krb5_data_free (&ap_rep_data);
    krb5_data_free (&krb_priv_data);
}
Beispiel #28
0
int
dump(struct dump_options *opt, int argc, char **argv)
{
    krb5_error_code ret;
    FILE *f;
    HDB *db = NULL;

    if(!local_flag) {
	krb5_warnx(context, "dump is only available in local (-l) mode");
	return 0;
    }

    db = _kadm5_s_get_db(kadm_handle);

    if(argc == 0)
	f = stdout;
    else
	f = fopen(argv[0], "w");

    if(f == NULL) {
	krb5_warn(context, errno, "open: %s", argv[0]);
	goto out;
    }
    ret = db->hdb_open(context, db, O_RDONLY, 0600);
    if(ret) {
	krb5_warn(context, ret, "hdb_open");
	goto out;
    }

    hdb_foreach(context, db, opt->decrypt_flag ? HDB_F_DECRYPT : 0,
		hdb_print_entry, f);

    db->hdb_close(context, db);
out:
    if(f && f != stdout)
	fclose(f);
    return 0;
}
Beispiel #29
0
int
rename_entry(void *opt, int argc, char **argv)
{
    krb5_error_code ret;
    krb5_principal princ1, princ2;

    ret = krb5_parse_name(context, argv[0], &princ1);
    if(ret){
	krb5_warn(context, ret, "krb5_parse_name(%s)", argv[0]);
	return ret != 0;
    }
    ret = krb5_parse_name(context, argv[1], &princ2);
    if(ret){
	krb5_free_principal(context, princ1);
	krb5_warn(context, ret, "krb5_parse_name(%s)", argv[1]);
	return ret != 0;
    }
    ret = kadm5_rename_principal(kadm_handle, princ1, princ2);
    if(ret)
	krb5_warn(context, ret, "rename");
    krb5_free_principal(context, princ1);
    krb5_free_principal(context, princ2);
    return ret != 0;
}
Beispiel #30
0
krb5_error_code
v5_prop(krb5_context context, HDB *db, hdb_entry_ex *entry, void *appdata)
{
    krb5_error_code ret;
    struct prop_data *pd = appdata;
    krb5_data data;

    if(encrypt_flag) {
	ret = hdb_seal_keys_mkey(context, &entry->entry, mkey5);
	if (ret) {
	    krb5_warn(context, ret, "hdb_seal_keys_mkey");
	    return ret;
	}
    }
    if(decrypt_flag) {
	ret = hdb_unseal_keys_mkey(context, &entry->entry, mkey5);
	if (ret) {
	    krb5_warn(context, ret, "hdb_unseal_keys_mkey");
	    return ret;
	}
    }

    ret = hdb_entry2value(context, &entry->entry, &data);
    if(ret) {
	krb5_warn(context, ret, "hdb_entry2value");
	return ret;
    }

    if(to_stdout)
	ret = krb5_write_message(context, &pd->sock, &data);
    else
	ret = krb5_write_priv_message(context, pd->auth_context,
				      &pd->sock, &data);
    krb5_data_free(&data);
    return ret;
}