예제 #1
0
파일: h_mfmt.c 프로젝트: hydrix1/tacacs
void h_mfmt(struct context *ctx, char *arg)
{
    char *t;
    struct stat st;
    struct tm tm;

    DebugIn(DEBUG_COMMAND);

    t = arg;

    while (*arg && !isspace((int) *arg))
	arg++;

    if (!isspace((int) *arg)) {
	reply(ctx, MSG_500_arguments_required);
	DebugOut(DEBUG_COMMAND);
	return;
    }

    memset(&tm, 0, sizeof(tm));
    *arg++ = 0;

    if (*arg && 6 == sscanf(t, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)) {
	struct utimbuf ut;
	tm.tm_year -= 1900;
	tm.tm_mon--;
	ut.modtime = mktime(&tm);

	if ((t = buildpath(ctx, arg)) && (!pickystat(ctx, &st, t))
	    && (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
	    && st.st_uid == ctx->uid) {
	    ut.actime = st.st_atime;
	    if (utime(t, &ut))
		reply(ctx, MSG_550_Permission_denied);
	    else {
		struct stat sst;
		char u[40];
		if (stat(t, &sst))
		    sst.st_mtime = ut.modtime;
		strftime(u, sizeof(u), "213 Modify=%Y%m%d%H%M%S; ", gmtime(&sst.st_mtime));
		replyf(ctx, "%s%s\r\n", u, t);
	    }
	} else
	    reply(ctx, MSG_550_Permission_denied);
    } else
	reply(ctx, MSG_500_missing_filename);

    DebugOut(DEBUG_COMMAND);
}
예제 #2
0
bool http_servlet::doPost(acl::HttpServletRequest& req,
	acl::HttpServletResponse& res)
{
	// 如果需要 http session 控制,请打开下面注释,且需要保证
	// 在 master_service.cpp 的函数 thread_on_read 中设置的
	// memcached 服务正常工作
	/*
	const char* sid = req.getSession().getAttribute("sid");
	if (*sid == 0)
		req.getSession().setAttribute("sid", "xxxxxx");
	sid = req.getSession().getAttribute("sid");
	*/

	// 如果需要取得浏览器 cookie 请打开下面注释
	/*
	
	*/

	res.setContentType("text/xml; charset=utf-8")	// 设置响应字符集
		.setKeepAlive(req.isKeepAlive())	// 设置是否保持长连接
		.setContentEncoding(true)		// 自动支持压缩传输
		.setChunkedTransferEncoding(false);	// chunk 传输方式

	const char* cmd = req.getParameter("cmd");
	if (cmd == NULL || *cmd == 0)
	{
		logger_error("cmd not found");
		return replyf(req, res, 400, "%s", "no cmd");
	}

#define EQ	!strcasecmp

	acl::string buf;
	commands_action action(addr_, req, res, cmd);
	action.set_conf(conf_);
	int status = action.run(buf);
	return reply_json(req, res, status, buf);
}
예제 #3
0
파일: h_stor.c 프로젝트: hydrix1/tacacs
static void h_xstor(struct context *ctx, char *arg, int flags)
{
    char *t;
    int f = -1;
    struct stat st;
    int stou = 0;
    char tbuf[PATH_MAX + 1];

    DebugIn(DEBUG_COMMAND);

    if (ctx->transfer_in_progress) {
	reply(ctx, MSG_501_Transfer_in_progress);
	DebugOut(DEBUG_COMMAND);
	return;
    }

    ctx->outgoing_data = 0;
    if (ctx->dfn > -1 && io_get_cb_i(ctx->io, ctx->dfn) == (void *) accept_data) {
	io_set_i(ctx->io, ctx->dfn);
	io_clr_o(ctx->io, ctx->dfn);
	io_set_cb_e(ctx->io, ctx->dfn, (void *) cleanup_data);
	io_set_cb_h(ctx->io, ctx->dfn, (void *) cleanup_data);
    }

    quota_add(ctx, 0);

    if (ctx->quota_path && (ctx->quota_ondisk >= ctx->quota_limit)) {
	reply(ctx, MSG_451_quota_exceeded);
	logmsg("%s: quota limit reached", ctx->user);
	DebugOut(DEBUG_COMMAND);
	return;
    }

    if (!arg) {
	stou = -1;
	snprintf(tbuf, sizeof(tbuf), "%s/stou.XXXXXX", ctx->cwd);
	arg = tbuf;

	t = buildpath(ctx, arg);
    } else if (acl_binary_only(ctx, arg, (t = buildpath(ctx, arg)))) {
	reply(ctx, MSG_504_no_ascii);
	cleanup_data_reuse(ctx, ctx->dfn);
	DebugOut(DEBUG_COMMAND);
	return;
    }

    st.st_size = 0;

    if (t)
	acl_set_umask(ctx, arg, t);

    if (ctx->anonymous || stou)
	flags |= O_EXCL;

    if (t && (!ctx->anonymous || check_incoming(ctx, t, 077)) &&
	!pickystat_path(ctx, &st, t) &&
	(stat(t, &st), (f = myopen(t, O_RDWR | O_CREAT | O_LARGEFILE | O_NOFOLLOW | flags, ctx->chmod_filemask | (0644 & ~ctx->umask), stou)) > -1)) {

	fcntl(f, F_SETFD, FD_CLOEXEC);

	ctx->quota_filesize_before_stor = st.st_size;
	ctx->quota_update_on_close = 1;

	if (ctx->dfn < 0)
	    connect_port(ctx);

	if (ctx->dfn < 0) {
	    reply(ctx, MSG_431_Opening_datacon_failed);
	    close(f);
	    ctx->dbuf = buffer_free_all(ctx->dbuf);
	    DebugOut(DEBUG_COMMAND);
	    return;
	}

	ctx->ffn = f;
	if (strlen(t) >= sizeof(ctx->filename)) {
	    logerr("buffer too small in %s:%d (%s/%s)", __FILE__, __LINE__, ctx->user, t);
	    reply(ctx, MSG_551_Internal_error);
	    close(f);
	    cleanup(ctx, ctx->dfn);
	    ctx->dbuf = buffer_free_all(ctx->dbuf);
	    DebugOut(DEBUG_COMMAND);
	    return;
	}
	strcpy(ctx->filename, t);
	ctx->filesize = 0;
	ctx->bytecount = 0;

	if (io_get_cb_i(ctx->io, ctx->dfn) == (void *) socket2buffer || is_connected(ctx->dfn)) {
	    if (stou)
		replyf(ctx, "125 FILE: %s\r\n", ctx->filename + ctx->rootlen);
	    else
		replyf(ctx, MSG_125_Starting_dc, ctx->use_ascii ? "ASCII" : "BINARY", ctx->use_tls_d ? "TLS " : "");
	} else {
	    if (stou)
		replyf(ctx, "150 FILE: %s\r\n", ctx->filename + ctx->rootlen);
	    else
		replyf(ctx, MSG_150_Opening_dc, ctx->use_ascii ? "ASCII" : "BINARY", ctx->use_tls_d ? "TLS " : "");
	}

	ctx->transfer_in_progress = 1;

	if (ctx->io_offset) {
	    if (ctx->use_ascii) {
		ctx->offset = 0;
		ctx->remaining = st.st_size;
		io_sched_add(ctx->io, ctx, (void *) skipbytes, 0, 0);
#ifdef WITH_MMAP
		if (use_mmap)
		    ctx->iomode = IOMODE_mmap;
		else
#endif
		    ctx->iomode = IOMODE_read, ctx->iomode_fixed = 1;
	    } else {
		lseek(f, ctx->io_offset, SEEK_SET);
		ctx->io_offset = 0;
	    }
	}

	if (io_get_cb_i(ctx->io, ctx->dfn) == (void *) socket2buffer) {
	    /* already connected */
	    io_clr_o(ctx->io, ctx->dfn);
	    io_set_i(ctx->io, ctx->dfn);
	}

	ctx->transferstart = io_now.tv_sec;
	ctx->count_files++;
    } else {
	if (stou && errno == EEXIST)
	    reply(ctx, MSG_451_unique_file_failure);
	else
	    reply(ctx, MSG_550_Permission_denied);
	cleanup_data_reuse(ctx, ctx->dfn);
    }

    DebugOut(DEBUG_COMMAND);
}
예제 #4
0
파일: readme.c 프로젝트: hydrix1/tacacs
void file2control(struct context *ctx, char *arg, char *file)
{
    Debug((DEBUG_PROC, "+ %s (%s)\n", __func__, file ? file : "(NULL)"));

    if (file && ctx->multiline_banners) {
	int i = -1;
	struct stat st;
	int is_banner = file == ctx->welcome || file == ctx->banner || file == ctx->goodbye;
	char form[PATH_MAX + 1], path[PATH_MAX + 1];
	char *l, *t, llang[10];

	if (!is_banner && ctx->readme_once && (!pickystat(ctx, &st, ctx->cwd)) && dir_visited(ctx, &st)) {
	    Debug((DEBUG_PROC, "already visited\n"));
	    DebugOut(DEBUG_PROC);
	    return;
	}

	l = llang, t = lang[ctx->lang];
	*l++ = '-';
	while (*t)
	    *l++ = tolower((int) *t++);
	*l = 0;

	if ((sizeof(form) <= (size_t) snprintf(form, sizeof(form), "%s/%s", (is_banner || file[0] == '/')
					       ? "" : ctx->cwd, file)) || (sizeof(path) <= (size_t) snprintf(path, sizeof(path), form, llang))) {
	    DebugOut(DEBUG_PROC);
	    return;
	}

	if (is_banner) {
	    i = open(path, O_RDONLY);
	    if (i < 0 && strstr(form, "%s")) {
		if (sizeof(path) <= (size_t) snprintf(path, sizeof(path), form, "")) {
		    DebugOut(DEBUG_PROC);
		    return;
		}
		i = open(path, O_RDONLY);
	    }
	} else {
	    if (((pickystat(ctx, &st, path) || (i = open(path, O_RDONLY)) < 0)) && strstr(form, "%s")) {
		if (sizeof(path) <= (size_t) snprintf(path, sizeof(path), form, "")) {
		    DebugOut(DEBUG_PROC);
		    return;
		}
		if (!pickystat(ctx, &st, path))
		    i = open(path, O_RDONLY);
	    }

	    if (i > -1 && ctx->readme_notify) {
		long days_ago = (io_now.tv_sec - st.st_mtime) / 86400;
		char tb[2 * PATH_MAX];
		close(i);

		replyf(ctx, "%s-", arg);
		replyf(ctx, MSG_Readme_notify_1, file);

		strftime(tb, sizeof(tb), MSG_Readme_notify_2, localtime(&st.st_mtime));
		replyf(ctx, "%s-%s", arg, tb);

		if (days_ago == 1)
		    reply(ctx, MSG_Readme_notify_31);
		else
		    replyf(ctx, MSG_Readme_notify_3n, days_ago);

		DebugOut(DEBUG_PROC);
		return;
	    }
	}

	if (i > -1) {
	    char tbuf[BUFSIZE];
	    char *lineend, *linestart = NULL;
	    size_t offset = 0;
	    ssize_t inlength;

	    while ((inlength = read(i, tbuf + offset, sizeof(tbuf) - 1 - offset)) > 0) {
		inlength += offset;
		tbuf[inlength] = 0;
		linestart = tbuf;
		while ((lineend = strchr(linestart, '\n'))) {
		    *lineend = 0;
		    chomp(linestart);
		    replyf(ctx, "%s-%s\r\n", arg, cook(ctx, linestart, NULL, NULL, 0));
		    linestart = lineend + 1;
		}
#ifdef README_LOOP
/*
 * Don't allow arbitrary sized README files. Noone's able or willing to
 * read thousands of lines rushing by. BUFSIZE is our upper limit. For
 * unlimited file sizes, #define README_LOOP. Yes, that could be made
 * a configuration option. No, I don't think it makes sense.
 */
		if ((offset = tbuf + inlength - linestart))
		    memmove(tbuf, linestart, offset);
		else
#endif
		    break;
	    }
	    close(i);
	}
    }
    DebugOut(DEBUG_PROC);
}