Beispiel #1
0
// The return code of this is the return code of the standalone process.
int champ_chooser_server_standalone(struct conf **globalcs)
{
	int ret=1;
	struct sdirs *sdirs=NULL;
	struct conf **cconfs=NULL;
	const char *orig_client=get_string(globalcs[OPT_ORIG_CLIENT]);

	if(!(cconfs=confs_alloc()))
		goto end;
	confs_init(cconfs);
	// We need to be given a client name and load the relevant server side
	// clientconfdir file, because various settings may be overridden
	// there.
	if(set_string(cconfs[OPT_CNAME], orig_client)
	  || conf_load_clientconfdir(globalcs, cconfs)
	  || !(sdirs=sdirs_alloc())
	  || sdirs_init_from_confs(sdirs, cconfs)
	  || champ_chooser_server(sdirs, cconfs, 0 /* resume */))
		goto end;
	ret=0;
end:
	confs_free(&cconfs);
	sdirs_free(&sdirs);
	return ret;
}
Beispiel #2
0
static int check_client_and_password(struct conf **globalcs,
	const char *password, struct conf **cconfs)
{
	const char *cname;
	int password_check;
	// Cannot load it until here, because we need to have the name of the
	// client.
	if(conf_load_clientconfdir(globalcs, cconfs)) return -1;

	cname=get_string(cconfs[OPT_CNAME]);
	password_check=get_int(cconfs[OPT_PASSWORD_CHECK]);

	if(!get_string(cconfs[OPT_SSL_PEER_CN]))
	{
		logp("ssl_peer_cn unset");
		if(cname)
		{
			logp("Falling back to using '%s'\n", cname);
			if(set_string(cconfs[OPT_SSL_PEER_CN], cname))
				return -1;
		}
	}

	cname=get_string(cconfs[OPT_CNAME]);

	if(password_check)
	{
		const char *conf_passwd=get_string(cconfs[OPT_PASSWD]);
		const char *conf_password=get_string(cconfs[OPT_PASSWORD]);
		if(!conf_password && !conf_passwd)
		{
			logp("password rejected for client %s\n", cname);
			return -1;
		}
		// check against plain text
		if(conf_password && strcmp(conf_password, password))
		{
			logp("password rejected for client %s\n", cname);
			return -1;
		}
		// check against encypted passwd
		if(conf_passwd && !check_passwd(conf_passwd, password))
		{
			logp("password rejected for client %s\n", cname);
			return -1;
		}
	}

	if(!get_strlist(cconfs[OPT_KEEP]))
	{
		logp("%s: you cannot set the keep value for a client to 0!\n",
			cname);
		return -1;
	}
	return 0;
}
Beispiel #3
0
// FIX THIS: need to unit test this.
static int do_conf_switch_to_orig_client(struct conf **globalcs,
	struct conf **cconfs, const char *orig_client, const char *buf)
{
	int ret=-1;
	int loadrc;
	struct conf **sconfs=NULL;
	if(!(sconfs=confs_alloc())
	  || confs_init(sconfs)) goto end;
	if(set_string(sconfs[OPT_CNAME], orig_client))
		goto end;
	logp("Client wants to switch to client: %s\n",
		get_string(sconfs[OPT_CNAME]));

	// Allow unit testing using a buffer.
#ifdef UTEST
	if(buf) loadrc=conf_load_overrides_buf(globalcs, sconfs, buf);
	else
#endif
		loadrc=conf_load_clientconfdir(globalcs, sconfs);
	if(loadrc)
	{
		logp("Could not load alternate config: %s",
			get_string(sconfs[OPT_CNAME]));
		goto end;
	}
	set_int(sconfs[OPT_SEND_CLIENT_CNTR],
		get_int(cconfs[OPT_SEND_CLIENT_CNTR]));

	if(!restore_client_allowed(cconfs, sconfs))
		goto end;

	if(set_string(sconfs[OPT_RESTORE_PATH],
		get_string(cconfs[OPT_RESTORE_PATH])))
			goto end;
	if(set_string(cconfs[OPT_RESTORE_PATH], NULL))
		goto end;
	set_cntr(sconfs[OPT_CNTR], get_cntr(cconfs[OPT_CNTR]));
	set_cntr(cconfs[OPT_CNTR], NULL);
	confs_free_content(cconfs);
	confs_init(cconfs);
	confs_memcpy(cconfs, sconfs);
	confs_null(sconfs);
	if(set_string(cconfs[OPT_RESTORE_CLIENT],
		get_string(cconfs[OPT_CNAME]))) goto end;
	if(set_string(cconfs[OPT_ORIG_CLIENT],
		get_string(cconfs[OPT_CNAME]))) goto end;

