📄 mod_wrap2.c
字号:
tab->tab_name = "builtin"; /* Set the necessary callbacks. */ tab->tab_close = builtin_close_cb; tab->tab_fetch_clients = builtin_fetch_clients_cb; tab->tab_fetch_daemons = builtin_fetch_daemons_cb; tab->tab_fetch_options = builtin_fetch_options_cb; return tab;}/* Configuration handlers *//* usage: Wrap{Allow,Deny}Msg mesg */MODRET set_wrapmsg(cmd_rec *cmd) { config_rec *c = NULL; CHECK_ARGS(cmd, 1); CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL|CONF_ANON); c = add_config_param_str(cmd->argv[0], 1, cmd->argv[1]); c->flags |= CF_MERGEDOWN; return PR_HANDLED(cmd);}/* usage: WrapEngine on|off */MODRET set_wrapengine(cmd_rec *cmd) { int bool = -1; config_rec *c = NULL; CHECK_ARGS(cmd, 1); CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL); if ((bool = get_boolean(cmd, 1)) == -1) CONF_ERROR(cmd, "expecting Boolean parameter"); c = add_config_param(cmd->argv[0], 1, NULL); c->argv[0] = pcalloc(c->pool, sizeof(unsigned char)); *((unsigned char *) c->argv[0]) = (unsigned char) bool; return PR_HANDLED(cmd);}/* usage: WrapGroupTables group-and-expression allow-table deny-table */MODRET set_wrapgrouptables(cmd_rec *cmd) { register wrap2_regtab_t *regtab = NULL; register unsigned int i = 0; unsigned char have_registration = FALSE; config_rec *c = NULL; int argc = 1; char **argv = NULL; array_header *acl = NULL; CHECK_ARGS(cmd, 3); CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL); /* Verify that the requested source types have been registered. */ for (i = 2; i < cmd->argc-1; i++) { char *tmp = NULL; if ((tmp = strchr(cmd->argv[i], ':')) == NULL) CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "badly table parameter: '", cmd->argv[i], "'", NULL)); *tmp = '\0'; for (regtab = wrap2_regtab_list; regtab; regtab = regtab->next) if (!strcmp(regtab->regtab_name, cmd->argv[i])) { have_registration = TRUE; break; } if (!have_registration) CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "unsupported table source type: '", cmd->argv[1], "'", NULL)); *tmp = ':'; } c = add_config_param(cmd->argv[0], 0); acl = pr_expr_create(cmd->tmp_pool, &argc, &cmd->argv[0]); /* Build the desired config_rec manually. */ c->argc = argc + 2; c->argv = pcalloc(c->pool, (argc + 3) * sizeof(char *)); argv = (char **) c->argv; /* The tables are the first two parameters */ *argv++ = pstrdup(c->pool, cmd->argv[2]); *argv++ = pstrdup(c->pool, cmd->argv[3]); /* Now populate the group-expression names */ if (argc && acl) while (argc--) { *argv++ = pstrdup(c->pool, *((char **) acl->elts)); acl->elts = ((char **) acl->elts) + 1; } /* Do not forget the terminating NULL */ *argv = NULL; c->flags |= CF_MERGEDOWN; return PR_HANDLED(cmd);}/* usage: WrapLog file|"none" */MODRET set_wraplog(cmd_rec *cmd) { CHECK_ARGS(cmd, 1); CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL); add_config_param_str(cmd->argv[0], 1, cmd->argv[1]); return PR_HANDLED(cmd);}/* usage: WrapServiceName <name> */MODRET set_wrapservicename(cmd_rec *cmd) { CHECK_ARGS(cmd, 1); CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL); add_config_param_str(cmd->argv[0], 1, cmd->argv[1]); return PR_HANDLED(cmd);}/* usage: WrapTables allow-table deny-table */MODRET set_wraptables(cmd_rec *cmd) { register wrap2_regtab_t *regtab = NULL; register unsigned int i = 0; unsigned char have_registration = FALSE; config_rec *c = NULL; CHECK_ARGS(cmd, 2); CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL); /* Verify that the requested source types have been registered. */ for (i = 1; i < cmd->argc-1; i++) { char *tmp = NULL; if ((tmp = strchr(cmd->argv[i], ':')) == NULL) CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "badly table parameter: '", cmd->argv[i], "'", NULL)); *tmp = '\0'; for (regtab = wrap2_regtab_list; regtab; regtab = regtab->next) if (!strcmp(regtab->regtab_name, cmd->argv[i])) { have_registration = TRUE; break; } if (!have_registration) CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "unsupported table source type: '", cmd->argv[1], "'", NULL)); *tmp = ':'; } c = add_config_param_str(cmd->argv[0], 2, cmd->argv[1], cmd->argv[2]); c->flags |= CF_MERGEDOWN; return PR_HANDLED(cmd);}/* usage: WrapUserTables user-or-expression allow-table deny-table */MODRET set_wrapusertables(cmd_rec *cmd) { register wrap2_regtab_t *regtab = NULL; register unsigned int i = 0; unsigned char have_registration = FALSE; config_rec *c = NULL; int argc = 1; char **argv = NULL; array_header *acl = NULL; CHECK_ARGS(cmd, 3); CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL); /* Verify that the requested source types have been registered. */ for (i = 2; i < cmd->argc-1; i++) { char *tmp = NULL; if ((tmp = strchr(cmd->argv[i], ':')) == NULL) CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "badly table parameter: '", cmd->argv[i], "'", NULL)); *tmp = '\0'; for (regtab = wrap2_regtab_list; regtab; regtab = regtab->next) if (!strcmp(regtab->regtab_name, cmd->argv[i])) { have_registration = TRUE; break; } if (!have_registration) CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "unsupported table source type: '", cmd->argv[1], "'", NULL)); *tmp = ':'; } c = add_config_param(cmd->argv[0], 0); acl = pr_expr_create(cmd->tmp_pool, &argc, &cmd->argv[0]); /* Build the desired config_rec manually. */ c->argc = argc + 2; c->argv = pcalloc(c->pool, (argc + 3) * sizeof(char *)); argv = (char **) c->argv; /* The tables are the first two parameters */ *argv++ = pstrdup(c->pool, cmd->argv[2]); *argv++ = pstrdup(c->pool, cmd->argv[3]); /* Now populate the user-expression names */ if (argc && acl) while (argc--) { *argv++ = pstrdup(c->pool, *((char **) acl->elts)); acl->elts = ((char **) acl->elts) + 1; } /* Do not forget the terminating NULL */ *argv = NULL; c->flags |= CF_MERGEDOWN; return PR_HANDLED(cmd);}/* Command handlers */MODRET wrap2_pre_pass(cmd_rec *cmd) { wrap2_conn_t con; unsigned char have_tables = FALSE; char *user = NULL; config_rec *c = NULL; if (!wrap2_engine) return PR_DECLINED(cmd); /* Hide passwords */ session.hide_password = TRUE; user = get_param_ptr(cmd->server->conf, C_USER, FALSE); if (!user) return PR_DECLINED(cmd); wrap2_ctxt = pr_auth_get_anon_config(cmd->pool, &user, NULL, NULL); if (!user) return PR_DECLINED(cmd); { /* Cheat a little here, and pre-populate some of session's members. Do * not worry: these values are only temporary, and will be overwritten * during the login process. This needs to be done here, before the * call to wrap2_allow_access(), for that function does the opening of * the tables. */ struct passwd *pw = NULL; pw = pr_auth_getpwnam(cmd->pool, user); if (pw != NULL) { struct group *gr = NULL; /* For the dir_realpath() function to work, some session members need to * be set. */ session.user = pstrdup(cmd->pool, pw->pw_name); session.login_uid = pw->pw_uid; session.login_gid = pw->pw_gid; gr = pr_auth_getgrgid(cmd->pool, session.login_gid); if (gr != NULL) session.group = pstrdup(cmd->pool, gr->gr_name); else wrap2_log("unable to resolve GID for '%s'", user); } else { wrap2_log("unable to resolve UID for '%s'", user); return PR_DECLINED(cmd); } } /* Search first for user-specific access tables. Multiple WrapUserTables * directives are allowed. */ c = find_config(wrap2_ctxt ? wrap2_ctxt->subset : main_server->conf, CONF_PARAM, "WrapUserTables", FALSE); while (c) { array_header *user_array = make_array(cmd->tmp_pool, 0, sizeof(char *)); *((char **) push_array(user_array)) = pstrdup(cmd->tmp_pool, user); /* Check the user OR expression. Do not forget the offset, to skip * the table name strings in c->argv. */ if (wrap2_eval_or_expression((char **) &c->argv[2], user_array)) { wrap2_log("matched WrapUserTables expression for user '%s'", user); wrap2_allow_table = c->argv[0]; wrap2_deny_table = c->argv[1]; wrap2_client_name = session.user; have_tables = TRUE; c = NULL; break; } c = find_config_next(c, c->next, CONF_PARAM, "WrapUserTables", FALSE); } /* Next, search for group-specific access tables. Multiple WrapGroupTables * directives are allowed. */ if (!have_tables) c = find_config(wrap2_ctxt ? wrap2_ctxt->subset : main_server->conf, CONF_PARAM, "WrapGroupTables", FALSE); while (c) { array_header *gid_array = make_array(cmd->pool, 0, sizeof(gid_t)); array_header *group_array = make_array(cmd->pool, 0, sizeof(char *)); if (pr_auth_getgroups(cmd->pool, user, &gid_array, &group_array) < 1) wrap2_log("no supplemental groups found for user '%s'", user); else { /* Check the group AND expression. Do not forget the offset, to skip * the table names strings in c->argv. */ if (wrap2_eval_and_expression((char **) &c->argv[2], group_array)) { wrap2_log("matched WrapGroupTables expression for user '%s'", user); wrap2_allow_table = c->argv[0]; wrap2_deny_table = c->argv[1]; wrap2_client_name = session.group; have_tables = TRUE; c = NULL; break; } } c = find_config_next(c, c->next, CONF_PARAM, "WrapGroupTables", FALSE); } /* Finally for globally-applicable access files. Only one such directive * is allowed. */ if (!have_tables) c = find_config(wrap2_ctxt ? wrap2_ctxt->subset : main_server->conf, CONF_PARAM, "WrapTables", FALSE); if (c) { wrap2_allow_table = c->argv[0]; wrap2_deny_table = c->argv[1]; wrap2_client_name = ""; have_tables = TRUE; } if (have_tables) { /* Log the names of the allow/deny tables being used. */ wrap2_log("using '%s' for allow table", wrap2_allow_table); wrap2_log("using '%s' for deny table", wrap2_deny_table); } else { wrap2_log("no tables configured, allowing connection"); return PR_DECLINED(cmd); } wrap2_log("looking under service name '%s'", wrap2_service_name); memset(&con, '\0', sizeof(con)); wrap2_conn_set(&con, WRAP2_CONN_DAEMON, wrap2_service_name, WRAP2_CONN_SOCK_FD, session.c->rfd, 0); wrap2_log("%s", "checking access rules for connection"); if (strcasecmp(wrap2_get_hostname(con.client), WRAP2_PARANOID) == 0 || !wrap2_allow_access(&con)) { char *msg = NULL; /* Log the denied connection */ wrap2_log("refused connection from %s", wrap2_get_client(&con)); /* Check for a configured WrapDenyMsg. If not present, then use the * default denied message. */ msg = get_param_ptr(wrap2_ctxt ? wrap2_ctxt->subset : main_server->conf, "WrapDenyMsg", FALSE); if (msg != NULL) msg = sreplace(cmd->tmp_pool, msg, "%u", user, NULL); pr_response_send(R_530, msg ? msg : "Access denied"); end_login(0); } wrap2_log("allowed connection from %s", wrap2_get_client(&con)); return PR_DECLINED(cmd);}MODRET wrap2_post_pass(cmd_rec *cmd) { char *msg = NULL; if (!wrap2_engine) return PR_DECLINED(cmd); /* Check for a configured WrapAllowMsg. If the connection were denied, * it would have been terminated before reaching this command handler. */ msg = get_param_ptr(wrap2_ctxt ? wrap2_ctxt->subset : main_server->conf, "WrapAllowMsg", FALSE); if (msg != NULL) { char *user = get_param_ptr(cmd->server->conf, C_USER, FALSE); msg = sreplace(cmd->tmp_pool, msg, "%u", user, NULL); pr_response_add(R_DUP, "%s", msg); } return PR_DECLINED(cmd);}/* Event handlers */static void wrap2_exit_ev(const void *event_data, void *user_data) { wrap2_closelog(); return;}#if defined(PR_SHARED_MODULE)static void wrap2_mod_unload_ev(const void *event_data, void *user_data) { if (strcmp("mod_wrap2.c", (const char *) event_data) == 0) { /* Unregister ourselves from all events. */ pr_event_unregister(&wrap2_module, NULL, NULL); if (wrap2_pool) { destroy_pool(wrap2_pool); wrap2_pool = NULL; } }}#endif /* PR_SHARED_MODULE */static void wrap2_restart_ev(const void *event_data, void *user_data) { /* Bounce the log file descriptor. */ wrap2_closelog(); wrap2_openlog(); /* Reset the module's memory pool. */ destroy_pool(wrap2_pool); wrap2_pool = make_sub_pool(permanent_pool); pr_pool_tag(wrap2_pool, MOD_WRAP2_VERSION);}/* Initialization routines */static int wrap2_init(void) { /* Initialize the module's memory pool. */ if (!wrap2_pool) { wrap2_pool = make_sub_pool(permanent_pool); pr_pool_tag(wrap2_pool, MOD_WRAP2_VERSION); }#if defined(PR_SHARED_MODULE) pr_event_register(&wrap2_module, "core.module-unload", wrap2_mod_unload_ev, NULL);#endif /* PR_SHARED_MODULE */ pr_event_register(&wrap2_module, "core.restart", wrap2_restart_ev, NULL); /* Initialize the source object for type "builtin". */ wrap2_register("builtin", builtin_open_cb); return 0;}static int wrap2_sess_init(void) { unsigned char *engine = NULL; engine = get_param_ptr(main_server->conf, "WrapEngine", FALSE); if (engine != NULL && *engine == TRUE) wrap2_engine = TRUE; else { wrap2_engine = FALSE; return 0; } /* Look up any configured WrapServiceName */ wrap2_service_name = get_param_ptr(main_server->conf, "WrapServiceName", FALSE); if (wrap2_service_name == NULL) wrap2_service_name = WRAP2_DEFAULT_SERVICE_NAME; wrap2_openlog(); /* Make sure that tables will be closed when the child exits. */ pr_event_register(&wrap2_module, "core.exit", wrap2_exit_ev, NULL); return 0;}/* Module API tables */static conftable wrap2_conftab[] = { { "WrapAllowMsg", set_wrapmsg, NULL }, { "WrapDenyMsg", set_wrapmsg, NULL }, { "WrapEngine", set_wrapengine, NULL }, { "WrapGroupTables", set_wrapgrouptables, NULL }, { "WrapLog", set_wraplog, NULL }, { "WrapServiceName", set_wrapservicename, NULL }, { "WrapTables", set_wraptables, NULL }, { "WrapUserTables", set_wrapusertables, NULL }, { NULL }};static cmdtable wrap2_cmdtab[] = { { PRE_CMD, C_PASS, G_NONE, wrap2_pre_pass, FALSE, FALSE }, { POST_CMD, C_PASS, G_NONE, wrap2_post_pass,FALSE, FALSE }, { 0, NULL }};module wrap2_module = { NULL, NULL, /* Module API version 2.0 */ 0x20, /* Module name */ "wrap2", /* Mmodule configuration handler table */ wrap2_conftab, /* Module command handler table */ wrap2_cmdtab, /* Module authentication handler table */ NULL, /* Module initialization */ wrap2_init, /* Session initialization */ wrap2_sess_init, /* Module version */ MOD_WRAP2_VERSION};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -