/* borrowed from GNU sh-utils' "su.c" */ static bool restricted_shell (const char *shellstr) { char *line; setusershell (); while ((line = getusershell ()) != NULL) { if (('#' != *line) && (strcmp (line, shellstr) == 0)) { endusershell (); return false; } } endusershell (); return true; }
static bool restricted_shell (const char* shell) { char* line; setusershell (); while ((line = getusershell ()) != NULL) { if (*line != '#' && !strcmp (line, shell)) { endusershell (); return false; } } endusershell (); return true; }
static int shells(int argc, char *argv[]) { const char *sh; int i, rv = RV_OK; setusershell(); if (argc == 2) { while ((sh = getusershell()) != NULL) SHELLSPRINT; } else { for (i = 2; i < argc; i++) { setusershell(); while ((sh = getusershell()) != NULL) { if (strcmp(sh, argv[i]) == 0) { SHELLSPRINT; break; } } if (sh == NULL) { rv = RV_NOTFOUND; break; } } } endusershell(); return rv; }
int checkshell() { #ifdef HAVE_GETUSERSHELL char *cp; struct passwd *pwd; #if 0 //brcm if (!strcasecmp(config_getoption("AUTH_ETCSHELLS"), "no")) return 0; #endif //brcm pwd = getpwnam(user); while ((cp = getusershell())) if (!strcmp(cp, pwd->pw_shell)) break; endusershell(); if (!cp) return 1; else return 0; #else return 0; # warning "Your system doesn't have getusershell(). You can not" # warning "use /etc/shells authentication with bftpd." #endif }
static Eina_Bool _entrance_session_begin(struct passwd *pwd, const char *cookie) { PT("Session Init\n"); if (pwd->pw_shell[0] == '\0') { setusershell(); strcpy(pwd->pw_shell, getusershell()); endusershell(); } #ifdef HAVE_PAM char *term = getenv("TERM"); if (term) entrance_pam_env_set("TERM", term); entrance_pam_env_set("HOME", pwd->pw_dir); entrance_pam_env_set("SHELL", pwd->pw_shell); entrance_pam_env_set("USER", pwd->pw_name); entrance_pam_env_set("LOGNAME", pwd->pw_name); entrance_pam_env_set("PATH", entrance_config->session_path); entrance_pam_env_set("DISPLAY", ":0.0"); entrance_pam_env_set("MAIL", ""); entrance_pam_env_set("XAUTHORITY", cookie); entrance_pam_env_set("XDG_SESSION_CLASS", "greeter"); #endif return EINA_TRUE; }
void setusershell ( void ) { if ( isopen ) endusershell ( ); fp = fopen ( "/etc/shells", "r" ); cursh = validsh; isopen = 1; }
struct passwd* Input::GetPasswdStruct() { struct passwd* pw = getpwnam(NameBuffer); endpwent(); if (pw->pw_shell[0] == '\0') { setusershell(); pw->pw_shell = getusershell(); endusershell(); } return pw; }
int ok_shell(char *name) { char *p, *sh; setusershell(); while ((sh = getusershell())) { if (!strcmp(name, sh)) { endusershell(); return (1); } /* allow just shell name, but use "real" path */ if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) { endusershell(); return (1); } } endusershell(); return (0); }
static int verifyUserSettings(WINDOW *ds_win) { char tmp[256], *cp; long luid; WINDOW *save; int rv; if (strlen(uname) == 0) { feepout("The user name field must not be empty!"); return 0; } snprintf(tmp, 256, "pw user show -q -n %s > /dev/null", uname); if (vsystem(tmp) == 0) { feepout("This user name is already in use."); return 0; } if (strlen(uid) > 0) { luid = strtol(uid, &cp, 10); if (luid < 0 || luid >= 65536 || (*cp != '\0' && !isspace(*cp))) { feepout("The UID must be a number between 1 and 65535."); return 0; } } if (strlen(shell) > 0) { while((cp = getusershell()) != NULL) if (strcmp(cp, shell) == 0) break; endusershell(); if (cp == NULL) { save = savescr(); rv = msgYesNo("Warning:\n\n" "The requested shell \"%s\" is not\n" "a valid user shell.\n\n" "Use it anyway?\n", shell); restorescr(save); wrefresh(ds_win); if (rv != DITEM_SUCCESS) return 0; } } if (strlen(umemb) > 0) { if (strpbrk(umemb, " \t") != NULL) { feepout("The member groups list must not contain any whitespace;\n" "use commas to separate the names."); return 0; } } return 1; }
/* Return 1 if SHELL is a restricted shell (one not returned by getusershell), else 0, meaning it is a standard shell. */ int restricted_shell(const char *shell) { char *line; setusershell(); while ((line = getusershell())) { if (*line != '#' && strcmp(line, shell) == 0) return 0; } endusershell(); return 1; }
char * dup_shell(char *name) { char *p, *sh, *ret; setusershell(); while ((sh = getusershell())) { if (!strcmp(name, sh)) { endusershell(); return (strdup(name)); } /* allow just shell name, but use "real" path */ if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) { ret = strdup(sh); endusershell(); return (ret); } } endusershell(); return (NULL); }
int isvalid_shell(const char *shell) { char *t; int ret = 0; while ((t = getusershell()) != NULL) { if (strcmp(t, shell) == 0) { ret = 1; break; } } endusershell(); return (ret); }
static errno_t nss_get_etc_shells(TALLOC_CTX *mem_ctx, char ***_shells) { int i = 0; char *sh; char **shells = NULL; TALLOC_CTX *tmp_ctx; errno_t ret; int size; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; shells = talloc_array(tmp_ctx, char *, SHELL_REALLOC_INCREMENT); if (!shells) { ret = ENOMEM; goto done; } size = SHELL_REALLOC_INCREMENT; setusershell(); while ((sh = getusershell())) { shells[i] = talloc_strdup(shells, sh); if (!shells[i]) { endusershell(); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Found shell %s in /etc/shells\n", shells[i]); i++; if (i == size) { size += SHELL_REALLOC_INCREMENT; if (size > SHELL_REALLOC_MAX) { DEBUG(SSSDBG_FATAL_FAILURE, "Reached maximum number of shells [%d]. " "Users may be denied access. " "Please check /etc/shells for sanity\n", SHELL_REALLOC_MAX); break; } shells = talloc_realloc(NULL, shells, char *, size); if (!shells) { ret = ENOMEM; goto done; } } }
/* Return 1 if SHELL is a restricted shell (one not returned by * getusershell), else 0, meaning it is a standard shell. */ static int restricted_shell(const char *shell) { char *line; int result = 1; /*setusershell(); - getusershell does it itself*/ while ((line = getusershell()) != NULL) { if (/* *line != '#' && */ strcmp(line, shell) == 0) { result = 0; break; } } if (ENABLE_FEATURE_CLEAN_UP) endusershell(); return result; }
static int is_valid_shell(const char *shell) { int valid = 0; char *l; setusershell(); while ((l = getusershell()) != NULL) { if (strcmp(l, shell) == 0) { valid = 1; break; } } endusershell(); return valid; }
int validsh(char *rootsh) { char *sh, *getusershell(); int ret = 0; setusershell(); while((sh = getusershell()) != NULL ) { if( strcmp( rootsh, sh) == 0 ) { ret = 1; break; } } endusershell(); return(ret); }
/** * This function checks to see if the shell is known in /etc/shells. * If so, it returns 0. On error or illegal shell, it returns -1. */ static int verify_shell(const char *shell_name) { int rc = -1; const char *buf; if (!(shell_name && shell_name[0])) return rc; while ((buf = getusershell()) != NULL) { /* ignore comments */ if (*buf == '#') continue; /* check the shell skipping newline char */ if (!strcmp(shell_name, buf)) { rc = 0; break; } } endusershell(); return rc; }
static gboolean user_classify_is_excluded_by_heuristics (const gchar *username, const gchar *shell, const gchar *password_hash) { gboolean ret = FALSE; if (shell != NULL) { char *basename, *nologin_basename, *false_basename; #ifdef HAVE_GETUSERSHELL char *valid_shell; ret = TRUE; setusershell (); while ((valid_shell = getusershell ()) != NULL) { if (g_strcmp0 (shell, valid_shell) != 0) continue; ret = FALSE; } endusershell (); #endif basename = g_path_get_basename (shell); nologin_basename = g_path_get_basename (PATH_NOLOGIN); false_basename = g_path_get_basename (PATH_FALSE); if (shell[0] == '\0') { ret = TRUE; } else if (g_strcmp0 (basename, nologin_basename) == 0) { ret = TRUE; } else if (g_strcmp0 (basename, false_basename) == 0) { ret = TRUE; } g_free (basename); g_free (nologin_basename); g_free (false_basename); } if (password_hash != NULL) { /* skip over the account-is-locked '!' prefix if present */ if (password_hash[0] == '!') password_hash++; if (password_hash[0] != '\0') { /* modern hashes start with "$n$" */ if (password_hash[0] == '$') { if (strlen (password_hash) < 4) ret = TRUE; /* DES crypt is base64 encoded [./A-Za-z0-9]* */ } else if (!g_ascii_isalnum (password_hash[0]) && password_hash[0] != '.' && password_hash[0] != '/') { ret = TRUE; } } } return ret; }
int __pw_scan(char *bp, struct passwd *pw, int flags) { uid_t id; int root; char *ep, *p, *sh; unsigned long temp; if (pw_big_ids_warning == -1) pw_big_ids_warning = getenv("PW_SCAN_BIG_IDS") == NULL ? 1 : 0; pw->pw_fields = 0; if (!(pw->pw_name = strsep(&bp, ":"))) /* login */ goto fmt; root = !strcmp(pw->pw_name, "root"); if (pw->pw_name[0] && (pw->pw_name[0] != '+' || pw->pw_name[1] == '\0')) pw->pw_fields |= _PWF_NAME; if (!(pw->pw_passwd = strsep(&bp, ":"))) /* passwd */ goto fmt; if (pw->pw_passwd[0]) pw->pw_fields |= _PWF_PASSWD; if (!(p = strsep(&bp, ":"))) /* uid */ goto fmt; if (p[0]) pw->pw_fields |= _PWF_UID; else { if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') { if (flags & _PWSCAN_WARN) warnx("no uid for user %s", pw->pw_name); return (0); } } errno = 0; temp = strtoul(p, &ep, 10); if ((temp == ULONG_MAX && errno == ERANGE) || temp > UID_MAX) { if (flags & _PWSCAN_WARN) warnx("%s > max uid value (%u)", p, UID_MAX); return (0); } id = temp; if (*ep != '\0') { if (flags & _PWSCAN_WARN) warnx("%s uid is incorrect", p); return (0); } if (root && id) { if (flags & _PWSCAN_WARN) warnx("root uid should be 0"); return (0); } if (flags & _PWSCAN_WARN && pw_big_ids_warning && id > USHRT_MAX) { warnx("%s > recommended max uid value (%u)", p, USHRT_MAX); /*return (0);*/ /* THIS SHOULD NOT BE FATAL! */ } pw->pw_uid = id; if (!(p = strsep(&bp, ":"))) /* gid */ goto fmt; if (p[0]) pw->pw_fields |= _PWF_GID; else { if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') { if (flags & _PWSCAN_WARN) warnx("no gid for user %s", pw->pw_name); return (0); } } errno = 0; temp = strtoul(p, &ep, 10); if ((temp == ULONG_MAX && errno == ERANGE) || temp > GID_MAX) { if (flags & _PWSCAN_WARN) warnx("%s > max gid value (%u)", p, GID_MAX); return (0); } id = temp; if (*ep != '\0') { if (flags & _PWSCAN_WARN) warnx("%s gid is incorrect", p); return (0); } if (flags & _PWSCAN_WARN && pw_big_ids_warning && id > USHRT_MAX) { warnx("%s > recommended max gid value (%u)", p, USHRT_MAX); /* return (0); This should not be fatal! */ } pw->pw_gid = id; if (flags & _PWSCAN_MASTER ) { if (!(pw->pw_class = strsep(&bp, ":"))) /* class */ goto fmt; if (pw->pw_class[0]) pw->pw_fields |= _PWF_CLASS; if (!(p = strsep(&bp, ":"))) /* change */ goto fmt; if (p[0]) pw->pw_fields |= _PWF_CHANGE; pw->pw_change = atol(p); if (!(p = strsep(&bp, ":"))) /* expire */ goto fmt; if (p[0]) pw->pw_fields |= _PWF_EXPIRE; pw->pw_expire = atol(p); } if (!(pw->pw_gecos = strsep(&bp, ":"))) /* gecos */ goto fmt; if (pw->pw_gecos[0]) pw->pw_fields |= _PWF_GECOS; if (!(pw->pw_dir = strsep(&bp, ":"))) /* directory */ goto fmt; if (pw->pw_dir[0]) pw->pw_fields |= _PWF_DIR; if (!(pw->pw_shell = strsep(&bp, ":"))) /* shell */ goto fmt; p = pw->pw_shell; if (root && *p) { /* empty == /bin/sh */ for (setusershell();;) { if (!(sh = getusershell())) { if (flags & _PWSCAN_WARN) warnx("warning, unknown root shell"); break; } if (!strcmp(p, sh)) break; } endusershell(); } if (p[0]) pw->pw_fields |= _PWF_SHELL; if ((p = strsep(&bp, ":"))) { /* too many */ fmt: if (flags & _PWSCAN_WARN) warnx("corrupted entry"); return (0); } return (1); }
Boolean ssh_login_permitted(const char *user, SshUser uc) { char passwd[20]; /* Only for account lock check */ strncpy(passwd, uc->correct_encrypted_passwd, sizeof(passwd)); passwd[sizeof(passwd) - 1] = '\0'; #ifdef HAVE_USERSEC_H { char *expiration, current_time[100], normalized[100]; int rlogin_permitted; ssh_time t; struct SshCalendarTimeRec tm[1]; int account_is_locked; if (setuserdb(S_READ) < 0) { if (getuid() == 0) /* It's OK to fail here if we are not root */ { SSH_DEBUG(2, ("setuserdb S_READ failed: %.200s.", strerror(errno))); } return FALSE; } if (getuserattr((char *)user, S_RLOGINCHK, &rlogin_permitted, SEC_BOOL) < 0) { if (getuid() == 0) /* It's OK to fail here if we are not root */ { SSH_DEBUG(2, ("getuserattr S_RLOGINCHK failed: %.200s", strerror(errno))); } enduserdb(); return FALSE; } if (getuserattr((char *)user, S_EXPIRATION, &expiration, SEC_CHAR) < 0) { SSH_DEBUG(2, ("getuserattr S_EXPIRATION failed: %.200s.", strerror(errno))); enduserdb(); return FALSE; } #ifdef S_LOCKED if (getuserattr(user, S_LOCKED, &account_is_locked, SEC_BOOL) < 0) { SSH_DEBUG(2, ("getuserattr S_LOCKED failed: %.200s.", strerror(errno))); enduserdb(); return FALSE; } if (account_is_locked) { SSH_DEBUG(2, ("Account %.100s is locked.", user)); enduserdb(); return FALSE; } #endif /* S_LOCKED */ if (!rlogin_permitted) { SSH_DEBUG(2, ("Remote logins to account %.100s not permitted by " "user profile.", user)); enduserdb(); return FALSE; } if (strcmp(expiration, "0") == 0) { /* The account does not expire - return success immediately. */ enduserdb(); return TRUE; } if (strlen(expiration) != 10) { SSH_DEBUG(2, ("Account %.100s expiration date is in wrong format.", user)); enduserdb(); return FALSE; } t = ssh_time(); ssh_calendar_time(t, tm, TRUE); snprintf(current_time, sizeof(current_time), "%04d%02d%02d%02d%02d", tm->year, tm->month + 1, tm->monthday, tm->hour, tm->minute); if (expiration[8] < '7') /* Assume year < 70 is 20YY. */ strcpy(normalized, "20"); else strcpy(normalized, "19"); strcat(normalized, expiration + 8); strcat(normalized, expiration); normalized[12] = '\0'; if (strcmp(normalized, current_time) < 0) { SSH_DEBUG(2, ("Account %.100s has expired - access denied.", user)); enduserdb(); return FALSE; } enduserdb(); } #endif /* HAVE_USERSEC_H */ #ifdef HAVE_ETC_SHADOW { struct spwd *sp; sp = (struct spwd *)getspnam(user); #if defined(SECURE_RPC) && defined(NIS_PLUS) if (geteuid() == UID_ROOT && ssh_user_uid(uc) != UID_ROOT && (!sp || !sp->sp_pwdp || !strcmp(sp->sp_pwdp,"*NP*"))) { if (seteuid(ssh_user_uid(uc)) >= 0) { sp = getspnam(user); /* retry as user */ seteuid(UID_ROOT); } } #endif /* SECURE_RPC && NIS_PLUS */ if (!sp) { /* * Some systems, e.g.: IRIX, may or may not have /etc/shadow. * Just check if there is one. If such system is also an YP * client, then valid password might already be present in passwd * structure. Just check if it's other than "x". Assume that * YP server is always right if this is the case. * [email protected] */ struct stat sbf; if ((stat(SHADOW, &sbf) == 0) && strcmp(uc->correct_encrypted_passwd, "x") == 0) { SSH_DEBUG(2, ("Can't find %.100s's shadow - access denied.", user)); endspent(); return FALSE; } } else { SshTime today = ssh_time()/24/60/60; /* what a day! */ #ifdef HAVE_STRUCT_SPWD_EXPIRE /* Check for expiration date */ if (sp->sp_expire > 0 && today > sp->sp_expire) { SSH_DEBUG(2, ("Account %.100s has expired - access denied.", user)); endspent(); return FALSE; } #endif #ifdef HAVE_STRUCT_SPWD_INACT /* Check for last login */ if (sp->sp_inact > 0) { char buf[64]; SshTime llt; llt = ssh_user_get_last_login_time(uc, buf, sizeof(buf)); if (llt && (today - llt/24/60/60) > sp->sp_inact) { SSH_DEBUG(2, ("Account %.100s was inactive for more than %d days.", user, sp->sp_inact)); endspent(); return FALSE; } } #endif /* Check if password is valid */ if (sp->sp_lstchg == 0 || (sp->sp_max > 0 && today > sp->sp_lstchg + sp->sp_max)) { SSH_DEBUG(2, ("Account %.100s's password is too old - forced to change.", user)); uc->password_needs_change = TRUE; } strncpy(passwd, sp->sp_pwdp, sizeof(passwd)); passwd[sizeof(passwd) - 1] = '\0'; } endspent(); } #endif /* HAVE_ETC_SHADOW */ /* * Check if account is locked. Check if encrypted password starts * with "*LK*". */ { if (strncmp(passwd,"*LK*", 4) == 0) { SSH_DEBUG(2, ("Account %.100s is locked.", user)); return FALSE; } } #ifdef CHECK_ETC_SHELLS { int invalid = 1; char *shell = pwd->pw_shell, *etc_shell, *getusershell(); if (!shell || !*shell) shell = DEFAULT_SHELL; while (invalid && (etc_shell = getusershell())) invalid = strcmp(etc_shell, shell); endusershell(); if (invalid) { SSH_DEBUG(2, ("Account %.100s doesn't have valid shell", user)); return FALSE; } } #endif /* CHECK_ETC_SHELLS */ return TRUE; }
void parse(option * c, const char *file) { FILE *f; // unsigned int line_number//, i; char line[BUFSIZ]; int leftside; char key[BUFSIZ], value[BUFSIZ]; // char *arg, *cmt, *opt; char *p; struct stat defshell_stat; char *shell; int found = FALSE; unsigned int x=0;//, y=0; bzero(c, sizeof (struct s_option)); // Set up some defaults strcpy(c->logdir, LOGDIR); c->fdl='-'; strcpy(c->defshell, "/bin/sh"); c->priority=-1; // No defaults here c->facility=-1; // or here... c->clearenvironment=1; f = fopen(file, "r"); if (f==NULL) { fprintf(stderr,"Warning: No config file found. Using compiled-in defaults:\nLogdir\t%s\nDefault Shell:\t%s\nSyslog disabled\n",c->logdir, c->defshell); // Just run with the defaults, ignore the rest return; } while (fgets(line, BUFSIZ-1, f)) { p=strchr(line,'='); if (!p) { // fprintf(stderr, "Invalid line in config file: %s\n",line); continue; } leftside=1; key[0]=value[0]=0; if (line[0]=='#') continue; // Ignore comments, blank lines // Trim the whitespace, split into key/value for (x=0 ; x<strlen(line);x++) if (!isspace(line[x])) { if (line[x]=='=') { leftside=0; continue; } if (leftside) strncat(key, &line[x], 1); else strncat(value, &line[x], 1); } // fprintf(stderr, "Parsed key [%s] and value [%s]\n",key, value); if(strcmp(key,"throttlebps")==0) c->bytespersecond=strtol(value,NULL,10); if (strcmp(key,"-cargallow")==0) { strcat(c->argallow,"$"); strcat(c->argallow,value); strcat(c->argallow,"$"); } if (strcmp(key,"logdir")==0) strcpy(c->logdir,value); if (strcmp(key,"clearenvironment")==0) { if(strncmp(value,"no",2)==0) { c->clearenvironment=0; } else c->clearenvironment=1; } if (strcmp(key,"defaultshell")==0) strcpy(c->defshell,value); if (strcmp(key,"delimiter")==0) c->fdl=value[0]; if (strcmp(key,"syslog.facility")==0) { // I really hate the way this is done... found = FALSE; #ifdef LOG_AUTH if (!strcmp(value, "LOG_AUTH")) { c->facility = LOG_AUTH; found = TRUE; } #endif /* LOG_AUTH */ #ifdef LOG_AUTHPRIV if (!strcmp(value, "LOG_AUTHPRIV")) { c->facility = LOG_AUTHPRIV; found = TRUE; } #endif /* LOG_AUTHPRIV */ #ifdef LOG_CRON if (!strcmp(value, "LOG_CRON")) { c->facility = LOG_CRON; found = TRUE; } #endif /* LOG_CRON */ #ifdef LOG_DAEMON if (!strcmp(value, "LOG_DAEMON")) { c->facility = LOG_DAEMON; found = TRUE; } #endif /* LOG_DAEMON */ #ifdef LOG_FTP if (!strcmp(value, "LOG_FTP")) { c->facility = LOG_FTP; found = TRUE; } #endif /* LOG_FTP */ #ifdef LOG_KERN if (!strcmp(value, "LOG_KERN")) { c->facility = LOG_KERN; found = TRUE; } #endif /* LOG_KERN */ #ifdef LOG_LOCAL0 if (!strcmp(value, "LOG_LOCAL0")) { c->facility = LOG_LOCAL0; found = TRUE; } #endif /* LOG_LOCAL0 */ #ifdef LOG_LOCAL1 if (!strcmp(value, "LOG_LOCAL1")) { c->facility = LOG_LOCAL1; found = TRUE; } #endif /* LOG_LOCAL1 */ #ifdef LOG_LOCAL2 if (!strcmp(value, "LOG_LOCAL2")) { c->facility = LOG_LOCAL2; found = TRUE; } #endif /* LOG_LOCAL2 */ #ifdef LOG_LOCAL3 if (!strcmp(value, "LOG_LOCAL3")) { c->facility = LOG_LOCAL3; found = TRUE; } #endif /* LOG_LOCAL3 */ #ifdef LOG_LOCAL4 if (!strcmp(value, "LOG_LOCAL4")) { c->facility = LOG_LOCAL4; found = TRUE; } #endif /* LOG_LOCAL4 */ #ifdef LOG_LOCAL5 if (!strcmp(value, "LOG_LOCAL5")) { c->facility = LOG_LOCAL5; found = TRUE; } #endif /* LOG_LOCAL5 */ #ifdef LOG_LOCAL6 if (!strcmp(value, "LOG_LOCAL6")) { c->facility = LOG_LOCAL6; found = TRUE; } #endif /* LOG_LOCAL6 */ #ifdef LOG_LOCAL7 if (!strcmp(value, "LOG_LOCAL7")) { c->facility = LOG_LOCAL7; found = TRUE; } #endif /* LOG_LOCAL7 */ #ifdef LOG_LPR if (!strcmp(value, "LOG_LPR")) { c->facility = LOG_LPR; found = TRUE; } #endif /* LOG_LPR */ #ifdef LOG_MAIL if (!strcmp(value, "LOG_MAIL")) { c->facility = LOG_MAIL; found = TRUE; } #endif /* LOG_MAIL */ #ifdef LOG_NEWS if (!strcmp(value, "LOG_NEWS")) { c->facility = LOG_NEWS; found = TRUE; } #endif /* LOG_NEWS */ #ifdef LOG_SYSLOG if (!strcmp(value, "LOG_SYSLOG")) { c->facility = LOG_SYSLOG; found = TRUE; } #endif /* LOG_SYSLOG */ #ifdef LOG_USER if (!strcmp(value, "LOG_USER")) { c->facility = LOG_USER; found = TRUE; } #endif /* LOG_USER */ #ifdef LOG_UUCP if (!strcmp(value, "LOG_UUCP")) { c->facility = LOG_UUCP; found = TRUE; } #endif /* LOG_UUCP */ if (found == FALSE) { fprintf(stderr,"Invalid syslog.facility in config file\n"); exit(-1); } } if (strcmp(key,"syslog.priority")==0) { int found = FALSE; #ifdef LOG_EMERG if (!strcmp(value, "LOG_EMERG")) { c->priority = LOG_EMERG; found = TRUE; } #endif /* LOG_EMERG */ #ifdef LOG_ALERT if (!strcmp(value, "LOG_ALERT")) { c->priority = LOG_ALERT; found = TRUE; } #endif /* LOG_ALERT */ #ifdef LOG_CRIT if (!strcmp(value, "LOG_CRIT")) { c->priority = LOG_CRIT; found = TRUE; } #endif /* LOG_CRIT */ #ifdef LOG_ERR if (!strcmp(value, "LOG_ERR")) { c->priority = LOG_ERR; found = TRUE; } #endif /* LOG_ERR */ #ifdef LOG_WARNING if (!strcmp(value, "LOG_WARNING")) { c->priority = LOG_WARNING; found = TRUE; } #endif /* LOG_WARNING */ #ifdef LOG_NOTICE if (!strcmp(value, "LOG_NOTICE")) { c->priority = LOG_NOTICE; found = TRUE; } #endif /* LOG_NOTICE */ #ifdef LOG_INFO if (!strcmp(value, "LOG_INFO")) { c->priority = LOG_INFO; found = TRUE; } #endif /* LOG_INFO */ #ifdef LOG_DEBUG if (!strcmp(value, "LOG_DEBUG")) { c->priority = LOG_DEBUG; found = TRUE; } #endif /* LOG_DEBUG */ if (found == FALSE) { fprintf(stderr, "%s: syslog.priority: level '%s' is unknown.\n", file, value); exit(EXIT_FAILURE); } } } // Validation // delimiter if (!ispunct(c->fdl)) { fprintf(stderr,"%s: delimiter [%c] must be punctuation\n",file, c->fdl); exit(EXIT_FAILURE); } // defaultshell #ifdef HAVE_GETUSERSHELL setusershell(); while ((shell = (char *)getusershell())) if (!strcmp(shell, c->defshell)) found = TRUE; endusershell(); if (!found) { fprintf(stderr, "default shell '%s' is not in /etc/shells.\n", c->defshell); exit(EXIT_FAILURE); } #endif /* HAVE_GETUSERSHELL */ if ((stat(c->defshell, &defshell_stat)) == -1) { fprintf(stderr, "default shell '%s': %s (%i)\n", value, strerror(errno), errno); exit(EXIT_FAILURE); } fclose(f); }
static int #if defined(USE_PAM) || defined(_AIX) isNoPassAllowed( const char *un ) { struct passwd *pw = 0; # ifdef HAVE_GETSPNAM /* (sic!) - not USESHADOW */ struct spwd *spw; # endif #else isNoPassAllowed( const char *un, struct passwd *pw ) { #endif struct group *gr; char **fp; int hg; if (!*un) return 0; if (cursource != PWSRC_MANUAL) return 1; for (hg = 0, fp = td->noPassUsers; *fp; fp++) if (**fp == '@') hg = 1; else if (!strcmp( un, *fp )) return 1; else if (!strcmp( "*", *fp )) { #if defined(USE_PAM) || defined(_AIX) if (!(pw = getpwnam( un ))) return 0; if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') continue; # ifdef HAVE_GETSPNAM /* (sic!) - not USESHADOW */ if ((spw = getspnam( un )) && (spw->sp_pwdp[0] == '!' || spw->sp_pwdp[0] == '*')) continue; # endif #endif if (pw->pw_uid) return 1; } #if defined(USE_PAM) || defined(_AIX) if (hg && (pw || (pw = getpwnam( un )))) { #else if (hg) { #endif for (setgrent(); (gr = getgrent()); ) for (fp = td->noPassUsers; *fp; fp++) if (**fp == '@' && !strcmp( gr->gr_name, *fp + 1 )) { if (pw->pw_gid == gr->gr_gid) { endgrent(); return 1; } for (; *gr->gr_mem; gr->gr_mem++) if (!strcmp( un, *gr->gr_mem )) { endgrent(); return 1; } } endgrent(); } return 0; } #if !defined(USE_PAM) && !defined(_AIX) && defined(HAVE_SETUSERCONTEXT) # define LC_RET0 do { login_close(lc); return 0; } while(0) #else # define LC_RET0 return 0 #endif int verify( GConvFunc gconv, int rootok ) { #ifdef USE_PAM const char *psrv; struct pam_data pdata; int pretc, pnopass; char psrvb[64]; #elif defined(_AIX) char *msg, *curret; int i, reenter; #else struct stat st; const char *nolg; char *buf; int fd; # ifdef HAVE_GETUSERSHELL char *s; # endif # if defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || defined(USESHADOW) int tim, expir, warntime, quietlog; # endif #endif debug( "verify ...\n" ); #ifdef USE_PAM pnopass = FALSE; if (!strcmp( curtype, "classic" )) { if (!gconv( GCONV_USER, 0 )) return 0; if (isNoPassAllowed( curuser )) { gconv( GCONV_PASS_ND, 0 ); if (!*curpass) { pnopass = TRUE; sprintf( psrvb, "%.31s-np", PAMService ); psrv = psrvb; } else psrv = PAMService; } else psrv = PAMService; pdata.usecur = TRUE; } else { sprintf( psrvb, "%.31s-%.31s", PAMService, curtype ); psrv = psrvb; pdata.usecur = FALSE; } pdata.gconv = gconv; if (!doPAMAuth( psrv, &pdata )) return 0; #elif defined(_AIX) if ((td->displayType & d_location) == dForeign) { char *tmpch; strncpy( hostname, td->name, sizeof(hostname) - 1 ); hostname[sizeof(hostname)-1] = '\0'; if ((tmpch = strchr( hostname, ':' ))) *tmpch = '\0'; } else hostname[0] = '\0'; /* tty names should only be 15 characters long */ # if 0 for (i = 0; i < 15 && td->name[i]; i++) { if (td->name[i] == ':' || td->name[i] == '.') tty[i] = '_'; else tty[i] = td->name[i]; } tty[i] = '\0'; # else memcpy( tty, "/dev/xdm/", 9 ); for (i = 0; i < 6 && td->name[i]; i++) { if (td->name[i] == ':' || td->name[i] == '.') tty[9 + i] = '_'; else tty[9 + i] = td->name[i]; } tty[9 + i] = '\0'; # endif if (!strcmp( curtype, "classic" )) { if (!gconv( GCONV_USER, 0 )) return 0; if (isNoPassAllowed( curuser )) { gconv( GCONV_PASS_ND, 0 ); if (!*curpass) { debug( "accepting despite empty password\n" ); goto done; } } else if (!gconv( GCONV_PASS, 0 )) return 0; enduserdb(); msg = NULL; if ((i = authenticate( curuser, curpass, &reenter, &msg ))) { debug( "authenticate() failed: %s\n", msg ); if (msg) free( msg ); loginfailed( curuser, hostname, tty ); if (i == ENOENT || i == ESAD) V_RET_AUTH; else V_RET_FAIL( 0 ); } if (reenter) { logError( "authenticate() requests more data: %s\n", msg ); free( msg ); V_RET_FAIL( 0 ); } } else if (!strcmp( curtype, "generic" )) { if (!gconv( GCONV_USER, 0 )) return 0; for (curret = 0;;) { msg = NULL; if ((i = authenticate( curuser, curret, &reenter, &msg ))) { debug( "authenticate() failed: %s\n", msg ); if (msg) free( msg ); loginfailed( curuser, hostname, tty ); if (i == ENOENT || i == ESAD) V_RET_AUTH; else V_RET_FAIL( 0 ); } if (curret) free( curret ); if (!reenter) break; if (!(curret = gconv( GCONV_HIDDEN, msg ))) return 0; free( msg ); } } else { logError( "Unsupported authentication type %\"s requested\n", curtype ); V_RET_FAIL( 0 ); } if (msg) { displayStr( V_MSG_INFO, msg ); free( msg ); } done: #else if (strcmp( curtype, "classic" )) { logError( "Unsupported authentication type %\"s requested\n", curtype ); V_RET_FAIL( 0 ); } if (!gconv( GCONV_USER, 0 )) return 0; if (!(p = getpwnam( curuser ))) { debug( "getpwnam() failed.\n" ); gconv( GCONV_PASS, 0 ); V_RET_AUTH; } if (p->pw_passwd[0] == '!' || p->pw_passwd[0] == '*') { debug( "account is locked\n" ); gconv( GCONV_PASS, 0 ); V_RET_AUTH; } # ifdef USESHADOW if ((sp = getspnam( curuser ))) { p->pw_passwd = sp->sp_pwdp; if (p->pw_passwd[0] == '!' || p->pw_passwd[0] == '*') { debug( "account is locked\n" ); gconv( GCONV_PASS, 0 ); V_RET_AUTH; } } else debug( "getspnam() failed: %m. Are you root?\n" ); # endif if (!*p->pw_passwd) { if (!td->allowNullPasswd) { debug( "denying user with empty password\n" ); gconv( GCONV_PASS, 0 ); V_RET_AUTH; } goto nplogin; } if (isNoPassAllowed( curuser, p )) { nplogin: gconv( GCONV_PASS_ND, 0 ); if (!*curpass) { debug( "accepting password-less login\n" ); goto done; } } else if (!gconv( GCONV_PASS, 0 )) return 0; # ifdef KERBEROS if (p->pw_uid) { int ret; char realm[REALM_SZ]; if (krb_get_lrealm( realm, 1 )) { logError( "Cannot get KerberosIV realm.\n" ); V_RET_FAIL( 0 ); } sprintf( krbtkfile, "%s.%.*s", TKT_ROOT, MAXPATHLEN - strlen( TKT_ROOT ) - 2, td->name ); krb_set_tkt_string( krbtkfile ); unlink( krbtkfile ); ret = krb_verify_user( curuser, "", realm, curpass, 1, "rcmd" ); if (ret == KSUCCESS) { chown( krbtkfile, p->pw_uid, p->pw_gid ); debug( "KerberosIV verify succeeded\n" ); goto done; } else if (ret != KDC_PR_UNKNOWN && ret != SKDC_CANT) { logError( "KerberosIV verification failure %\"s for %s\n", krb_get_err_text( ret ), curuser ); krbtkfile[0] = '\0'; V_RET_FAIL( 0 ); } debug( "KerberosIV verify failed: %s\n", krb_get_err_text( ret ) ); } krbtkfile[0] = '\0'; # endif /* KERBEROS */ # if defined(ultrix) || defined(__ultrix__) if (authenticate_user( p, curpass, NULL ) < 0) # elif defined(HAVE_PW_ENCRYPT) if (strcmp( pw_encrypt( curpass, p->pw_passwd ), p->pw_passwd )) # elif defined(HAVE_CRYPT) if (strcmp( crypt( curpass, p->pw_passwd ), p->pw_passwd )) # else if (strcmp( curpass, p->pw_passwd )) # endif { debug( "password verify failed\n" ); V_RET_AUTH; } done: #endif /* !defined(USE_PAM) && !defined(_AIX) */ debug( "restrict %s ...\n", curuser ); #if defined(USE_PAM) || defined(_AIX) if (!(p = getpwnam( curuser ))) { logError( "getpwnam(%s) failed.\n", curuser ); V_RET_FAIL( 0 ); } #endif if (!p->pw_uid) { if (!rootok && !td->allowRootLogin) V_RET_FAIL( "Root logins are not allowed" ); return 1; /* don't deny root to log in */ } #ifdef USE_PAM debug( " pam_acct_mgmt() ...\n" ); pretc = pam_acct_mgmt( pamh, 0 ); reInitErrorLog(); debug( " pam_acct_mgmt() returned: %s\n", pam_strerror( pamh, pretc ) ); if (pretc == PAM_NEW_AUTHTOK_REQD) { pdata.usecur = FALSE; pdata.gconv = conv_interact; /* pam will have output a message already, so no prepareErrorGreet() */ if (gconv != conv_interact || pnopass) { pam_end( pamh, PAM_SUCCESS ); pamh = 0; gSendInt( V_CHTOK_AUTH ); /* this cannot auth the wrong user, as only classic auths get here */ while (!doPAMAuth( PAMService, &pdata )) if (pdata.abort) return 0; gSendInt( V_PRE_OK ); } else gSendInt( V_CHTOK ); for (;;) { debug( " pam_chauthtok() ...\n" ); pretc = pam_chauthtok( pamh, PAM_CHANGE_EXPIRED_AUTHTOK ); reInitErrorLog(); debug( " pam_chauthtok() returned: %s\n", pam_strerror( pamh, pretc ) ); if (pdata.abort) { pam_end( pamh, PAM_SUCCESS ); pamh = 0; return 0; } if (pretc == PAM_SUCCESS) break; /* effectively there is only PAM_AUTHTOK_ERR */ gSendInt( V_FAIL ); } if (curpass) free( curpass ); curpass = newpass; newpass = 0; } else if (pretc != PAM_SUCCESS) { pam_end( pamh, pretc ); pamh = 0; V_RET_AUTH; } #elif defined(_AIX) /* USE_PAM */ msg = NULL; if (loginrestrictions( curuser, ((td->displayType & d_location) == dForeign) ? S_RLOGIN : S_LOGIN, tty, &msg ) == -1) { debug( "loginrestrictions() - %s\n", msg ? msg : "error" ); loginfailed( curuser, hostname, tty ); prepareErrorGreet(); if (msg) { displayStr( V_MSG_ERR, msg ); free( msg ); } gSendInt( V_AUTH ); return 0; } if (msg) free( (void *)msg ); #endif /* USE_PAM || _AIX */ #ifndef _AIX # ifdef HAVE_SETUSERCONTEXT # ifdef HAVE_LOGIN_GETCLASS lc = login_getclass( p->pw_class ); # else lc = login_getpwclass( p ); # endif if (!lc) V_RET_FAIL( 0 ); p->pw_shell = login_getcapstr( lc, "shell", p->pw_shell, p->pw_shell ); # endif # ifndef USE_PAM /* restrict_expired */ # if defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || defined(USESHADOW) # if !defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || (!defined(HAVE_SETUSERCONTEXT) && defined(USESHADOW)) if (sp) # endif { # define DEFAULT_WARN (2L * 7L) /* Two weeks */ tim = time( NULL ) / 86400L; # ifdef HAVE_SETUSERCONTEXT quietlog = login_getcapbool( lc, "hushlogin", 0 ); warntime = login_getcaptime( lc, "warnexpire", DEFAULT_WARN * 86400L, DEFAULT_WARN * 86400L ) / 86400L; # else quietlog = 0; # ifdef USESHADOW warntime = sp->sp_warn != -1 ? sp->sp_warn : DEFAULT_WARN; # else warntime = DEFAULT_WARN; # endif # endif # ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE if (p->pw_expire) { expir = p->pw_expire / 86400L; # else if (sp->sp_expire != -1) { expir = sp->sp_expire; # endif if (tim > expir) { displayStr( V_MSG_ERR, "Your account has expired;" " please contact your system administrator" ); gSendInt( V_FAIL ); LC_RET0; } else if (tim > (expir - warntime) && !quietlog) { displayMsg( V_MSG_INFO, "Warning: your account will expire in %d day(s)", expir - tim ); } } # ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE if (p->pw_change) { expir = p->pw_change / 86400L; # else if (!sp->sp_lstchg) { displayStr( V_MSG_ERR, "You are required to change your password immediately" " (root enforced)" ); /* XXX todo password change */ gSendInt( V_FAIL ); LC_RET0; } else if (sp->sp_max != -1) { expir = sp->sp_lstchg + sp->sp_max; if (sp->sp_inact != -1 && tim > expir + sp->sp_inact) { displayStr( V_MSG_ERR, "Your account has expired;" " please contact your system administrator" ); gSendInt( V_FAIL ); LC_RET0; } # endif if (tim > expir) { displayStr( V_MSG_ERR, "You are required to change your password immediately" " (password aged)" ); /* XXX todo password change */ gSendInt( V_FAIL ); LC_RET0; } else if (tim > (expir - warntime) && !quietlog) { displayMsg( V_MSG_INFO, "Warning: your password will expire in %d day(s)", expir - tim ); } } } # endif /* HAVE_STRUCT_PASSWD_PW_EXPIRE || USESHADOW */ /* restrict_nologin */ # ifndef _PATH_NOLOGIN # define _PATH_NOLOGIN "/etc/nologin" # endif if (( # ifdef HAVE_SETUSERCONTEXT /* Do we ignore a nologin file? */ !login_getcapbool( lc, "ignorenologin", 0 )) && (!stat( (nolg = login_getcapstr( lc, "nologin", "", NULL )), &st ) || # endif !stat( (nolg = _PATH_NOLOGIN), &st ))) { if (st.st_size && (fd = open( nolg, O_RDONLY )) >= 0) { if ((buf = Malloc( st.st_size + 1 ))) { if (read( fd, buf, st.st_size ) == st.st_size) { close( fd ); buf[st.st_size] = 0; displayStr( V_MSG_ERR, buf ); free( buf ); gSendInt( V_FAIL ); LC_RET0; } free( buf ); } close( fd ); } displayStr( V_MSG_ERR, "Logins are not allowed at the moment.\nTry again later" ); gSendInt( V_FAIL ); LC_RET0; } /* restrict_time */ # if defined(HAVE_SETUSERCONTEXT) && defined(HAVE_AUTH_TIMEOK) if (!auth_timeok( lc, time( NULL ) )) { displayStr( V_MSG_ERR, "You are not allowed to login at the moment" ); gSendInt( V_FAIL ); LC_RET0; } # endif # ifdef HAVE_GETUSERSHELL for (;;) { if (!(s = getusershell())) { debug( "shell not in /etc/shells\n" ); endusershell(); V_RET_FAIL( "Your login shell is not listed in /etc/shells" ); } if (!strcmp( s, p->pw_shell )) { endusershell(); break; } } # endif # endif /* !USE_PAM */ /* restrict_nohome */ # ifdef HAVE_SETUSERCONTEXT if (login_getcapbool( lc, "requirehome", 0 )) { struct stat st; if (!*p->pw_dir || stat( p->pw_dir, &st ) || st.st_uid != p->pw_uid) { displayStr( V_MSG_ERR, "Home folder not available" ); gSendInt( V_FAIL ); LC_RET0; } } # endif #endif /* !_AIX */ return 1; } static const char *envvars[] = { "TZ", /* SYSV and SVR4, but never hurts */ #ifdef _AIX "AUTHSTATE", /* for kerberos */ #endif NULL }; #if defined(USE_PAM) && defined(HAVE_INITGROUPS) static int num_saved_gids; static gid_t *saved_gids; static int saveGids( void ) { num_saved_gids = getgroups( 0, 0 ); if (!(saved_gids = Malloc( sizeof(gid_t) * num_saved_gids ))) return 0; if (getgroups( num_saved_gids, saved_gids ) < 0) { logError( "saving groups failed: %m\n" ); return 0; } return 1; } static int restoreGids( void ) { if (setgroups( num_saved_gids, saved_gids ) < 0) { logError( "restoring groups failed: %m\n" ); return 0; } if (setgid( p->pw_gid ) < 0) { logError( "restoring gid failed: %m\n" ); return 0; } return 1; } #endif /* USE_PAM && HAVE_INITGROUPS */ static int resetGids( void ) { #ifdef HAVE_INITGROUPS if (setgroups( 0, &p->pw_gid /* anything */ ) < 0) { logError( "restoring groups failed: %m\n" ); return 0; } #endif if (setgid( 0 ) < 0) { logError( "restoring gid failed: %m\n" ); return 0; } return 1; } static int setGid( const char *name, int gid ) { if (setgid( gid ) < 0) { logError( "setgid(%d) (user %s) failed: %m\n", gid, name ); return 0; } #ifdef HAVE_INITGROUPS if (initgroups( name, gid ) < 0) { logError( "initgroups for %s failed: %m\n", name ); setgid( 0 ); return 0; } #endif /* QNX4 doesn't support multi-groups, no initgroups() */ return 1; } static int setUid( const char *name, int uid ) { if (setuid( uid ) < 0) { logError( "setuid(%d) (user %s) failed: %m\n", uid, name ); return 0; } return 1; } static int setUser( const char *name, int uid, int gid ) { if (setGid( name, gid )) { if (setUid( name, uid )) return 1; resetGids(); } return 0; } #if defined(SECURE_RPC) || defined(K5AUTH) static void nukeAuth( int len, const char *name ) { int i; for (i = 0; i < td->authNum; i++) if (td->authorizations[i]->name_length == len && !memcmp( td->authorizations[i]->name, name, len )) { memcpy( &td->authorizations[i], &td->authorizations[i+1], sizeof(td->authorizations[i]) * (--td->authNum - i) ); break; } } #endif static void mergeSessionArgs( int cansave ) { char *mfname; const char *fname; int i, needsave; mfname = 0; fname = ".dmrc"; if ((!curdmrc || newdmrc) && *dmrcDir) if (strApp( &mfname, dmrcDir, "/", curuser, fname, (char *)0 )) fname = mfname; needsave = 0; if (!curdmrc) { curdmrc = iniLoad( fname ); if (!curdmrc) { strDup( &curdmrc, "[Desktop]\nSession=default\n" ); needsave = 1; } } if (newdmrc) { curdmrc = iniMerge( curdmrc, newdmrc ); needsave = 1; } if (needsave && cansave) if (!iniSave( curdmrc, fname ) && errno == ENOENT && mfname) { for (i = 0; mfname[i]; i++) if (mfname[i] == '/') { mfname[i] = 0; mkdir( mfname, 0755 ); mfname[i] = '/'; } iniSave( curdmrc, mfname ); } if (mfname) free( mfname ); } static int createClientLog( const char *log ) { char randstr[32], *randstrp = 0, *lname; int lfd; for (;;) { struct expando macros[] = { { 'd', 0, td->name }, { 'u', 0, curuser }, { 'r', 0, randstrp }, { 0, 0, 0 } }; if (!(lname = expandMacros( log, macros ))) exit( 1 ); unlink( lname ); if ((lfd = open( lname, O_WRONLY|O_CREAT|O_EXCL, 0600 )) >= 0) { dup2( lfd, 1 ); dup2( lfd, 2 ); close( lfd ); free( lname ); return TRUE; } if (errno != EEXIST || !macros[2].uses) { free( lname ); return FALSE; } logInfo( "Session log file %s not usable, trying another one.\n", lname ); free( lname ); sprintf( randstr, "%d", secureRandom() ); randstrp = randstr; } }
int vsf_sysdep_check_auth(struct mystr* p_user_str, const struct mystr* p_pass_str, const struct mystr* p_remote_host) { /* Padavan */ (void) p_remote_host; return asus_check_auth(p_user_str, p_pass_str); #if 0 const char* p_crypted; const struct passwd* p_pwd = getpwnam(str_getbuf(p_user_str)); (void) p_remote_host; if (p_pwd == NULL) { return 0; } #ifdef VSF_SYSDEP_HAVE_USERSHELL if (tunable_check_shell) { const char* p_shell; while ((p_shell = getusershell()) != NULL) { if (!vsf_sysutil_strcmp(p_shell, p_pwd->pw_shell)) { break; } } endusershell(); if (p_shell == NULL) { return 0; } } #endif #ifdef VSF_SYSDEP_HAVE_SHADOW { const struct spwd* p_spwd = getspnam(str_getbuf(p_user_str)); if (p_spwd != NULL) { long curr_time = vsf_sysutil_get_time_sec(); int days; days = curr_time / (60 * 60 * 24); if (p_spwd->sp_expire > 0 && p_spwd->sp_expire < days) { return 0; } if (p_spwd->sp_lstchg > 0 && p_spwd->sp_max > 0 && p_spwd->sp_lstchg + p_spwd->sp_max < days) { return 0; } p_crypted = crypt(str_getbuf(p_pass_str), p_spwd->sp_pwdp); if (!vsf_sysutil_strcmp(p_crypted, p_spwd->sp_pwdp)) { return 1; } } } #endif /* VSF_SYSDEP_HAVE_SHADOW */ p_crypted = crypt(str_getbuf(p_pass_str), p_pwd->pw_passwd); if (!vsf_sysutil_strcmp(p_crypted, p_pwd->pw_passwd)) { return 1; } return 0; #endif }
void pw_unix_check(AuthResult * const result, const char *account, const char *password, const struct sockaddr_storage * const sa, const struct sockaddr_storage * const peer) { const char *cpwd = NULL; struct passwd pw, *pw_; #ifdef USE_SHADOW struct spwd *spw; #endif char *dir = NULL; (void) sa; (void) peer; result->auth_ok = 0; if ((pw_ = getpwnam(account)) == NULL) { return; } pw = *pw_; result->auth_ok--; #ifdef HAVE_SETUSERSHELL if (pw.pw_shell == NULL) { return; } if (strcasecmp(pw.pw_shell, FAKE_SHELL) != 0) { const char *shell; setusershell(); while ((shell = (char *) getusershell()) != NULL && strcmp(pw.pw_shell, shell) != 0); endusershell(); if (shell == NULL) { return; } } #endif if ((dir = strdup(pw.pw_dir)) == NULL) { return; } #ifdef USE_SHADOW if ((((pw.pw_passwd)[0] == 'x' && (pw.pw_passwd)[1] == 0) || ((pw.pw_passwd)[0] == '#' && (pw.pw_passwd)[1] == '#' && strcmp(pw.pw_passwd + 2, account) == 0)) && (spw = getspnam(account)) != NULL && spw->sp_pwdp != NULL) { cpwd = spw->sp_pwdp[0] == '@' ? NULL : spw->sp_pwdp; if (spw->sp_expire > 0 || spw->sp_max > 0) { long today = time(NULL) / (24L * 60L * 60L); if (spw->sp_expire > 0 && spw->sp_expire < today) { goto bye; /* account expired */ } if (spw->sp_max > 0 && spw->sp_lstchg > 0 && (spw->sp_lstchg + spw->sp_max < today)) { goto bye; /* password expired */ } } } else #endif { cpwd = pw.pw_passwd; } { const char *crypted; if (cpwd == NULL || (crypted = (const char *) crypt(password, cpwd)) == NULL || strcmp(cpwd, crypted) != 0) { goto bye; } } result->uid = pw.pw_uid; result->gid = pw.pw_gid; result->dir = dir; result->slow_tilde_expansion = 0; result->auth_ok = -result->auth_ok; return; bye: free(dir); }
int run_tests(const char *snapshot_file, enum test_methods method) { struct usershell_test_data td, td_snap; struct usershell ushell; int rv; rv = 0; TEST_DATA_INIT(usershell, &td, clone_usershell, free_usershell); TEST_DATA_INIT(usershell, &td_snap, clone_usershell, free_usershell); setusershell(); while ((ushell.path = getusershell()) != NULL) { printf("usershell found:\n"); dump_usershell(&ushell); TEST_DATA_APPEND(usershell, &td, &ushell); } endusershell(); if (snapshot_file != NULL) { if (access(snapshot_file, W_OK | R_OK) != 0) { if (errno == ENOENT) method = TEST_BUILD_SNAPSHOT; else { printf("can't access the snapshot file %s\n", snapshot_file); rv = -1; goto fin; } } else { rv = TEST_SNAPSHOT_FILE_READ(usershell, snapshot_file, &td_snap, usershell_read_snapshot_func); if (rv != 0) { printf("error reading snapshot file\n"); goto fin; } } } switch (method) { case TEST_GETUSERSHELL: rv = DO_2PASS_TEST(usershell, &td, &td_snap, compare_usershell, NULL); break; case TEST_BUILD_SNAPSHOT: if (snapshot_file != NULL) { rv = TEST_SNAPSHOT_FILE_WRITE(usershell, snapshot_file, &td, sdump_usershell); } break; default: rv = 0; break; } fin: TEST_DATA_DESTROY(usershell, &td_snap); TEST_DATA_DESTROY(usershell, &td); return (rv); }
int main(void) { struct passwd *pwd; #ifdef USE_SHADOW struct spwd *spw; #endif const char *pw; struct stat st; #ifdef HAVE_SETLOCALE # ifdef LC_MESSAGES (void) setlocale(LC_MESSAGES, ""); # endif # ifdef LC_CTYPE (void) setlocale(LC_CTYPE, ""); # endif # ifdef LC_COLLATE (void) setlocale(LC_COLLATE, ""); # endif #endif setpwent(); while ((pwd = getpwent()) != NULL) { if (pwd->pw_name == NULL) { continue; } if (pwd->pw_uid <= (uid_t) 0 || pwd->pw_gid <= (gid_t) 0) { continue; } if (stat(pwd->pw_dir, &st) != 0 || !S_ISDIR(st.st_mode)) { continue; } #ifdef HAVE_SETUSERSHELL if (strcasecmp(pwd->pw_shell, FAKE_SHELL) != 0) { const char *shell; setusershell(); while ((shell = (char *) getusershell()) != NULL && strcmp(pwd->pw_shell, shell) != 0); endusershell(); if (shell == NULL) { continue; } } #endif pw = pwd->pw_passwd; #ifdef USE_SHADOW if (pwd->pw_passwd != NULL && pwd->pw_name != NULL && (((pwd->pw_passwd)[0] == 'x' && (pwd->pw_passwd)[1] == 0) || (strcmp(pwd->pw_passwd, "********") == 0) || ((pwd->pw_passwd)[0] == '#' && (pwd->pw_passwd)[1] == '#' && strcmp(pwd->pw_passwd + 2, pwd->pw_name) == 0)) && (spw = getspnam(pwd->pw_name)) != NULL && spw->sp_pwdp != NULL) { pw = spw->sp_pwdp[0] == '@' ? "*" : spw->sp_pwdp; } #endif if (pw == NULL || *pw == 0) { pw = "*"; } { char *coma; if (pwd->pw_gecos != NULL && (coma = strchr(pwd->pw_gecos, ',')) != NULL) { *coma = 0; } } printf("%s:%s:%lu:%lu:%s:%s/./\n", pwd->pw_name, pw, (unsigned long) pwd->pw_uid, (unsigned long) pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir); } endpwent(); return 0; }
_X_INTERNAL int Verify (struct display *d, struct greet_info *greet, struct verify_info *verify) { struct passwd *p; login_cap_t *lc; auth_session_t *as; char *style, *shell, *home, *s, **argv; char path[MAXPATHLEN]; int authok; size_t passwd_len; /* User may have specified an authentication style. */ if ((style = strchr(greet->name, ':')) != NULL) *style++ = '\0'; Debug ("Verify %s, style %s ...\n", greet->name, style ? style : "default"); p = getpwnam (greet->name); if (!p || strlen (greet->name) == 0) { Debug("getpwnam() failed.\n"); explicit_bzero(greet->password, strlen(greet->password)); return 0; } if ((lc = login_getclass(p->pw_class)) == NULL) { Debug("login_getclass() failed.\n"); explicit_bzero(greet->password, strlen(greet->password)); return 0; } if ((style = login_getstyle(lc, style, "xdm")) == NULL) { Debug("login_getstyle() failed.\n"); explicit_bzero(greet->password, strlen(greet->password)); return 0; } if ((as = auth_open()) == NULL) { Debug("auth_open() failed.\n"); login_close(lc); explicit_bzero(greet->password, strlen(greet->password)); return 0; } if (auth_setoption(as, "login", "yes") == -1) { Debug("auth_setoption() failed.\n"); login_close(lc); explicit_bzero(greet->password, strlen(greet->password)); return 0; } passwd_len = strlen(greet->password); /* Set up state for no challenge, just check a response. */ auth_setstate(as, 0); auth_setdata(as, "", 1); auth_setdata(as, greet->password, passwd_len + 1); /* wipe password now, otherwise it'll be copied fork() in auth_call */ explicit_bzero(greet->password, passwd_len); /* Build path of the auth script and call it */ snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style); auth_call(as, path, style, "-s", "response", greet->name, lc->lc_class, (void *)NULL); authok = auth_getstate(as); if ((authok & AUTH_ALLOW) == 0) { Debug("password verify failed\n"); auth_close(as); login_close(lc); return 0; } /* Run the approval script */ if (!auth_approval(as, lc, greet->name, "auth-xdm")) { Debug("login not approved\n"); auth_close(as); login_close(lc); return 0; } auth_close(as); login_close(lc); /* Check empty passwords against allowNullPasswd */ if (!greet->allow_null_passwd && passwd_len == 0) { Debug("empty password not allowed\n"); return 0; } /* Only accept root logins if allowRootLogin resource is set */ if (p->pw_uid == 0 && !greet->allow_root_login) { Debug("root logins not allowed\n"); return 0; } /* * Shell must be in /etc/shells */ for (;;) { s = getusershell(); if (s == NULL) { /* did not found the shell in /etc/shells -> failure */ Debug("shell not in /etc/shells\n"); endusershell(); return 0; } if (strcmp(s, p->pw_shell) == 0) { /* found the shell in /etc/shells */ endusershell(); break; } } Debug ("verify succeeded\n"); verify->uid = p->pw_uid; verify->gid = p->pw_gid; home = p->pw_dir; shell = p->pw_shell; argv = NULL; if (d->session) argv = parseArgs (argv, d->session); if (greet->string) argv = parseArgs (argv, greet->string); if (!argv) argv = parseArgs (argv, "xsession"); verify->argv = argv; verify->userEnviron = userEnv (d, p->pw_uid == 0, greet->name, home, shell); Debug ("user environment:\n"); printEnv (verify->userEnviron); verify->systemEnviron = systemEnv (d, greet->name, home); Debug ("system environment:\n"); printEnv (verify->systemEnviron); Debug ("end of environments\n"); return 1; }
int main (int argc, char *argv[], char *environ[]) { int n = 1; int valid = -1; char iobuf[BUFSIZ]; char sysconfdir[BUFSIZ]; char c_str[BUFSIZ]; char c_command[BUFSIZ]; char *p = NULL; char *rand = rand2str (16); time_t now = time ((time_t *) NULL); struct stat s; struct sigaction saterm; struct sigaction sawinch; struct sigaction sachild; struct timeval tv; double oldtime, newtime; struct stat ttybuf; int c; char argtest[BUFSIZ]; user.vshell = NULL; user.shell.ptr = NULL; user.home.ptr = NULL; user.term.ptr = NULL; progname = argv[0]; if ((p = (char *) strrchr (progname, '/')) != NULL) progname = p + 1; if (*progname == '-') loginshell = 1; /* Who are you? */ user.pw = getpwuid ((uid_t) getuid ()); if (user.pw == NULL) { fprintf (stderr, "I do not know who you are. Stopping.\n"); perror ("getpwuid"); exit (EXIT_FAILURE); } strncpy (user.to, user.pw->pw_name, BUFSIZ - 1); user.term.ptr = getenv ("TERM"); if (user.term.ptr == NULL) user.term.ptr = "dumb"; if (strlen (user.term.ptr) < 1) user.term.ptr = "dumb"; snprintf (sysconfdir, BUFSIZ - 1, "%s/sudosh.conf", SYSCONFDIR); parse (&sudosh_option, sysconfdir); while ((c = getopt (argc, argv, "c:hivV")) != EOF) { switch (c) { case 'c': // fprintf(stderr,"optarg is [%s]\n",optarg); strncpy (user.from, user.pw->pw_name, BUFSIZ - 1); strncpy (c_str, optarg, BUFSIZ - 1); strncpy (c_command, optarg, BUFSIZ - 1); p = strchr (c_str, ' '); if (p) { p[0] = 0; // fprintf(stderr,"args=%s\n",c_args); } if (c_str[0] != 0) { // Test for methods of escape if (strchr (c_command, ';') != NULL || strchr (c_command, '&') != NULL || strchr (c_command, '|') != NULL || strchr (c_command, '<') != NULL || strchr (c_command, '>') != NULL || strchr (c_command, '`') != NULL) { fprintf (stderr, "\"%s\" isn't allowed to be executed with process or redirect controls.\n", c_command); exit (EXIT_FAILURE); } // fprintf(stderr,"Testing c\n"); // Make sure that c_str is in argallow sprintf (argtest, "$%.100s$", c_str); // fprintf(stderr,"Testing for %s\n",argtest); if (strstr (sudosh_option.argallow, argtest) != NULL || strchr(sudosh_option.argallow, '*')!=NULL) { FILE *f; snprintf (script.name, (size_t) BUFSIZ - 1, "%s/%s%c%s%cinteractive%c%i%c%s", sudosh_option.logdir, user.from, sudosh_option.fdl, user.to, sudosh_option.fdl, sudosh_option.fdl, (int) now, sudosh_option.fdl, rand); f = fopen (script.name, "w"); if (f == (FILE *) 0) { fprintf (stderr, "%.100s: %.100s (%i)\n", script.name, strerror (errno), errno); exit (EXIT_FAILURE); } fprintf (f, "%.256s\n", c_str); fclose (f); execl ("/bin/sh", "sh", "-c", c_command, (char *) 0); exit (EXIT_SUCCESS); break; } else { fprintf (stderr, "\"%s\" isn't allowed to be executed.\n", c_str); exit (EXIT_FAILURE); break; } } break; case 'h': case '?': fprintf (stdout, "Usage: sudosh\n" "sudo shell that supports input and output logging to syslog\n" "\n" "-h, --help display this help and exit\n" "-i, --init initialize logdir (mkdir and chmod) (ignored for compatibility)\n" "-v, --version output version information and exit\n" "\n" "Report bugs to <%s>\n", PACKAGE_BUGREPORT); exit (EXIT_SUCCESS); break; case 'i': fprintf (stdout, "Ignoring initialize option, this is done automatically\n"); exit (EXIT_SUCCESS); break; case 'v': case 'V': fprintf (stdout, "%s version %s\n", PACKAGE_NAME, VERSION); exit (EXIT_SUCCESS); break; default: fputs ("Try `sudosh -h' for more information.\n", stderr); exit (EXIT_FAILURE); break; } } if (ttyname (0) != NULL) { if (stat (ttyname (0), &ttybuf) == 0) { if ((getpwuid (ttybuf.st_uid)->pw_name) == NULL) { fprintf (stderr, "I have no idea who you are.\n"); exit (EXIT_FAILURE); } strncpy (user.from, getpwuid (ttybuf.st_uid)->pw_name, BUFSIZ - 1); } else { fprintf (stderr, "Couldn't stat %s\n", ttyname (0)); exit (EXIT_FAILURE); } } else { fprintf (stderr, "%s: couldn't get your controlling terminal.\n", progname); exit (EXIT_FAILURE); } user.pw = getpwuid ((uid_t) getuid ()); snprintf (user.home.str, BUFSIZ - 1, "HOME=%s", user.pw->pw_dir); strncpy (user.to_home.str, user.pw->pw_dir, BUFSIZ - 1); snprintf (user.term.str, BUFSIZ - 1, "TERM=%s", user.term.ptr); #ifdef HAVE_GETUSERSHELL if ((user.shell.ptr = getenv ("SHELL")) == NULL) user.shell.ptr = user.pw->pw_shell; /* check against /etc/shells to make sure it's a real shell */ setusershell (); while ((user.vshell = (char *) getusershell ()) != (char *) 0) { if (strcmp (user.shell.ptr, user.vshell) == 0) valid = 1; } endusershell (); if (valid != 1) { if (user.shell.ptr == NULL) { fprintf (stderr, "Could not determine a valid shell.\n"); if (sudosh_option.priority != -1) mysyslog (sudosh_option.priority, "Could not determine a valid shell"); exit (EXIT_FAILURE); } else { fprintf (stderr, "%s is not in /etc/shells\n", user.shell.ptr); mysyslog (sudosh_option.priority, "%s,%s: %s is not in /etc/shells", user.from, ttyname (0), user.shell.ptr); exit (EXIT_FAILURE); } } if (stat ((const char *) user.shell.ptr, &s) == -1) { fprintf (stderr, "Shell %s doesn't exist.\n", user.shell.ptr); if (sudosh_option.priority != -1) mysyslog (sudosh_option.priority, "%s,%s: shell %s doesn't exist.", user.from, ttyname (0), user.shell.ptr); exit (EXIT_FAILURE); } #else user.shell.ptr = user.pw->pw_shell; #endif /* HAVE_GETUSERSHELL */ if (loginshell) user.shell.ptr = sudosh_option.defshell; snprintf (script.name, (size_t) BUFSIZ - 1, "%s/%s%c%s%cscript%c%i%c%s", sudosh_option.logdir, user.from, sudosh_option.fdl, user.to, sudosh_option.fdl, sudosh_option.fdl, (int) now, sudosh_option.fdl, rand); snprintf (timing.name, (size_t) BUFSIZ - 1, "%s/%s%c%s%ctime%c%i%c%s", sudosh_option.logdir, user.from, sudosh_option.fdl, user.to, sudosh_option.fdl, sudosh_option.fdl, (int) now, sudosh_option.fdl, rand); #ifdef RECORDINPUT snprintf (input.name, (size_t) BUFSIZ - 1, "%s/%s%c%s%cinput%c%i%c%s", sudosh_option.logdir, user.from, sudosh_option.fdl, user.to, sudosh_option.fdl, sudosh_option.fdl, (int) now, sudosh_option.fdl, rand); #endif snprintf (start_msg, BUFSIZ - 1, "starting session for %s as %s, tty %s, shell %s", user.from, user.to, ttyname (0), user.shell.ptr); set_perms_and_open_file(&script); set_perms_and_open_file(&timing); #ifdef RECORDINPUT set_perms_and_open_file(&input); #endif if (sudosh_option.priority != -1) mysyslog (sudosh_option.priority, start_msg); rawmode (0); if (findms (&pspair) < 0) { perror ("open pty failed"); bye (EXIT_FAILURE); } switch (fork ()) { case 0: close (pspair.mfd); prepchild (&pspair); case -1: perror ("fork failed"); bye (EXIT_FAILURE); default: close (pspair.sfd); } orig_euid = geteuid(); if (seteuid (getuid ()) != 0) { perror ("setuid failed"); bye (EXIT_FAILURE); } memset (&sawinch, 0, sizeof sawinch); sawinch.sa_handler = newwinsize; sawinch.sa_flags = SA_RESTART; sigaction (SIGWINCH, &sawinch, (struct sigaction *) 0); memset (&saterm, 0, sizeof saterm); saterm.sa_handler = bye; sigaction (SIGTERM, &sawinch, (struct sigaction *) 0); memset (&sachild, 0, sizeof sachild); sachild.sa_handler = bye; sigaction (SIGCHLD, &sachild, (struct sigaction *) 0); oldtime = time (NULL); while (n > 0) { fd_set readfds; FD_ZERO (&readfds); FD_SET (pspair.mfd, &readfds); FD_SET (0, &readfds); gettimeofday ((struct timeval *) &tv, NULL); if (select (pspair.mfd + 1, &readfds, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0) < 0) { if (errno == EINTR) continue; perror ("select"); bye (EXIT_FAILURE); } if (FD_ISSET (pspair.mfd, &readfds)) { if ((n = read (pspair.mfd, iobuf, sizeof (iobuf))) > 0) { DO_WRITE (1, iobuf, n); script.bytes += DO_WRITE (script.fd, iobuf, n); } newtime = tv.tv_sec + (double) tv.tv_usec / 1000000; snprintf (timing.str, BUFSIZ - 1, "%f %i\n", newtime - oldtime, n); timing.bytes += DO_WRITE (timing.fd, &timing.str, strlen (timing.str)); oldtime = newtime; } if (FD_ISSET (0, &readfds)) { if ((n = read (0, iobuf, BUFSIZ)) > 0) { DO_WRITE (pspair.mfd, iobuf, n); #ifdef RECORDINPUT switch (*iobuf) { case '\r': snprintf (input.str, BUFSIZ - 1, "\n"); break; case 0x003: snprintf (input.str, BUFSIZ - 1, "(CTRL-C)"); break; case 0x004: snprintf (input.str, BUFSIZ - 1, "(CTRL-D)\n"); break; case 0x1a: snprintf (input.str, BUFSIZ - 1, "(CTRL-Z)\n"); break; case 0x1b: snprintf (input.str, BUFSIZ - 1, "(ESC)"); break; default: DO_WRITE (input.fd, iobuf, 1); written = 1; break; } if (written == 0) { DO_WRITE (input.fd, &input.str, strlen (input.str)); } #endif } } } bye (EXIT_SUCCESS); return (0); }
int Verify (struct display *d, struct greet_info *greet, struct verify_info *verify) { struct passwd *p; login_cap_t *lc; auth_session_t *as; char *style, *shell, *home, *s, **argv; char path[MAXPATHLEN]; int authok; /* User may have specified an authentication style. */ if ((style = strchr(greet->name, ':')) != NULL) *style++ = '\0'; Debug ("Verify %s, style %s ...\n", greet->name, style ? style : "default"); p = getpwnam (greet->name); endpwent(); if (!p || strlen (greet->name) == 0) { Debug("getpwnam() failed.\n"); bzero(greet->password, strlen(greet->password)); return 0; } if ((lc = login_getclass(p->pw_class)) == NULL) { Debug("login_getclass() failed.\n"); bzero(greet->password, strlen(greet->password)); return 0; } if ((style = login_getstyle(lc, style, "xdm")) == NULL) { Debug("login_getstyle() failed.\n"); bzero(greet->password, strlen(greet->password)); return 0; } if ((as = auth_open()) == NULL) { Debug("auth_open() failed.\n"); login_close(lc); bzero(greet->password, strlen(greet->password)); return 0; } if (auth_setoption(as, "login", "yes") == -1) { Debug("auth_setoption() failed.\n"); login_close(lc); bzero(greet->password, strlen(greet->password)); return 0; } /* Set up state for no challenge, just check a response. */ auth_setstate(as, 0); auth_setdata(as, "", 1); auth_setdata(as, greet->password, strlen(greet->password) + 1); /* Build path of the auth script and call it */ snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style); auth_call(as, path, style, "-s", "response", greet->name, lc->lc_class, (void *)NULL); authok = auth_getstate(as); if ((authok & AUTH_ALLOW) == 0) { Debug("password verify failed\n"); bzero(greet->password, strlen(greet->password)); auth_close(as); login_close(lc); return 0; } /* Run the approval script */ if (!auth_approval(as, lc, greet->name, "auth-xdm")) { Debug("login not approved\n"); bzero(greet->password, strlen(greet->password)); auth_close(as); login_close(lc); return 0; } auth_close(as); login_close(lc); /* Check empty passwords against allowNullPasswd */ if (!greet->allow_null_passwd && strlen(greet->password) == 0) { Debug("empty password not allowed\n"); return 0; } /* Only accept root logins if allowRootLogin resource is set */ if (p->pw_uid == 0 && !greet->allow_root_login) { Debug("root logins not allowed\n"); bzero(greet->password, strlen(greet->password)); return 0; } /* * Shell must be in /etc/shells */ for (;;) { s = getusershell(); if (s == NULL) { /* did not found the shell in /etc/shells -> failure */ Debug("shell not in /etc/shells\n"); bzero(greet->password, strlen(greet->password)); endusershell(); return 0; } if (strcmp(s, p->pw_shell) == 0) { /* found the shell in /etc/shells */ endusershell(); break; } } #else /* !USE_BSDAUTH */ int Verify (struct display *d, struct greet_info *greet, struct verify_info *verify) { struct passwd *p; #ifdef USE_PAM pam_handle_t **pamhp = thepamhp(); #else #ifdef USESHADOW struct spwd *sp; #endif char *user_pass = NULL; #endif #ifdef __OpenBSD__ char *s; struct timeval tp; #endif char *shell, *home; char **argv; Debug ("Verify %s ...\n", greet->name); #if defined(sun) && defined(SVR4) /* Solaris: If CONSOLE is set to /dev/console in /etc/default/login, then root can only login on system console */ # define SOLARIS_LOGIN_DEFAULTS "/etc/default/login" if (strcmp(greet->name, "root") == 0) { char *console = NULL, *tmp = NULL; FILE *fs; if ((fs= fopen(SOLARIS_LOGIN_DEFAULTS, "r")) != NULL) { char str[120]; while (!feof(fs)) { fgets(str, 120, fs); if(str[0] == '#' || strlen(str) < 8) continue; if((tmp = strstr(str, "CONSOLE=")) != NULL) console = strdup((tmp+8)); } fclose(fs); if ( console != NULL && (strncmp(console, "/dev/console", 12) == 0) && (strncmp(d->name,":0",2) != 0) ) { Debug("Not on system console\n"); bzero(greet->password, strlen(greet->password)); XFree(console); return 0; } XFree(console); } else { Debug("Could not open %s\n", SOLARIS_LOGIN_DEFAULTS); } } #endif #ifndef USE_PAM p = getpwnam (greet->name); endpwent(); if (!p || strlen (greet->name) == 0) { Debug ("getpwnam() failed.\n"); bzero(greet->password, strlen(greet->password)); return 0; } else { #ifdef linux if (!strcmp(p->pw_passwd, "!") || !strcmp(p->pw_passwd, "*")) { Debug ("The account is locked, no login allowed.\n"); bzero(greet->password, strlen(greet->password)); return 0; } #endif user_pass = p->pw_passwd; } #endif #ifdef KERBEROS if(strcmp(greet->name, "root") != 0){ char name[ANAME_SZ]; char realm[REALM_SZ]; char *q; int ret; if(krb_get_lrealm(realm, 1)){ Debug ("Can't get Kerberos realm.\n"); } else { sprintf(krbtkfile, "%s.%s", TKT_ROOT, d->name); krb_set_tkt_string(krbtkfile); unlink(krbtkfile); ret = krb_verify_user(greet->name, "", realm, greet->password, 1, "rcmd"); if(ret == KSUCCESS){ chown(krbtkfile, p->pw_uid, p->pw_gid); Debug("kerberos verify succeeded\n"); if (k_hasafs()) { if (k_setpag() == -1) LogError ("setpag() failed for %s\n", greet->name); if((ret = k_afsklog(NULL, NULL)) != KSUCCESS) LogError("Warning %s\n", krb_get_err_text(ret)); } goto done; } else if(ret != KDC_PR_UNKNOWN && ret != SKDC_CANT){ /* failure */ Debug("kerberos verify failure %d\n", ret); krbtkfile[0] = '\0'; } } } #endif #ifndef USE_PAM #ifdef USESHADOW errno = 0; sp = getspnam(greet->name); if (sp == NULL) { Debug ("getspnam() failed, errno=%d. Are you root?\n", errno); } else { user_pass = sp->sp_pwdp; } #ifndef QNX4 endspent(); #endif /* QNX4 doesn't need endspent() to end shadow passwd ops */ #endif #if defined(ultrix) || defined(__ultrix__) if (authenticate_user(p, greet->password, NULL) < 0) #else if (strcmp (crypt (greet->password, user_pass), user_pass)) #endif { if(!greet->allow_null_passwd || strlen(p->pw_passwd) > 0) { Debug ("password verify failed\n"); bzero(greet->password, strlen(greet->password)); return 0; } /* else: null passwd okay */ } #ifdef KERBEROS done: #endif #ifdef __OpenBSD__ /* * Only accept root logins if allowRootLogin resource is set */ if ((p->pw_uid == 0) && !greet->allow_root_login) { Debug("root logins not allowed\n"); bzero(greet->password, strlen(greet->password)); return 0; } /* * Shell must be in /etc/shells */ for (;;) { s = getusershell(); if (s == NULL) { /* did not found the shell in /etc/shells -> failure */ Debug("shell not in /etc/shells\n"); bzero(greet->password, strlen(greet->password)); endusershell(); return 0; } if (strcmp(s, p->pw_shell) == 0) { /* found the shell in /etc/shells */ endusershell(); break; } } /* * Test for expired password */ if (p->pw_change || p->pw_expire) (void)gettimeofday(&tp, (struct timezone *)NULL); if (p->pw_change) { if (tp.tv_sec >= p->pw_change) { Debug("Password has expired.\n"); bzero(greet->password, strlen(greet->password)); return 0; } } if (p->pw_expire) { if (tp.tv_sec >= p->pw_expire) { Debug("account has expired.\n"); bzero(greet->password, strlen(greet->password)); return 0; } } #endif /* __OpenBSD__ */ bzero(user_pass, strlen(user_pass)); /* in case shadow password */ #else /* USE_PAM */ #define PAM_BAIL \ if (pam_error != PAM_SUCCESS) goto pam_failed; PAM_password = greet->password; pam_error = pam_start("xdm", greet->name, &PAM_conversation, pamhp); PAM_BAIL; pam_error = pam_set_item(*pamhp, PAM_TTY, d->name); PAM_BAIL; pam_error = pam_set_item(*pamhp, PAM_RHOST, ""); PAM_BAIL; pam_error = pam_authenticate(*pamhp, 0); PAM_BAIL; pam_error = pam_acct_mgmt(*pamhp, 0); /* really should do password changing, but it doesn't fit well */ PAM_BAIL; pam_error = pam_setcred(*pamhp, 0); PAM_BAIL; p = getpwnam (greet->name); endpwent(); if (!p || strlen (greet->name) == 0) { Debug ("getpwnam() failed.\n"); bzero(greet->password, strlen(greet->password)); return 0; } if (pam_error != PAM_SUCCESS) { pam_failed: pam_end(*pamhp, PAM_SUCCESS); *pamhp = NULL; return 0; } #undef PAM_BAIL #endif /* USE_PAM */ #endif /* USE_BSDAUTH */ Debug ("verify succeeded\n"); /* The password is passed to StartClient() for use by user-based authorization schemes. It is zeroed there. */ verify->uid = p->pw_uid; verify->gid = p->pw_gid; home = p->pw_dir; shell = p->pw_shell; argv = 0; if (d->session) argv = parseArgs (argv, d->session); if (greet->string) argv = parseArgs (argv, greet->string); if (!argv) argv = parseArgs (argv, "xsession"); verify->argv = argv; verify->userEnviron = userEnv (d, p->pw_uid == 0, greet->name, home, shell); Debug ("user environment:\n"); printEnv (verify->userEnviron); verify->systemEnviron = systemEnv (d, greet->name, home); Debug ("system environment:\n"); printEnv (verify->systemEnviron); Debug ("end of environments\n"); return 1; }
void pw_unix_check(AuthResult * const result, const char *account, const char *password, const struct sockaddr_storage * const sa, const struct sockaddr_storage * const peer) { //RCP - check user and password dbgmsg("checking user/password"); if (result == NULL || password == NULL || strlen(password) == 0) return; // initialize shared memory RcpShm *shm; if ((shm = rcpShmemInit(RCP_PROC_CLI)) == NULL) { dbgmsg("cannot initialize memory, exiting...\n"); return; } RcpAdmin *admin = admin_find(shm, account); if (admin == NULL) { dbgmsg("failed to find an RCP administrator account, exiting...\n"); return; } { // check password char solt[RCP_CRYPT_SALT_LEN + 1]; int i; for (i = 0; i < RCP_CRYPT_SALT_LEN; i++) solt[i] = admin->password[i]; solt[RCP_CRYPT_SALT_LEN] = '\0'; char *cp = rcpCrypt(password, solt); if (strcmp(admin->password + RCP_CRYPT_SALT_LEN + 1, cp + RCP_CRYPT_SALT_LEN + 4) != 0) return; } // user/password combination is ok // for the login into /home/rcp, with rcp as the real user account = "rcp"; //RCP const char *cpwd = NULL; struct passwd pw, *pw_; #ifdef USE_SHADOW struct spwd *spw; #endif char *dir = NULL; (void) sa; (void) peer; result->auth_ok = 0; if ((pw_ = getpwnam(account)) == NULL) { /*RCP*/dbgmsg("failed getpwnam"); return; } pw = *pw_; result->auth_ok--; #ifdef HAVE_SETUSERSHELL if (pw.pw_shell == NULL) { /*RCP*/dbgmsg("failed pw_shell"); return; } #if 0 // RCP disabled if (strcasecmp(pw.pw_shell, FAKE_SHELL) != 0) { const char *shell; setusershell(); while ((shell = (char *) getusershell()) != NULL && strcmp(pw.pw_shell, shell) != 0); endusershell(); if (shell == NULL) { return; } } #endif //RCP #endif if ((dir = strdup(pw.pw_dir)) == NULL) { /*RCP*/dbgmsg("failed strdup"); return; } #if 0 //disabeld for RCP #ifdef USE_SHADOW if ((((pw.pw_passwd)[0] == 'x' && (pw.pw_passwd)[1] == 0) || ((pw.pw_passwd)[0] == '#' && (pw.pw_passwd)[1] == '#' && strcmp(pw.pw_passwd + 2, account) == 0)) && (spw = getspnam(account)) != NULL && spw->sp_pwdp != NULL) { cpwd = spw->sp_pwdp[0] == '@' ? NULL : spw->sp_pwdp; if (spw->sp_expire > 0 || spw->sp_max > 0) { long today = time(NULL) / (24L * 60L * 60L); if (spw->sp_expire > 0 && spw->sp_expire < today) { goto bye; /* account expired */ } if (spw->sp_max > 0 && spw->sp_lstchg > 0 && (spw->sp_lstchg + spw->sp_max < today)) { goto bye; /* password expired */ } } } else #endif { cpwd = pw.pw_passwd; } { const char *crypted; if (cpwd == NULL || (crypted = (const char *) crypt(password, cpwd)) == NULL || strcmp(cpwd, crypted) != 0) { goto bye; } } #endif //RCP result->uid = pw.pw_uid; result->gid = pw.pw_gid; result->dir = dir; result->slow_tilde_expansion = 0; result->auth_ok = -result->auth_ok; /*RCP*/dbgmsg("RCP admin check ok"); return; bye: free(dir); /*RCP*/dbgmsg("failed RCP admin check"); }