	logp("Switched to client %s\n", get_string(cconfs[OPT_CNAME]));
	ret=0;
end:
	confs_free(&sconfs);
	return ret;
}
Beispiel #4
0
END_TEST

static void check_restore_clients(struct cstat *cstat,
	struct conf **parentconf, const char *restore_clients, int permitted)
{
	struct conf **cconfs=NULL;
	fail_unless((cconfs=confs_alloc())!=NULL);
	fail_unless(!confs_init(cconfs));
	fail_unless(!set_string(cconfs[OPT_CNAME], "cli1"));
	build_clientconfdir_file("cli1", restore_clients);
	fail_unless(!conf_load_clientconfdir(parentconf, cconfs));
	fail_unless(!set_string(parentconf[OPT_CNAME], "cli2"));
	fail_unless(cstat_permitted(cstat, parentconf, cconfs)==permitted);
	confs_free(&cconfs);
}
Beispiel #5
0
// FIX THIS: need to unit test this.
int conf_switch_to_orig_client(struct conf **globalcs,
	struct conf **cconfs, const char *orig_client)
{
	int ret=-1;
	struct conf **sconfs=NULL;
	if(!(sconfs=confs_alloc())
	  || confs_init(sconfs)) goto end;
	if(set_string(sconfs[OPT_CNAME], orig_client))
		goto end;
	logp("Client wants to switch to client: %s\n",
		get_string(sconfs[OPT_CNAME]));

	if(conf_load_clientconfdir(globalcs, sconfs))
	{
		logp("Could not load alternate config: %s",
			get_string(sconfs[OPT_CNAME]));
		goto end;
	}
	set_int(sconfs[OPT_SEND_CLIENT_CNTR],
		get_int(cconfs[OPT_SEND_CLIENT_CNTR]));

	if(!restore_client_allowed(cconfs, sconfs))
		goto end;

	if(set_string(sconfs[OPT_RESTORE_PATH],
		get_string(cconfs[OPT_RESTORE_PATH])))
			goto end;
	if(set_string(cconfs[OPT_RESTORE_PATH], NULL))
		goto end;
	set_cntr(sconfs[OPT_CNTR], get_cntr(cconfs));
	set_cntr(cconfs[OPT_CNTR], NULL);
	confs_free_content(cconfs);
	confs_init(cconfs);
	confs_memcpy(cconfs, sconfs);
	confs_null(sconfs);
	if(set_string(cconfs[OPT_RESTORE_CLIENT],
		get_string(cconfs[OPT_CNAME]))) goto end;
	if(set_string(cconfs[OPT_ORIG_CLIENT],
		get_string(cconfs[OPT_CNAME]))) goto end;

	logp("Switched to client %s\n", get_string(cconfs[OPT_CNAME]));
	ret=0;
end:
	confs_free(&sconfs);
	return ret;
}
Beispiel #6
0
static int run_test_confs(struct conf **confs, const char *client)
{
	int ret=-1;
	struct conf **cconfs=NULL;
	if(!client)
	{
		confs_dump(confs, 0);
		ret=0;
		goto end;
	}
	if(!(cconfs=confs_alloc()))
		goto end;
	confs_init(cconfs);
	if(set_string(cconfs[OPT_CNAME], client)
	  || set_string(cconfs[OPT_PEER_VERSION], VERSION)
	  || conf_load_clientconfdir(confs, cconfs))
		goto end;
	confs_dump(cconfs, CONF_FLAG_CC_OVERRIDE|CONF_FLAG_INCEXC);

end:
	confs_free(&cconfs);
	return ret;
}
Beispiel #7
0
static
#endif
int cstat_reload_from_client_confs(struct cstat **clist,
                                   struct conf **globalcs, struct conf **cconfs)
{
    struct cstat *c;
    struct stat statp;
    static time_t global_mtime=0;
    time_t global_mtime_new=0;
    const char *globalconffile;
    int reloaded=0;

    globalconffile=get_string(globalcs[OPT_CONFFILE]);

    if(stat(globalconffile, &statp)
            || !S_ISREG(statp.st_mode))
    {
        logp("Could not stat main conf file %s: %s\n",
             globalconffile, strerror(errno));
        return -1;
    }
    global_mtime_new=statp.st_mtime;

