static int af_setpwent(pool *p) { if (af_user_file != NULL) { if (af_user_file->af_file != NULL) { /* If already opened, rewind */ rewind(af_user_file->af_file); return 0; } else { int xerrno; PRIVS_ROOT af_user_file->af_file = fopen(af_user_file->af_path, "r"); xerrno = errno; PRIVS_RELINQUISH if (af_user_file->af_file == NULL) { struct stat st; if (pr_fsio_stat(af_user_file->af_path, &st) == 0) { pr_log_pri(PR_LOG_WARNING, "error: unable to open AuthUserFile file '%s' (file owned by " "UID %s, GID %s, perms %04o, accessed by UID %s, GID %s): %s", af_user_file->af_path, pr_uid2str(p, st.st_uid), pr_gid2str(p, st.st_gid), st.st_mode & ~S_IFMT, pr_uid2str(p, geteuid()), pr_gid2str(p, getegid()), strerror(xerrno)); } else { pr_log_pri(PR_LOG_WARNING, "error: unable to open AuthUserFile file '%s': %s", af_user_file->af_path, strerror(xerrno)); } errno = xerrno; return -1; } /* As the file may contain sensitive data, we do not want it lingering * around in stdio buffers. */ (void) setvbuf(af_user_file->af_file, NULL, _IONBF, 0); if (fcntl(fileno(af_user_file->af_file), F_SETFD, FD_CLOEXEC) < 0) { pr_log_pri(PR_LOG_WARNING, MOD_AUTH_FILE_VERSION ": unable to set CLOEXEC on AuthUserFile %s (fd %d): %s", af_user_file->af_path, fileno(af_user_file->af_file), strerror(errno)); } pr_log_debug(DEBUG7, MOD_AUTH_FILE_VERSION ": using passwd file '%s'", af_user_file->af_path); return 0; } } pr_trace_msg(trace_channel, 8, "no AuthUserFile configured"); errno = EPERM; return -1; }
static int copy_symlink(pool *p, const char *src_dir, const char *src_path, const char *dst_dir, const char *dst_path, uid_t uid, gid_t gid) { char *link_path = pcalloc(p, PR_TUNABLE_BUFFER_SIZE); int len; len = pr_fsio_readlink(src_path, link_path, PR_TUNABLE_BUFFER_SIZE-1); if (len < 0) { pr_log_pri(PR_LOG_WARNING, "CreateHome: error reading link '%s': %s", src_path, strerror(errno)); return -1; } link_path[len] = '\0'; /* If the target of the link lies within the src path, rename that portion * of the link to be the corresponding part of the dst path. */ if (strncmp(link_path, src_dir, strlen(src_dir)) == 0) { link_path = pdircat(p, dst_dir, link_path + strlen(src_dir), NULL); } if (pr_fsio_symlink(link_path, dst_path) < 0) { pr_log_pri(PR_LOG_WARNING, "CreateHome: error symlinking '%s' to '%s': %s", link_path, dst_path, strerror(errno)); return -1; } /* Make sure the new symlink has the proper ownership. */ if (pr_fsio_chown(dst_path, uid, gid) < 0) { pr_log_pri(PR_LOG_WARNING, "CreateHome: error chown'ing '%s' to %u/%u: %s", dst_path, (unsigned int) uid, (unsigned int) gid, strerror(errno)); } return 0; }
static int wrap_is_usable_file(char *filename) { struct stat statbuf; pr_fh_t *fh = NULL; /* check the easy case first */ if (filename == NULL) return FALSE; if (pr_fsio_stat(filename, &statbuf) == -1) { pr_log_pri(PR_LOG_INFO, MOD_WRAP_VERSION ": \"%s\": %s", filename, strerror(errno)); return FALSE; } /* OK, the file exists. Now, to make sure that the current process * can _read_ the file */ fh = pr_fsio_open(filename, O_RDONLY); if (fh == NULL) { pr_log_pri(PR_LOG_INFO, MOD_WRAP_VERSION ": \"%s\": %s", filename, strerror(errno)); return FALSE; } pr_fsio_close(fh); return TRUE; }
struct passwd *pr_auth_getpwent(pool *p) { cmd_rec *cmd = NULL; modret_t *mr = NULL; struct passwd *res = NULL; cmd = make_cmd(p, 0); mr = dispatch_auth(cmd, "getpwent", NULL); if (MODRET_ISHANDLED(mr) && MODRET_HASDATA(mr)) res = mr->data; if (cmd->tmp_pool) { destroy_pool(cmd->tmp_pool); cmd->tmp_pool = NULL; } /* Sanity check */ if (res == NULL) return NULL; /* Make sure the UID and GID are not -1 */ if (res->pw_uid == (uid_t) -1) { pr_log_pri(PR_LOG_ERR, "error: UID of -1 not allowed"); return NULL; } if (res->pw_gid == (gid_t) -1) { pr_log_pri(PR_LOG_ERR, "error: GID of -1 not allowed"); return NULL; } return res; }
static int copy_symlink(pool *p, const char *src_path, const char *dst_path) { char *link_path = pcalloc(p, PR_TUNABLE_BUFFER_SIZE); int len; len = pr_fsio_readlink(src_path, link_path, PR_TUNABLE_BUFFER_SIZE-1); if (len < 0) { int xerrno = errno; pr_log_pri(PR_LOG_WARNING, MOD_COPY_VERSION ": error reading link '%s': %s", src_path, strerror(xerrno)); errno = xerrno; return -1; } link_path[len] = '\0'; if (pr_fsio_symlink(link_path, dst_path) < 0) { int xerrno = errno; pr_log_pri(PR_LOG_WARNING, MOD_COPY_VERSION ": error symlinking '%s' to '%s': %s", link_path, dst_path, strerror(xerrno)); errno = xerrno; return -1; } return 0; }
static RETSIGTYPE sig_alarm(int signo) { struct sigaction act; act.sa_handler = sig_alarm; sigemptyset(&act.sa_mask); act.sa_flags = 0; #ifdef SA_INTERRUPT act.sa_flags |= SA_INTERRUPT; #endif /* Install this handler for SIGALRM. */ if (sigaction(SIGALRM, &act, NULL) < 0) { pr_log_pri(PR_LOG_WARNING, "unable to install SIGALRM handler via sigaction(2): %s", strerror(errno)); } #ifdef HAVE_SIGINTERRUPT if (siginterrupt(SIGALRM, 1) < 0) { pr_log_pri(PR_LOG_WARNING, "unable to allow SIGALRM to interrupt system calls: %s", strerror(errno)); } #endif recvd_signal_flags |= RECEIVED_SIG_ALRM; nalarms++; /* Reset the alarm */ _total_time += _current_timeout; if (_current_timeout) { _alarmed_time = time(NULL); alarm(_current_timeout); } }
/* Masks/unmasks all important signals (as opposed to blocking alarms) */ static void mask_signals(unsigned char block) { static sigset_t mask_sigset; if (block) { sigemptyset(&mask_sigset); sigaddset(&mask_sigset, SIGTERM); sigaddset(&mask_sigset, SIGCHLD); sigaddset(&mask_sigset, SIGUSR1); sigaddset(&mask_sigset, SIGINT); sigaddset(&mask_sigset, SIGQUIT); sigaddset(&mask_sigset, SIGALRM); #ifdef SIGIO sigaddset(&mask_sigset, SIGIO); #endif #ifdef SIGBUS sigaddset(&mask_sigset, SIGBUS); #endif sigaddset(&mask_sigset, SIGHUP); if (sigprocmask(SIG_BLOCK, &mask_sigset, NULL) < 0) { pr_log_pri(PR_LOG_NOTICE, "unable to block signal set: %s", strerror(errno)); } } else { if (sigprocmask(SIG_UNBLOCK, &mask_sigset, NULL) < 0) { pr_log_pri(PR_LOG_NOTICE, "unable to unblock signal set: %s", strerror(errno)); } } }
static int create_dir(const char *dir, uid_t uid, gid_t gid, mode_t mode) { mode_t prev_mask; struct stat st; int res = -1; pr_fs_clear_cache2(dir); res = pr_fsio_stat(dir, &st); if (res == -1 && errno != ENOENT) { int xerrno = errno; pr_log_pri(PR_LOG_WARNING, "error checking '%s': %s", dir, strerror(xerrno)); errno = xerrno; return -1; } /* The directory already exists. */ if (res == 0) { pr_trace_msg(trace_channel, 8, "'%s' already exists", dir); pr_log_debug(DEBUG3, "CreateHome: '%s' already exists", dir); return 0; } /* The given mode is absolute, not subject to any Umask setting. */ prev_mask = umask(0); if (pr_fsio_mkdir(dir, mode) < 0) { int xerrno = errno; umask(prev_mask); pr_log_pri(PR_LOG_WARNING, "error creating '%s': %s", dir, strerror(xerrno)); errno = xerrno; return -1; } umask(prev_mask); if (pr_fsio_chown(dir, uid, gid) < 0) { int xerrno = errno; pr_log_pri(PR_LOG_WARNING, "error setting ownership of '%s': %s", dir, strerror(xerrno)); errno = xerrno; return -1; } pr_trace_msg(trace_channel, 8, "directory '%s' created", dir); pr_log_debug(DEBUG6, "CreateHome: directory '%s' created", dir); return 0; }
static int dso_init(void) { #ifdef PR_USE_CTRLS register unsigned int i = 0; #endif /* PR_USE_CTRLS */ /* Allocate the pool for this module's use. */ dso_pool = make_sub_pool(permanent_pool); pr_pool_tag(dso_pool, MOD_DSO_VERSION); lt_dlpreload_default(lt_preloaded_symbols); /* Initialize libltdl. */ if (lt_dlinit() < 0) { pr_log_pri(PR_LOG_ERR, MOD_DSO_VERSION ": error initializing libltdl: %s", lt_dlerror()); return -1; } /* Explicitly set the search path used for opening modules. */ if (lt_dlsetsearchpath(dso_module_path) < 0) { pr_log_pri(PR_LOG_ERR, MOD_DSO_VERSION ": error setting module path: %s", lt_dlerror()); return -1; } #ifdef PR_USE_CTRLS /* Register ctrls handlers. */ for (i = 0; dso_acttab[i].act_action; i++) { pool *sub_pool = make_sub_pool(dso_pool); /* Allocate and initialize the ACL for this control. */ dso_acttab[i].act_acl = pcalloc(sub_pool, sizeof(ctrls_acl_t)); dso_acttab[i].act_acl->acl_pool = sub_pool; pr_ctrls_init_acl(dso_acttab[i].act_acl); if (pr_ctrls_register(&dso_module, dso_acttab[i].act_action, dso_acttab[i].act_desc, dso_acttab[i].act_cb) < 0) pr_log_pri(PR_LOG_INFO, MOD_DSO_VERSION ": error registering '%s' control: %s", dso_acttab[i].act_action, strerror(errno)); } #endif /* PR_USE_CTRLS */ /* Ideally, we'd call register a listener for the 'core.exit' event * and call lt_dlexit() there, politely freeing up any resources allocated * by the ltdl library. However, it's possible that other modules, later in * the dispatch cycles, may need to use pointers to memory in shared modules * that would become invalid by such finalization. So we skip it, for now. * * If there was a way to schedule this handler, to happen after all other * exit handlers, that'd be best. */ pr_event_register(&dso_module, "core.restart", dso_restart_ev, NULL); return 0; }
static int af_setpwent(void) { if (af_user_file != NULL) { if (af_user_file->af_file != NULL) { /* If already opened, rewind */ rewind(af_user_file->af_file); return 0; } else { int xerrno; PRIVS_ROOT af_user_file->af_file = fopen(af_user_file->af_path, "r"); xerrno = errno; PRIVS_RELINQUISH if (af_user_file->af_file == NULL) { struct stat st; if (pr_fsio_stat(af_user_file->af_path, &st) == 0) { pr_log_pri(PR_LOG_WARNING, "error: unable to open AuthUserFile file '%s' (file owned by " "UID %lu, GID %lu, perms %04o, accessed by UID %lu, GID %lu): %s", af_user_file->af_path, (unsigned long) st.st_uid, (unsigned long) st.st_gid, st.st_mode & ~S_IFMT, (unsigned long) geteuid(), (unsigned long) getegid(), strerror(xerrno)); } else { pr_log_pri(PR_LOG_WARNING, "error: unable to open AuthUserFile file '%s': %s", af_user_file->af_path, strerror(xerrno)); } errno = xerrno; return -1; } if (fcntl(fileno(af_user_file->af_file), F_SETFD, FD_CLOEXEC) < 0) { pr_log_pri(PR_LOG_WARNING, MOD_AUTH_FILE_VERSION ": unable to set CLOEXEC on AuthUserFile %s (fd %d): %s", af_user_file->af_path, fileno(af_user_file->af_file), strerror(errno)); } pr_log_debug(DEBUG7, MOD_AUTH_FILE_VERSION ": using passwd file '%s'", af_user_file->af_path); return 0; } } pr_trace_msg(trace_channel, 8, "no AuthUserFile configured"); errno = EPERM; return -1; }
static void dynmasq_refresh(void) { server_rec *s; pr_log_debug(DEBUG2, MOD_DYNMASQ_VERSION ": resolving all MasqueradeAddress directives (could take a little while)"); for (s = (server_rec *) server_list->xas_list; s; s = s->next) { config_rec *c; c = find_config(s->conf, CONF_PARAM, "MasqueradeAddress", FALSE); if (c != NULL) { const char *masq_addr; pr_netaddr_t *na; masq_addr = c->argv[1]; pr_netaddr_clear_ipcache(masq_addr); na = pr_netaddr_get_addr(s->pool, masq_addr, NULL); if (na != NULL) { /* Compare the obtained netaddr with the one already present. * Only update the "live" netaddr if they differ. */ pr_log_debug(DEBUG2, MOD_DYNMASQ_VERSION ": resolved MasqueradeAddress '%s' to IP address %s", masq_addr, pr_netaddr_get_ipstr(na)); if (pr_netaddr_cmp(c->argv[0], na) != 0) { pr_log_pri(PR_LOG_DEBUG, MOD_DYNMASQ_VERSION ": MasqueradeAddress '%s' updated for new address %s (was %s)", masq_addr, pr_netaddr_get_ipstr(na), pr_netaddr_get_ipstr(c->argv[0])); /* Overwrite the old netaddr pointer. Note that this constitutes * a minor memory leak, as there currently isn't a way to free * the memory used by a netaddr object. Hrm. */ c->argv[0] = na; } else { pr_log_debug(DEBUG2, MOD_DYNMASQ_VERSION ": MasqueradeAddress '%s' has not changed addresses", masq_addr); } } else { pr_log_pri(PR_LOG_INFO, MOD_DYNMASQ_VERSION ": unable to resolve '%s', keeping previous address", masq_addr); } } } return; }
static int mcache_init(void) { const char *version; memcache_pool = make_sub_pool(permanent_pool); pr_pool_tag(memcache_pool, MOD_MEMCACHE_VERSION); memcache_server_lists = make_array(memcache_pool, 2, sizeof(memcached_server_st **)); memcache_init(); pr_event_register(&memcache_module, "core.restart", mcache_restart_ev, NULL); version = memcached_lib_version(); if (strcmp(version, LIBMEMCACHED_VERSION_STRING) != 0) { pr_log_pri(PR_LOG_INFO, MOD_MEMCACHE_VERSION ": compiled using libmemcached-%s headers, but linked to " "libmemcached-%s library", LIBMEMCACHED_VERSION_STRING, version); } else { pr_log_debug(DEBUG2, MOD_MEMCACHE_VERSION ": using libmemcached-%s", version); } return 0; }
void init_bindings(void) { int res = 0; #ifdef PR_USE_IPV6 int sock; /* Check to see whether we can actually create an IPv6 socket. */ sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); if (sock < 0) { pr_netaddr_disable_ipv6(); } else { (void) close(sock); } #endif /* PR_USE_IPV6 */ if (ServerType == SERVER_INETD) { res = init_inetd_bindings(); } else if (ServerType == SERVER_STANDALONE) { res = init_standalone_bindings(); } if (res < 0) { pr_log_pri(PR_LOG_ERR, "%s", "Unable to start proftpd; check logs for more details"); exit(1); } }
int xferlog_open(const char *path) { if (path == NULL) { if (xferlogfd != -1) { xferlog_close(); } return 0; } if (xferlogfd == -1) { pr_log_debug(DEBUG6, "opening TransferLog '%s'", path); pr_log_openfile(path, &xferlogfd, PR_TUNABLE_XFER_LOG_MODE); if (xferlogfd < 0) { int xerrno = errno; pr_log_pri(PR_LOG_NOTICE, "unable to open TransferLog '%s': %s", path, strerror(xerrno)); errno = xerrno; } } return xferlogfd; }
struct group *pr_auth_getgrgid(pool *p, gid_t gid) { cmd_rec *cmd = NULL; modret_t *mr = NULL; struct group *res = NULL; cmd = make_cmd(p, 1, (void *) &gid); mr = dispatch_auth(cmd, "getgrgid", NULL); if (MODRET_ISHANDLED(mr) && MODRET_HASDATA(mr)) res = mr->data; if (cmd->tmp_pool) { destroy_pool(cmd->tmp_pool); cmd->tmp_pool = NULL; } /* Sanity check */ if (res == NULL) { errno = ENOENT; return NULL; } /* Make sure the GID is not -1 */ if (res->gr_gid == (gid_t) -1) { pr_log_pri(PR_LOG_ERR, "error: GID of -1 not allowed"); return NULL; } pr_log_debug(DEBUG10, "retrieved group '%s' for GID %lu", res->gr_name, (unsigned long) gid); return res; }
static int sftppam_init(void) { #if defined(PR_SHARED_MODULE) pr_event_register(&sftp_pam_module, "core.module-unload", sftppam_mod_unload_ev, NULL); #endif /* !PR_SHARED_MODULE */ /* Prepare our driver. */ memset(&sftppam_driver, 0, sizeof(sftppam_driver)); sftppam_driver.open = sftppam_driver_open; sftppam_driver.authenticate = sftppam_driver_authenticate; sftppam_driver.close = sftppam_driver_close; /* Register ourselves with mod_sftp. */ if (sftp_kbdint_register_driver("pam", &sftppam_driver) < 0) { int xerrno = errno; pr_log_pri(PR_LOG_NOTICE, MOD_SFTP_PAM_VERSION ": notice: error registering 'keyboard-interactive' driver: %s", strerror(xerrno)); errno = xerrno; return -1; } return 0; }
static void *null_alloc(size_t size) { void *ret = NULL; if (size == 0) { /* Yes, this code is correct. * * The size argument is the originally requested amount of memory. * null_alloc() is called because smalloc() returned NULL. But why, * exactly? If the requested size is zero, then it may not have been * an error -- or it may be because the system is actually out of memory. * To differentiate, we do a malloc(0) call here if the requested size is * zero. If malloc(0) returns NULL, then we really do have an error. */ ret = malloc(size); } if (ret == NULL) { pr_log_pri(PR_LOG_ALERT, "Out of memory!"); #ifdef PR_USE_DEVEL if (debug_flags & PR_POOL_DEBUG_FL_OOM_DUMP_POOLS) { pr_pool_debug_memory(oom_printf); } #endif exit(1); } return ret; }
static void qos_data_connect_ev(const void *event_data, void *user_data) { const struct socket_ctx *sc; sc = event_data; /* Only set TOS flags on IPv4 sockets; IPv6 sockets don't seem to support * them. */ if (pr_netaddr_get_family(sc->addr) == AF_INET) { config_rec *c; c = find_config(sc->server->conf, CONF_PARAM, "QoSOptions", FALSE); if (c) { int dataqos, res; dataqos = *((int *) c->argv[1]); res = setsockopt(sc->sockfd, ip_level, IP_TOS, (void *) &dataqos, sizeof(dataqos)); if (res < 0) { pr_log_pri(PR_LOG_NOTICE, MOD_QOS_VERSION ": error setting data socket IP_TOS: %s", strerror(errno)); } } } }
static int af_setpwent(void) { if (af_user_file) { if (af_user_file->af_file) { /* If already opened, rewind */ rewind(af_user_file->af_file); return 0; } else { af_user_file->af_file = fopen(af_user_file->af_path, "r"); if (af_user_file->af_file == NULL) { pr_log_pri(PR_LOG_ERR, "error: unable to open passwd file '%s': %s", af_user_file->af_path, strerror(errno)); return -1; } pr_log_debug(DEBUG7, MOD_AUTH_FILE_VERSION ": using passwd file '%s'", af_user_file->af_path); return 0; } } errno = EPERM; return -1; }
static struct group *af_getgrent(void) { struct group *grp = NULL, *res = NULL; if (!af_group_file || !af_group_file->af_file) { errno = EINVAL; return NULL; } while (TRUE) { #ifdef HAVE_FGETGRENT pr_signals_handle(); grp = fgetgrent(af_group_file->af_file); #else char *cp = NULL, *buf = NULL; int buflen = BUFSIZ; pr_signals_handle(); buf = malloc(BUFSIZ); if (buf == NULL) { pr_log_pri(PR_LOG_CRIT, "%s", "Out of memory!"); _exit(1); } grp = NULL; while (af_getgrentline(&buf, &buflen, af_group_file->af_file) != NULL) { /* Ignore comment and empty lines */ if (buf[0] == '\0' || buf[0] == '#') { continue; } cp = strchr(buf, '\n'); if (cp != NULL) *cp = '\0'; grp = af_getgrp(buf); free(buf); break; } #endif /* !HAVE_FGETGRENT */ /* If grp is NULL now, the file is empty - nothing more to be read. */ if (grp == NULL) { break; } if (af_allow_grent(grp) < 0) { continue; } res = grp; break; } return res; }
struct group *pr_auth_getgrent(pool *p) { cmd_rec *cmd = NULL; modret_t *mr = NULL; struct group *res = NULL; cmd = make_cmd(p, 0); mr = dispatch_auth(cmd, "getgrent", NULL); if (MODRET_ISHANDLED(mr) && MODRET_HASDATA(mr)) { res = mr->data; } if (cmd->tmp_pool) { destroy_pool(cmd->tmp_pool); cmd->tmp_pool = NULL; } /* Sanity check */ if (res == NULL) return NULL; /* Make sure the GID is not -1 */ if (res->gr_gid == (gid_t) -1) { pr_log_pri(PR_LOG_WARNING, "error: GID of -1 not allowed"); return NULL; } return res; }
static int dynmasq_init(void) { #if defined(PR_SHARED_MODULE) pr_event_register(&dynmasq_module, "core.module-unload", dynmasq_mod_unload_ev, NULL); #endif /* !PR_SHARED_MODULE */ pr_event_register(&dynmasq_module, "core.postparse", dynmasq_postparse_ev, NULL); pr_event_register(&dynmasq_module, "core.restart", dynmasq_restart_ev, NULL); #ifdef PR_USE_CTRLS if (pr_ctrls_register(&dynmasq_module, "dynmasq", "mod_dynmasq controls", dynmasq_handle_dynmasq) < 0) { pr_log_pri(PR_LOG_NOTICE, MOD_DYNMASQ_VERSION ": error registering 'dynmasq' control: %s", strerror(errno)); } else { register unsigned int i; dynmasq_act_pool = make_sub_pool(permanent_pool); pr_pool_tag(dynmasq_act_pool, "DynMasq Controls Pool"); for (i = 0; dynmasq_acttab[i].act_action; i++) { dynmasq_acttab[i].act_acl = palloc(dynmasq_act_pool, sizeof(ctrls_acl_t)); pr_ctrls_init_acl(dynmasq_acttab[i].act_acl); } } #endif /* PR_USE_CTRLS */ return 0; }
static unsigned int sym_type_hash(pr_stash_type_t sym_type, const char *name, size_t namelen) { unsigned int hash; /* XXX Ugly hack to support mixed cases of directives in config files. */ if (sym_type != PR_SYM_CONF) { hash = symtab_hash(name, namelen); } else { register unsigned int i; char *buf; buf = malloc(namelen+1); if (buf == NULL) { pr_log_pri(PR_LOG_ALERT, "Out of memory!"); exit(1); } buf[namelen] = '\0'; for (i = 0; i < namelen; i++) { buf[i] = tolower((int) name[i]); } hash = symtab_hash(buf, namelen); free(buf); } return hash; }
int pr_scoreboard_add_entry(void) { unsigned char found_slot = FALSE; if (scoreboard_fd < 0) { errno = EINVAL; return -1; } /* Write-lock the scoreboard file. */ if (wlock_scoreboard() < 0) return -1; /* No interruptions, please. */ pr_signals_block(); /* If the scoreboard is open, the file position is already past the * header. */ while (TRUE) { int res = 0; while ((res = read(scoreboard_fd, &entry, sizeof(entry))) == sizeof(entry)) { /* If this entry's PID is marked as zero, it means this slot can be * reused. */ if (!entry.sce_pid) { entry_lock.l_start = lseek(scoreboard_fd, 0, SEEK_CUR) - sizeof(entry); found_slot = TRUE; break; } } if (res == 0) { entry_lock.l_start = lseek(scoreboard_fd, 0, SEEK_CUR); found_slot = TRUE; } if (found_slot) break; } memset(&entry, '\0', sizeof(entry)); entry.sce_pid = getpid(); entry.sce_uid = geteuid(); entry.sce_gid = getegid(); if (write_entry() < 0) pr_log_pri(PR_LOG_NOTICE, "error writing scoreboard entry: %s", strerror(errno)); pr_signals_unblock(); /* We can unlock the scoreboard now. */ unlock_scoreboard(); return 0; }
static void wrap_log_request_denied(int priority, struct request_info *request) { pr_log_pri(priority, MOD_WRAP_VERSION ": refused connection from %s", eval_client(request)); /* done */ return; }
static struct passwd *af_getpasswd(const char *buf, unsigned int lineno) { register unsigned int i; register char *cp = NULL; char *ep = NULL, *buffer = NULL; char **fields = NULL; struct passwd *pwd = NULL; fields = pwdfields; buffer = pwdbuf; pwd = &pwent; sstrncpy(buffer, buf, BUFSIZ-1); buffer[BUFSIZ-1] = '\0'; for (cp = buffer, i = 0; i < NPWDFIELDS && cp; i++) { fields[i] = cp; while (*cp && *cp != ':') { ++cp; } if (*cp) { *cp++ = '\0'; } else { cp = 0; } } if (i != NPWDFIELDS) { pr_log_pri(PR_LOG_ERR, "Malformed entry in AuthUserFile file (line %u)", lineno); return NULL; } if (*fields[2] == '\0' || *fields[3] == '\0') { return NULL; } pwd->pw_name = fields[0]; pwd->pw_passwd = fields[1]; if (fields[2][0] == '\0' || ((pwd->pw_uid = strtol(fields[2], &ep, 10)) == 0 && *ep)) { return NULL; } if (fields[3][0] == '\0' || ((pwd->pw_gid = strtol(fields[3], &ep, 10)) == 0 && *ep)) { return NULL; } pwd->pw_gecos = fields[4]; pwd->pw_dir = fields[5]; pwd->pw_shell = fields[6]; return pwd; }
static int wrap_is_usable_file(char *filename) { struct stat st; pr_fh_t *fh = NULL; /* check the easy case first */ if (filename == NULL) return FALSE; /* Make sure that the current process can _read_ the file. */ fh = pr_fsio_open(filename, O_RDONLY); if (fh == NULL) { int xerrno = errno; pr_log_pri(PR_LOG_NOTICE, MOD_WRAP_VERSION ": failed to read \"%s\": %s", filename, strerror(xerrno)); errno = xerrno; return FALSE; } if (pr_fsio_fstat(fh, &st) < 0) { int xerrno = errno; pr_log_pri(PR_LOG_NOTICE, MOD_WRAP_VERSION ": failed to stat \"%s\": %s", filename, strerror(xerrno)); pr_fsio_close(fh); errno = xerrno; return FALSE; } if (S_ISDIR(st.st_mode)) { int xerrno = EISDIR; pr_log_pri(PR_LOG_NOTICE, MOD_WRAP_VERSION ": unable to use \"%s\": %s", filename, strerror(xerrno)); pr_fsio_close(fh); errno = xerrno; return FALSE; } pr_fsio_close(fh); return TRUE; }
const char *pr_netaddr_get_ipstr(pr_netaddr_t *na) { #ifdef PR_USE_IPV6 char buf[INET6_ADDRSTRLEN]; #else char buf[INET_ADDRSTRLEN]; #endif /* PR_USE_IPV6 */ int res = 0; if (!na) { errno = EINVAL; return NULL; } /* If this pr_netaddr_t has already been resolved to an IP string, return the * cached string. */ if (na->na_have_ipstr) return na->na_ipstr; memset(buf, '\0', sizeof(buf)); res = pr_getnameinfo(pr_netaddr_get_sockaddr(na), pr_netaddr_get_sockaddr_len(na), buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); if (res != 0) { if (res != EAI_SYSTEM) { pr_log_pri(PR_LOG_INFO, "getnameinfo error: %s", pr_gai_strerror(res)); } else { pr_log_pri(PR_LOG_INFO, "getnameinfo system error: [%d] %s", errno, strerror(errno)); } return NULL; } /* Copy the string into the pr_netaddr_t cache as well, so we only * have to do this once for this pr_netaddr_t. */ memset(na->na_ipstr, '\0', sizeof(na->na_ipstr)); sstrncpy(na->na_ipstr, buf, sizeof(na->na_ipstr)); na->na_have_ipstr = TRUE; return na->na_ipstr; }
static struct group *af_getgrp(const char *buf, unsigned int lineno) { int i; char *cp; i = strlen(buf) + 1; if (!grpbuf) { grpbuf = malloc(i); } else { char *new_buf; new_buf = realloc(grpbuf, i); if (new_buf == NULL) { return NULL; } grpbuf = new_buf; } if (!grpbuf) return NULL; sstrncpy(grpbuf, buf, i); cp = strrchr(grpbuf, '\n'); if (cp) { *cp = '\0'; } for (cp = grpbuf, i = 0; i < NGRPFIELDS && cp; i++) { grpfields[i] = cp; cp = strchr(cp, ':'); if (cp) { *cp++ = 0; } } if (i < (NGRPFIELDS - 1)) { pr_log_pri(PR_LOG_ERR, "Malformed entry in AuthGroupFile file (line %u)", lineno); return NULL; } if (*grpfields[2] == '\0') { return NULL; } grent.gr_name = grpfields[0]; grent.gr_passwd = grpfields[1]; grent.gr_gid = atoi(grpfields[2]); grent.gr_mem = af_getgrmems(grpfields[3]); return &grent; }
static void null_alloc(void) { pr_log_pri(PR_LOG_ALERT, "Out of memory!"); #ifdef PR_USE_DEVEL if (debug_flags & PR_POOL_DEBUG_FL_OOM_DUMP_POOLS) { pr_pool_debug_memory(oom_printf); } #endif exit(1); }