// Initialize users garray and fill it with os usernames. // Return Ok for success, FAIL for failure. int os_get_usernames(garray_T *users) { if (users == NULL) { return FAIL; } ga_init(users, sizeof(char *), 20); # if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H) char *user; struct passwd *pw; setpwent(); while ((pw = getpwent()) != NULL) { // pw->pw_name shouldn't be NULL but just in case... if (pw->pw_name != NULL) { ga_grow(users, 1); user = xstrdup(pw->pw_name); ((char **)(users->ga_data))[users->ga_len++] = user; } } endpwent(); # endif return OK; }
int duo_check_groups(struct passwd *pw, char **groups, int groups_cnt) { int i; if (groups_cnt > 0) { int matched = 0; if (ga_init(pw->pw_name, pw->pw_gid) < 0) { duo_log(LOG_ERR, "Couldn't get groups", pw->pw_name, NULL, strerror(errno)); return (-1); } for (i = 0; i < groups_cnt; i++) { if (ga_match_pattern_list(groups[i])) { matched = 1; break; } } ga_free(); /* User in configured groups for Duo auth? */ return matched; } else { return 1; } }
static int match_cfg_line_group(const char *grps, int line, const char *user) { int result = 0; struct passwd *pw; if (user == NULL) goto out; if ((pw = getpwnam(user)) == NULL) { debug("Can't match group at line %d because user %.100s does " "not exist", line, user); } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { debug("Can't Match group because user %.100s not in any group " "at line %d", user, line); } else if (ga_match_pattern_list(grps) != 1) { debug("user %.100s does not match group list %.100s at line %d", user, grps, line); } else { debug("user %.100s matched group list %.100s at line %d", user, grps, line); result = 1; } out: ga_free(); return result; }
double optimise_parameters(int helices, int r){ rotation = r; vbest = VBIG; ncalls = 0; /* printf("Optimum Parameter Search Program\n"); printf("Build date : %s\n",__DATE__); printf("Copyright (C) 1994/2005 David T. Jones\n\n"); */ randomise(); readparams(helices); /* printf("Number of parameters = %d\n", genlen); printf("Pool size = %d\n", poolsize); printf("Mutation rate = %f\n", mutrate); printf("Crossover rate = %f\n", crosrate); printf("Mutation scaling factor = %f\n", mutscfac); */ ga_init(); run_ga(); printf("Best score:\t%f\n",best); return(best); }
/* * ":menutrans". * This function is also defined without the +multi_lang feature, in which * case the commands are ignored. */ void ex_menutranslate(exarg_T *eap) { char_u *arg = eap->arg; menutrans_T *tp; char_u *from, *from_noamp, *to; if (menutrans_ga.ga_itemsize == 0) ga_init(&menutrans_ga, (int)sizeof(menutrans_T), 5); /* * ":menutrans clear": clear all translations. */ if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) { tp = (menutrans_T *)menutrans_ga.ga_data; for (int i = 0; i < menutrans_ga.ga_len; ++i) { free(tp[i].from); free(tp[i].from_noamp); free(tp[i].to); } ga_clear(&menutrans_ga); /* Delete all "menutrans_" global variables. */ del_menutrans_vars(); } else { /* ":menutrans from to": add translation */ from = arg; arg = menu_skip_part(arg); to = skipwhite(arg); *arg = NUL; arg = menu_skip_part(to); if (arg == to) EMSG(_(e_invarg)); else { ga_grow(&menutrans_ga, 1); tp = (menutrans_T *)menutrans_ga.ga_data; from = vim_strsave(from); from_noamp = menu_text(from, NULL, NULL); to = vim_strnsave(to, (int)(arg - to)); if (from_noamp != NULL) { menu_translate_tab_and_shift(from); menu_translate_tab_and_shift(to); menu_unescape_name(from); menu_unescape_name(to); tp[menutrans_ga.ga_len].from = from; tp[menutrans_ga.ga_len].from_noamp = from_noamp; tp[menutrans_ga.ga_len].to = to; ++menutrans_ga.ga_len; } else { free(from); free(from_noamp); free(to); } } } }
/// Initializes the module bool server_init(void) { ga_init(&servers, sizeof(Server *), 1); bool must_free = false; const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR); if (listen_address == NULL) { must_free = true; listen_address = (char *)vim_tempname(); } bool ok = (server_start(listen_address) == 0); if (must_free) { xfree((char *) listen_address); } return ok; }
// Initialize users garray and fill it with os usernames. // Return Ok for success, FAIL for failure. int os_get_usernames(garray_T *users) { if (users == NULL) { return FAIL; } ga_init(users, sizeof(char *), 20); # if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H) struct passwd *pw; setpwent(); while ((pw = getpwent()) != NULL) { // pw->pw_name shouldn't be NULL but just in case... if (pw->pw_name != NULL) { GA_APPEND(char *, users, xstrdup(pw->pw_name)); } }
/* * ":menutrans". * This function is also defined without the +multi_lang feature, in which * case the commands are ignored. */ void ex_menutranslate(exarg_T *eap) { char_u *arg = eap->arg; char_u *from, *from_noamp, *to; if (menutrans_ga.ga_itemsize == 0) ga_init(&menutrans_ga, (int)sizeof(menutrans_T), 5); /* * ":menutrans clear": clear all translations. */ if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) { GA_DEEP_CLEAR(&menutrans_ga, menutrans_T, FREE_MENUTRANS); /* Delete all "menutrans_" global variables. */ del_menutrans_vars(); } else { /* ":menutrans from to": add translation */ from = arg; arg = menu_skip_part(arg); to = skipwhite(arg); *arg = NUL; arg = menu_skip_part(to); if (arg == to) EMSG(_(e_invarg)); else { from = vim_strsave(from); from_noamp = menu_text(from, NULL, NULL); to = vim_strnsave(to, (int)(arg - to)); if (from_noamp != NULL) { menu_translate_tab_and_shift(from); menu_translate_tab_and_shift(to); menu_unescape_name(from); menu_unescape_name(to); menutrans_T* tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga); tp->from = from; tp->from_noamp = from_noamp; tp->to = to; } else { free(from); free(to); } } } }
static double *ga_location(ga_array *ga_array_ptr, size_t index) { size_t skips = index/GARRAYBLOCK; size_t subindex = index%GARRAYBLOCK; size_t i; ga_array *subarray; subarray = ga_array_ptr; for(i=0;i<skips;i++) { if(subarray->next==NULL) { subarray->next = malloc(sizeof(ga_array)); if(subarray->next==NULL) return NULL; ga_init(subarray->next); } subarray=subarray->next; } return &(subarray->data[subindex]); }
/// Initializes the module bool server_init(void) { ga_init(&watchers, sizeof(SocketWatcher *), 1); bool must_free = false; const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR); if (listen_address == NULL) { must_free = true; listen_address = server_address_new(); } if (!listen_address) { return false; } bool ok = (server_start(listen_address) == 0); if (must_free) { xfree((char *) listen_address); } return ok; }
/// Clear an allocated growing array. void ga_clear(garray_T *gap) { vim_free(gap->ga_data); ga_init(gap); }
int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg) { uv_stdio_container_t proc_stdio[3]; uv_process_options_t proc_opts; uv_process_t proc; uv_pipe_t proc_stdin, proc_stdout; uv_write_t write_req; int expected_exits = 1; ProcessData pdata = { .reading = false, .exited = 0, .old_mode = cur_tmode, .old_state = State, .shell_stdin = (uv_stream_t *)&proc_stdin, .wbuffer = NULL, }; out_flush(); if (opts & kShellOptCooked) { // set to normal mode settmode(TMODE_COOK); } // While the child is running, ignore terminating signals signal_reject_deadly(); // Create argv for `uv_spawn` // TODO(tarruda): we can use a static buffer for small argument vectors. 1024 // bytes should be enough for most of the commands and if more is necessary // we can allocate a another buffer proc_opts.args = shell_build_argv(cmd, extra_shell_arg); proc_opts.file = proc_opts.args[0]; proc_opts.exit_cb = exit_cb; // Initialize libuv structures proc_opts.stdio = proc_stdio; proc_opts.stdio_count = 3; // Hide window on Windows :) proc_opts.flags = UV_PROCESS_WINDOWS_HIDE; proc_opts.cwd = NULL; proc_opts.env = NULL; // The default is to inherit all standard file descriptors(this will change // when the UI is moved to an external process) proc_stdio[0].flags = UV_INHERIT_FD; proc_stdio[0].data.fd = 0; proc_stdio[1].flags = UV_INHERIT_FD; proc_stdio[1].data.fd = 1; proc_stdio[2].flags = UV_INHERIT_FD; proc_stdio[2].data.fd = 2; if (opts & (kShellOptHideMess | kShellOptExpand)) { // Ignore the shell stdio(redirects to /dev/null on unixes) proc_stdio[0].flags = UV_IGNORE; proc_stdio[1].flags = UV_IGNORE; proc_stdio[2].flags = UV_IGNORE; } else { State = EXTERNCMD; if (opts & kShellOptWrite) { // Write from the current buffer into the process stdin uv_pipe_init(uv_default_loop(), &proc_stdin, 0); write_req.data = &pdata; proc_stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; proc_stdio[0].data.stream = (uv_stream_t *)&proc_stdin; } if (opts & kShellOptRead) { // Read from the process stdout into the current buffer uv_pipe_init(uv_default_loop(), &proc_stdout, 0); proc_stdout.data = &pdata; proc_stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; proc_stdio[1].data.stream = (uv_stream_t *)&proc_stdout; ga_init(&pdata.ga, 1, BUFFER_LENGTH); } } if (uv_spawn(uv_default_loop(), &proc, &proc_opts)) { // Failed, probably due to `sh` not being executable if (!emsg_silent) { MSG_PUTS(_("\nCannot execute shell ")); msg_outtrans(p_sh); msg_putchar('\n'); } return proc_cleanup_exit(&pdata, &proc_opts, opts); } // Assign the flag address after `proc` is initialized by `uv_spawn` proc.data = &pdata; if (opts & kShellOptWrite) { // Queue everything for writing to the shell stdin write_selection(&write_req); expected_exits++; } if (opts & kShellOptRead) { // Start the read stream for the shell stdout uv_read_start((uv_stream_t *)&proc_stdout, alloc_cb, read_cb); expected_exits++; } // Keep running the loop until all three handles are completely closed while (pdata.exited < expected_exits) { uv_run(uv_default_loop(), UV_RUN_ONCE); if (got_int) { // Forward SIGINT to the shell // TODO(tarruda): for now this is only needed if the terminal is in raw // mode, but when the UI is externalized we'll also need it, so leave it // here uv_process_kill(&proc, SIGINT); got_int = false; } } if (opts & kShellOptRead) { if (pdata.ga.ga_len > 0) { // If there's an unfinished line in the growable array, append it now. append_ga_line(&pdata.ga); // remember that the NL was missing curbuf->b_no_eol_lnum = curwin->w_cursor.lnum; } else { curbuf->b_no_eol_lnum = 0; } ga_clear(&pdata.ga); } if (opts & kShellOptWrite) { free(pdata.wbuffer); } return proc_cleanup_exit(&pdata, &proc_opts, opts); } static int tokenize(char_u *str, char **argv) { int argc = 0, len; char_u *p = str; while (*p != NUL) { len = word_length(p); if (argv != NULL) { // Fill the slot argv[argc] = xmalloc(len + 1); memcpy(argv[argc], p, len); argv[argc][len] = NUL; } argc++; p += len; p = skipwhite(p); } return argc; }
/* * Check if the user is allowed to log in via ssh. If user is listed * in DenyUsers or one of user's groups is listed in DenyGroups, false * will be returned. If AllowUsers isn't empty and user isn't listed * there, or if AllowGroups isn't empty and one of user's groups isn't * listed there, false will be returned. * If the user's shell is not executable, false will be returned. * Otherwise true is returned. */ int allowed_user(struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; u_int i; #ifdef USE_SHADOW struct spwd *spw = NULL; #endif /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #ifdef USE_SHADOW if (!options.use_pam) spw = getspnam(pw->pw_name); #ifdef HAS_SHADOW_EXPIRE if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw)) return 0; #endif /* HAS_SHADOW_EXPIRE */ #endif /* USE_SHADOW */ /* grab passwd field for locked account check */ passwd = pw->pw_passwd; #ifdef USE_SHADOW if (spw != NULL) #ifdef USE_LIBIAF passwd = get_iaf_password(pw); #else passwd = spw->sp_pwdp; #endif /* USE_LIBIAF */ #endif /* check for locked account */ if (!options.use_pam && passwd && *passwd) { int locked = 0; #ifdef LOCKED_PASSWD_STRING if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) locked = 1; #endif #ifdef LOCKED_PASSWD_PREFIX if (strncmp(passwd, LOCKED_PASSWD_PREFIX, strlen(LOCKED_PASSWD_PREFIX)) == 0) locked = 1; #endif #ifdef LOCKED_PASSWD_SUBSTR if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) locked = 1; #endif #ifdef USE_LIBIAF free((void *) passwd); #endif /* USE_LIBIAF */ if (locked) { logit("User %.100s not allowed because account is locked", pw->pw_name); return 0; } } /* * Deny if shell does not exist or is not executable unless we * are chrooting. */ if (options.chroot_directory == NULL || strcasecmp(options.chroot_directory, "none") == 0) { char *shell = xstrdup((pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ if (stat(shell, &st) != 0) { logit("User %.100s not allowed because shell %.100s " "does not exist", pw->pw_name, shell); xfree(shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { logit("User %.100s not allowed because shell %.100s " "is not executable", pw->pw_name, shell); xfree(shell); return 0; } xfree(shell); } if (options.num_deny_users > 0 || options.num_allow_users > 0 || options.num_deny_groups > 0 || options.num_allow_groups > 0) { hostname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); } /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { for (i = 0; i < options.num_deny_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i])) { logit("User %.100s from %.100s not allowed " "because listed in DenyUsers", pw->pw_name, hostname); return 0; } } /* Return false if AllowUsers isn't empty and user isn't listed there */ if (options.num_allow_users > 0) { for (i = 0; i < options.num_allow_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i])) break; /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) { logit("User %.100s from %.100s not allowed because " "not listed in AllowUsers", pw->pw_name, hostname); return 0; } } if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { /* Get the user's group access list (primary and supplementary) */ if (ga_init(pw->pw_name, pw->pw_gid) == 0) { logit("User %.100s from %.100s not allowed because " "not in any group", pw->pw_name, hostname); return 0; } /* Return false if one of user's groups is listed in DenyGroups */ if (options.num_deny_groups > 0) if (ga_match(options.deny_groups, options.num_deny_groups)) { ga_free(); logit("User %.100s from %.100s not allowed " "because a group is listed in DenyGroups", pw->pw_name, hostname); return 0; } /* * Return false if AllowGroups isn't empty and one of user's groups * isn't listed there */ if (options.num_allow_groups > 0) if (!ga_match(options.allow_groups, options.num_allow_groups)) { ga_free(); logit("User %.100s from %.100s not allowed " "because none of user's groups are listed " "in AllowGroups", pw->pw_name, hostname); return 0; } ga_free(); } #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER if (!sys_auth_allowed_user(pw, &loginmsg)) return 0; #endif /* We found no reason not to let this user try to log on... */ return 1; }
/// Convert the string "str[orglen]" to do ignore-case comparing. Uses the /// current locale. /// /// When "buf" is NULL returns an allocated string (NULL for out-of-memory). /// Otherwise puts the result in "buf[buflen]". /// /// @param str /// @param orglen /// @param buf /// @param buflen /// /// @return converted string. char_u* str_foldcase(char_u *str, int orglen, char_u *buf, int buflen) { garray_T ga; int i; int len = orglen; #define GA_CHAR(i) ((char_u *)ga.ga_data)[i] #define GA_PTR(i) ((char_u *)ga.ga_data + i) #define STR_CHAR(i) (buf == NULL ? GA_CHAR(i) : buf[i]) #define STR_PTR(i) (buf == NULL ? GA_PTR(i) : buf + i) // Copy "str" into "buf" or allocated memory, unmodified. if (buf == NULL) { ga_init(&ga, 1, 10); if (ga_grow(&ga, len + 1) == FAIL) { return NULL; } memmove(ga.ga_data, str, (size_t)len); ga.ga_len = len; } else { if (len >= buflen) { // Ugly! len = buflen - 1; } memmove(buf, str, (size_t)len); } if (buf == NULL) { GA_CHAR(len) = NUL; } else { buf[len] = NUL; } // Make each character lower case. i = 0; while (STR_CHAR(i) != NUL) { if (enc_utf8 || (has_mbyte && (MB_BYTE2LEN(STR_CHAR(i)) > 1))) { if (enc_utf8) { int c = utf_ptr2char(STR_PTR(i)); int olen = utf_ptr2len(STR_PTR(i)); int lc = utf_tolower(c); // Only replace the character when it is not an invalid // sequence (ASCII character or more than one byte) and // utf_tolower() doesn't return the original character. if (((c < 0x80) || (olen > 1)) && (c != lc)) { int nlen = utf_char2len(lc); // If the byte length changes need to shift the following // characters forward or backward. if (olen != nlen) { if (nlen > olen) { if ((buf == NULL) ? (ga_grow(&ga, nlen - olen + 1) == FAIL) : (len + nlen - olen >= buflen)) { // out of memory, keep old char lc = c; nlen = olen; } } if (olen != nlen) { if (buf == NULL) { STRMOVE(GA_PTR(i) + nlen, GA_PTR(i) + olen); ga.ga_len += nlen - olen; } else { STRMOVE(buf + i + nlen, buf + i + olen); len += nlen - olen; } } } (void)utf_char2bytes(lc, STR_PTR(i)); } } // skip to next multi-byte char i += (*mb_ptr2len)(STR_PTR(i)); } else { if (buf == NULL) { GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i)); } else { buf[i] = TOLOWER_LOC(buf[i]); } ++i; } } if (buf == NULL) { return (char_u *)ga.ga_data; } return buf; }
/* * Check if the user is allowed to log in via ssh. If user is listed * in DenyUsers or one of user's groups is listed in DenyGroups, false * will be returned. If AllowUsers isn't empty and user isn't listed * there, or if AllowGroups isn't empty and one of user's groups isn't * listed there, false will be returned. * If the user's shell is not executable, false will be returned. * Otherwise true is returned. */ int allowed_user(struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL; char *shell; int i; #ifdef WITH_AIXAUTHENTICATE char *loginmsg; #endif /* WITH_AIXAUTHENTICATE */ #if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) struct spwd *spw; /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #define DAY (24L * 60 * 60) /* 1 day in seconds */ spw = getspnam(pw->pw_name); if (spw != NULL) { time_t today = time(NULL) / DAY; debug3("allowed_user: today %d sp_expire %d sp_lstchg %d" " sp_max %d", (int)today, (int)spw->sp_expire, (int)spw->sp_lstchg, (int)spw->sp_max); /* * We assume account and password expiration occurs the * day after the day specified. */ if (spw->sp_expire != -1 && today > spw->sp_expire) { log("Account %.100s has expired", pw->pw_name); return 0; } if (spw->sp_lstchg == 0) { log("User %.100s password has expired (root forced)", pw->pw_name); return 0; } if (spw->sp_max != -1 && today > spw->sp_lstchg + spw->sp_max) { log("User %.100s password has expired (password aged)", pw->pw_name); return 0; } } #else /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #endif /* * Get the shell from the password data. An empty shell field is * legal, and means /bin/sh. */ shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; /* deny if shell does not exists or is not executable */ if (stat(shell, &st) != 0) { log("User %.100s not allowed because shell %.100s does not exist", pw->pw_name, shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { log("User %.100s not allowed because shell %.100s is not executable", pw->pw_name, shell); return 0; } if (options.num_deny_users > 0 || options.num_allow_users > 0) { hostname = get_canonical_hostname(options.verify_reverse_mapping); ipaddr = get_remote_ipaddr(); } /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { for (i = 0; i < options.num_deny_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i])) { log("User %.100s not allowed because listed in DenyUsers", pw->pw_name); return 0; } } /* Return false if AllowUsers isn't empty and user isn't listed there */ if (options.num_allow_users > 0) { for (i = 0; i < options.num_allow_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i])) break; /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) { log("User %.100s not allowed because not listed in AllowUsers", pw->pw_name); return 0; } } if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { /* Get the user's group access list (primary and supplementary) */ if (ga_init(pw->pw_name, pw->pw_gid) == 0) { log("User %.100s not allowed because not in any group", pw->pw_name); return 0; } /* Return false if one of user's groups is listed in DenyGroups */ if (options.num_deny_groups > 0) if (ga_match(options.deny_groups, options.num_deny_groups)) { ga_free(); log("User %.100s not allowed because a group is listed in DenyGroups", pw->pw_name); return 0; } /* * Return false if AllowGroups isn't empty and one of user's groups * isn't listed there */ if (options.num_allow_groups > 0) if (!ga_match(options.allow_groups, options.num_allow_groups)) { ga_free(); log("User %.100s not allowed because none of user's groups are listed in AllowGroups", pw->pw_name); return 0; } ga_free(); } #ifdef WITH_AIXAUTHENTICATE if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) { if (loginmsg && *loginmsg) { /* Remove embedded newlines (if any) */ char *p; for (p = loginmsg; *p; p++) { if (*p == '\n') *p = ' '; } /* Remove trailing newline */ *--p = '\0'; log("Login restricted for %s: %.100s", pw->pw_name, loginmsg); } return 0; } #endif /* WITH_AIXAUTHENTICATE */ /* We found no reason not to let this user try to log on... */ return 1; }
/* * Check if the user is allowed to log in via ssh. If user is listed * in DenyUsers or one of user's groups is listed in DenyGroups, false * will be returned. If AllowUsers isn't empty and user isn't listed * there, or if AllowGroups isn't empty and one of user's groups isn't * listed there, false will be returned. * If the user's shell is not executable, false will be returned. * Otherwise true is returned. */ int allowed_user(struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; char *shell; int i; #ifdef USE_SHADOW struct spwd *spw = NULL; #endif /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #ifdef USE_SHADOW if (!options.use_pam) spw = getspnam(pw->pw_name); #ifdef HAS_SHADOW_EXPIRE if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw)) return 0; #endif /* HAS_SHADOW_EXPIRE */ #endif /* USE_SHADOW */ /* grab passwd field for locked account check */ #ifdef USE_SHADOW if (spw != NULL) passwd = spw->sp_pwdp; #else passwd = pw->pw_passwd; #endif /* check for locked account */ if (!options.use_pam && passwd && *passwd) { int locked = 0; #ifdef LOCKED_PASSWD_STRING if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) locked = 1; #endif #ifdef LOCKED_PASSWD_PREFIX if (strncmp(passwd, LOCKED_PASSWD_PREFIX, strlen(LOCKED_PASSWD_PREFIX)) == 0) locked = 1; #endif #ifdef LOCKED_PASSWD_SUBSTR if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) locked = 1; #endif if (locked) { logit("User %.100s not allowed because account is locked", pw->pw_name); return 0; } } /* * Get the shell from the password data. An empty shell field is * legal, and means /bin/sh. */ shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; /* deny if shell does not exists or is not executable */ if (stat(shell, &st) != 0) { logit("User %.100s not allowed because shell %.100s does not exist", pw->pw_name, shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { logit("User %.100s not allowed because shell %.100s is not executable", pw->pw_name, shell); return 0; } if (options.num_deny_users > 0 || options.num_allow_users > 0) { hostname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); } /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { for (i = 0; i < options.num_deny_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i])) { logit("User %.100s not allowed because listed in DenyUsers", pw->pw_name); return 0; } } /* Return false if AllowUsers isn't empty and user isn't listed there */ if (options.num_allow_users > 0) { for (i = 0; i < options.num_allow_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i])) break; /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) { logit("User %.100s not allowed because not listed in AllowUsers", pw->pw_name); return 0; } } if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { /* Get the user's group access list (primary and supplementary) */ if (ga_init(pw->pw_name, pw->pw_gid) == 0) { logit("User %.100s not allowed because not in any group", pw->pw_name); return 0; } /* Return false if one of user's groups is listed in DenyGroups */ if (options.num_deny_groups > 0) if (ga_match(options.deny_groups, options.num_deny_groups)) { ga_free(); logit("User %.100s not allowed because a group is listed in DenyGroups", pw->pw_name); return 0; } /* * Return false if AllowGroups isn't empty and one of user's groups * isn't listed there */ if (options.num_allow_groups > 0) if (!ga_match(options.allow_groups, options.num_allow_groups)) { ga_free(); logit("User %.100s not allowed because none of user's groups are listed in AllowGroups", pw->pw_name); return 0; } ga_free(); } #ifdef WITH_AIXAUTHENTICATE /* * Don't check loginrestrictions() for root account (use * PermitRootLogin to control logins via ssh), or if running as * non-root user (since loginrestrictions will always fail). */ if ((pw->pw_uid != 0) && (geteuid() == 0)) { char *msg; if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) { int loginrestrict_errno = errno; if (msg && *msg) { buffer_append(&loginmsg, msg, strlen(msg)); aix_remove_embedded_newlines(msg); logit("Login restricted for %s: %.100s", pw->pw_name, msg); } /* Don't fail if /etc/nologin set */ if (!(loginrestrict_errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0)) return 0; } } #endif /* WITH_AIXAUTHENTICATE */ /* We found no reason not to let this user try to log on... */ return 1; }
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int pam_flags, int argc, const char *argv[]) { struct duo_config cfg; struct passwd *pw; duo_t *duo; duo_code_t code; duopam_const char *config, *cmd, *ip, *p, *service, *user; int i, flags, pam_err; memset(&cfg, 0, sizeof(cfg)); cfg.failmode = DUO_FAIL_SAFE; /* Parse configuration */ config = DUO_CONF; for (i = 0; i < argc; i++) { if (strncmp("conf=", argv[i], 5) == 0) { config = argv[i] + 5; } else if (strcmp("debug", argv[i]) == 0) { options |= PAM_OPT_DEBUG; } else if (strcmp("try_first_pass", argv[i]) == 0) { options |= PAM_OPT_TRY_FIRST_PASS; } else if (strcmp("use_first_pass", argv[i]) == 0) { options |= PAM_OPT_USE_FIRST_PASS|PAM_OPT_TRY_FIRST_PASS; } else if (strcmp("use_uid", argv[i]) == 0) { options |= PAM_OPT_USE_UID; } else if (strcmp("push", argv[i]) == 0) { options |= PAM_OPT_PUSH; } else { _syslog(LOG_ERR, "Invalid pam_duo option: '%s'", argv[i]); return (PAM_SERVICE_ERR); } } i = duo_parse_config(config, __ini_handler, &cfg); if (i == -2) { _syslog(LOG_ERR, "%s must be readable only by user 'root'", config); return (PAM_SERVICE_ERR); } else if (i == -1) { _syslog(LOG_ERR, "Couldn't open %s: %s", config, strerror(errno)); return (PAM_SERVICE_ERR); } else if (i > 0) { _syslog(LOG_ERR, "Parse error in %s, line %d", config, i); return (PAM_SERVICE_ERR); } else if (!cfg.host || !cfg.host[0] || !cfg.skey || !cfg.skey[0] || !cfg.ikey || !cfg.ikey[0]) { _syslog(LOG_ERR, "Missing host, ikey, or skey in %s", config); return (PAM_SERVICE_ERR); } /* Check user */ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || (pw = getpwnam(user)) == NULL) { return (PAM_USER_UNKNOWN); } /* XXX - Service-specific behavior */ flags = 0; cmd = NULL; if (pam_get_item(pamh, PAM_SERVICE, (duopam_const void **) (duopam_const void *)&service) != PAM_SUCCESS) { return (PAM_SERVICE_ERR); } if (options & PAM_OPT_USE_UID) { /* Check calling user for Duo auth, just like sudo */ if ((pw = getpwuid(getuid())) == NULL) { return (PAM_USER_UNKNOWN); } user = pw->pw_name; } if (strcmp(service, "sshd") == 0) { /* * Disable incremental status reporting for sshd :-( * OpenSSH accumulates PAM_TEXT_INFO from modules to send in * an SSH_MSG_USERAUTH_BANNER post-auth, not real-time! */ flags |= DUO_FLAG_SYNC; } else if (strcmp(service, "sudo") == 0) { cmd = getenv("SUDO_COMMAND"); } /* Check group membership */ if (cfg.groups_cnt > 0) { int matched = 0; if (ga_init(pw->pw_name, pw->pw_gid) < 0) { _log(LOG_ERR, "Couldn't get groups", pw->pw_name, NULL, strerror(errno)); return (PAM_SERVICE_ERR); } for (i = 0; i < cfg.groups_cnt; i++) { if (ga_match_pattern_list(cfg.groups[i])) { matched = 1; break; } } ga_free(); /* User in configured groups for Duo auth? */ if (!matched) return (PAM_SUCCESS); } ip = NULL; pam_get_item(pamh, PAM_RHOST, (duopam_const void **)(duopam_const void *)&ip); /* Honor configured http_proxy */ if (cfg.http_proxy != NULL) { setenv("http_proxy", cfg.http_proxy, 1); } /* Try Duo auth */ if ((duo = duo_open(cfg.host, cfg.ikey, cfg.skey, "pam_duo/" PACKAGE_VERSION, cfg.noverify ? "" : cfg.cafile)) == NULL) { _log(LOG_ERR, "Couldn't open Duo API handle", user, ip, NULL); return (PAM_SERVICE_ERR); } duo_set_conv_funcs(duo, __duo_prompt, __duo_status, pamh); pam_err = PAM_SERVICE_ERR; for (i = 0; i < MAX_RETRIES; i++) { code = duo_login(duo, user, ip, flags, cfg.pushinfo ? cmd : NULL); if (code == DUO_FAIL) { _log(LOG_WARNING, "Failed Duo login", user, ip, duo_geterr(duo)); if ((flags & DUO_FLAG_SYNC) == 0) { pam_info(pamh, "%s", ""); } /* Keep going */ continue; } /* Terminal conditions */ if (code == DUO_OK) { if ((p = duo_geterr(duo)) != NULL) { _log(LOG_WARNING, "Skipped Duo login", user, ip, p); } else { _log(LOG_INFO, "Successful Duo login", user, ip, NULL); } pam_err = PAM_SUCCESS; } else if (code == DUO_ABORT) { _log(LOG_WARNING, "Aborted Duo login", user, ip, duo_geterr(duo)); pam_err = PAM_ABORT; } else if (cfg.failmode == DUO_FAIL_SAFE && (code == DUO_CONN_ERROR || code == DUO_CLIENT_ERROR || code == DUO_SERVER_ERROR)) { _log(LOG_WARNING, "Failsafe Duo login", user, ip, duo_geterr(duo)); pam_err = PAM_SUCCESS; } else { _log(LOG_ERR, "Error in Duo login", user, ip, duo_geterr(duo)); pam_err = PAM_SERVICE_ERR; } break; } if (i == MAX_RETRIES) { pam_err = PAM_MAXTRIES; } duo_close(duo); return (pam_err); }
/* * Check if the user is allowed to log in via ssh. If user is listed * in DenyUsers or one of user's groups is listed in DenyGroups, false * will be returned. If AllowUsers isn't empty and user isn't listed * there, or if AllowGroups isn't empty and one of user's groups isn't * listed there, false will be returned. * If the user's shell is not executable, false will be returned. * Otherwise true is returned. */ int allowed_user(struct passwd * pw) { #ifdef HAVE_LOGIN_CAP extern login_cap_t *lc; int match_name, match_ip; char *cap_hlist, *hp; #endif struct ssh *ssh = active_state; /* XXX */ struct stat st; const char *hostname = NULL, *ipaddr = NULL; int r; u_int i; /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #ifdef HAVE_LOGIN_CAP hostname = auth_get_canonical_hostname(ssh, options.use_dns); ipaddr = ssh_remote_ipaddr(ssh); lc = login_getclass(pw->pw_class); /* * Check the deny list. */ cap_hlist = login_getcapstr(lc, "host.deny", NULL, NULL); if (cap_hlist != NULL) { hp = strtok(cap_hlist, ","); while (hp != NULL) { match_name = match_hostname(hostname, hp); match_ip = match_hostname(ipaddr, hp); /* * Only a positive match here causes a "deny". */ if (match_name > 0 || match_ip > 0) { free(cap_hlist); login_close(lc); return 0; } hp = strtok(NULL, ","); } free(cap_hlist); } /* * Check the allow list. If the allow list exists, and the * remote host is not in it, the user is implicitly denied. */ cap_hlist = login_getcapstr(lc, "host.allow", NULL, NULL); if (cap_hlist != NULL) { hp = strtok(cap_hlist, ","); if (hp == NULL) { /* Just in case there's an empty string... */ free(cap_hlist); login_close(lc); return 0; } while (hp != NULL) { match_name = match_hostname(hostname, hp); match_ip = match_hostname(ipaddr, hp); /* * Negative match causes an immediate "deny". * Positive match causes us to break out * of the loop (allowing a fallthrough). */ if (match_name < 0 || match_ip < 0) { free(cap_hlist); login_close(lc); return 0; } if (match_name > 0 || match_ip > 0) break; hp = strtok(NULL, ","); } free(cap_hlist); if (hp == NULL) { login_close(lc); return 0; } } login_close(lc); #endif #ifdef USE_PAM if (!options.use_pam) { #endif /* * password/account expiration. */ if (pw->pw_change || pw->pw_expire) { struct timeval tv; (void)gettimeofday(&tv, (struct timezone *)NULL); if (pw->pw_expire) { if (tv.tv_sec >= pw->pw_expire) { logit("User %.100s not allowed because account has expired", pw->pw_name); return 0; /* expired */ } } #ifdef _PASSWORD_CHGNOW if (pw->pw_change == _PASSWORD_CHGNOW) { logit("User %.100s not allowed because password needs to be changed", pw->pw_name); return 0; /* can't force password change (yet) */ } #endif if (pw->pw_change) { if (tv.tv_sec >= pw->pw_change) { logit("User %.100s not allowed because password has expired", pw->pw_name); return 0; /* expired */ } } } #ifdef USE_PAM } #endif /* * Deny if shell does not exist or is not executable unless we * are chrooting. */ /* * XXX Should check to see if it is executable by the * XXX requesting user. --thorpej */ if (options.chroot_directory == NULL || strcasecmp(options.chroot_directory, "none") == 0) { char *shell = xstrdup((pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ if (stat(shell, &st) != 0) { logit("User %.100s not allowed because shell %.100s " "does not exist", pw->pw_name, shell); free(shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { logit("User %.100s not allowed because shell %.100s " "is not executable", pw->pw_name, shell); free(shell); return 0; } free(shell); } /* * XXX Consider nuking {Allow,Deny}{Users,Groups}. We have the * XXX login_cap(3) mechanism which covers all other types of * XXX logins, too. */ if (options.num_deny_users > 0 || options.num_allow_users > 0 || options.num_deny_groups > 0 || options.num_allow_groups > 0) { hostname = auth_get_canonical_hostname(ssh, options.use_dns); ipaddr = ssh_remote_ipaddr(ssh); } /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { for (i = 0; i < options.num_deny_users; i++) { r = match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i]); if (r < 0) { fatal("Invalid DenyUsers pattern \"%.100s\"", options.deny_users[i]); } else if (r != 0) { logit("User %.100s from %.100s not allowed " "because listed in DenyUsers", pw->pw_name, hostname); return 0; } } } /* Return false if AllowUsers isn't empty and user isn't listed there */ if (options.num_allow_users > 0) { for (i = 0; i < options.num_allow_users; i++) { r = match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i]); if (r < 0) { fatal("Invalid AllowUsers pattern \"%.100s\"", options.allow_users[i]); } else if (r == 1) break; } /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) { logit("User %.100s from %.100s not allowed because " "not listed in AllowUsers", pw->pw_name, hostname); return 0; } } if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { /* Get the user's group access list (primary and supplementary) */ if (ga_init(pw->pw_name, pw->pw_gid) == 0) { logit("User %.100s from %.100s not allowed because " "not in any group", pw->pw_name, hostname); return 0; } /* Return false if one of user's groups is listed in DenyGroups */ if (options.num_deny_groups > 0) if (ga_match(options.deny_groups, options.num_deny_groups)) { ga_free(); logit("User %.100s from %.100s not allowed " "because a group is listed in DenyGroups", pw->pw_name, hostname); return 0; } /* * Return false if AllowGroups isn't empty and one of user's groups * isn't listed there */ if (options.num_allow_groups > 0) if (!ga_match(options.allow_groups, options.num_allow_groups)) { ga_free(); logit("User %.100s from %.100s not allowed " "because none of user's groups are listed " "in AllowGroups", pw->pw_name, hostname); return 0; } ga_free(); } /* We found no reason not to let this user try to log on... */ return 1; }
/// Initialize a growing array. /// /// @param gap /// @param itemsize /// @param growsize void ga_init2(garray_T *gap, int itemsize, int growsize) { ga_init(gap); gap->ga_itemsize = itemsize; gap->ga_growsize = growsize; }
/// ":loadkeymap" command: load the following lines as the keymap. /// /// @param eap void ex_loadkeymap(exarg_T *eap) { char_u *line; char_u *p; char_u *s; #define KMAP_LLEN 200 // max length of "to" and "from" together char_u buf[KMAP_LLEN + 11]; char_u *save_cpo = p_cpo; if (!getline_equal(eap->getline, eap->cookie, getsourceline)) { EMSG(_("E105: Using :loadkeymap not in a sourced file")); return; } // Stop any active keymap and clear the table. keymap_unload(); curbuf->b_kmap_state = 0; ga_init(&curbuf->b_kmap_ga, (int)sizeof(kmap_T), 20); // Set 'cpoptions' to "C" to avoid line continuation. p_cpo = (char_u *)"C"; // Get each line of the sourced file, break at the end. for (;;) { line = eap->getline(0, eap->cookie, 0); if (line == NULL) { break; } p = skipwhite(line); if ((*p != '"') && (*p != NUL)) { kmap_T *kp = GA_APPEND_VIA_PTR(kmap_T, &curbuf->b_kmap_ga); s = skiptowhite(p); kp->from = vim_strnsave(p, (size_t)(s - p)); p = skipwhite(s); s = skiptowhite(p); kp->to = vim_strnsave(p, (size_t)(s - p)); if ((STRLEN(kp->from) + STRLEN(kp->to) >= KMAP_LLEN) || (*kp->from == NUL) || (*kp->to == NUL)) { if (*kp->to == NUL) { EMSG(_("E791: Empty keymap entry")); } xfree(kp->from); xfree(kp->to); --curbuf->b_kmap_ga.ga_len; } } xfree(line); } // setup ":lnoremap" to map the keys for (int i = 0; i < curbuf->b_kmap_ga.ga_len; ++i) { vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s %s", ((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].from, ((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].to); (void)do_map(2, buf, LANGMAP, FALSE); } p_cpo = save_cpo; curbuf->b_kmap_state |= KEYMAP_LOADED; status_redraw_curbuf(); }
int main(int argc, char ** argv) { /*OpenMP*/ int thread_count = strtol(argv[1],NULL,10); struct timeval t_begin,t_end; int i; int j; float elapsed[TESTS_TO_DO]; float best = 1000000; float best_var[VAR]; float worst = -1; float worst_var[VAR]; float solution; int generations; population popul; for(i=0;i<TESTS_TO_DO;i++) { ga_init(&popul,VAR); /* Get time */ #ifdef __unix__ gettimeofday(&t_begin, NULL); #else clock_t t = clock(); #endif generations = 0; while(generations < STOP_GENERATIONS) { /* Fitness */ fitness(my_fitness,&popul,thread_count); /* Crossover */ crossover(&popul,thread_count); generations++; } /* Get time */ #ifdef __unix__ gettimeofday(&t_end, NULL); elapsed[i] = ((t_end.tv_sec+t_end.tv_usec/1000000.0)) - \ (t_begin.tv_sec+t_begin.tv_usec/1000000.0); #else t = clock() - t; elapsed[i] = ((float)t)/CLOCKS_PER_SEC; #endif /* Apply fitness to sort */ fitness(my_fitness,&popul,thread_count); solution = my_fitness(popul.chromosomes[popul.size-1]); if(solution < best) { best = solution; for(j=0;j<VAR;j++) { best_var[j] = \ interpret(popul.chromosomes[popul.size-1][j], \ LIMIT_INFERIOR_X1,LIMIT_SUPERIOR_X1); } } else if (solution > worst) { worst = solution; for(j=0;j<VAR;j++) { worst_var[j] = \ interpret(popul.chromosomes[popul.size-1][j], \ LIMIT_INFERIOR_X1,LIMIT_SUPERIOR_X1); } } /* Free memory allocated */ ga_end(&popul); } /* Print results */ float mean = 0.0; for(i=0;i<TESTS_TO_DO;i++) { printf("Elapsed Time %i: %.6fs\n",i,elapsed[i]); mean += elapsed[i]; } printf("Elapsed Time - Mean: %f\n\n",(mean/TESTS_TO_DO)); printf("Worst Result:\t%.8f\n",worst); for(j=0;j<VAR;j++) printf("x%d: %.8f\n",j,worst_var[j]); printf("Best Result:\t%.8f\n",best); for(j=0;j<VAR;j++) printf("x%d: %.8f\n",j,best_var[j]); return 0; }