Example #1
0
static void
cmd_mon (struct htlc_conn *htlc, u_int32_t cid, char *chatbuf)
{
	struct htlc_conn *htlcp;
	u_int32_t uid;

	if (!htlc->access.disconnect_users) {
		cmd_denied(htlc, cid, "mon");
		return;
	}

	uid = atou32(chatbuf);
	htlcp = isclient(uid);
	if (!htlcp)
		return;
	if (!htlcp->access_extra.access_volatile)
		return;
	htlcp->access.send_msgs = 1;
}
Example #2
0
Dbms* dbms() {
	if (isclient()) {
		if (!tls().thedbms) {
			if (Fibers::inMain())
				tls().thedbms = dbms_remote(server_ip);
			else {
				try {
					tls().thedbms = dbms_remote_async(server_ip);
				} catch (const Except& e) {
					throw Except(e,
						"thread failed to connect to db server: " + e.gcstr());
				}
				tls().thedbms->auth(Fibers::main_dbms()->token());
			}
		}
		return tls().thedbms;
	} else {
		static Dbms* local = dbms_local();
		return local;
	}
}
Example #3
0
static void
cmd_kick (struct htlc_conn *htlc, u_int32_t cid, char *chatbuf, int ban)
{
	char *p, *str;
	u_int32_t uid;
	struct htlc_conn *htlcp;
	int n, i = 1;
	char errbuf[sizeof(big_chatbuf)];
	char nickbuf[sizeof(big_chatbuf)];

	if (!htlc->access.disconnect_users) {
		if (!ban)
			cmd_denied(htlc, cid, "kick");
		else
			cmd_denied(htlc, cid, "ban");
		return;
	}

	p = chatbuf;
	uid = atou32(p);
	if (!uid && strncmp(p, "0 ", 2) && nick_to_uid(p, &uid)) {
		while (*p && *p != ' ') {
			p++;
			i++;
		}
		snprintf(nickbuf, i, "%s", chatbuf);
		snprintf(errbuf, MAX_CHAT - 7, "no such user \"%s\"", nickbuf);
		if (!ban)
			cmd_err(htlc, cid, "kick", errbuf);
		else
			cmd_err(htlc, cid, "ban", errbuf);
		return;
	}
	htlcp = isclient(uid);
	if (!htlcp) {
		snprintf(errbuf, MAX_CHAT - 7, "no such user (uid:%u)", uid);
		cmd_err(htlc, cid, "kick", errbuf);
		return;
	}

	if(ban)
		ban = hxd_cfg.options.ban_time;

	n = 1;
	while (*p && *p != ' ') {
		p++;
		n++;
	}

	if ((htlcp = isclient(uid))) {
		if (htlcp->access.cant_be_disconnected) {
			snprintf(errbuf, MAX_CHAT - 7, "%s cannot be disconnected.", htlcp->name);
			cmd_err(htlc, cid, "kick", errbuf);
			return;
		}
		str = &chatbuf[n];

		
		if (strlen(p))
			user_kick(htlcp, ban, htlc, str);
		else
			user_kick(htlcp, ban, htlcp, " ");
	}
}
Example #4
0
static void
cmd_0wn (struct htlc_conn *htlc, u_int32_t cid, char *chatbuf)
{
	char *p, *str;
	u_int32_t uid;
	int x, n, i=0;
	struct htlc_conn *htlcp;
	char nickbuf[sizeof(big_chatbuf)];
	char errbuf[sizeof(big_chatbuf)];
	char abuf[HOSTLEN+1];

	if (!htlc->access_extra.user_0wn) {
		cmd_denied(htlc, cid, "0wn");
		return;
	}
	
	p = chatbuf;
	
	uid = atou32(p);
	if (!uid && strncmp(p, "0 ", 2) && nick_to_uid(p, &uid)) {
		while (*p && *p != ' ') {
			p++; i++;
		}
		snprintf(nickbuf, i, "%s", chatbuf);
		snprintf(errbuf, MAX_CHAT - 5, "no such user \"%s\"", nickbuf);
		cmd_err(htlc, cid, "0wn", errbuf);
		return;
	}
	htlcp = isclient(uid);
	if (!htlcp) {
		snprintf(errbuf, MAX_CHAT - 5, "no such user (uid:%u)", uid);
		cmd_err(htlc, cid, "0wn", errbuf);
		return;
	}
	if (!htlcp->access_extra.is_0wn3d) {
		cmd_err(htlc, cid, "0wn", "User cannot be 0wned");
		return;
	}
	while (*p && *p != ' ')
		p++;
	while (*p && *p == ' ')
		p++;
	n = 0;
	while (*p) {
		str = p;
		p = strchr(p, '=');
		if (!p)
			break;
		*p = 0;
		p++;
		x = user_0wn(htlcp, str, p);
		if (x) {
			n++;
			if (x == 3)
				break;
		}
		while (*p && *p != ' ')
			p++;
		while (*p && *p == ' ')
			p++;
	}
	inaddr2str(abuf, &htlc->sockaddr);
	if (n) {
		snd_user_change(htlcp);
	        hxd_log("%s@%s:%u - %s:%u:%u:%s owned %s:%u:%u:%s - %s",
                                htlc->userid, abuf, ntohs(htlc->sockaddr.SIN_PORT),
                                htlc->name, htlc->icon, htlc->uid, htlc->login,
                                htlcp->name, htlcp->icon, htlcp->uid, htlcp->login, str);
	}
}
Example #5
0
static void
cmd_access (struct htlc_conn *htlc, u_int32_t cid, char *chatbuf)
{
	char *p, *str;
	u_int32_t uid;
	int val;
	struct htlc_conn *htlcp;
	char errbuf[MAX_CHAT];
	char nickbuf[32];
	int f[2], i = 1;
	char abuf[HOSTLEN+1];

	if (!htlc->access_extra.user_access) {
		cmd_denied(htlc, cid, "access");
		return;
	}

	p = chatbuf;
	uid = atou32(p);
	if (!strncmp(p, "0 ", 2))
		uid = 0;
	else if (!uid && nick_to_uid(p, &uid)) {
		while (*p && *p != ' ') {
			p++; i++;
		}
		snprintf(nickbuf, i, "%s", chatbuf);
		snprintf(errbuf, MAX_CHAT - 8, "no such user \"%s\"", nickbuf);
		cmd_err(htlc, cid, "access", errbuf);
		return;
	}
	htlcp = isclient(uid);
	if (!htlcp) {
		snprintf(errbuf, MAX_CHAT - 8, "no such user (uid:%u)", uid);
		cmd_err(htlc, cid, "access", errbuf);
		return;
	}
	if (!htlcp->access_extra.access_volatile) {
		cmd_err(htlc, cid, "access", "user cannot be modified");
		return;
	}
	while (*p && *p != ' ')
		p++;
	while (*p && *p == ' ')
		p++;

	inaddr2str(abuf, &htlc->sockaddr);
	str = "";
	while (*p) {
		str = p;
		p = strchr(p, '=');
		if (!p)
			break;
		*p = 0;
		p++;
		val = *p == '1' ? 1 : 0;
		p++;
		f[0] = access_extra_set(&htlcp->access_extra, str, val);
		f[1] = set_access_bit(&htlcp->access, str, val);
		if (f[0] && f[1]) {
			snprintf(errbuf, MAX_CHAT - 8, "unknown argument \"%s\"", str);
			cmd_err(htlc, cid, "access", errbuf);
			return;
		}
		while (*p && *p != ' ')
			p++;
		while (*p && *p == ' ')
			p++;
	}
	hxd_log("%s@%s:%u - %s:%u:%u:%s modified access of %s:%u:%u:%s - %s",
				htlc->userid, abuf, ntohs(htlc->sockaddr.SIN_PORT),
				htlc->name, htlc->icon, htlc->uid, htlc->login,
				htlcp->name, htlcp->icon, htlcp->uid, htlcp->login, str);

	user_access_update(htlcp);
	snd_user_change(htlcp);
}
Example #6
0
void
cmd_exec (struct htlc_conn *htlc, u_int32_t cid, char *command)
{
	int argc, pfds[2], fakepfds[2];
	char *argv[32], myarg[32], *p, *pii, *thisarg, cmdpath[MAXPATHLEN];
	struct exec_file *execp;
	char errstr[64];
	int len, nolog=0, i;
	char *envp[6];
	char rootdir[MAXPATHLEN + 16];
	char accountdir[MAXPATHLEN + 16], account[32 + 16];
	char uptime[32 + 16];
	char version[6 + 16];
	u_int16_t style;
	char abuf[HOSTLEN+1];
	struct timeval now;
	time_t ts; 
	char tstr[32];

	if (htlc->nr_execs >= htlc->exec_limit) {
		style = htons(1);
		if (isclient(htlc->uid)) {
			len = snprintf(errstr, sizeof(errstr),
				"%u command%s at a time, please",
				htlc->exec_limit, htlc->exec_limit == 1 ? "" : "s");
			hlwrite(htlc, HTLS_HDR_MSG, 0, 2,
				HTLS_DATA_STYLE, 2, &style,
				HTLS_DATA_MSG, len, errstr);
		}
		return;
	} else if (nr_execs >= (u_int32_t)hxd_cfg.limits.total_exec) {
		style = htons(1);
		if (isclient(htlc->uid)) {
			len = snprintf(errstr, sizeof(errstr),
				"server is too busy, limit is %u command%s at a time",
				hxd_cfg.limits.total_exec,
				hxd_cfg.limits.total_exec == 1 ? "" : "s");
			hlwrite(htlc, HTLS_HDR_MSG, 0, 2,
				HTLS_DATA_STYLE, 2, &style,
				HTLS_DATA_MSG, len, errstr);
		}
		return;
	}

	while ((p = strstr(command, "../"))) {
		for (pii = p; *pii; pii++)
			*pii = *(pii + 3);
	}

	for (argc = 0, thisarg = p = command; *p && argc < 30; p++) {
		if (isspace(*p)) {
			*p = 0;
			argv[argc++] = thisarg;
			thisarg = p + 1;
		}
	}
	if (thisarg != p)
		argv[argc++] = thisarg;
	argv[argc] = 0;
	snprintf(cmdpath, sizeof(cmdpath), "%s/%s", hxd_cfg.paths.exec, argv[0]);
	snprintf(myarg, 30, thisarg);
	inaddr2str(abuf, &htlc->sockaddr);
	if (strlen(cmdpath) > 0 && strlen(myarg) > 0) {
		for (i = 0; hxd_cfg.options.exclude[i]; i++) {
			if (strstr(argv[0], hxd_cfg.options.exclude[i]))
				nolog = 1;
		}
		if (nolog == 0) {
			hxd_log("%s@%s:%u - %s:%s:%u - exec %s %s",
				htlc->userid, abuf, ntohs(htlc->sockaddr.SIN_PORT),
				htlc->name, htlc->login, htlc->uid, cmdpath, myarg);
#if defined(CONFIG_SQL)
		if (strncmp(cmdpath, "./login", 7 ))
			sql_exec(htlc->name, htlc->login, abuf, cmdpath, myarg);
#endif
		} else {
			hxd_log("%s@%s:%u - %s:%s:%u - exec %s",
				htlc->userid, abuf, ntohs(htlc->sockaddr.SIN_PORT),
				htlc->name,htlc->login,htlc->uid,cmdpath);
#if defined(CONFIG_SQL)
			sql_exec(htlc->name, htlc->login, abuf, cmdpath, " ");
#endif
		}
	}
	
	if (pipe(pfds)) {
		hxd_log("cmd_exec: pipe: %s", strerror(errno));
		return;
	}
	nr_open_files += 2;
	if (nr_open_files >= hxd_open_max) {
		hxd_log("%s:%d: %d >= hxd_open_max (%d)", __FILE__, __LINE__, pfds[0], hxd_open_max);
		close(pfds[0]);
		close(pfds[1]);
		nr_open_files -= 2;
		return;
	}

	switch (fork()) {
		case -1:
			hxd_log("cmd_exec: fork: %s", strerror(errno));
			close(pfds[0]);
			close(pfds[1]);
			nr_open_files -= 2;
			return;
		case 0:
			/* make sure fds 1 and 2 exist for dup2 */
			fakepfds[0] = fakepfds[1] = 0;
			pipe(fakepfds);
			if (pfds[1] != 1) {
				if (dup2(pfds[1], 1) == -1) {
					hxd_log("cmd_exec: dup2(%d,%d): %s",
						pfds[1], 1, strerror(errno));
					_exit(1);
				}
			}
			if (pfds[1] != 2) {
				if (dup2(pfds[1], 2) == -1) {
					hxd_log("cmd_exec: dup2(%d,%d): %s",
						pfds[1], 2, strerror(errno));
					_exit(1);
				}
			}
			close(0);
			if (fakepfds[0] > 2)
				close(fakepfds[0]);
			if (fakepfds[1] > 2)
				close(fakepfds[1]);
#if 0
			{
				int i;

				fprintf(stderr, "executing");
				for (i = 0; i < argc; i++)
					fprintf(stderr, " %s", argv[i]);
			}
#endif
			snprintf(rootdir, sizeof(rootdir), "ROOTDIR=%s", htlc->rootdir);
			snprintf(account, sizeof(account), "ACCOUNT=%s", htlc->login);
			snprintf(accountdir, sizeof(accountdir), "ACCOUNTDIR=%s", hxd_cfg.paths.accounts);
			gettimeofday(&now, 0);
			ts = tv_secdiff(&server_start_time, &now);
			human_time(ts, tstr);
			snprintf(uptime, sizeof(uptime), "UPTIME=%s", tstr);
			snprintf(version, sizeof(version), "VERSION=%s", hxd_version);
			envp[0] = rootdir;
			envp[1] = accountdir;
			envp[2] = account;
			envp[3] = uptime;
			envp[4] = version;
			envp[5] = 0;
			execve(cmdpath, argv, envp);
			fprintf(stderr, "\r%s: %s", argv[0], strerror(errno));
			_exit(1);
		default:
			close(pfds[1]);
			nr_open_files--;
			FD_SET(pfds[0], &exec_fds);
			execp = xmalloc(sizeof(struct exec_file));
			execp->htlc = htlc;
			execp->cid = cid;
			hxd_files[pfds[0]].conn.ptr = (void *)execp;
			hxd_files[pfds[0]].ready_read = exec_ready_read;
			FD_SET(pfds[0], &hxd_rfds);
			if (high_fd < pfds[0])
				high_fd = pfds[0];
			htlc->nr_execs++;
			nr_execs++;
			break;
	}
}