Beispiel #1
0
static krb5_error_code
add_db(krb5_context context, struct krb5_kdc_configuration *c,
       const char *conf, const char *master_key)
{
    krb5_error_code ret;
    void *ptr;

    ptr = realloc(c->db, (c->num_db + 1) * sizeof(*c->db));
    if (ptr == NULL) {
	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
	return ENOMEM;
    }
    c->db = ptr;
    
    ret = hdb_create(context, &c->db[c->num_db], conf);
    if(ret)
	return ret;

    c->num_db++;

    if (master_key) {
	ret = hdb_set_master_keyfile(context, c->db[c->num_db - 1], master_key);
	if (ret)
	    return ret;
    }

    return 0;
}
Beispiel #2
0
static kadm5_ret_t
kadm5_s_init_with_context(krb5_context context,
			  const char *client_name,
			  const char *service_name,
			  kadm5_config_params *realm_params,
			  unsigned long struct_version,
			  unsigned long api_version,
			  void **server_handle)
{
    kadm5_ret_t ret;
    kadm5_server_context *ctx;
    ret = _kadm5_s_init_context(&ctx, realm_params, context);
    if(ret)
	return ret;

    assert(ctx->config.dbname != NULL);
    assert(ctx->config.stash_file != NULL);
    assert(ctx->config.acl_file != NULL);
    assert(ctx->log_context.log_file != NULL);
#ifndef NO_UNIX_SOCKETS
    assert(ctx->log_context.socket_name.sun_path[0] != '\0');
#else
    assert(ctx->log_context.socket_info != NULL);
#endif

    ret = hdb_create(ctx->context, &ctx->db, ctx->config.dbname);
    if(ret)
	return ret;
    ret = hdb_set_master_keyfile (ctx->context,
				  ctx->db, ctx->config.stash_file);
    if(ret)
	return ret;

    ctx->log_context.log_fd   = -1;

#ifndef NO_UNIX_SOCKETS
    ctx->log_context.socket_fd = socket (AF_UNIX, SOCK_DGRAM, 0);
#else
    ctx->log_context.socket_fd = socket (ctx->log_context.socket_info->ai_family,
					 ctx->log_context.socket_info->ai_socktype,
					 ctx->log_context.socket_info->ai_protocol);
#endif

    ret = krb5_parse_name(ctx->context, client_name, &ctx->caller);
    if(ret)
	return ret;

    ret = _kadm5_acl_init(ctx);
    if(ret)
	return ret;

    *server_handle = ctx;
    return 0;
}
Beispiel #3
0
static krb5_error_code KRB5_CALLCONV
hdb_start_seq_get(krb5_context context,
		  krb5_keytab id,
		  krb5_kt_cursor *cursor)
{
    krb5_error_code ret;
    struct hdb_cursor *c;
    struct hdb_data *d = id->data;
    const char *dbname = d->dbname;
    const char *mkey   = d->mkey;
    HDB *db;
   
    if (dbname == NULL) {
	/*
	 * We don't support enumerating without being told what 
	 * backend to enumerate on
	 */
  	ret = KRB5_KT_NOTFOUND;
	return ret;
    }

    ret = hdb_create (context, &db, dbname);
    if (ret)
	return ret;
    ret = hdb_set_master_keyfile (context, db, mkey);
    if (ret) {
	(*db->hdb_destroy)(context, db);
	return ret;
    }
	
    ret = (*db->hdb_open)(context, db, O_RDONLY, 0);
    if (ret) {
	(*db->hdb_destroy)(context, db);
	return ret;
    }

    cursor->data = c = malloc (sizeof(*c));
    if(c == NULL){
	(*db->hdb_close)(context, db);
	(*db->hdb_destroy)(context, db);
	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
	return ENOMEM;
    }

    c->db = db;
    c->first = TRUE;
    c->next = TRUE;
    c->key_idx = 0;

    cursor->data = c;
    return ret;
}
Beispiel #4
0
static krb5_error_code KRB5_CALLCONV
hdb_get_entry(krb5_context context,
	      krb5_keytab id,
	      krb5_const_principal principal,
	      krb5_kvno kvno,
	      krb5_enctype enctype,
	      krb5_keytab_entry *entry)
{
    hdb_entry_ex ent;
    krb5_error_code ret;
    struct hdb_data *d = id->data;
    const char *dbname = d->dbname;
    const char *mkey   = d->mkey;
    char *fdbname = NULL, *fmkey = NULL;
    HDB *db;
    int i;

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

    if (dbname == NULL) {
	ret = find_db(context, &fdbname, &fmkey, principal);
	if (ret)
	    return ret;
	dbname = fdbname;
	mkey = fmkey;
    }

    ret = hdb_create (context, &db, dbname);
    if (ret)
	goto out2;
    ret = hdb_set_master_keyfile (context, db, mkey);
    if (ret) {
	(*db->hdb_destroy)(context, db);
	goto out2;
    }
	
    ret = (*db->hdb_open)(context, db, O_RDONLY, 0);
    if (ret) {
	(*db->hdb_destroy)(context, db);
	goto out2;
    }
    
    ret = (*db->hdb_fetch_kvno)(context, db, principal,
				HDB_F_DECRYPT|HDB_F_KVNO_SPECIFIED|
				HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
				kvno, &ent);

    if(ret == HDB_ERR_NOENTRY) {
	ret = KRB5_KT_NOTFOUND;
	goto out;
    }else if(ret)
	goto out;

    if(kvno && ent.entry.kvno != kvno) {
	hdb_free_entry(context, &ent);
 	ret = KRB5_KT_NOTFOUND;
	goto out;
    }
    if(enctype == 0)
	if(ent.entry.keys.len > 0)
	    enctype = ent.entry.keys.val[0].key.keytype;
    ret = KRB5_KT_NOTFOUND;
    for(i = 0; i < ent.entry.keys.len; i++) {
	if(ent.entry.keys.val[i].key.keytype == enctype) {
	    krb5_copy_principal(context, principal, &entry->principal);
	    entry->vno = ent.entry.kvno;
	    krb5_copy_keyblock_contents(context,
					&ent.entry.keys.val[i].key,
					&entry->keyblock);
	    ret = 0;
	    break;
	}
    }
    hdb_free_entry(context, &ent);
 out:
    (*db->hdb_close)(context, db);
    (*db->hdb_destroy)(context, db);
 out2:
    free(fdbname);
    free(fmkey);
    return ret;
}
Beispiel #5
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    
    ret = krb5_init_context(&context);
    if (ret == KRB5_CONFIG_BADFORMAT)
	errx (1, "krb5_init_context failed to parse configuration file");
    else if (ret)
	errx (1, "krb5_init_context failed: %d", ret);

    configure(argc, argv);

    if(databases == NULL) {
	db = malloc(sizeof(*db));
	num_db = 1;
	ret = hdb_create(context, &db[0], NULL);
	if(ret)
	    krb5_err(context, 1, ret, "hdb_create %s", HDB_DEFAULT_DB);
	ret = hdb_set_master_keyfile(context, db[0], NULL);
	if (ret)
	    krb5_err(context, 1, ret, "hdb_set_master_keyfile");
    } else {
	struct dbinfo *d;
	int i;
	/* count databases */
	for(d = databases, i = 0; d; d = d->next, i++);
	db = malloc(i * sizeof(*db));
	for(d = databases, num_db = 0; d; d = d->next, num_db++) {
	    ret = hdb_create(context, &db[num_db], d->dbname);
	    if(ret)
		krb5_err(context, 1, ret, "hdb_create %s", d->dbname);
	    ret = hdb_set_master_keyfile(context, db[num_db], d->mkey_file);
	    if (ret)
		krb5_err(context, 1, ret, "hdb_set_master_keyfile");
	}
    }

