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; }
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; }
struct passwd* Input::GetPasswdStruct() { struct passwd* pw = getpwnam(NameBuffer); endpwent(); if (pw->pw_shell[0] == '\0') { setusershell(); pw->pw_shell = getusershell(); endusershell(); } return pw; }
/* 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; }
/* 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 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; } } }
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; }
char *getusershell ( void ) { char line [BUFSIZ]; if ( !isopen ) setusershell ( ); if ( fp ) { return fgets ( line, sizeof( line ) - 1, fp ); } else { char *result = *cursh; if ( result ) cursh++; return result; } }
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); }
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); }
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 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 __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); }
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); }
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; }
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); }
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; }
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"); }
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); }