    // FIX THIS: If '. included' conf files have changed, this code will
    // not detect them. I guess that conf.c should make a list of them.
    while(1)
    {
        for(c=*clist; c; c=c->next)
        {
            // Look at the client conf files to see if they have
            // changed, and reload bits and pieces if they have.

            if(!c->conffile) continue;
            if(stat(c->conffile, &statp)
                    || !S_ISREG(statp.st_mode))
            {
                cstat_remove(clist, &c);
                break; // Go to the beginning of the list.
            }
            if(statp.st_mtime==c->conf_mtime
                    && global_mtime_new==global_mtime)
            {
                // The conf files have not changed - no need to
                // do anything.
                continue;
            }
            c->conf_mtime=statp.st_mtime;

            confs_free_content(cconfs);
            if(set_string(cconfs[OPT_CNAME], c->name))
                return -1;
            if(conf_load_clientconfdir(globalcs, cconfs))
            {
                // If the file has junk in it, we will keep
                // trying to reload it after removal.
                // So, just deny permission to view it.
                c->permitted=0;
                continue;
            }

            if(set_cstat_from_conf(c, globalcs, cconfs))
                return -1;
            reloaded++;
        }
        // Only stop if the end of the list was not reached.
        if(!c) break;
    }
    if(global_mtime!=global_mtime_new)
        global_mtime=global_mtime_new;
    return reloaded;
}
Beispiel #8
0
static int iterate_over_clients(struct conf **globalcs,
	struct strlist *grouplist, const char *ext, unsigned int maxlinks)
{
	int ret=0;
	DIR *dirp=NULL;
	struct conf **cconfs=NULL;
	struct dirent *dirinfo=NULL;
	const char *globalclientconfdir=get_string(globalcs[OPT_CLIENTCONFDIR]);

	signal(SIGABRT, &sighandler);
	signal(SIGTERM, &sighandler);
	signal(SIGINT, &sighandler);

	if(!(cconfs=confs_alloc())) return -1;
	if(confs_init(cconfs)) return -1;

	if(!(dirp=opendir(globalclientconfdir)))
	{
		logp("Could not opendir '%s': %s\n",
			globalclientconfdir, strerror(errno));
		return 0;
	}
	while((dirinfo=readdir(dirp)))
	{
		char *lockfile=NULL;
		char *lockfilebase=NULL;
		char *client_lockdir=NULL;
		struct lock *lock=NULL;

		if(dirinfo->d_ino==0
		// looks_like...() also avoids '.' and '..'.
		  || looks_like_tmp_or_hidden_file(dirinfo->d_name)
		  || !is_regular_file(globalclientconfdir, dirinfo->d_name))
			continue;

		confs_free_content(cconfs);
		if(confs_init(cconfs)) return -1;

		if(set_string(cconfs[OPT_CNAME], dirinfo->d_name))
			return -1;

		if(conf_load_clientconfdir(globalcs, cconfs))
		{
			logp("could not load config for client %s\n",
				dirinfo->d_name);
			return 0;
		}

		if(grouplist)
		{
			const char *dedup_group=
				get_string(cconfs[OPT_DEDUP_GROUP]);
			if(!dedup_group
			  || !in_group(grouplist, dedup_group))
				continue;
		}

		if(!(client_lockdir=get_string(cconfs[OPT_CLIENT_LOCKDIR])))
			client_lockdir=get_string(cconfs[OPT_DIRECTORY]);

		if(!(lockfilebase=prepend(client_lockdir,
			dirinfo->d_name, "/"))
		 || !(lockfile=prepend(lockfilebase,
			BEDUP_LOCKFILE_NAME, "/")))
		{
			free_w(&lockfilebase);
			free_w(&lockfile);
			ret=-1;
			break;
		}
		free_w(&lockfilebase);

		if(!(lock=lock_alloc_and_init(lockfile)))
		{
			ret=-1;
			break;
		}
		lock_get(lock);
		free_w(&lockfile);

		if(lock->status!=GET_LOCK_GOT)
		{
			logp("Could not get %s\n", lock->path);
			continue;
		}
		logp("Got %s\n", lock->path);

		// Remember that we got that lock.
		lock_add_to_list(&locklist, lock);

		if(process_dir(get_string(cconfs[OPT_DIRECTORY]),
			dirinfo->d_name,
			ext, maxlinks, 1 /* burp mode */, 0 /* level */))
		{
			ret=-1;
			break;
		}

		ccount++;
	}
	closedir(dirp);

	locks_release_and_free(&locklist);

	confs_free(&cconfs);

	return ret;
}