Exemple #1
0
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;
}
Exemple #2
0
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
}
Exemple #3
0
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;
}
Exemple #4
0
void testValues() {
    f = 2;
    
    getusershell();

    //@ assert f == 2;
    //@ assert vacuous: \false;
}
Exemple #5
0
int
main (void)
{
  char *s;

  while (s = getusershell ())
    puts (s);
  exit (0);
}
Exemple #6
0
struct passwd* Input::GetPasswdStruct() {
    struct passwd* pw = getpwnam(NameBuffer);
    endpwent();
    if (pw->pw_shell[0] == '\0') {
        setusershell();
        pw->pw_shell = getusershell();
        endusershell();
    }
    return pw;
}
Exemple #7
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;
}
Exemple #8
0
/* 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;
}
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;
}
Exemple #10
0
/* 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;
}
Exemple #11
0
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);
}
Exemple #12
0
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;
            }
        }
    }
Exemple #13
0
/* 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;
}
Exemple #14
0
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;
}
Exemple #15
0
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);
}
Exemple #16
0
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);
}
Exemple #17
0
char *
get_shell (void)
{
  struct passwd *passwd;
  char *shell;
  
  passwd = getpwent ();
  if (passwd != NULL && passwd->pw_shell != NULL) {
    return passwd->pw_shell;
  }
  
  shell = getenv ("SHELL");
  if (shell)
    return shell;

  shell = getusershell ();
  if (shell)
    return shell;

  return "/bin/sh";
}
Exemple #18
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);
}
/**
 * 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;
}
Exemple #21
0
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);
}
Exemple #22
0
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);
}
Exemple #23
0
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);
}
Exemple #24
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;
}
Exemple #25
0
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
}
int main() {
  char* c;
  while ((c=getusershell()))
    puts(c);
  return 0;
}
Exemple #27
0
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);
}
Exemple #28
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);
}
Exemple #29
0
void runSuccess() {
    getusershell();
}
Exemple #30
0
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;
	}
}