int main(int argc, char **argv) { // test shell config struct stat shelltest; struct wordnode* commands; //head for list of possible paths to commands int rv = stat("shell-config", &shelltest); if (rv < 0) { printf("shell-config DNE. Please enter full path"); } else { int num_words = 0; commands = load_commands("shell-config",&num_words); //commands = "/bin/"; } char prompt[] = "prompt> "; printf("%s",prompt); fflush(stdout); int m=0; //keep track of mode char buffer[1024]; while (fgets(buffer, 1024, stdin) != NULL) { //handles comments, but only at the end of command int i=0; while (buffer[i]!='\0') { if (buffer[i]=='#') { buffer[i] = '\0'; i--; } i++; } // int size = size_of_array(buffer); char** argv = (char**) malloc(sizeof(char*)*(size+1)); make_array(buffer,argv,size); //print_array(argv,size); //printf("%d\n", size); if (m==0) { m = run_sequential(argv,size,commands); } else if (m==1) { m = run_par(argv,size); //pid_t pid; //int num; /*while ((pid = waitpid(-1, &stat, WNOHANG))>0) { printf("child process finished /n"); }*/ } printf("%s",prompt); } // end shell while loop free(argv); free_wordlist(commands); return 0; }
JSOBJECT* JS_NEW_ARRAY( JSContext* cx, uint32_t size ) { return make_array(cx, size); }
void test_op_assign (const T*, std::valarray<T>& (std::valarray<T>::*op_assign)(const std::valarray<T>&), const char *tname, // T's type name const char *opname, // which assignment operator int line, // test case line number const char *lhs_str, // left hand side of assignment const char *rhs_str, // right hand side of assignment const char *res_str) // result of assignment { std::size_t nelems = 0; std::size_t tmp; // create an array of values of type T from the string lhs_str // representing the left-hand side argument of the assignment const T* const lhs_array = make_array ((const T*)0, lhs_str, &nelems); // create an array of values of type T from the string rhs_str // representing the right-hand side argument of the assignment const T* const rhs_array = make_array ((const T*)0, rhs_str, &tmp); // both arguments of the assignment must have the same size RW_ASSERT (tmp == nelems); // create an array of values of type T from the string res_str // representing the result of the assignment const T* const res_array = make_array ((const T*)0, res_str, &tmp); // the result of the assignment must have the same size as both // arguments RW_ASSERT (tmp == nelems); // construct valarray arguments from the arrays created above /* const */ std::valarray<T> lhs_va (lhs_array, nelems); const std::valarray<T> rhs_va (rhs_array, nelems); char* fname = 0; std::size_t size = 0; // pointer to a counter keeping track of all objects of type T // in existence (non-null only for T=UserClass) const std::size_t* const pcounter = count ((const T*)0); // get the number of objects of type T (only possible for user // defined T) before invoking the operator std::size_t nobjects = pcounter ? *pcounter : 0; // format the name of the function call to be used in diagnostic // messages below rw_asnprintf (&fname, &size, "valarray<%s>(%s) %s std::valarray<%1$s>(%s)", tname, lhs_str, opname, rhs_str); // invoke the assignment operator through the member pointer std::valarray<T> &res = (lhs_va.*op_assign)(rhs_va); // verify that the resturned reference refers to the assignee rw_assert (&res == &lhs_va, 0, line, "line %d == %#p, got %#p", __LINE__, fname, &lhs_va, &res); // verify the size of the array rw_assert (lhs_va.size () == nelems, 0, line, "line %d. %s.size() == %zu, got %zu", __LINE__, fname, nelems, lhs_va.size ()); if (pcounter) { // verify that the assignment didn't leak any objects nobjects = *pcounter - nobjects; rw_assert (0 == nobjects, 0, line, "line %d. %s constucted %zu objects, expected %zu", __LINE__, fname, nobjects, nelems); } // verify the element values for (std::size_t i = 0; i != nelems; ++i) { if (!rw_assert (lhs_va [i] == res_array [i], 0, line, "line %d. %s: element at index %zu == %d, got %d", __LINE__, fname, i, value (res_array [i]), value (lhs_va [i]))) break; } delete_array (lhs_array, nelems); delete_array (rhs_array, nelems); std::free (fname); }
int main(int argc, char *argv[]) { unsigned char verbose = FALSE; char **respargv = NULL; const char *cmdopts = "hs:v"; register int i = 0; char *socket_file = PR_RUN_DIR "/proftpd.sock"; int sockfd = -1, optc = 0, status = 0, respargc = 0; unsigned int reqargc = 0; pool *ctl_pool = NULL; array_header *reqargv = NULL; /* Make sure we were called with at least one argument. */ if (argc-1 < 1) { fprintf(stdout, "%s: missing required arguments\n", program); exit(1); } /* Set the POSIXLY_CORRECT environment variable, so that control handlers * can themselves have optional flags. */ if (putenv("POSIXLY_CORRECT=1") < 0) { fprintf(stderr, "%s: unable to set POSIXLY_CORRECT: %s\n", program, strerror(errno)); exit(1); } opterr = 0; while ((optc = getopt(argc, argv, cmdopts)) != -1) { switch (optc) { case 'h': usage(); return 0; case 's': if (*optarg != '/') { fprintf(stderr, "%s: alternate socket path must be an absolute " "path\n", program); return 1; } socket_file = optarg; break; case 'v': verbose = TRUE; break; case '?': fprintf(stdout, "%s: unknown option: %c\n", program, (char) optopt); break; } } signal(SIGPIPE, sig_pipe); /* Allocate some memory for proftpd objects. */ ctl_pool = make_sub_pool(NULL); reqargv = make_array(ctl_pool, 0, sizeof(char *)); /* Process the command-line args into an array_header. */ for (i = optind; i < argc; i++) { if (verbose) fprintf(stdout, "%s: adding \"%s\" to reqargv\n", program, argv[i]); *((char **) push_array(reqargv)) = pstrdup(ctl_pool, argv[i]); reqargc++; } /* Don't forget to NULL-terminate the array. */ *((char **) push_array(reqargv)) = NULL; /* Open a connection to the socket maintained by mod_ctrls. */ if (verbose) fprintf(stdout, "%s: contacting server using '%s'\n", program, socket_file); sockfd = pr_ctrls_connect(socket_file); if (sockfd < 0) { fprintf(stderr, "%s: error contacting server using '%s': %s\n", program, socket_file, strerror(errno)); exit(1); } if (verbose) fprintf(stdout, "%s: sending control request\n", program); if (pr_ctrls_send_msg(sockfd, 0, reqargc, (char **) reqargv->elts) < 0) { fprintf(stderr, "%s: error sending request: %s\n", program, strerror(errno)); exit(1); } /* Read and display the responses. */ if (verbose) fprintf(stdout, "%s: receiving control response\n", program); /* Manually set errno to this value, so that if an error (like a segfault) * occurs, the error string displayed to the user is more indicative of * the cause of the lack of responses. */ errno = EPERM; if ((respargc = pr_ctrls_recv_response(ctl_pool, sockfd, &status, &respargv)) < 0) { fprintf(stdout, "%s: error receiving response: %s\n", program, strerror(errno)); exit(1); } if (respargv != NULL) { for (i = 0; i < respargc; i++) fprintf(stdout, "%s: %s\n", program, respargv[i]); } else fprintf(stdout, "%s: no response from server\n", program); destroy_pool(ctl_pool); ctl_pool = NULL; return 0; }
persistent_array_map_t* make_persistent_array_map() { persistent_array_map_t* map = malloc(sizeof(persistent_array_map_t)); map->arr = make_array(0); return map; }
int sftp_auth_kbdint_init(pool *p) { kbdint_drivers = make_array(p, 0, sizeof(char *)); return 0; }
cmd_rec *pr_parser_parse_line(pool *p) { register unsigned int i; char buf[PR_TUNABLE_BUFFER_SIZE+1], *arg = "", *word = NULL; cmd_rec *cmd = NULL; pool *sub_pool = NULL; array_header *arr = NULL; if (p == NULL) { errno = EINVAL; return NULL; } memset(buf, '\0', sizeof(buf)); while (pr_parser_read_line(buf, sizeof(buf)-1) != NULL) { char *bufp = buf; pr_signals_handle(); /* Build a new pool for the command structure and array */ sub_pool = make_sub_pool(p); pr_pool_tag(sub_pool, "parser cmd subpool"); cmd = pcalloc(sub_pool, sizeof(cmd_rec)); cmd->pool = sub_pool; cmd->stash_index = -1; cmd->stash_hash = 0; /* Add each word to the array */ arr = make_array(cmd->pool, 4, sizeof(char **)); while ((word = pr_str_get_word(&bufp, 0)) != NULL) { char *tmp; tmp = get_config_word(cmd->pool, word); *((char **) push_array(arr)) = tmp; cmd->argc++; } /* Terminate the array with a NULL. */ *((char **) push_array(arr)) = NULL; /* The array header's job is done, we can forget about it and * it will get purged when the command's pool is destroyed. */ cmd->argv = (char **) arr->elts; /* Perform a fixup on configuration directives so that: * * -argv[0]-- -argv[1]-- ----argv[2]----- * <Option /etc/adir /etc/anotherdir> * * becomes: * * -argv[0]-- -argv[1]- ----argv[2]---- * <Option> /etc/adir /etc/anotherdir */ if (cmd->argc && *(cmd->argv[0]) == '<') { char *cp = cmd->argv[cmd->argc-1]; if (*(cp + strlen(cp)-1) == '>' && cmd->argc > 1) { if (strncmp(cp, ">", 2) == 0) { cmd->argv[cmd->argc-1] = NULL; cmd->argc--; } else { *(cp + strlen(cp)-1) = '\0'; } cp = cmd->argv[0]; if (*(cp + strlen(cp)-1) != '>') { cmd->argv[0] = pstrcat(cmd->pool, cp, ">", NULL); } } } if (cmd->argc < 2) { arg = pstrdup(cmd->pool, arg); } for (i = 1; i < cmd->argc; i++) { arg = pstrcat(cmd->pool, arg, *arg ? " " : "", cmd->argv[i], NULL); } cmd->arg = arg; return cmd; } return NULL; }
constexpr array<T, N> make_array(const T(& arr)[N]) { return make_array(arr, std::make_index_sequence<N>{}); }
static array_header *sqltab_fetch_clients_cb(wrap2_table_t *sqltab, const char *name) { pool *tmp_pool = NULL; cmdtable *sql_cmdtab = NULL; cmd_rec *sql_cmd = NULL; modret_t *sql_res = NULL; array_header *sql_data = NULL; char *query = NULL, **vals = NULL; array_header *clients_list = NULL; /* Allocate a temporary pool for the duration of this read. */ tmp_pool = make_sub_pool(sqltab->tab_pool); query = ((char **) sqltab->tab_data)[0]; /* Find the cmdtable for the sql_lookup command. */ sql_cmdtab = pr_stash_get_symbol(PR_SYM_HOOK, "sql_lookup", NULL, NULL); if (sql_cmdtab == NULL) { wrap2_log("error: unable to find SQL hook symbol 'sql_lookup'"); destroy_pool(tmp_pool); return NULL; } /* Prepare the SELECT query. */ sql_cmd = sql_cmd_create(tmp_pool, 3, "sql_lookup", query, name); /* Call the handler. */ sql_res = call_module(sql_cmdtab->m, sql_cmdtab->handler, sql_cmd); /* Check the results. */ if (!sql_res) { wrap2_log("NamedQuery '%s' returned no data", query); destroy_pool(tmp_pool); return NULL; } if (MODRET_ISERROR(sql_res)) { wrap2_log("error processing NamedQuery '%s'", query); destroy_pool(tmp_pool); return NULL; } /* Construct a single string, concatenating the returned client tokens * together. */ sql_data = (array_header *) sql_res->data; vals = (char **) sql_data->elts; if (sql_data->nelts < 1) { wrap2_log("NamedQuery '%s' returned no data", query); destroy_pool(tmp_pool); return NULL; } clients_list = make_array(sqltab->tab_pool, sql_data->nelts, sizeof(char *)); *((char **) push_array(clients_list)) = pstrdup(sqltab->tab_pool, vals[0]); if (sql_data->nelts > 1) { register unsigned int i = 0; for (i = 1; i < sql_data->nelts; i++) { *((char **) push_array(clients_list)) = pstrdup(sqltab->tab_pool, vals[i]); } } destroy_pool(tmp_pool); return clients_list; }
cmd_rec *pr_parser_parse_line(pool *p, const char *text, size_t text_len) { register unsigned int i; char *arg = "", *ptr, *word = NULL; cmd_rec *cmd = NULL; pool *sub_pool = NULL; array_header *arr = NULL; if (p == NULL || text == NULL) { errno = EINVAL; return NULL; } if (text_len == 0) { text_len = strlen(text); } if (text_len == 0) { errno = ENOENT; return NULL; } ptr = (char *) text; /* Build a new pool for the command structure and array */ sub_pool = make_sub_pool(p); pr_pool_tag(sub_pool, "parser cmd subpool"); cmd = pcalloc(sub_pool, sizeof(cmd_rec)); cmd->pool = sub_pool; cmd->stash_index = -1; cmd->stash_hash = 0; /* Add each word to the array */ arr = make_array(cmd->pool, 4, sizeof(char **)); while ((word = pr_str_get_word(&ptr, 0)) != NULL) { char *ptr2; pr_signals_handle(); ptr2 = get_config_word(cmd->pool, word); *((char **) push_array(arr)) = ptr2; cmd->argc++; } /* Terminate the array with a NULL. */ *((char **) push_array(arr)) = NULL; /* The array header's job is done, we can forget about it and * it will get purged when the command's pool is destroyed. */ cmd->argv = (void **) arr->elts; /* Perform a fixup on configuration directives so that: * * -argv[0]-- -argv[1]-- ----argv[2]----- * <Option /etc/adir /etc/anotherdir> * * becomes: * * -argv[0]-- -argv[1]- ----argv[2]---- * <Option> /etc/adir /etc/anotherdir */ if (cmd->argc && *((char *) cmd->argv[0]) == '<') { char *cp; size_t cp_len; cp = cmd->argv[cmd->argc-1]; cp_len = strlen(cp); if (*(cp + cp_len-1) == '>' && cmd->argc > 1) { if (strncmp(cp, ">", 2) == 0) { cmd->argv[cmd->argc-1] = NULL; cmd->argc--; } else { *(cp + cp_len-1) = '\0'; } cp = cmd->argv[0]; cp_len = strlen(cp); if (*(cp + cp_len-1) != '>') { cmd->argv[0] = pstrcat(cmd->pool, cp, ">", NULL); } } } if (cmd->argc < 2) { arg = pstrdup(cmd->pool, arg); } for (i = 1; i < cmd->argc; i++) { arg = pstrcat(cmd->pool, arg, *arg ? " " : "", cmd->argv[i], NULL); } cmd->arg = arg; return cmd; }
constexpr array<T, End - Begin> make_array(const T* arr) { return make_array(arr + Begin, std::make_index_sequence<End - Begin>{}); }
static bool make_array(const char*& p, std::vector<calc_element>& oData) { while (true) { // 被演算子または単項演算子を取得 if ( *p == '(' ) { oData.push_back( calc_element("(", 110) ); if ( !make_array(++p, oData) ) // カッコ内を再帰処理 return false; // エラーはトップまで伝える if ( *p++ !=')' ) return false; oData.push_back( calc_element(")", 10) ); } else { if ( !isdigit(*p) && (*p)!='.') { string str; if ( *p=='!' ) str="!"; else if ( *p=='+' ) str="+"; else if ( *p=='-' ) str="-"; else return false; // 単項演算子じゃない、順番が変 ++p; oData.push_back( calc_element(str, 90) ); continue; } int len=0; while (isdigit(p[len]) || p[len]=='.') ++len; string str(p,len); if ( count(str,".")>=2 ) return false; // 小数点が2個以上ある oData.push_back( calc_element(str, 100) ); p+=len; } // 被演算子の後にのみ、正常脱出 if ( *p=='\0' || *p==')' ) return true; // 2項演算子を取得 const char* oprs[] = { // 長いもの順に比較するの。 "&&","||","==","!=","<=",">=","<",">","+","-","*","/"/*,"."*/}; int len=0, i=0; for (i=0 ; i<sizeof(oprs)/sizeof(oprs[0]) ; ++i) { len = strlen(oprs[i]); if ( strncmp(p, oprs[i], len) == 0 ) break; } if ( i==sizeof(oprs)/sizeof(oprs[0]) ) return false; // どの演算子でもない // 演算子に応じて優先度を設定 string str(p,len); p+=len; int priority; /*if ( str=="." ) { priority=85; } // 小数点 else */if ( str=="^" ) { priority=80; } else if ( str=="*" || str=="/" || str=="%" ) { priority=70; } else if ( str=="+" || str=="-" ) { priority=60; } else if ( str=="<" || str==">" || str=="<=" || str==">=" ) { priority=50; } else if ( str=="==" || str=="!=" ) { priority=45; } else if ( str=="&&" ) { priority=40; } else if ( str=="||" ) { priority=35; } else return false; oData.push_back( calc_element(str, priority) ); } }
static int parse_wildcard_config_path(pool *p, const char *path, unsigned int depth) { register unsigned int i; int res, xerrno; pool *tmp_pool; array_header *globbed_dirs = NULL; const char *component = NULL, *parent_path = NULL, *suffix_path = NULL; struct stat st; size_t path_len, component_len; char *name_pattern = NULL; void *dirh = NULL; struct dirent *dent = NULL; if (depth > PR_PARSER_INCLUDE_MAX_DEPTH) { pr_log_pri(PR_LOG_WARNING, "error: resolving wildcard pattern in '%s' " "exceeded maximum filesystem depth (%u)", path, (unsigned int) PR_PARSER_INCLUDE_MAX_DEPTH); errno = EINVAL; return -1; } path_len = strlen(path); if (path_len < 2) { pr_trace_msg(trace_channel, 7, "path '%s' too short to be wildcard path", path); /* The first character must be a slash, and we need at least one more * character in the path as a glob character. */ errno = EINVAL; return -1; } tmp_pool = make_sub_pool(p); pr_pool_tag(tmp_pool, "Include sub-pool"); /* We need to find the first component of the path which contains glob * characters. We then use the path up to the previous component as the * parent directory to open, and the glob-bearing component as the filter * for directories within the parent. */ component = path + 1; while (TRUE) { int last_component = FALSE; char *ptr; pr_signals_handle(); ptr = strchr(component, '/'); if (ptr != NULL) { component_len = ptr - component; } else { component_len = strlen(component); last_component = TRUE; } if (memchr(component, (int) '*', component_len) != NULL || memchr(component, (int) '?', component_len) != NULL || memchr(component, (int) '[', component_len) != NULL) { name_pattern = pstrndup(tmp_pool, component, component_len); if (parent_path == NULL) { parent_path = pstrndup(tmp_pool, "/", 1); } if (ptr != NULL) { suffix_path = pstrdup(tmp_pool, ptr + 1); } break; } if (parent_path != NULL) { parent_path = pdircat(tmp_pool, parent_path, pstrndup(tmp_pool, component, component_len), NULL); } else { parent_path = pstrndup(tmp_pool, "/", 1); } if (last_component) { break; } component = ptr + 1; } if (name_pattern == NULL) { pr_trace_msg(trace_channel, 4, "unable to process invalid, non-globbed path '%s'", path); errno = ENOENT; return -1; } pr_fs_clear_cache2(parent_path); if (pr_fsio_lstat(parent_path, &st) < 0) { xerrno = errno; pr_log_pri(PR_LOG_WARNING, "error: failed to check configuration path '%s': %s", parent_path, strerror(xerrno)); destroy_pool(tmp_pool); errno = xerrno; return -1; } if (S_ISLNK(st.st_mode) && !(parser_include_opts & PR_PARSER_INCLUDE_OPT_ALLOW_SYMLINKS)) { pr_log_pri(PR_LOG_WARNING, "error: cannot read configuration path '%s': Symbolic link", parent_path); destroy_pool(tmp_pool); errno = ENOTDIR; return -1; } pr_log_pri(PR_LOG_DEBUG, "processing configuration directory '%s' using pattern '%s', suffix '%s'", parent_path, name_pattern, suffix_path); dirh = pr_fsio_opendir(parent_path); if (dirh == NULL) { pr_log_pri(PR_LOG_WARNING, "error: unable to open configuration directory '%s': %s", parent_path, strerror(errno)); destroy_pool(tmp_pool); errno = EINVAL; return -1; } globbed_dirs = make_array(tmp_pool, 0, sizeof(char *)); while ((dent = pr_fsio_readdir(dirh)) != NULL) { pr_signals_handle(); if (strncmp(dent->d_name, ".", 2) == 0 || strncmp(dent->d_name, "..", 3) == 0) { continue; } if (parser_include_opts & PR_PARSER_INCLUDE_OPT_IGNORE_TMP_FILES) { if (is_tmp_file(dent->d_name) == TRUE) { pr_trace_msg(trace_channel, 19, "ignoring temporary file '%s' found in directory '%s'", dent->d_name, parent_path); continue; } } if (pr_fnmatch(name_pattern, dent->d_name, PR_FNM_PERIOD) == 0) { pr_trace_msg(trace_channel, 17, "matched '%s' path with wildcard pattern '%s'", dent->d_name, name_pattern); *((char **) push_array(globbed_dirs)) = pdircat(tmp_pool, parent_path, dent->d_name, suffix_path, NULL); } } pr_fsio_closedir(dirh); if (globbed_dirs->nelts == 0) { pr_log_pri(PR_LOG_WARNING, "error: no matches found for wildcard directory '%s'", path); destroy_pool(tmp_pool); errno = ENOENT; return -1; } depth++; qsort((void *) globbed_dirs->elts, globbed_dirs->nelts, sizeof(char *), config_filename_cmp); for (i = 0; i < globbed_dirs->nelts; i++) { const char *globbed_dir; globbed_dir = ((const char **) globbed_dirs->elts)[i]; res = parse_config_path2(p, globbed_dir, depth); if (res < 0) { xerrno = errno; pr_trace_msg(trace_channel, 7, "error parsing wildcard path '%s': %s", globbed_dir, strerror(xerrno)); destroy_pool(tmp_pool); errno = xerrno; return -1; } } destroy_pool(tmp_pool); return 0; }
int parse_config_path2(pool *p, const char *path, unsigned int depth) { struct stat st; int have_glob; void *dirh; struct dirent *dent; array_header *file_list; char *dup_path, *ptr; pool *tmp_pool; if (p == NULL || path == NULL || (depth > PR_PARSER_INCLUDE_MAX_DEPTH)) { errno = EINVAL; return -1; } if (pr_fs_valid_path(path) < 0) { errno = EINVAL; return -1; } have_glob = pr_str_is_fnmatch(path); if (have_glob) { /* Even though the path may be valid, it also may not be a filesystem * path; consider custom FSIO modules. Thus if the path does not start * with a slash, it should not be treated as having globs. */ if (*path != '/') { have_glob = FALSE; } } pr_fs_clear_cache2(path); if (have_glob) { pr_trace_msg(trace_channel, 19, "parsing '%s' as a globbed path", path); } if (!have_glob && pr_fsio_lstat(path, &st) < 0) { return -1; } /* If path is not a glob pattern, and is a symlink OR is not a directory, * then use the normal parsing function for the file. */ if (have_glob == FALSE && (S_ISLNK(st.st_mode) || !S_ISDIR(st.st_mode))) { int res, xerrno; PRIVS_ROOT res = pr_parser_parse_file(p, path, NULL, 0); xerrno = errno; PRIVS_RELINQUISH errno = xerrno; return res; } tmp_pool = make_sub_pool(p); pr_pool_tag(tmp_pool, "Include sub-pool"); /* Handle the glob/directory. */ dup_path = pstrdup(tmp_pool, path); ptr = strrchr(dup_path, '/'); if (have_glob) { int have_glob_dir; /* Note that we know, by definition, that ptr CANNOT be null here; dup_path * is a duplicate of path, and the first character (if nothing else) of * path MUST be a slash, per earlier checks. */ *ptr = '\0'; /* We just changed ptr, thus we DO need to check whether the now-modified * path contains fnmatch(3) characters again. */ have_glob_dir = pr_str_is_fnmatch(dup_path); if (have_glob_dir) { const char *glob_dir; if (parser_include_opts & PR_PARSER_INCLUDE_OPT_IGNORE_WILDCARDS) { pr_log_pri(PR_LOG_WARNING, "error: wildcard patterns not allowed in " "configuration directory name '%s'", dup_path); destroy_pool(tmp_pool); errno = EINVAL; return -1; } *ptr = '/'; glob_dir = pstrdup(p, dup_path); destroy_pool(tmp_pool); return parse_wildcard_config_path(p, glob_dir, depth); } ptr++; /* Check the directory component. */ pr_fs_clear_cache2(dup_path); if (pr_fsio_lstat(dup_path, &st) < 0) { int xerrno = errno; pr_log_pri(PR_LOG_WARNING, "error: failed to check configuration path '%s': %s", dup_path, strerror(xerrno)); destroy_pool(tmp_pool); errno = xerrno; return -1; } if (S_ISLNK(st.st_mode) && !(parser_include_opts & PR_PARSER_INCLUDE_OPT_ALLOW_SYMLINKS)) { pr_log_pri(PR_LOG_WARNING, "error: cannot read configuration path '%s': Symbolic link", path); destroy_pool(tmp_pool); errno = ENOTDIR; return -1; } if (have_glob_dir == FALSE && pr_str_is_fnmatch(ptr) == FALSE) { pr_log_pri(PR_LOG_WARNING, "error: wildcard pattern required for file '%s'", ptr); destroy_pool(tmp_pool); errno = EINVAL; return -1; } } pr_log_pri(PR_LOG_DEBUG, "processing configuration directory '%s'", dup_path); dirh = pr_fsio_opendir(dup_path); if (dirh == NULL) { pr_log_pri(PR_LOG_WARNING, "error: unable to open configuration directory '%s': %s", dup_path, strerror(errno)); destroy_pool(tmp_pool); errno = EINVAL; return -1; } file_list = make_array(tmp_pool, 0, sizeof(char *)); while ((dent = pr_fsio_readdir(dirh)) != NULL) { pr_signals_handle(); if (strncmp(dent->d_name, ".", 2) == 0 || strncmp(dent->d_name, "..", 3) == 0) { continue; } if (parser_include_opts & PR_PARSER_INCLUDE_OPT_IGNORE_TMP_FILES) { if (is_tmp_file(dent->d_name) == TRUE) { pr_trace_msg(trace_channel, 19, "ignoring temporary file '%s' found in directory '%s'", dent->d_name, dup_path); continue; } } if (have_glob == FALSE || (ptr != NULL && pr_fnmatch(ptr, dent->d_name, PR_FNM_PERIOD) == 0)) { *((char **) push_array(file_list)) = pdircat(tmp_pool, dup_path, dent->d_name, NULL); } } pr_fsio_closedir(dirh); if (file_list->nelts) { register unsigned int i; qsort((void *) file_list->elts, file_list->nelts, sizeof(char *), config_filename_cmp); for (i = 0; i < file_list->nelts; i++) { int res, xerrno; char *file; file = ((char **) file_list->elts)[i]; /* Make sure we always parse the files with root privs. The * previously parsed file might have had root privs relinquished * (e.g. by its directive handlers), but when we first start up, * we have root privs. See Bug#3855. */ PRIVS_ROOT res = pr_parser_parse_file(tmp_pool, file, NULL, 0); xerrno = errno; PRIVS_RELINQUISH if (res < 0) { pr_log_pri(PR_LOG_WARNING, "error: unable to open parse file '%s': %s", file, strerror(xerrno)); } } } destroy_pool(tmp_pool); return 0; }
int sftp_auth_publickey_init(pool *p) { publickey_fps = make_array(p, 0, sizeof(char *)); return 0; }
int pr_ipbind_listen(fd_set *readfds) { int listen_flags = PR_INET_LISTEN_FL_FATAL_ON_ERROR, maxfd = 0; register unsigned int i = 0; /* sanity check */ if (readfds == NULL) { errno = EINVAL; return -1; } FD_ZERO(readfds); if (binding_pool == NULL) { binding_pool = make_sub_pool(permanent_pool); pr_pool_tag(binding_pool, "Bindings Pool"); } /* Reset the listener list. */ if (!listener_list) { listener_list = make_array(binding_pool, 1, sizeof(conn_t *)); } else { /* Nasty hack to "clear" the list by making it think it has no * elements. */ listener_list->nelts = 0; } /* Slower than the hash lookup, but...we have to check each and every * ipbind in the table. */ for (i = 0; i < PR_BINDINGS_TABLE_SIZE; i++) { pr_ipbind_t *ipbind = NULL; for (ipbind = ipbind_table[i]; ipbind; ipbind = ipbind->ib_next) { /* Skip inactive bindings, but only if SocketBindTight is in effect. */ if (SocketBindTight && !ipbind->ib_isactive) continue; if (ipbind->ib_listener) { if (ipbind->ib_listener->mode == CM_NONE) { pr_inet_listen(ipbind->ib_listener->pool, ipbind->ib_listener, tcpBackLog, listen_flags); } if (ipbind->ib_listener->mode == CM_ACCEPT) { if (pr_inet_resetlisten(ipbind->ib_listener->pool, ipbind->ib_listener) < 0) { pr_trace_msg(trace_channel, 3, "error resetting %s#%u for listening: %s", pr_netaddr_get_ipstr(ipbind->ib_addr), ipbind->ib_port, strerror(errno)); } } if (ipbind->ib_listener->mode == CM_LISTEN) { FD_SET(ipbind->ib_listener->listen_fd, readfds); if (ipbind->ib_listener->listen_fd > maxfd) maxfd = ipbind->ib_listener->listen_fd; /* Add this to the listener list as well. */ *((conn_t **) push_array(listener_list)) = ipbind->ib_listener; } } } } return maxfd; }
int main(int argc, char **argv) { auto x = make_array(3, 2.); auto y = make_array<int>(3, 2.); return 0; }
int pr_namebind_create(server_rec *server, const char *name, const pr_netaddr_t *addr, unsigned int server_port) { pr_ipbind_t *ipbind = NULL; pr_namebind_t *namebind = NULL, **namebinds = NULL; unsigned int port; if (server == NULL || name == NULL) { errno = EINVAL; return -1; } /* First, find the ipbind to hold this namebind. */ port = ntohs(pr_netaddr_get_port(addr)); if (port == 0) { port = server_port; } ipbind = pr_ipbind_find(addr, port, FALSE); pr_trace_msg(trace_channel, 19, "found ipbind %p for namebind (name '%s', addr %s, port %u)", ipbind, name, pr_netaddr_get_ipstr(addr), port); if (ipbind == NULL) { pr_netaddr_t wildcard_addr; int addr_family; /* If not found, look for the wildcard address. */ addr_family = pr_netaddr_get_family(addr); pr_netaddr_clear(&wildcard_addr); pr_netaddr_set_family(&wildcard_addr, addr_family); pr_netaddr_set_sockaddr_any(&wildcard_addr); ipbind = pr_ipbind_find(&wildcard_addr, port, FALSE); #ifdef PR_USE_IPV6 if (ipbind == FALSE && addr_family == AF_INET6 && pr_netaddr_use_ipv6()) { /* No IPv6 wildcard address found; try the IPv4 wildcard address. */ pr_netaddr_clear(&wildcard_addr); pr_netaddr_set_family(&wildcard_addr, AF_INET); pr_netaddr_set_sockaddr_any(&wildcard_addr); ipbind = pr_ipbind_find(&wildcard_addr, port, FALSE); } #endif /* PR_USE_IPV6 */ pr_trace_msg(trace_channel, 19, "found wildcard ipbind %p for namebind (name '%s', addr %s, port %u)", ipbind, name, pr_netaddr_get_ipstr(addr), port); } if (ipbind == NULL) { errno = ENOENT; return -1; } /* Make sure we can add this namebind. */ if (!ipbind->ib_namebinds) { ipbind->ib_namebinds = make_array(binding_pool, 0, sizeof(pr_namebind_t *)); } else { register unsigned int i = 0; namebinds = (pr_namebind_t **) ipbind->ib_namebinds->elts; /* See if there is already a namebind for the given name. */ for (i = 0; i < ipbind->ib_namebinds->nelts; i++) { namebind = namebinds[i]; if (namebind != NULL && namebind->nb_name != NULL) { /* DNS names are case-insensitive, hence the case-insensitive check * here. * * XXX Ideally, we should check whether any existing namebinds which * are globs will match the newly added namebind as well. */ if (strcasecmp(namebind->nb_name, name) == 0) { errno = EEXIST; return -1; } } } } namebind = (pr_namebind_t *) pcalloc(server->pool, sizeof(pr_namebind_t)); namebind->nb_name = name; namebind->nb_server = server; namebind->nb_isactive = FALSE; if (pr_str_is_fnmatch(name) == TRUE) { namebind->nb_iswildcard = TRUE; } pr_trace_msg(trace_channel, 8, "created named binding '%s' for %s#%u, server %p", name, pr_netaddr_get_ipstr(server->addr), server->ServerPort, server->ServerName); /* The given server should already have the following populated: * * server->ServerName * server->ServerAddress * server->ServerFQDN */ /* These TCP socket tweaks will not apply to the control connection (it will * already have been established by the time this named vhost is used), * but WILL apply to any data connections established to this named vhost. */ #if 0 namebind->nb_server->tcp_mss_len = (server->tcp_mss_len ? server->tcp_mss_len : main_server->tcp_mss_len); namebind->nb_server->tcp_rcvbuf_len = (server->tcp_rcvbuf_len ? server->tcp_rcvbuf_len : main_server->tcp_rcvbuf_len); namebind->nb_server->tcp_rcvbuf_override = (server->tcp_rcvbuf_override ? TRUE : main_server->tcp_rcvbuf_override); namebind->nb_server->tcp_sndbuf_len = (server->tcp_sndbuf_len ? server->tcp_sndbuf_len : main_server->tcp_sndbuf_len); namebind->nb_server->tcp_sndbuf_override = (server->tcp_sndbuf_override ? TRUE : main_server->tcp_sndbuf_override); /* XXX Shouldn't need these; the ipbind container handles all of the * connection (listener, port, addr) stuff. */ namebind->nb_server->addr = (server->addr ? server->addr : main_server->addr); namebind->nb_server->ServerPort = (server->ServerPort ? server->ServerPort : main_server->ServerPort); namebind->nb_listener = (server->listen ? server->listen : main_server->listen); #endif *((pr_namebind_t **) push_array(ipbind->ib_namebinds)) = namebind; return 0; }
void save(output_archive& ar, const boost::multi_array<T, N, Allocator>& marray, unsigned) { ar & make_array(marray.shape(), marray.num_dimensions()); ar & make_array(marray.data(), marray.num_elements()); }
friend array<value_type, domain_type::rank> make_regular(array_expr const &x) { return make_array(x); }
static constexpr auto make(index_sequence<Is...>, index_sequence<Js...>, Ls... ls) { return make_array(make<F>(index_sequence<Is..., Js>{}, ls...)...); }
friend array_const_view<value_type, domain_type::rank> make_const_view(array_expr const &x) { return make_array(x); }
void test_ctor (const T*, const char *tname, CtorId which, bool copy, int line, const char *str, std::size_t nelems) { std::valarray<T> *pva = 0; T* const array = make_array ((const T*)0, str, &nelems); char* fname = 0; std::size_t size = 0; // pointer to a counter keepint track of all objects of type T // in existence (non-null only for T=UserClass) const std::size_t* const pcounter = count ((const T*)0); // get the number of objects of type T before invoking the ctor std::size_t nobjects = pcounter ? *pcounter : 0; switch (which) { case DefaultCtor: rw_asnprintf (&fname, &size, "valarray<%s>::valarray()", tname); pva = new std::valarray<T>; break; case SizeCtor: rw_asnprintf (&fname, &size, "valarray<%s>::valarray(size_t = %zu)", tname, nelems); pva = new std::valarray<T>(nelems); break; case ValueCtor: { rw_asnprintf (&fname, &size, "valarray<%s>::valarray(const %1$s& = %1$s(%d), " "size_t = %zu)", tname, value (array [0]), nelems); pva = new std::valarray<T>(array [0], nelems); break; } case ArrayCtor: { rw_asnprintf (&fname, &size, "valarray<%s>::valarray(const %1$s* = {%s}, " "size_t = %zu)", tname, str, nelems); pva = new std::valarray<T>(array, nelems); break; } } std::valarray<T> *psave = 0; if (copy) { char *tmpbuf = 0; std::size_t tmpsize = 0; rw_asnprintf (&tmpbuf, &tmpsize, "valarray<%s>::valarray(%s)", tname, fname); std::free (fname); fname = tmpbuf; size = tmpsize; // replace the stored object counter value nobjects = pcounter ? *pcounter : 0; // save the original and replace it with the new array psave = pva; // invoke the copy ctor pva = new std::valarray<T>(*pva); } // verify the size of the array rw_assert (pva->size () == nelems, 0, line, "line %d. %s.size() == %zu, got %zu", __LINE__, fname, nelems, pva->size ()); if (pcounter) { // compute the number of objects of type T constructed // by the ctor (valid only for T=UserClass) nobjects = *pcounter - nobjects; rw_assert (nobjects == nelems, 0, line, "line %d. %s constucted %zu objects, expected %zu", __LINE__, fname, nobjects, nelems); } // verify the element values for (std::size_t i = 0; i != nelems; ++i) { if (!((*pva)[i] == array [i])) { rw_assert (i == nelems, 0, line, "line %d. %s[%zu] == %s(%d), got %4$s(%d)", __LINE__, fname, i, tname, value (array [i]), value ((*pva)[i])); break; } } delete_array (array, nelems); // get the number of objects of type T before invoking the dtor nobjects = pcounter ? *pcounter : 0; delete pva; if (pcounter) { // compute the number of objects of type T destroyed by the dtor nobjects = nobjects - *pcounter; // verify that all objects constructed by the ctor have been // destroyed (i.e., none leaked) rw_assert (nobjects == nelems, 0, line, "line %d. %s dtor destroyed %zu objects, expected %zu", __LINE__, fname, nobjects, nelems); } delete psave; std::free (fname); }
static int zeqproc(i_ctx_t *i_ctx_p) { os_ptr op = osp; ref2_t stack[MAX_DEPTH + 1]; ref2_t *top = stack; make_array(&stack[0].proc1, 0, 1, op - 1); make_array(&stack[0].proc2, 0, 1, op); for (;;) { long i; if (r_size(&top->proc1) == 0) { /* Finished these arrays, go up to next level. */ if (top == stack) { /* We're done matching: it succeeded. */ make_true(op - 1); pop(1); return 0; } --top; continue; } /* Look at the next elements of the arrays. */ i = r_size(&top->proc1) - 1; array_get(imemory, &top->proc1, i, &top[1].proc1); array_get(imemory, &top->proc2, i, &top[1].proc2); r_dec_size(&top->proc1, 1); ++top; /* * Amazingly enough, the objects' executable attributes are not * required to match. This means { x load } will match { /x load }, * even though this is clearly wrong. */ #if 0 if (r_has_attr(&top->proc1, a_executable) != r_has_attr(&top->proc2, a_executable) ) break; #endif if (obj_eq(imemory, &top->proc1, &top->proc2)) { /* Names don't match strings. */ if (r_type(&top->proc1) != r_type(&top->proc2) && (r_type(&top->proc1) == t_name || r_type(&top->proc2) == t_name) ) break; --top; /* no recursion */ continue; } if (r_is_array(&top->proc1) && r_is_array(&top->proc2) && r_size(&top->proc1) == r_size(&top->proc2) && top < stack + (MAX_DEPTH - 1) ) { /* Descend into the arrays. */ continue; } break; } /* An exit from the loop indicates that matching failed. */ make_false(op - 1); pop(1); return 0; }
/** * @brief Create a range array from a port_range string. * * @param[in] port_range Valid port_range string. * * @return Range array. */ array_t* port_range_ranges (const char *port_range) { gchar **split, **point, *range_start, *current; array_t *ranges; int tcp; ranges = make_array (); while (*port_range && isblank (*port_range)) port_range++; /* Accepts T: and U: before any of the ranges. This toggles the remaining * ranges, as in nmap. Treats a leading naked range as TCP, whereas nmap * treats it as TCP and UDP. */ /* Treat newlines like commas. */ range_start = current = g_strdup (port_range); while (*current) { if (*current == '\n') *current = ','; current++; } tcp = 1; split = g_strsplit (range_start, ",", 0); g_free (range_start); point = split; while (*point) { gchar *hyphen, *element; range_t *range; element = g_strstrip (*point); if (strlen (element) >= 2) { if ((element[0] == 'T') && (element[1] == ':')) { tcp = 1; element = element + 2; } else if ((element[0] == 'U') && (element[1] == ':')) { tcp = 0; element = element + 2; } /* Else tcp stays as it is. */ } /* Skip any space that followed the type specifier. */ while (*element && isblank (*element)) element++; hyphen = strchr (element, '-'); if (hyphen) { *hyphen = '\0'; hyphen++; while (*hyphen && isblank (*hyphen)) hyphen++; assert (*hyphen); /* Validation checks this. */ /* A range. */ range = (range_t*) g_malloc0 (sizeof (range_t)); range->start = atoi (element); range->end = atoi (hyphen); range->type = tcp ? PORT_PROTOCOL_TCP : PORT_PROTOCOL_UDP; range->exclude = 0; array_add (ranges, range); } else if (*element) { /* A single port. */ range = (range_t*) g_malloc0 (sizeof (range_t)); range->start = atoi (element); range->end = range->start; range->type = tcp ? PORT_PROTOCOL_TCP : PORT_PROTOCOL_UDP; range->exclude = 0; array_add (ranges, range); } /* Else skip over empty range. */ point += 1; } g_strfreev (split); return ranges; }
void *vroot_fsio_opendir(pr_fs_t *fs, const char *orig_path) { int res, xerrno; char vpath[PR_TUNABLE_PATH_MAX + 1], *path = NULL; void *dirh = NULL; struct stat st; size_t pathlen = 0; pool *tmp_pool = NULL; unsigned int alias_count; if (session.curr_phase == LOG_CMD || session.curr_phase == LOG_CMD_ERR || (session.sf_flags & SF_ABORT) || vroot_path_have_base() == FALSE) { /* NOTE: once stackable FS modules are supported, have this fall through * to the next module in the stack. */ return opendir(orig_path); } tmp_pool = make_sub_pool(session.pool); pr_pool_tag(tmp_pool, "VRoot FSIO opendir pool"); /* If the given path ends in a slash, remove it. The handling of * VRootAliases is sensitive to trailing slashes. */ path = pstrdup(tmp_pool, orig_path); vroot_path_clean(path); /* If the given path ends in a slash, remove it. The handling of * VRootAliases is sensitive to such things. */ pathlen = strlen(path); if (pathlen > 1 && path[pathlen-1] == '/') { path[pathlen-1] = '\0'; pathlen--; } if (vroot_path_lookup(NULL, vpath, sizeof(vpath)-1, path, 0, NULL) < 0) { xerrno = errno; destroy_pool(tmp_pool); errno = xerrno; return NULL; } /* Check if the looked-up vpath is a symlink; we may need to resolve any * links ourselves, rather than assuming that the system opendir(3) can * handle it. */ res = vroot_fsio_lstat(fs, vpath, &st); while (res == 0 && S_ISLNK(st.st_mode)) { char data[PR_TUNABLE_PATH_MAX + 1]; pr_signals_handle(); memset(data, '\0', sizeof(data)); res = vroot_fsio_readlink(fs, vpath, data, sizeof(data)-1); if (res < 0) { break; } data[res] = '\0'; sstrncpy(vpath, data, sizeof(vpath)); res = vroot_fsio_lstat(fs, vpath, &st); } dirh = opendir(vpath); if (dirh == NULL) { xerrno = errno; (void) pr_log_writefile(vroot_logfd, MOD_VROOT_VERSION, "error opening virtualized directory '%s' (from '%s'): %s", vpath, path, strerror(xerrno)); destroy_pool(tmp_pool); errno = xerrno; return NULL; } alias_count = vroot_alias_count(); if (alias_count > 0) { unsigned long *cache_dirh = NULL; if (vroot_dirtab == NULL) { vroot_dir_pool = make_sub_pool(session.pool); pr_pool_tag(vroot_dir_pool, "VRoot Directory Pool"); vroot_dirtab = pr_table_alloc(vroot_dir_pool, 0); /* Since this table will use DIR pointers as keys, we want to override * the default hashing and key comparison functions used. */ pr_table_ctl(vroot_dirtab, PR_TABLE_CTL_SET_KEY_HASH, vroot_dirtab_hash_cb); pr_table_ctl(vroot_dirtab, PR_TABLE_CTL_SET_KEY_CMP, vroot_dirtab_keycmp_cb); } cache_dirh = palloc(vroot_dir_pool, sizeof(unsigned long)); *cache_dirh = (unsigned long) dirh; if (pr_table_kadd(vroot_dirtab, cache_dirh, sizeof(unsigned long), pstrdup(vroot_dir_pool, vpath), strlen(vpath) + 1) < 0) { (void) pr_log_writefile(vroot_logfd, MOD_VROOT_VERSION, "error stashing path '%s' (key %p) in directory table: %s", vpath, dirh, strerror(errno)); } else { vroot_dir_aliases = make_array(vroot_dir_pool, 0, sizeof(char *)); res = vroot_alias_do(vroot_alias_dirscan, vpath); if (res < 0) { (void) pr_log_writefile(vroot_logfd, MOD_VROOT_VERSION, "error doing dirscan on aliases table: %s", strerror(errno)); } else { register unsigned int i; (void) pr_log_writefile(vroot_logfd, MOD_VROOT_VERSION, "found %d %s in directory '%s'", vroot_dir_aliases->nelts, vroot_dir_aliases->nelts != 1 ? "VRootAliases" : "VRootAlias", vpath); vroot_dir_idx = 0; for (i = 0; i < vroot_dir_aliases->nelts; i++) { char **elts = vroot_dir_aliases->elts; (void) pr_log_writefile(vroot_logfd, MOD_VROOT_VERSION, "'%s' aliases: [%u] %s", vpath, i, elts[i]); } } } } destroy_pool(tmp_pool); return dirh; }
Array<float, 2> a2(2, 3); CHECK(a2.itemSize() == sizeof(float)); CHECK(a2.length() == 2 * 3); CHECK(a2.ndims() == 2); CHECK(a2.size(0) == 2); CHECK(a2.size(1) == 3); CHECK(a2.stride(0) == 1); CHECK(a2.stride(1) == 2); CHECK(a2.raw_ptr() != nullptr); CHECK_FALSE(empty(a2)); CHECK(byteSize(a2) == 2 * 3 * sizeof(int)); Array<double, 3> a3(make_array(2, 3, 4)); CHECK(a3.itemSize() == sizeof(double)); CHECK(a3.length() == 2 * 3 * 4); CHECK(a3.ndims() == 3); CHECK(a3.size(0) == 2); CHECK(a3.size(1) == 3); CHECK(a3.size(2) == 4); CHECK(a3.stride(0) == 1); CHECK(a3.stride(1) == 2); CHECK(a3.stride(2) == 6); CHECK(a3.raw_ptr() != nullptr); CHECK_FALSE(empty(a3)); CHECK(byteSize(a3) == 2 * 3 * 4 * sizeof(double));
MODRET wrap_handle_request(cmd_rec *cmd) { /* these variables are names expected to be set by the TCP wrapper code */ struct request_info request; char *user = NULL; config_rec *conf = NULL, *access_conf = NULL, *syslog_conf = NULL; hosts_allow_table = NULL; hosts_deny_table = NULL; /* hide passwords */ session.hide_password = TRUE; /* Sneaky...found in mod_auth.c's cmd_pass() function. Need to find the * login UID in order to resolve the possibly-login-dependent filename. */ user = pr_table_get(session.notes, "mod_auth.orig-user", NULL); /* It's possible that a PASS command came before USER. This is a PRE_CMD * handler, so it won't be protected from this case; we'll need to do * it manually. */ if (!user) return PR_DECLINED(cmd); /* Use mod_auth's _auth_resolve_user() [imported for use here] to get the * right configuration set, since the user may be logging in anonymously, * and the session struct hasn't yet been set for that yet (thus short- * circuiting the easiest way to get the right context...the macros. */ conf = wrap_resolve_user(cmd->pool, &user); /* Search first for user-specific access files. Multiple TCPUserAccessFiles * directives are allowed. */ if ((access_conf = find_config(conf ? conf->subset : CURRENT_CONF, CONF_PARAM, "TCPUserAccessFiles", FALSE)) != NULL) { int matched = FALSE; array_header *user_array = NULL; while (access_conf) { user_array = make_array(cmd->tmp_pool, 0, sizeof(char *)); *((char **) push_array(user_array)) = pstrdup(cmd->tmp_pool, user); /* Check the user expression -- don't forget the offset, to skip * the access file name strings in argv */ if (wrap_eval_expression(((char **) access_conf->argv) + 2, user_array)) { pr_log_debug(DEBUG4, MOD_WRAP_VERSION ": matched TCPUserAccessFiles expression"); matched = TRUE; break; } access_conf = find_config_next(access_conf, access_conf->next, CONF_PARAM, "TCPUserAccessFiles", FALSE); } if (!matched) access_conf = NULL; } /* Next, search for group-specific access files. Multiple * TCPGroupAccessFiles directives are allowed. */ if (!access_conf && (access_conf = find_config(conf ? conf->subset : CURRENT_CONF, CONF_PARAM, "TCPGroupAccessFiles", FALSE)) != NULL) { unsigned char matched = FALSE; /* NOTE: this gid_array is only necessary until Bug#1461 is fixed */ array_header *gid_array = make_array(cmd->pool, 0, sizeof(gid_t)); array_header *group_array = make_array(cmd->pool, 0, sizeof(char *)); while (access_conf) { if (pr_auth_getgroups(cmd->pool, user, &gid_array, &group_array) < 1) { pr_log_debug(DEBUG3, MOD_WRAP_VERSION ": no supplemental groups found for user '%s'", user); } else { /* Check the group expression -- don't forget the offset, to skip * the access file names strings in argv */ if (wrap_eval_expression(((char **) access_conf->argv) + 2, group_array)) { pr_log_debug(DEBUG4, MOD_WRAP_VERSION ": matched TCPGroupAccessFiles expression"); matched = TRUE; break; } } access_conf = find_config_next(access_conf, access_conf->next, CONF_PARAM, "TCPGroupAccessFiles", FALSE); } if (!matched) access_conf = NULL; } /* Finally for globally-applicable access files. Only one such directive * is allowed. */ if (!access_conf) { access_conf = find_config(conf ? conf->subset : CURRENT_CONF, CONF_PARAM, "TCPAccessFiles", FALSE); } if (access_conf) { hosts_allow_table = (char *) access_conf->argv[0]; hosts_deny_table = (char *) access_conf->argv[1]; } /* Now, check the retrieved filename, and see if it requires a login-time * file. */ if (hosts_allow_table != NULL && hosts_allow_table[0] == '~' && hosts_allow_table[1] == '/') { char *allow_real_table = NULL; allow_real_table = wrap_get_user_table(cmd, user, hosts_allow_table); if (!wrap_is_usable_file(allow_real_table)) { pr_log_pri(PR_LOG_WARNING, MOD_WRAP_VERSION ": configured TCPAllowFile %s is unusable", hosts_allow_table); hosts_allow_table = NULL; } else hosts_allow_table = allow_real_table; } if (hosts_deny_table != NULL && hosts_deny_table[0] == '~' && hosts_deny_table[1] == '/') { char *deny_real_table = NULL; deny_real_table = dir_realpath(cmd->pool, hosts_deny_table); if (!wrap_is_usable_file(deny_real_table)) { pr_log_pri(PR_LOG_WARNING, MOD_WRAP_VERSION ": configured TCPDenyFile %s is unusable", hosts_deny_table); hosts_deny_table = NULL; } else hosts_deny_table = deny_real_table; } /* Make sure that _both_ allow and deny TCPAccessFiles are present. * If not, log the missing file, and by default allow request to succeed. */ if (hosts_allow_table != NULL && hosts_deny_table != NULL) { /* Most common case...nothing more necessary */ } else if (hosts_allow_table == NULL && hosts_deny_table != NULL) { /* Log the missing file */ pr_log_pri(PR_LOG_INFO, MOD_WRAP_VERSION ": no usable allow access file -- " "allowing connection"); return PR_DECLINED(cmd); } else if (hosts_allow_table != NULL && hosts_deny_table == NULL) { /* log the missing file */ pr_log_pri(PR_LOG_INFO, MOD_WRAP_VERSION ": no usable deny access file -- " "allowing connection"); return PR_DECLINED(cmd); } else { /* Neither set -- assume the admin hasn't configured these directives * at all. */ return PR_DECLINED(cmd); } /* Log the names of the allow/deny files being used. */ pr_log_pri(PR_LOG_DEBUG, MOD_WRAP_VERSION ": using access files: %s, %s", hosts_allow_table, hosts_deny_table); /* retrieve the user-defined syslog priorities, if any. Fall back to the * defaults as seen in tcpd.h if not defined. */ syslog_conf = find_config(main_server->conf, CONF_PARAM, "TCPAccessSyslogLevels", FALSE); if (syslog_conf) { allow_severity = *((int *) syslog_conf->argv[0]); deny_severity = *((int *) syslog_conf->argv[1]); } else { allow_severity = PR_LOG_INFO; deny_severity = PR_LOG_WARNING; } /* While it may look odd to OR together the syslog facility and level, * that is the way that syslog(3) says to do it: * * "The priority argument is formed by ORing the facility and the level * values..." * * Note that we do this OR here because the allow_severity/deny_severity * values are ALSO used by the libwrap library; it is also why we need * to mask off some bits later, when using proftpd's logging functions. */ allow_severity = log_getfacility() | allow_severity; deny_severity = log_getfacility() | deny_severity; pr_log_debug(DEBUG4, MOD_WRAP_VERSION ": checking under service name '%s'", wrap_service_name); request_init(&request, RQ_DAEMON, wrap_service_name, RQ_FILE, session.c->rfd, 0); fromhost(&request); if (STR_EQ(eval_hostname(request.client), paranoid) || !hosts_access(&request)) { char *denymsg = NULL; /* log the denied connection */ wrap_log_request_denied(deny_severity, &request); /* Broadcast this event to any interested listeners. */ pr_event_generate("mod_wrap.connection-denied", NULL); /* check for AccessDenyMsg */ if ((denymsg = (char *) get_param_ptr(TOPLEVEL_CONF, "AccessDenyMsg", FALSE)) != NULL) denymsg = sreplace(cmd->tmp_pool, denymsg, "%u", user, NULL); if (denymsg) return PR_ERROR_MSG(cmd, R_530, denymsg); else return PR_ERROR_MSG(cmd, R_530, _("Access denied")); } /* If request is allowable, return DECLINED (for engine to act as if this * handler was never called, else ERROR (for engine to abort processing and * deny request. */ wrap_log_request_allowed(allow_severity, &request); return PR_DECLINED(cmd); }
pr_netaddr_t *pr_netaddr_get_addr(pool *p, const char *name, array_header **addrs) { struct sockaddr_in v4; #ifdef PR_USE_IPV6 struct sockaddr_in6 v6; #endif /* PR_USE_IPV6 */ pr_netaddr_t *na = NULL; int res; if (p == NULL || name == NULL) { errno = EINVAL; return NULL; } /* Attempt to translate the given name into a pr_netaddr_t using * pr_inet_pton() first. * * First, if IPv6 support is enabled, we try to translate the name using * pr_inet_pton(AF_INET6) on the hopes that the given string is a valid * representation of an IPv6 address. If that fails, or if IPv6 support * is not enabled, we try with pr_inet_pton(AF_INET). If that fails, we * assume that the given name is a DNS name, and we call pr_getaddrinfo(). */ na = (pr_netaddr_t *) pcalloc(p, sizeof(pr_netaddr_t)); #ifdef PR_USE_IPV6 memset(&v6, 0, sizeof(v6)); v6.sin6_family = AF_INET6; # ifdef SIN6_LEN v6.sin6_len = sizeof(struct sockaddr_in6); # endif /* SIN6_LEN */ res = pr_inet_pton(AF_INET6, name, &v6.sin6_addr); if (res > 0) { pr_netaddr_set_family(na, AF_INET6); pr_netaddr_set_sockaddr(na, (struct sockaddr *) &v6); if (addrs) *addrs = NULL; pr_log_debug(DEBUG10, "'%s' resolved to an IPv6 address", name); return na; } #endif memset(&v4, 0, sizeof(v4)); v4.sin_family = AF_INET; # ifdef SIN_LEN v4.sin_len = sizeof(struct sockaddr_in); # endif /* SIN_LEN */ res = pr_inet_pton(AF_INET, name, &v4.sin_addr); if (res > 0) { pr_netaddr_set_family(na, AF_INET); pr_netaddr_set_sockaddr(na, (struct sockaddr *) &v4); if (addrs) *addrs = NULL; pr_log_debug(DEBUG10, "'%s' resolved to an IPv4 address", name); return na; } else if (res == 0) { /* If pr_inet_pton() returns 0, it means that name does not represent a * valid network address in the specified address family. Usually, * this means that name is actually a DNS name, not an IP address * string. So we treat it as a DNS name, and use getaddrinfo(3) to * resolve that name to its IP address(es). */ struct addrinfo hints, *info = NULL; int gai_res = 0; memset(&hints, 0, sizeof(hints)); #ifdef PR_USE_IPV6 /* This looks up both IPv4 (as IPv6-mapped) and IPv6 addresses. */ hints.ai_family = AF_UNSPEC; #else hints.ai_family = AF_INET; #endif /* PR_USE_IPV6 */ hints.ai_socktype = SOCK_STREAM; pr_log_debug(DEBUG10, "attempting to resolve '%s' via DNS", name); gai_res = pr_getaddrinfo(name, NULL, &hints, &info); if (gai_res != 0) { pr_log_pri(PR_LOG_INFO, "getaddrinfo '%s' error: %s", name, res != EAI_SYSTEM ? pr_gai_strerror(gai_res) : strerror(errno)); return NULL; } if (info) { pr_log_debug(DEBUG10, "resolved '%s' to an %s address", name, info->ai_family == AF_INET ? "IPv4" : "IPv6"); /* Copy the first returned addr into na, as the return value. */ pr_netaddr_set_family(na, info->ai_family); pr_netaddr_set_sockaddr(na, info->ai_addr); /* If the caller provided a pointer for any additional addresses, * then we cycle through the rest of getaddrinfo(3)'s results and * build a list to return to the caller. */ if (addrs) { struct addrinfo *ai; *addrs = make_array(p, 0, sizeof(pr_netaddr_t *)); for (ai = info->ai_next; ai; ai = ai->ai_next) { pr_netaddr_t **elt = push_array(*addrs); *elt = pcalloc(p, sizeof(pr_netaddr_t)); pr_netaddr_set_family(*elt, ai->ai_family); pr_netaddr_set_sockaddr(*elt, ai->ai_addr); } } pr_freeaddrinfo(info); return na; } } pr_log_debug(DEBUG10, "failed to resolve '%s' to an IP address", name); return NULL; }
static bool on_begin_array (void * userContext, const string & name) { user_context * ctx = static_cast<user_context *>(userContext); ctx->ptr_stack.push(add_value(ctx, name, make_array())); return true; }