#ifdef HAVE_SIGACTION
    {
	struct sigaction sa;

	sa.sa_flags = 0;
	sa.sa_handler = sigterm;
	sigemptyset(&sa.sa_mask);

	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGXCPU, &sa, NULL);

	sa.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &sa, NULL);
    }
#else
    signal(SIGINT, sigterm);
    signal(SIGTERM, sigterm);
    signal(SIGXCPU, sigterm);
    signal(SIGPIPE, SIG_IGN);
#endif
    if (detach_from_console)
	daemon(0, 0);
    pidfile(NULL);
    loop();
    krb5_free_context(context);
    return 0;
}
Beispiel #6
0
static krb5_error_code
receive_everything (krb5_context context, int fd,
		    kadm5_server_context *server_context,
		    krb5_auth_context auth_context)
{
    int ret;
    krb5_data data;
    int32_t vno = 0;
    int32_t opcode;
    krb5_storage *sp;

    char *dbname;
    HDB *mydb;

    krb5_warnx(context, "receive complete database");

    asprintf(&dbname, "%s-NEW", server_context->db->hdb_name);
    ret = hdb_create(context, &mydb, dbname);
    if(ret)
	krb5_err(context,1, ret, "hdb_create");
    free(dbname);

    ret = hdb_set_master_keyfile (context,
				  mydb, server_context->config.stash_file);
    if(ret)
	krb5_err(context,1, ret, "hdb_set_master_keyfile");

    /* I really want to use O_EXCL here, but given that I can't easily clean
       up on error, I won't */
    ret = mydb->hdb_open(context, mydb, O_RDWR | O_CREAT | O_TRUNC, 0600);
    if (ret)
	krb5_err (context, 1, ret, "db->open");

    sp = NULL;
    do {
	ret = krb5_read_priv_message(context, auth_context, &fd, &data);

	if (ret) {
	    krb5_warn (context, ret, "krb5_read_priv_message");
	    goto cleanup;
	}

	sp = krb5_storage_from_data (&data);
	if (sp == NULL)
	    krb5_errx (context, 1, "krb5_storage_from_data");
	krb5_ret_int32 (sp, &opcode);
	if (opcode == ONE_PRINC) {
	    krb5_data fake_data;
	    hdb_entry_ex entry;

	    krb5_storage_free(sp);

	    fake_data.data   = (char *)data.data + 4;
	    fake_data.length = data.length - 4;

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

	    ret = hdb_value2entry (context, &fake_data, &entry.entry);
	    if (ret)
		krb5_err (context, 1, ret, "hdb_value2entry");
	    ret = mydb->hdb_store(server_context->context,
				  mydb,
				  0, &entry);
	    if (ret)
		krb5_err (context, 1, ret, "hdb_store");

	    hdb_free_entry (context, &entry);
	    krb5_data_free (&data);
	} else if (opcode == NOW_YOU_HAVE)
	    ;
	else
	    krb5_errx (context, 1, "strange opcode %d", opcode);
    } while (opcode == ONE_PRINC);

    if (opcode != NOW_YOU_HAVE)
	krb5_errx (context, 1, "receive_everything: strange %d", opcode);

    krb5_ret_int32 (sp, &vno);
    krb5_storage_free(sp);

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

    ret = kadm5_log_set_version (server_context, vno - 1);
    if (ret)
	krb5_err (context, 1, ret, "kadm5_log_set_version");

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

    ret = mydb->hdb_rename (context, mydb, server_context->db->hdb_name);
    if (ret)
	krb5_err (context, 1, ret, "db->rename");

 cleanup:
    krb5_data_free (&data);

    ret = mydb->hdb_close (context, mydb);
    if (ret)
	krb5_err (context, 1, ret, "db->close");

    ret = mydb->hdb_destroy (context, mydb);
    if (ret)
	krb5_err (context, 1, ret, "db->destroy");

    krb5_warnx(context, "receive complete database, version %ld", (long)vno);
    return ret;
}
Beispiel #7
0
static kadm5_ret_t
kadm5_s_init_with_context(krb5_context context,
			  const char *client_name,
			  const char *service_name,
			  kadm5_config_params *realm_params,
			  unsigned long struct_version,
			  unsigned long api_version,
			  void **server_handle)
{
    kadm5_ret_t ret;
    kadm5_server_context *ctx;
    char *dbname;
    char *stash_file;

    *server_handle = NULL;
    ret = _kadm5_s_init_context(&ctx, realm_params, context);
    if (ret)
	return ret;

    if (realm_params->mask & KADM5_CONFIG_DBNAME)
	dbname = realm_params->dbname;
    else
	dbname = ctx->config.dbname;

    if (realm_params->mask & KADM5_CONFIG_STASH_FILE)
	stash_file = realm_params->stash_file;
    else
	stash_file = ctx->config.stash_file;

    assert(dbname != NULL);
    assert(stash_file != NULL);
    assert(ctx->config.acl_file != NULL);
    assert(ctx->log_context.log_file != NULL);
#ifndef NO_UNIX_SOCKETS
    assert(ctx->log_context.socket_name.sun_path[0] != '\0');
#else
    assert(ctx->log_context.socket_info != NULL);
#endif

    ret = hdb_create(ctx->context, &ctx->db, dbname);
    if (ret == 0)
        ret = hdb_set_master_keyfile(ctx->context,
                                     ctx->db, stash_file);
    if (ret) {
        kadm5_s_destroy(ctx);
	return ret;
    }

    ctx->log_context.log_fd = -1;

#ifndef NO_UNIX_SOCKETS
    ctx->log_context.socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
#else
    ctx->log_context.socket_fd = socket(ctx->log_context.socket_info->ai_family,
					ctx->log_context.socket_info->ai_socktype,
					ctx->log_context.socket_info->ai_protocol);
#endif

    if (ctx->log_context.socket_fd != rk_INVALID_SOCKET)
        socket_set_nonblocking(ctx->log_context.socket_fd, 1);

    ret = krb5_parse_name(ctx->context, client_name, &ctx->caller);
    if (ret == 0)
        ret = _kadm5_acl_init(ctx);
    if (ret)
        kadm5_s_destroy(ctx);
    else
        *server_handle = ctx;
    return ret;
}