Beispiel #1
0
static struct SH_UTMP_S * sh_utmp_getutent(void)
{
  size_t in;
  static struct SH_UTMP_S out;

  SL_ENTER(_("sh_utmp_getutent"));

  ASSERT_RET((sh_utmpfile != NULL), _("sh_utmpfile != NULL"), (NULL))

  in = fread (&out, sizeof(struct SH_UTMP_S), 1, sh_utmpfile);

  if (in != 1) 
    {
      if (ferror (sh_utmpfile) != 0) 
	{
	  clearerr (sh_utmpfile);
	  SL_RETURN(NULL, _("sh_utmp_getutent"));
	} 
      else 
	{
	  SL_RETURN(NULL, _("sh_utmp_getutent"));
	}
    }
  SL_RETURN(&out, _("sh_utmp_getutent"));
}
Beispiel #2
0
int sh_readconf_setTime (const char * str, ShTimerItem what)
{
  unsigned long i = atoi (str);

  SL_ENTER( _("sh_readconf_setTime"));

  if (i < LONG_MAX) 
    {
      if      (what == SET_MAILTIME)
	{
	  TPT((0, FIL__, __LINE__, _("msg=<Set mail timer to %ld>\n"), i));
	  sh.mailTime.alarm_interval = i;
	}
      else if (what == SET_FILETIME)
	{
	  TPT((0, FIL__, __LINE__, _("msg=<Set filecheck timer to %ld>\n"),i));
	  sh.fileCheck.alarm_interval  = i;
	}

      SL_RETURN( 0, _("sh_readconf_setTime"));
    } 
  else 
    {
      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALL,
		     _("set timer"), (long) i);
      SL_RETURN( (-1), _("sh_readconf_setTime"));
    }
}
static 
int isin(uid_t n, uid_t *list)
{
  SL_ENTER(_("isin"));
  if (list == NULL)
    SL_IRETURN(S_FALSE, _("isin"));

  while(*list != tf_uid_neg && *list != n)
    {
#ifdef TRUST_DEBUG
      fprintf (stderr, 
	       "trustfile: owner_uid=%ld, trusted uid=%ld, no match\n", 
	       (UID_CAST) n, (UID_CAST) *list);
#endif 
      list++;
    }

  if (*list == tf_uid_neg)
    {
#ifdef TRUST_DEBUG
      fprintf (stderr, 
	       "trustfile: owner_uid=%ld, no match with any trusted user --> ERROR\n", 
	       (UID_CAST) n);
#endif 
      SL_IRETURN(S_FALSE, _("isin"));
    }

#ifdef TRUST_DEBUG
  fprintf (stderr, 
	   "trustfile: owner_uid=%ld, trusted_uid=%ld, match found --> OK\n", 
	   (UID_CAST)n, (UID_CAST)*list);
#endif 
  SL_IRETURN(S_TRUE, _("isin"));
}
Beispiel #4
0
int sh_utmp_end ()
{
  struct log_user * user    = userlist;
  struct log_user * userold;

  SL_ENTER(_("sh_utmp_end"));
  while (user)
    {
      userold = user;
      user    = user->next;
      SH_FREE(userold);
    }
  userlist = NULL;
#ifdef HAVE_UTTYPE
  (void) sh_utmp_login_clean();
#endif
  /* Reset the flag, such that the module
   * can be re-enabled.
   */
  set_defaults();
  init_done          = 0;

#if defined(HAVE_PTHREAD)
  sh_inotify_remove(&inotify_watch);
#endif

  SL_RETURN( (0), _("sh_utmp_end"));
}
Beispiel #5
0
int sh_utmp_set_login_activate (const char * c)
{
  int i;
  SL_ENTER(_("sh_utmp_set_login_activate"));
  i = sh_util_flagval(c, &ShUtmpActive);
  SL_RETURN(i, _("sh_utmp_set_login_activate"));
}
Beispiel #6
0
static void sh_utmp_endutent(void)
{
  SL_ENTER(_("sh_utmp_endutent"));
  if (NULL != sh_utmpfile)
    (void) sl_fclose(FIL__, __LINE__, sh_utmpfile);
  sh_utmpfile = NULL;
  SL_RET0(_("sh_utmp_endutent"));
}
Beispiel #7
0
int sh_readconf_setCaps(const char * c)
{
  int i;
  SL_ENTER(_("sh_readconf_setCaps"));

  i = sh_util_flagval(c, &sl_useCaps);
  SL_RETURN((i), _("sh_readconf_setCaps"));
}
Beispiel #8
0
static void sh_utmp_utmpname(const char * str)
{
  SL_ENTER(_("sh_utmp_utmpname"));
  if (sh_utmpfile != NULL)
    {
      (void) sl_fclose (FIL__, __LINE__, sh_utmpfile);
      sh_utmpfile = NULL;
    }

  (void) sl_strlcpy (sh_utmppath, str, 80);
  SL_RET0(_("sh_utmp_utmpname"));
}
Beispiel #9
0
int sh_utmp_set_logout_good (const char * c)
{
  int retval;
  char tmp[32];

  SL_ENTER(_("sh_utmp_set_logout_good"));
  tmp[0] = '='; tmp[1] = '\0';
  (void) sl_strlcat (tmp, c, 32);
  SH_MUTEX_LOCK(mutex_thread_nolog);
  retval = sh_error_set_level (tmp, &ShUtmpLogout);
  SH_MUTEX_UNLOCK(mutex_thread_nolog);
  SL_RETURN(retval, _("sh_utmp_set_logout_good"));
}
Beispiel #10
0
/* not static to circumvent stupid gcc 4 bug */ 
int getfname(const char *fname, char *rbuf, int rsz)
{
#ifndef TRUST_MAIN
  register int status;
#endif

  SL_ENTER(_("getfname"));
  /*
   * do the initial checking
   * NULL pointer
   */
  if (fname == NULL || rbuf == NULL)
    SL_IRETURN(SL_ENULL, _("getfname"));
  if (rsz <= 0)
    SL_IRETURN(SL_ERANGE, _("getfname"));
  
  
  /* already a full path name */
  if (*fname == '/')
    rbuf[0] = '\0';
  else
    {
      if (CURDIR(rbuf, rsz)  == NULL)
	{
#ifdef TRUST_DEBUG
	  fprintf(stderr, "trustfile: getcwd failed\n");
#endif 
	  SL_IRETURN(SL_EBADNAME, _("getfname"));
	}
    }
  
  /*
   * append the file name and reduce
   */
  if (fname != NULL && *fname != '\0')
    {
#ifndef TRUST_MAIN
      status = sl_strlcat(rbuf, "/", rsz);
      if (status == SL_ENONE)
	status = sl_strlcat(rbuf, fname, rsz);
      if (status != SL_ENONE)
	SL_IRETURN(status, _("getfname"));
#else
      strncat(rbuf, "/",   rsz-strlen(rbuf)-1);
      rbuf[rsz-1] = '\0';
      strncat(rbuf, fname, rsz-strlen(rbuf)-1);
      rbuf[rsz-1] = '\0';
#endif
    }
  SL_IRETURN(dirz(rbuf), _("getfname"));
}
static int sh_fInotify_watches(const char *s) 
{
  int retval = -1;
  char * foo;
  unsigned long value;
    
  SL_ENTER(_("sh_fInotify_watches"));

  value = strtoul(s, &foo, 0);
  if (*foo == '\0')
    {
      ShfInotifyWatches = (value > 2147483647) ? 2147483647 /* MAX_INT_32 */: value;
      retval = 0;
    }
  SL_RETURN((retval), _("sh_fInotify_watches"));
}
int sh_prelink_set_hash (const char * str)
{
  size_t len;
  SL_ENTER(_("sh_prelink_set_hash"));
  if (prelink_hash != NULL)
    SH_FREE(prelink_hash);
  len = sl_strlen (str);
  if (len != KEY_LEN)
    {
      prelink_hash = NULL;
      SL_RETURN((-1), _("sh_prelink_set_hash")); 
    }
  prelink_hash = SH_ALLOC(len+1);
  (void) sl_strlcpy(prelink_hash, str, len+1);
  SL_RETURN(0, _("sh_prelink_set_hash")); 
}
Beispiel #13
0
/*************
 *
 * module check
 *
 *************/
int sh_utmp_check ()
{
  SL_ENTER(_("sh_utmp_check"));
  if (ShUtmpActive == BAD)
    {
#if defined(HAVE_PTHREAD)
      sh_inotify_remove(&inotify_watch);
#endif
      SL_RETURN( (-1), _("sh_utmp_check"));
    }
  SH_MUTEX_LOCK(mutex_thread_nolog);
  sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_UT_CHECK);
  SH_MUTEX_UNLOCK(mutex_thread_nolog);
  sh_utmp_check_internal (1);

  SL_RETURN(0, _("sh_utmp_check"));
}
Beispiel #14
0
static void sh_utmp_setutent(void)
{
  int error;
  int fd;

  SL_ENTER(_("sh_utmp_setutent"));

  ASSERT((sh_utmppath != NULL), _("sh_utmppath != NULL"));

  if (sh_utmppath == NULL)
    SL_RET0(_("sh_utmp_setutent"));

  if (sh_utmpfile == NULL) 
    {
      SH_MUTEX_LOCK(mutex_thread_nolog);
      fd = (int) aud_open (FIL__, __LINE__, SL_NOPRIV, 
			   sh_utmppath, O_RDONLY, 0);
      SH_MUTEX_UNLOCK(mutex_thread_nolog);
      if (fd >= 0)
	{
	  sh_utmpfile = fdopen(fd, "r");
	}

      /* -- If (sh_utmpfile == NULL) then either the open() or the fdopen()
       *    has failed.
       */
      if (sh_utmpfile == NULL) 
	{
	  error = errno;
	  SH_MUTEX_LOCK(mutex_thread_nolog);
	  sh_error_handle ((-1), FIL__, __LINE__, error, MSG_E_ACCESS,
			   (long) sh.real.uid, sh_utmppath);
	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
	  SL_RET0(_("sh_utmp_setutent"));
	}
    }
  (void) fseek (sh_utmpfile, 0L, SEEK_SET);
  if (-1 == fseek (sh_utmpfile, sh_utmp_feed_forward, SEEK_CUR))
    {
      sh_utmp_feed_forward = 0; /* modified Apr 4, 2004 */
      (void) fseek (sh_utmpfile, 0L, SEEK_SET);
    }
  clearerr (sh_utmpfile);
  SL_RET0(_("sh_utmp_setutent"));
}
Beispiel #15
0
int sh_utmp_set_login_timer (const char * c)
{
  long val;

  SL_ENTER(_("sh_utmp_set_login_timer"));
  val = strtol (c, (char **)NULL, 10);
  if (val <= 0)
    {
      SH_MUTEX_LOCK(mutex_thread_nolog);
      sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
		       _("utmp timer"), c);
      SH_MUTEX_UNLOCK(mutex_thread_nolog);
      SL_RETURN((-1), _("sh_utmp_set_login_timer"));
    }

  ShUtmpInterval = (time_t) val;
  SL_RETURN(0, _("sh_utmp_set_login_timer"));
}
Beispiel #16
0
int sh_readconf_set_nice (const char * c)
{
  long val;

  SL_ENTER(_("sh_readconf_set_nice"));

  val = strtol (c, (char **)NULL, 10);
  if (val < -20 || val > 20)
    {
      SL_RETURN((-1), _("sh_readconf_set_nice"));
    }

  val = (val < -19 ? -19 : val);
  val = (val >  19 ?  19 : val);

  sh.flag.nice =  val;
  SL_RETURN((0), _("sh_readconf_set_nice"));
}
int sh_prelink_set_path (const char * str)
{
  SL_ENTER(_("sh_prelink_set_path"));
  if (prelink_path != NULL)
    SH_FREE(prelink_path);
  if (str[0] != '/')
    {
      prelink_path = NULL;
      SL_RETURN((-1), _("sh_prelink_set_path")); 
    }
#ifdef SH_EVAL_SHELL
  prelink_path = sh_util_strdup(str);
  SL_RETURN(0, _("sh_prelink_set_path")); 
#else
  prelink_path = NULL;
  SL_RETURN((-1), _("sh_prelink_set_path"));
#endif
}
static int sh_fInotify_active(const char *s) 
{
  int value;
    
  SL_ENTER(_("sh_fInotify_active"));
  value = sh_util_flagval(s, &ShfInotifyActive);
  if (value == 0 && ShfInotifyActive != S_FALSE)
    {
      sh.flag.inotify |= SH_INOTIFY_USE;
      sh.flag.inotify |= SH_INOTIFY_DOSCAN;
      sh.flag.inotify |= SH_INOTIFY_NEEDINIT;
    }
  if (value == 0 && ShfInotifyActive == S_FALSE)
    {
      sh.flag.inotify = 0;
    }
  SL_RETURN((value), _("sh_fInotify_active"));
}
Beispiel #19
0
static int sh_utmp_init_internal (void)
{

  SL_ENTER(_("sh_utmp_init"));
  if (ShUtmpActive == BAD)
    SL_RETURN( (-1), _("sh_utmp_init"));

  /* do not re-initialize after a re-configuration
   */
  if (init_done == 1) {
    SL_RETURN( (0), _("sh_utmp_init"));
  }
  lastcheck  = time (NULL);
  userlist   = NULL;
  memset (&save_utmp, 0, sizeof(struct SH_UTMP_S));
  sh_utmp_check_internal (2); /* current logins */
  sh_utmp_check_internal (0);
  init_done = 1;
  SL_RETURN( (0), _("sh_utmp_init"));
}
Beispiel #20
0
int sh_readconf_set_path (char * which, const char * what)
{
  int len;
  SL_ENTER( _("sh_readconf_set_path"));

  if (which == NULL || what == NULL)
    {
      TPT((0, FIL__, __LINE__ , _("msg=<Input error>\n")));
      SL_RETURN( -1, _("sh_readconf_set_path"));
    }

  if (0 == sl_strcmp(what, _("AUTO")))
    {
      len = sl_strlen(which);
      if ( (len + sl_strlen(sh.host.name) + 2) > SH_PATHBUF)
	{
	  TPT((0, FIL__, __LINE__ , _("msg=<Path too large: %s:%s>\n"), 
	       which, sh.host.name));
	  SL_RETURN( -1, _("sh_readconf_set_path"));
	}
      else
	{
	  which[len] = ':'; which[len+1] = '\0';
	  sl_strlcat(which, sh.host.name, SH_PATHBUF);
	}
    }
  else  /* not auto */
    {
      if (sl_strlen(what) > (SH_PATHBUF-1))
	{
	  TPT((0, FIL__, __LINE__ , _("msg=<Path too large: %s>\n"), what));
	  SL_RETURN( -1, _("sh_readconf_set_path"));
	}
      else
	{
	  sl_strlcpy(which, what, SH_PATHBUF);
	}
    }
  SL_RETURN( 0, _("sh_readconf_set_path"));
}
/* returns static storage
 */
int sh_prelink_run (char * path, char * file_hash, int alert_timeout, unsigned long mask)
{
  static int      init = S_FALSE;
  static int      args_filled = 0;
  static sh_tas_t task;

  int    status = 0;
  char * p;

  SL_ENTER(_("sh_prelink_run"));

  /* reset if path == NULL
   */
  if (path == NULL)
    {
      if (init == S_FALSE)
	{
	   SL_RETURN (0, _("sh_prelink_run"));
	}
      sh_ext_tas_free(&task);
      init = S_FALSE;
      args_filled = 0;
      SL_RETURN (0, _("sh_prelink_run"));
    }

  /* initialize task structure
   */
  if (init == S_FALSE)
    {
      char dir[SH_PATHBUF];

      sh_ext_tas_init(&task);
      p = sh_unix_getUIDdir (SH_ERR_ERR, task.run_user_uid, dir, sizeof(dir));
      if (p)
	{
	  (void) sh_ext_tas_add_envv (&task, _("HOME"), p);
	}
      (void) sh_ext_tas_add_envv (&task, _("SHELL"), 
				  _("/bin/sh")); 
      (void) sh_ext_tas_add_envv (&task, _("PATH"),  
				  _("/sbin:/usr/sbin:/bin:/usr/bin")); 
      if (sh.timezone != NULL)
	{
	  (void) sh_ext_tas_add_envv(&task,  "TZ", sh.timezone);
	}
      if (prelink_path == NULL)
	{
	  sh_ext_tas_command(&task,  _("/usr/sbin/prelink"));
	  (void) sh_ext_tas_add_argv(&task,  _("/usr/sbin/prelink"));
	}
      else
	{
	  sh_ext_tas_command(&task,  prelink_path);
	  (void) sh_ext_tas_add_argv(&task,  prelink_path);
	}
      args_filled = sh_ext_tas_add_argv(&task,  _("--verify"));

      if (prelink_hash != NULL)
	{
	  (void) sl_strlcpy(task.checksum, prelink_hash, KEY_LEN+1);
	}
      task.rw = 'r';
      task.fork_twice = S_FALSE;

      sh_prelink_fd(&task);

      init = S_TRUE;
    }

  /* rm filename arg if set; fill in filename
   */
  if (args_filled == 3)
    args_filled = sh_ext_tas_rm_argv(&task);
  if (args_filled == 2)
    args_filled = sh_ext_tas_add_argv(&task, path);
  else
    {
      sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, args_filled, MSG_E_SUBGEN, 
		      _("Bad argument count"), _("sh_prelink_run"));
      SL_RETURN ((-1), _("sh_prelink_run"));
    }

  /* open pipe
   */
  status = sh_ext_popen(&task);
  if (status != 0)
    {
      sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, status, MSG_E_SUBGEN, 
		      _("Could not open pipe"), _("sh_prelink_run"));
      SL_RETURN ((-1), _("sh_prelink_run"));
    }

  if (SL_ISERROR(task.pipeTI))
    {
      sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, task.pipeTI, MSG_E_SUBGEN, 
		      _("No valid ticket"), _("sh_prelink_run"));
      SL_RETURN ((-1), _("sh_prelink_run"));
    }

  /* read from pipe
   */
  sl_read_timeout_prep (task.pipeTI);

  {
    char hashbuf[KEYBUF_SIZE];
    UINT64 length_nolim = TIGER_NOLIM;
    if (sh.flag.opts == S_TRUE) sh_tiger_set_hashtype_mask(mask);
    sl_strlcpy(file_hash,
	       sh_tiger_generic_hash (path, task.pipeTI, &length_nolim, alert_timeout,
				      hashbuf, sizeof(hashbuf)),
	       KEY_LEN+1);
  }

  /* close pipe and return exit status
   */
  status = sh_ext_pclose(&task);
  SL_RETURN ((status), _("sh_prelink_run"));
}
Beispiel #22
0
static void sh_utmp_addlogin (struct SH_UTMP_S * ut)
{
  struct log_user   * user     = userlist;
  struct log_user   * userold  = userlist;
#ifdef HAVE_UTTYPE  
  struct log_user   * username = userlist;
#endif

  char   ttt[TIM_MAX];
#ifdef HAVE_UTTYPE
  volatile int    status;
#endif

  SL_ENTER(_("sh_utmp_addlogin"));

  if (ut->ut_line[0] == '\0')
    SL_RET0(_("sh_utmp_addlogin"));

  /* for some stupid reason, AIX repeats the wtmp entry for logouts
   * with ssh
   */
  if (memcmp (&save_utmp, ut, sizeof(struct SH_UTMP_S)) == 0)
    {
      memset(&save_utmp, (int) '\0', sizeof(struct SH_UTMP_S));
      SL_RET0(_("sh_utmp_addlogin"));
    }
  memcpy (&save_utmp, ut, sizeof(struct SH_UTMP_S));

  /* Take the address to keep gcc from putting them into registers. 
   * Avoids the 'clobbered by longjmp' warning. 
   */
  sh_dummy_userold = (void*) &userold;
  sh_dummy_user    = (void*) &user;

  /* ------- find user -------- 
   */
  while (user != NULL) 
    {
      if (0 == sl_strncmp((char*)(user->ut_tty), ut->ut_line, UT_LINESIZE) ) 
	break;
      userold = user;
      user = user->next;
    }

#ifdef HAVE_UTTYPE  
  while (username != NULL) 
    {
      if (0 == sl_strncmp(username->name, ut->ut_name, UT_NAMESIZE) ) 
	break;
      username = username->next;
    }
#endif
  
#ifdef HAVE_UTTYPE  
  /* ---------- LOGIN -------------- */
  if (ut->ut_type == USER_PROCESS) 
    {
      if (user == NULL)
	{
	  user = SH_ALLOC(sizeof(struct log_user));
	  user->next       = userlist;
	  userlist         = (struct log_user *) user;
	}
      (void) sl_strlcpy((char*)(user->ut_tty),  ut->ut_line, UT_LINESIZE+1);
      (void) sl_strlcpy((char*)(user->name),    ut->ut_name, UT_NAMESIZE+1);
#ifdef HAVE_UTHOST
      (void) sl_strlcpy((char*)(user->ut_host), ut->ut_host, UT_HOSTSIZE+1);
#else
      user->ut_host[0] = '\0';
#endif
#ifdef HAVE_UTADDR
#ifdef HAVE_UTADDR_V6
      my_inet_ntoa(ut->ut_addr_v6, user->ut_ship, SH_IP_BUF);
#else
      my_inet_ntoa(ut->ut_addr, user->ut_ship, SH_IP_BUF);
#endif
#endif
      user->time = ut->ut_time;

      if (username == NULL                              /* not yet logged in */
          || 0 == sl_strncmp(ut->ut_line, _("ttyp"), 4) /* in virt. console  */
          || 0 == sl_strncmp(ut->ut_line, _("ttyq"), 4) /* in virt. console  */
	  ) {
	status = sh_utmp_login_a((char*)user->name);
	SH_MUTEX_LOCK(mutex_thread_nolog);
	(void) sh_unix_time (user->time, ttt, TIM_MAX);
	sh_error_handle( ShUtmpLoginSolo, FIL__, __LINE__, 0,
#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
			 MSG_UT_LG1X,
#elif defined(HAVE_UTHOST)
			 MSG_UT_LG1A,
#else
			 MSG_UT_LG1B,
#endif
			 user->name,
			 user->ut_tty,
#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
			 user->ut_host,
			 user->ut_ship,
#elif defined(HAVE_UTHOST)
			 user->ut_host,
#endif
			 ttt,
			 status
			 );
	SH_MUTEX_UNLOCK(mutex_thread_nolog);
      } else
	if (0 == sh_utmp_is_virtual(ut->ut_line, (char*)user->ut_host))
	  {       
	    status = sh_utmp_login_a((char*)user->name);
	    SH_MUTEX_LOCK(mutex_thread_nolog);
	    (void) sh_unix_time (user->time, ttt, TIM_MAX);
	    sh_error_handle( ShUtmpLoginMulti, FIL__, __LINE__, 0,
#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
			     MSG_UT_LG2X,
#elif defined(HAVE_UTHOST)
			     MSG_UT_LG2A,
#else
			     MSG_UT_LG2B,
#endif
			     user->name,
			     user->ut_tty,
#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
			     user->ut_host,
			     user->ut_ship,
#elif defined(HAVE_UTHOST)
			     user->ut_host,
#endif
			     ttt,
			     status
			     );
	    SH_MUTEX_UNLOCK(mutex_thread_nolog);
	  }
      
      sh_utmp_login_morechecks(ut);
      goto out;
    }


  /* ---------  LOGOUT ---------------- */
  else if (ut->ut_name[0] == '\0'
	   || ut->ut_type == DEAD_PROCESS  /* solaris does not clear ut_name */
	   )
    {
      if (user != NULL)
	{
#if defined(__linux__)
	  if (0 == sh_utmp_is_virtual(ut->ut_line, (char*)user->ut_host)) {
#endif
	    status = sh_utmp_login_r((char*)user->name);
	    SH_MUTEX_LOCK(mutex_thread_nolog);
	    (void) sh_unix_time (ut->ut_time, ttt, TIM_MAX);
	    sh_error_handle( ShUtmpLogout, FIL__, __LINE__, 0,
#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
			     MSG_UT_LG3X,
#elif defined(HAVE_UTHOST)
			     MSG_UT_LG3A,
#else
			     MSG_UT_LG3B,
#endif
			     user->name,
			     user->ut_tty,
#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
			     user->ut_host,
			     user->ut_ship,
#elif defined(HAVE_UTHOST)
			     user->ut_host,
#endif
			     ttt,
			     status
			     );
	    SH_MUTEX_UNLOCK(mutex_thread_nolog);
	    userold->next = user->next;
	    if (user == userlist)
	      userlist = user->next;
	    sh_utmp_logout_morechecks((struct log_user *)user);
	    SH_FREE((struct log_user *)user);
	    user = NULL;
#if defined(__linux__)
	  }
#endif
	}
      else
	{
	  (void) sl_strlcpy(terminated_line, ut->ut_line, UT_HOSTSIZE);
	  SH_MUTEX_LOCK(mutex_thread_nolog);
	  (void) sh_unix_time (ut->ut_time, ttt, TIM_MAX);
	  sh_error_handle( ShUtmpLogout, FIL__, __LINE__, 0,
			   MSG_UT_LG3C,
			   terminated_line,
			   ttt, 0
			   );
	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
	}
      goto out;
    }

  /* default */
  goto out;

  /* #ifdef HAVE_UTTYPE                   */
#else

  if (user == NULL)   /* probably a login */
    {
      user = SH_ALLOC(sizeof(struct log_user));
      sl_strlcpy(user->ut_tty,  ut->ut_line, UT_LINESIZE+1);
      sl_strlcpy(user->name,    ut->ut_name, UT_NAMESIZE+1);
#ifdef HAVE_UTHOST
      sl_strlcpy(user->ut_host, ut->ut_host, UT_HOSTSIZE+1);
#endif
#ifdef HAVE_UTADDR
#ifdef HAVE_UTADDR_V6
      my_inet_ntoa(ut->ut_addr_v6, user->ut_ship, SH_IP_BUF);
#else
      my_inet_ntoa(ut->ut_addr, user->ut_ship, SH_IP_BUF);
#endif
#endif
      user->time       = ut->ut_time;
      user->next       = userlist;
      userlist         = user;

      SH_MUTEX_LOCK(mutex_thread_nolog);
      (void) sh_unix_time (user->time, ttt, TIM_MAX);
      sh_error_handle( ShUtmpLoginSolo, FIL__, __LINE__, 0,
#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
		       MSG_UT_LG1X,
#elif defined(HAVE_UTHOST)
		       MSG_UT_LG1A,
#else
		       MSG_UT_LG1B,
#endif
		       user->name,
		       user->ut_tty,
#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
		       user->ut_host,
		       user->ut_ship,
#elif defined(HAVE_UTHOST)
		       user->ut_host,
#endif
		       ttt,
		       1
		       );
      SH_MUTEX_UNLOCK(mutex_thread_nolog);
      sh_utmp_login_morechecks(ut);
    }
  else  /* probably a logout */
    {
      SH_MUTEX_LOCK(mutex_thread_nolog);
      (void) sh_unix_time (ut->ut_time, ttt, TIM_MAX);
      sh_error_handle( ShUtmpLogout, FIL__, __LINE__, 0,
#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
		       MSG_UT_LG2X,
#elif defined(HAVE_UTHOST)
		       MSG_UT_LG2A,
#else
		       MSG_UT_LG2B,
#endif
		       user->name,
		       user->ut_tty,
#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
		       user->ut_host,
		       user->ut_ship,
#elif defined(HAVE_UTHOST)
		       user->ut_host,
#endif
		       ttt,
		       1
		       );
      SH_MUTEX_UNLOCK(mutex_thread_nolog);
      sh_utmp_logout_morechecks(user);
      userold->next = user->next;
      if (user == userlist)       /* inserted Apr 4, 2004 */
	userlist = user->next;
      SH_FREE(user);
      user = NULL;
    }

#endif

 out:
  sh_dummy_user    = NULL;
  sh_dummy_userold = NULL;

  SL_RET0(_("sh_utmp_addlogin"));
}
Beispiel #23
0
static 
int dirz(char *path)
{
  register char *p = path;/* points to rest of path to clean up */
  register char *q;	/* temp pointer for skipping over stuff */

  static   char swp[MAXFILENAME];

  SL_ENTER(_("dirz"));
  /*
   * standard error checking
   */
  if (path == NULL)
    SL_IRETURN(SL_ENULL, _("dirz"));
  if (path[0] == '.')
    SL_IRETURN(SL_EINTERNAL, _("dirz"));
  
  
  /*
   * loop over the path name until everything is checked
   */
  while(*p)
    {
      /* skip 
       */
      if (*p != '/')
	{
	  p++;
	  continue;
	}

      /* "/./" or "/." 
       */
      if (p[1] == '.' && (p[2] == '/' || p[2] == '\0'))
	{
	  /* yes -- delete "/." 
	   */
	  (void) strcpy(swp, &p[2]);                     /* known to fit  */
	  (void) strcpy(p, swp);                         /* known to fit  */

	  /* special case "/." as full path name 
	   */
	  if (p == path && *p == '\0')
	    {
	    *p++ = '/';
	    *p = '\0';
	  }
      }

      /* "//" 
       */
      else if (p[1] == '/')
	{
	  /* yes -- skip 
	   */
	  for(q = &p[2]; *q == '/'; q++)
	    ;
	  (void) strcpy(swp, q);                         /* known to fit  */
	  (void) strcpy(&p[1], swp);                     /* known to fit  */
	}

      /* "/../" or "/.." 
       */
      else if (p[1] == '.' && p[2] == '.' && (p[3] == '/' || p[3] == '\0'))
	{
	  /* yes -- if it's root, delete .. only 
	   */
	  if (p == path)
	    {
	      (void) strcpy(swp, &p[3]);                 /* known to fit  */
	      (void) strcpy(p, swp);                     /* known to fit  */
	    }
	  else
	    {
	      /* back up over previous component 
	       */
	      q = p - 1;
	      while(q != path && *q != '/')
		q--;
	      /* now wipe it out 
	       */
	      (void) strcpy(swp, &p[3]);                 /* known to fit  */
	      (void) strcpy(q, swp);                     /* known to fit  */
	      p = q;
	    }
	}
      else
	p++;
    }
  SL_IRETURN(SL_ENONE, _("dirz"));
}
Beispiel #24
0
/* not static to circumvent stupid gcc 4 bug */ 
int isingrp(gid_t grp, uid_t *ulist, int * errval)
{
  struct passwd *w;	        /* info about group member */
  register uid_t *u;		/* points to current ulist member */
  register char **p;		/* points to current group member */
  struct group *g;	        /* pointer to group information */

  int status;
  
#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
  struct group    gr;
  char          * buffer = NULL;
  struct passwd   pwd;
  char          * pbuffer = NULL;
#endif

  SL_ENTER(_("isingrp"));

  *errval = 0;

#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
  buffer = calloc(1,SH_GRBUF_SIZE);
  status = sh_getgrgid_r(grp, &gr, buffer, SH_GRBUF_SIZE, &g);
#else
  errno = 0;
  g = sh_getgrgid(grp);
  status = errno;
#endif

  if (g == NULL)
    {
      if (status == ERANGE)
	*errval = status;

      goto end_false;
    }

  /* this will return at the first match
   */
#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
  pbuffer = calloc(1,SH_PWBUF_SIZE);
#endif

  for(p = g->gr_mem; *p != NULL; p++)
    {
      for(u = ulist; *u != tf_uid_neg; u++)
	{
	  /* map user name to UID and compare */
#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
	  sh_getpwnam_r(*p, &pwd, pbuffer, SH_PWBUF_SIZE, &w);
#else
	  w = sh_getpwnam(*p);
#endif

#ifdef TRUST_MAIN
	  if (w != NULL && *u == (uid_t)(w->pw_uid) )
	    goto end_true;
#else
	  if (w != NULL && *u == (uid_t)(w->pw_uid) )
	    {
	      goto end_true;
	    }
#endif
	}
    }
  /* added by R. Wichmann Fri Mar 30 08:16:14 CEST 2001: 
   * a user can have a GID but no entry in /etc/group
   */
  for(u = ulist; *u != tf_uid_neg; u++)
    {
#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R)
      sh_getpwuid_r(*u, &pwd, pbuffer, SH_PWBUF_SIZE, &w);
#else
      w = sh_getpwuid(*u);
#endif
#ifdef TRUST_MAIN
      if (w != NULL && grp == (gid_t)(w->pw_gid) )
	goto end_true;
#else
      if (w != NULL && grp == (gid_t)(w->pw_gid) )
	{
	  goto end_true;
	}
#endif
    }

 end_false:
#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
  if (buffer)  free(buffer);
  if (pbuffer) free(pbuffer);
#endif
  SL_IRETURN(S_FALSE, _("isingrp"));

 end_true:
#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
  if (buffer)  free(buffer);
  if (pbuffer) free(pbuffer);
#endif
  SL_IRETURN(S_TRUE, _("isingrp"));
}
Beispiel #25
0
/* not static to circumvent stupid gcc 4 bug */ 
int onlytrustedingrp(gid_t grp, uid_t *ulist, int * errval)
{
  struct passwd *w;	        /* info about group member */
  register uid_t *u;		/* points to current ulist member */
  register char **p;		/* points to current group member */
  struct group *g;	        /* pointer to group information */
  register int flag = -1;       /* group member found */

  int status;

#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
  struct group    gr;
  char          * buffer  = NULL;
  struct passwd   pw;
  char          * pbuffer = NULL;
#endif

  int retval = S_FALSE;

  SL_ENTER(_("onlytrustedingrp"));

  *errval = 0;

#ifdef TRUST_DEBUG
  fprintf(stderr, "trustfile: group writeable, group_gid: %ld\n", 
	  (UID_CAST)grp); 
#endif

#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
  buffer = calloc(1,SH_GRBUF_SIZE);
  status = sh_getgrgid_r(grp, &gr, buffer, SH_GRBUF_SIZE, &g);
#else
  errno = 0;
  g = sh_getgrgid(grp);
  status = errno;
#endif

  if (g == NULL)
    {
      if (status == ERANGE)
	*errval = status;

#ifdef TRUST_DEBUG
      fprintf(stderr, 
	      "trustfile: group_gid: %ld, no such group --> ERROR\n", 
	      (UID_CAST)grp); 
#endif
      retval = S_FALSE;
      goto end_retval;
    }

  /* empty group -> no problem
   
  if(g->gr_mem == NULL || g->gr_mem[0] == NULL )
    SL_IRETURN(S_TRUE, _("onlytrustedingrp") );
  */

  /* check for untrusted members of the group
   */
#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
  pbuffer = calloc(1,SH_PWBUF_SIZE);
#endif

  for(p = g->gr_mem; *p != NULL; p++)
    {
      flag = -1;
#ifdef TRUST_DEBUG
      fprintf(stderr, "trustfile: group_member: %s\n", *p); 
#endif
      /* map user name to UID and compare 
       */
#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
      sh_getpwnam_r(*p, &pw, pbuffer, SH_PWBUF_SIZE, &w);
#else
      w = sh_getpwnam(*p);
#endif

      if (w == NULL)    /* not a valid user, ignore    */
	{
	  flag = 0; 
	}
      else              /* check list of trusted users */
	{
#ifdef TRUST_DEBUG
	  fprintf (stderr, 
		   "trustfile: uid=%ld, checking whether it is trusted\n",
		   (UID_CAST)(w->pw_uid));
#endif 
	  for(u = ulist; *u != tf_uid_neg; u++)
	    {
	      if (*u == (w->pw_uid) )
		{
#ifdef TRUST_DEBUG
		  fprintf (stderr, 
			   "trustfile: uid=%ld, trusted_uid=%ld, match found --> OK\n", 
			   (UID_CAST)(w->pw_uid), (UID_CAST)*u);
#endif 
		  flag = 0;
		  break;
		}
	      else
		{
#ifdef TRUST_DEBUG
		  fprintf (stderr, 
			   "trustfile: uid=%ld, trusted_uid=%ld, no match\n", 
			   (UID_CAST)(w->pw_uid), (UID_CAST)*u);
#endif 
		  ;
		}
	    }
	}
      /* not found 
       */
      if (flag == -1)
	{
#ifdef TRUST_DEBUG
	  fprintf (stderr, 
		   "trustfile: user=%s (gid %ld), not a trusted user --> ERROR\n", *p, (UID_CAST)grp);
#endif 
	  tf_baduid = w->pw_uid;
	  retval = S_FALSE;
#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
	  if (pbuffer) free(pbuffer);
#endif
	  goto end_retval;
	}
    }

#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
  if (pbuffer) free(pbuffer);
#endif

#ifndef TEST_ONLY	
#ifdef HAVE_GETPWENT
  /* now check ALL users for their GID !!!
   */
  SH_MUTEX_LOCK(mutex_pwent);

  while (NULL != (w = sh_getpwent())) 
    {
      if (grp == (gid_t)(w->pw_gid))
	{
#ifdef TRUST_DEBUG
	  fprintf(stderr, "trustfile: checking group member %s, uid %ld\n", 
		  w->pw_name, (UID_CAST)w->pw_uid); 
#endif
	  /* is it a trusted user ?
	   */
	  flag = -1;
	  for(u = ulist; *u != tf_uid_neg; u++)
	    {
	      if (*u == (uid_t)(w->pw_uid))
		{
#ifdef TRUST_DEBUG
		  fprintf (stderr, 
			   "trustfile: uid=%ld, trusted_uid=%ld, match found --> OK\n", 
			   (UID_CAST)(w->pw_uid), (UID_CAST)(*u));
#endif 
		  flag = 0;
		  break;
		}
	      else
		{
#ifdef TRUST_DEBUG
		  fprintf (stderr, 
			   "trustfile: uid=%ld, trusted_uid=%ld, no match\n", 
			   (UID_CAST)(w->pw_uid), (UID_CAST)*u);
#endif 
		  ;
		}
	    }
	  /* not found */
	  if (flag == -1)
	    {
#ifdef TRUST_DEBUG
	      fprintf(stderr,"trustfile: group member %s not found in trusted users --> ERROR\n", w->pw_name); 
#endif
	      tf_baduid = w->pw_uid;
	      retval = S_FALSE;
	      goto out;
	      /* SL_IRETURN(S_FALSE, _("onlytrustedingrp")); */
	    }
	}
    }
  retval = S_TRUE;

 out:

#ifdef HAVE_ENDPWENT
  sh_endpwent();
#endif

  SH_MUTEX_UNLOCK(mutex_pwent);

  /* TEST_ONLY */
#endif
  /* #ifdef HAVE_GETPWENT */
#endif

#ifdef TRUST_DEBUG
  if (retval == S_TRUE)
    fprintf(stderr,
	    "trustfile: group %ld:  all members are trusted users --> OK\n", 
	    (UID_CAST)grp);
#endif
  /* all found
   */
 end_retval:
#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
  if (buffer)  free(buffer);
#endif
  SL_IRETURN(retval, _("onlytrustedingrp"));
}
Beispiel #26
0
int sl_trustfile(const char *fname, uid_t *okusers, uid_t *badusers)
{
  char * fexp = NULL;	        /* file name fully expanded        */
  register char *p;             /* used to hold name to be checked */
  struct stat stbuf;	        /* used to check file permissions  */
  char c;			/* used to hold temp char          */
  
  int errgrp = 0;

  SL_ENTER(_("sl_trustfile"));
  if (fname == NULL)
    SL_IRETURN(SL_EBADFILE, _("sl_trustfile"));

  fexp = calloc(1, MAXFILENAME );
  if (!fexp)
    SL_IRETURN(SL_EMEM, _("sl_trustfile"));

  p = fexp;

  /*
   * next expand to the full file name
   * getfname sets sl_errno as appropriate
   */
#ifdef TRUST_MAIN
  sl_errno = getfname(fname, fexp, MAXFILENAME);
  if (sl_errno != 0)
    {
      free(fexp);
      return sl_errno;
    }
#else
  if (SL_ISERROR(getfname(fname, fexp, MAXFILENAME)))
    {
      free(fexp);
      SL_IRETURN(sl_errno, _("sl_trustfile"));
    }
#endif

  if (okusers == NULL && badusers == NULL)
    {
      okusers = rootonly;
      rootonly[EUIDSLOT] = tf_euid;
    }

  /*
   * now loop through the path a component at a time
   * note we have to special-case root
   */
  while(*p)
    {
      /*
       * get next component
       */
      while(*p && *p != '/')
	p++;

      /* save where you are 
       */
      if (p == fexp)
	{
	  /* keep the / if it's the root dir 
	   */
	  c    = p[1];
	  p[1] = '\0';
	}
      else
	{
	  /* clobber the / if it isn't the root dir 
	   */
	  c  = *p;
	  *p = '\0';
	}

      /*
       * now get the information
       */
      if (retry_lstat(FIL__, __LINE__, fexp, &stbuf) < 0)
	{
	  (void) strncpy(tf_path, fexp, sizeof(tf_path));
	  tf_path[sizeof(tf_path)-1] = '\0';
#ifdef TRUST_MAIN
	  fprintf(stderr, "---------------------------------------------\n");
	  fprintf(stderr, "trustfile: ESTAT: stat(%s) failed,\n", fexp);
	  fprintf(stderr, "maybe the file does not exist\n");
	  fprintf(stderr, "---------------------------------------------\n");
#endif
	  free(fexp);
	  SL_IRETURN(SL_ESTAT, _("sl_trustfile"));
	}

#ifdef S_IFLNK
      /* 
       * if it's a symbolic link, recurse
       */
      if ((stbuf.st_mode & S_IFLNK) == S_IFLNK)
	{
	  /*
	   * this is tricky
	   * if the symlink is to an absolute path
	   * name, just call trustfile on it; but
	   * if it's a relative path name, it's 
	   * interpreted WRT the current working
	   * directory AND NOT THE FILE NAME!!!!!
	   * so, we simply put /../ at the end of
	   * the file name, then append the symlink
	   * contents; trustfile will canonicalize
	   * this, and the /../ we added "undoes"
	   * the name of the symlink to put us in
	   * the current working directory, at
	   * which point the symlink contents (appended
	   * to the CWD) are interpreted correctly.
	   * got it?
	   */
	  char * csym;	                /* contents of symlink file  */
	  char * full;	                /* "full" name of symlink    */
	  char *b;                      /* used to copy stuff around */
	  const char *t;	        /* used to copy stuff around */
	  int lsym;	                /* num chars in symlink ref  */
	  int i;		        /* trustworthy or not?       */
	  const char * t_const;
	  char *end;

	  /*
	   * get what the symbolic link points to
	   *
	   * The original code does not check the return code of readlink(),
	   * and has an off-by-one error 
	   * (MAXFILENAME instead of MAXFILENAME-1)
	   * R.W. Tue May 29 22:05:16 CEST 2001
	   */
	  csym = calloc(1, MAXFILENAME );
	  if (!csym)
	    {
	      free(fexp);
	      SL_IRETURN(SL_EMEM, _("sl_trustfile"));
	    }

	  lsym = readlink(fexp, csym, MAXFILENAME-1);
	  if (lsym >= 0) 
	    csym[lsym] = '\0';
	  else
	    {
#ifdef TRUST_MAIN
	      fprintf(stderr, "---------------------------------------------\n");
	      fprintf(stderr, "trustfile: EBADNAME: readlink(%s) failed\n",
		      fexp);
	      fprintf(stderr, "---------------------------------------------\n");
#endif
	      free(csym);
	      free(fexp);
	      SL_IRETURN(SL_EBADNAME, _("sl_trustfile"));
	    }

	  full = calloc(1, MAXFILENAME );
	  if (!full)
	    {
	      free(csym);
	      free(fexp);
	      SL_IRETURN(SL_EMEM, _("sl_trustfile"));
	    }

	  /*
	   * relative or absolute referent?
	   */
	  if (csym[0] != '/')
	    {
	      /* pointer to one above last element
	       */
	      end = &full[MAXFILENAME-1]; ++end;

	      /* initialize pointers 
	       */
	      b = full;

	      /* copy in base path 
	       */
	      t = fexp;
	      while(*t && b < end)
		*b++ = *t++;

	      /* smack on the /../ 
	       */
	      t_const = "/../"; t = (const char *)t_const;
	      while(*t && b < end)
		*b++ = *t++;

	      /* append the symlink referent 
	       */
	      t = csym;
	      while(*t && b < end)
		*b++ = *t++;

	      /* see if we're too big 
	       */
	      if (*t || b == end)
		{
		  /* yes -- error 
		   */
		  (void) strncpy(tf_path, fexp, sizeof(tf_path));
		  tf_path[sizeof(tf_path)-1] = '\0';
#ifdef TRUST_MAIN
		  fprintf(stderr, "---------------------------------------------\n");
		  fprintf(stderr, 
			  "trustfile: ETRUNC: normalized path too long (%s)\n",
			  fexp);
		  fprintf(stderr, "---------------------------------------------\n");
#endif
		  free(full);
		  free(csym);
		  free(fexp);
		  SL_IRETURN(SL_ETRUNC, _("sl_trustfile"));
		}
	      *b = '\0';
	    }
	  else
	    {
	      /* absolute -- just copy                */
	      /* overflow can't occur as the arrays   */
	      /* are the same size		      */
	      (void) strcpy(full, csym);                 /* known to fit  */
	    }
	  /*
	   * now check out this file and its ancestors
	   */
	  if ((i = sl_trustfile(full, okusers, badusers)) != SL_ENONE)
	    {
	      free(full);
	      free(csym);
	      free(fexp);
	      SL_IRETURN(i, _("sl_trustfile"));
	    }

	  /*
	   * okay, this part is valid ... let's check the rest
	   * put the / back
	   */
	  if (p == fexp)
	    {
	      /* special case for root */
	      p[1] = c;
	      p++;
	    }
	  else
	    {
	      /* ordinary case for everything else */
	      *p = c;
	      if (*p)
		p++;
	    }
	  free(full);
	  free(csym);
	  continue;
	}
#endif

			
#ifdef TRUST_DEBUG
      fprintf(stderr, "\ntrustfile: checking path=%s\n", fexp); 
#endif 
      /*
       * if the owner is not trusted then -- as the owner can
       * change protection modes -- he/she can write to the
       * file regardless of permissions, so bomb
       */
      if (((okusers != NULL && S_FALSE == isin((uid_t)stbuf.st_uid,okusers))||
	   (badusers != NULL && S_TRUE == isin((uid_t)stbuf.st_uid,badusers))))
	{
#ifdef TRUST_DEBUG
	  fprintf(stderr, "---------------------------------------------\n");
	  fprintf(stderr, "trustfile: EBADUID %s (owner not trusted)\n", 
		  fexp); 
	  fprintf(stderr, "The owner of this file/directory is not in samhains\n"); 
	  fprintf(stderr, "list of trusted users.\n");
	  fprintf(stderr, "Please run ./configure again with the option\n");
	  fprintf(stderr, " ./configure [more options] --with-trusted=0,...,UID\n"); 
	  fprintf(stderr, "where UID is the UID of the (yet) untrusted user.\n"); 
	  fprintf(stderr, "---------------------------------------------\n");
#endif 
	  (void) strncpy(tf_path, fexp, sizeof(tf_path));
	  tf_path[sizeof(tf_path)-1] = '\0';

	  tf_baduid = (uid_t) stbuf.st_uid;
	  free(fexp);
	  SL_IRETURN(SL_EBADUID, _("sl_trustfile"));
	}

      /*
       * if a group member can write but the
       * member is not trusted, bomb; but if
       * sticky bit semantics are honored, it's
       * okay
       */
      /* Thu Mar 29 21:10:28 CEST 2001 Rainer Wichmann
       * replace !isingrp() with onlytrustedingrp(), as isingrp()
       * will return at the first trusted user, even if there are additional
       * (untrusted) users in the group
       */
      if (((stbuf.st_mode & S_IWGRP) == S_IWGRP) &&
	  ((okusers != NULL && !onlytrustedingrp((gid_t)stbuf.st_gid,okusers,&errgrp))||
	   (badusers != NULL && isingrp((gid_t)stbuf.st_gid, badusers,&errgrp)))
#ifdef STICKY
	  && ((stbuf.st_mode&S_IFDIR) != S_IFDIR ||
	      (stbuf.st_mode&S_ISVTX) != S_ISVTX)
#endif
	  )
	{
#ifdef TRUST_DEBUG
	  fprintf(stderr, "---------------------------------------------\n");
	  fprintf(stderr, 
		  "trustfile: EBADGID %ld %s (group member not trusted)\n", 
		  (UID_CAST)stbuf.st_gid, fexp);
	  fprintf(stderr, "This file/directory is group writeable, and one of the group members\n");
	  fprintf(stderr, "is not in samhains list of trusted users.\n"); 
	  fprintf(stderr, "Please run ./configure again with the option\n");
	  fprintf(stderr, " ./configure [more options] --with-trusted=0,...,UID\n"); 
	  fprintf(stderr, "where UID is the UID of the (yet) untrusted user.\n"); 
	  fprintf(stderr, "---------------------------------------------\n");
#endif 
	  (void) strncpy(tf_path, fexp, sizeof(tf_path));
	  tf_path[sizeof(tf_path)-1] = '\0';

	  tf_badgid = (gid_t) stbuf.st_gid;
	  free(fexp);
	  SL_IRETURN((errgrp == ERANGE) ? SL_ERANGE : SL_EBADGID, _("sl_trustfile"));
	}
      /*
       * if other can write, bomb; but if the sticky
       * bit semantics are honored, it's okay
       */
      if (((stbuf.st_mode & S_IWOTH) == S_IWOTH)
#ifdef STICKY
	  && ((stbuf.st_mode&S_IFDIR) != S_IFDIR ||
	      (stbuf.st_mode&S_ISVTX) != S_ISVTX)
#endif
	  )
	{
#ifdef TRUST_DEBUG
	  fprintf(stderr, "---------------------------------------------\n");
	  fprintf(stderr, "trustfile: EBADOTH (world writeable): %s\n", 
		  fexp);
	  fprintf(stderr, "This file/directory is world writeable.\n");
	  fprintf(stderr, "---------------------------------------------\n");
#endif 
	  (void) strncpy(tf_path, fexp, sizeof(tf_path));
	  tf_path[sizeof(tf_path)-1] = '\0';

	  free(fexp);
	  SL_IRETURN(SL_EBADOTH, _("sl_trustfile"));
	}
      /*
       * put the / back
       */
      if (p == fexp)
	{
	  /* special case for root */
	  p[1] = c;
	  p++;
	}
      else
	{
	  /* ordinary case for everything else */
	  *p = c;
	  if (*p)
	    p++;
	}
    }
  /*
   * yes, it can be trusted
   */
  (void) strncpy(tf_path, fexp, sizeof(tf_path));
  tf_path[sizeof(tf_path)-1] = '\0';

  free(fexp);
  SL_IRETURN(SL_ENONE, _("sl_trustfile"));
}
Beispiel #27
0
/* --- Read the configuration file. ---
 */
int sh_readconf_read (void)
{
#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) 
  /* This is for modules. 
   */
  int    modnum;
#endif

  int i;

  SL_TICKET    fd    = -1;
#if defined(SH_STEALTH) && !defined(SH_STEALTH_MICRO)
  SL_TICKET    fdTmp = -1;
#endif
#if defined(WITH_GPG) || defined(WITH_PGP)
  SL_TICKET    fdGpg = -1;
#endif
  char * tmp;

#define SH_LINE_IN 16384
  char * line_in;
  char * line;

  /* This is for nested conditionals.
   */
  int    cond_depth  = 0;
  int    cond_excl   = 0;
  
  int    local_file = 1;
  char   local_flag = 'R';

#if defined(WITH_GPG) || defined(WITH_PGP)
  int    signed_content = S_FALSE;
  int    true_content   = S_FALSE;
#endif
#if defined(SH_STEALTH) && !defined(SH_STEALTH_MICRO)
  int    hidden_count = 0;
#endif
  uid_t  euid;
  char hashbuf[KEYBUF_SIZE];

  SL_ENTER(_("sh_readconf_read"));

  /* --- Open config file, exit on failure. ---
   */
#if defined(SH_WITH_CLIENT)
  if (0 == sl_strcmp(file_path('C', 'R'), _("REQ_FROM_SERVER")))
    {
      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_D_START);

      fd = sh_forward_req_file(_("CONF"));

      if (!SL_ISERROR(fd))
	{
	  local_file = 0;
	}
      else if (sh.flag.checkSum != SH_CHECK_INIT)
	{
	  aud_exit (FIL__, __LINE__, EXIT_FAILURE);
	}
      else
	{
	  sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_D_FAIL);
	  local_file = 1;
	  local_flag = 'I';
	}
    }
#endif

  /* Use a local configuration file.
   */
  if (local_file == 1)
    {
      if (0 != tf_trust_check (file_path('C', local_flag), SL_YESPRIV))
	{
	  sl_get_euid(&euid);
	  dlog(1, FIL__, __LINE__, 
	       _("The configuration file: %s is untrusted, i.e. an\nuntrusted user owns or can write to some directory in the path.\n"), 
	       ( (NULL == file_path('C', local_flag)) 
			     ? _("(null)") : file_path('C', local_flag) ));
	  sh_error_handle ((-1), FIL__, __LINE__, EACCES, MSG_TRUST, 
			   (long) euid, 
			   ( (NULL == file_path('C', local_flag)) 
			     ? _("(null)") : file_path('C', local_flag) )
			   );
	  aud_exit (FIL__, __LINE__, EXIT_FAILURE);
	}
      if (SL_ISERROR(fd = sl_open_read(FIL__, __LINE__, 
				       file_path('C',local_flag),SL_YESPRIV)))
	{
	  sl_get_euid(&euid);
	  dlog(1, FIL__, __LINE__, 
	       _("Could not open the local configuration file for reading because\nof the following error: %s (errnum = %ld)\nIf this is a permission problem, you need to change file permissions\nto make the file readable for the effective UID: %d\n"), 
	       sl_get_errmsg(), fd, (int) euid);
	  sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_NOACCESS, 
			   (long) euid, 
			   ( (NULL == file_path('C', local_flag)) 
			     ? _("(null)") : file_path('C', local_flag) )
			   );
	  aud_exit (FIL__, __LINE__, EXIT_FAILURE);
	}
    }

  /* Compute the checksum of the open file.
   */
  sl_strlcpy(sh.conf.hash, 
	     sh_tiger_hash(file_path('C',local_flag), fd, TIGER_NOLIM, 
			   hashbuf, sizeof(hashbuf)),
	     KEY_LEN+1);
  sl_rewind (fd);

  line_in = SH_ALLOC(SH_LINE_IN);

#if defined(SH_STEALTH) && !defined(SH_STEALTH_MICRO)
    /* extract the data and copy to temporary file
     */
  fdTmp = open_tmp(); 

  sh_unix_getline_stealth (0, NULL, 0); /* initialize */

  while ( sh_unix_getline_stealth (fd, line_in, SH_LINE_IN-2) > 0) {
    hidden_count++;
    if (line_in[0] == '\n')
      {
	sl_write(fdTmp, line_in, 1);
      }
    else
      {
	sl_write_line(fdTmp, line_in, sl_strlen(line_in));
      }
#if defined(WITH_GPG) || defined(WITH_PGP)
    if (0 == sl_strncmp(line_in, _("-----END PGP SIGNATURE-----"), 25))
      break;
#else
    if (0 == sl_strncmp(line_in, _("[EOF]"), 5))
      break;
#endif
    if (hidden_count > 1048576)  /* arbitrary safeguard, 1024*1024 */
      break;
  }
  sl_close(fd);
  fd = fdTmp;
  sl_rewind (fd);
#endif

#if defined(WITH_GPG) || defined(WITH_PGP)

  /* extract the data and copy to temporary file
   */
  fdGpg = sh_gpg_extract_signed(fd);

  sl_close(fd);
  fd = fdGpg;

  /* Validate signature of open file.
   */
  if (0 != sh_gpg_check_sign (fd, 0, 1))
    {
      SH_FREE(line_in);
      aud_exit (FIL__, __LINE__, EXIT_FAILURE);
    }
  sl_rewind (fd);
#endif


  /* ---  Start reading lines.  ---
   */
  conf_line = 0;

  while ( sh_unix_getline (fd, line_in, SH_LINE_IN-2) > 0) {

    ++conf_line;

    line = &(line_in[0]);

    /* fprintf(stderr, "<%s>\n", line); */

    /* Sun May 27 18:40:05 CEST 2001
     */
#if defined(WITH_GPG) || defined(WITH_PGP)
    if (signed_content == S_FALSE)
      { 
	if (0 == sl_strcmp(line, _("-----BEGIN PGP SIGNED MESSAGE-----")))
	  signed_content = S_TRUE;
	else 
	  continue;
      }
    else if (true_content == S_FALSE)
      {
	if (line[0] == '\n')
	  true_content = S_TRUE;
	else
	  continue;
      }
    else if (signed_content == S_TRUE)
      { 
	if (0 == sl_strcmp(line, _("-----BEGIN PGP SIGNATURE-----")))
	  break;
	else if (0 == sl_strcmp(line, _("-----BEGIN PGP SIGNED MESSAGE-----")))
	  {
	    sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
			    _("second signed message in file"),
			    _("sh_readconf_read"));
	    dlog(1, FIL__, __LINE__, 
		 _("There seems to be more than one signed message in the configuration\nfile. Please make sure there is only one signed message.\n"));
	    sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EXIT_ABORT1,
			     sh.prg_name);
	    SH_FREE(line_in);
	    aud_exit (FIL__, __LINE__,EXIT_FAILURE);
	  }
      }
#endif

    /* Skip leading white space.
     */
    while (isspace((int)*line)) ++line;


    /* Skip header etc. 
     */
    if (line[0] == '#' || line[0] == '\0' || line[0] == ';' || 
	(line[0] == '/' && line[1] == '/'))
      continue; 
  
    /* Clip off trailing white space.                 
     */
    tmp = line + sl_strlen( line ); --tmp;
    while( isspace((int) *tmp ) && tmp >= line ) *tmp-- = '\0';


    /* ---  an @host/@if/$system directive -------------- */

    if (line[0] == '@' || (line[0] == '!' && line[1] == '@') || 
	line[0] == '$' || (line[0] == '!' && line[1] == '$'))
      {
	if (sh_readconf_is_end(line))
	  {
	    if (0 == cond_depth) {
	      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALD,
			       _("config file"), 
			       (long) conf_line);
	    }
	    else {
	      if (cond_excl == cond_depth)
		cond_excl = 0;
	      --cond_depth;
	    }
	  }
	else if (sh_readconf_is_else(line))
	  {
	    if (0 == cond_depth) {
	      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALD,
			       _("config file"), 
			       (long) conf_line);
	    }
	    else if (cond_excl == cond_depth) {
	      cond_excl = 0;
	    }
	    else if (cond_excl == 0) {
	      cond_excl = cond_depth;
	    }
	  }
	else
	  {
	    if (sh_readconf_cond_match(line, conf_line)) {
	      ++cond_depth;
	    }
	    else {
	      ++cond_depth;
	      if (cond_excl == 0)
		cond_excl = cond_depth;
	    }
	  }
	continue;
      }

    /****************************************************
     *
     * Only carry on if this section is intended for us
     *
     ****************************************************/
    
    if (cond_excl != 0) {
      continue;
    }

    /* -------  starts a section  ------------  */
    
    else if (line[0] == '[')
      { 
	read_mode = SH_SECTION_NONE;

	if (0 == sl_strncasecmp (line,  _("[EOF]"), 5)) {
	  goto nopel;
	}

	i = 0;

	while (tab_ListSections[i].name != 0)
	  {
	    if (sl_strncasecmp (line, _(tab_ListSections[i].name), 
				sl_strlen(tab_ListSections[i].name)) == 0)
	      { 
		read_mode = tab_ListSections[i].type;
		break;
	      }
	    ++i;
	  }

#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) 
	if (read_mode == SH_SECTION_NONE)
	  {
	    for (modnum = 0; modList[modnum].name != NULL; ++modnum) 
	      {
		if (0 == sl_strncasecmp (line, _(modList[modnum].conf_section),
					 sl_strlen(modList[modnum].conf_section)) )
		  read_mode = SH_SECTION_OTHER;
	      }
	  }
#endif
	if (read_mode == SH_SECTION_NONE)
	  {
	    sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALHEAD,
			     (long) conf_line);
	  }
      } 

    /* ---  an %schedule directive ------------ */

    else if (line[0] == '%' || (line[0] == '!' && line[1] == '%')) 
      {
#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
	if (line[0] == '!' && 0 == sl_strcasecmp(&(line[2]), _("SCHEDULE_TWO")))
	  set_dirList(1);
	else if (0 == sl_strcasecmp(&(line[1]), _("SCHEDULE_TWO")))
	  set_dirList(2);
#else
	;
#endif
      }

    /* ------  no new section -------------- */


    else if (read_mode != SH_SECTION_NONE)
      { 
	if (0 != sh_readconfig_line (line))
	  {
	    sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALCONF,
			     (long) conf_line);
	  }
      }
  } /* while getline() */

 nopel:
	   
  if (0 != cond_depth)
    sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALDD,
		     _("config file"), 
		     (long) conf_line);

  sl_close (fd);

  sh_error_fixup();

  read_mode = SH_SECTION_NONE; /* reset b/o sighup reload */

  SH_FREE(line_in);
  SL_RETURN( 0, _("sh_readconf_read"));
}
Beispiel #28
0
static void sh_utmp_check_internal (int mode)
{
  struct stat   buf;
  int           error;
  struct SH_UTMP_S * ut;
  unsigned long this_read;
  int           val_retry;

  SL_ENTER(_("sh_utmp_check_internal"));

  /* error if no access
   */
  do {
    val_retry = /*@-unrecog@*/lstat ( mode_path[mode], &buf)/*@+unrecog@*/;
  } while (val_retry < 0 && errno == EINTR);

  if (0 != val_retry) 
    {
      error = errno;
      SH_MUTEX_LOCK(mutex_thread_nolog);
      sh_error_handle((-1), FIL__, __LINE__, error, MSG_E_ACCESS,
		      (long) sh.real.uid, mode_path[mode]);
      SH_MUTEX_UNLOCK(mutex_thread_nolog);
      SL_RET0(_("sh_utmp_check_internal"));
    }

  /* modification time
   */
  if (mode < 2)
    {
      if (/*@-usedef@*/buf.st_mtime <= lastmod/*@+usedef@*/)
	{ 
	  SL_RET0(_("sh_utmp_check_internal"));
	}
      else
	lastmod = buf.st_mtime;
    }

  /* file size
   */
  if (/*@-usedef@*/buf.st_size < lastsize/*@+usedef@*/ && mode < 2) 
    { 
      SH_MUTEX_LOCK(mutex_thread_nolog);
      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_UT_ROT,
		      mode_path[mode]);
      SH_MUTEX_UNLOCK(mutex_thread_nolog);
      lastread = 0;
#ifndef USE_SETUTENT
      sh_utmp_feed_forward = 0L;
#endif
    }

  if (mode < 2)
    lastsize = buf.st_size;

  if (buf.st_size == 0) 
    SL_RET0(_("sh_utmp_check_internal"));

  sh_utmp_utmpname(mode_path[mode]);
  sh_utmp_setutent();

  /* 
   * feed forward if initializing
   * we need to do this here
   */
  this_read = 0;

  if (mode < 2)
    {
      while (this_read < lastread) {
	(void) sh_utmp_getutent();
	++this_read;
      }
    }

  /* start reading
   */
  this_read = 0;
  while (1 == 1) {
    ut = sh_utmp_getutent();
    if (ut == NULL) 
      break;
    /* modified: ut_user --> ut_name */
    if (mode == 1 || (mode == 2 && ut->ut_name[0] != '\0'
#ifdef HAVE_UTTYPE
		      && ut->ut_type != DEAD_PROCESS
#endif
		      ))
      sh_utmp_addlogin (ut);
    ++this_read;
  }

  sh_utmp_endutent();

  if (mode < 2)
    {
      lastread += this_read;
#ifndef USE_SETUTENT
      sh_utmp_feed_forward += (long) (this_read * sizeof(struct SH_UTMP_S));
      lastread = 0;
#endif
    }

  SL_RET0(_("sh_utmp_check_internal"));
}
Beispiel #29
0
static int sh_readconfig_line (char * line)
{
  char * key;
  const char * value;
  char * tmp;
  int    i;
  int    good_opt = -1;

#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) 
  int    modnum, modkey;
#endif

  static const char  *dummy = N_("dummy");

  static const char  *closing[] = {
    N_("closecommand"),
    N_("closeaddress"),
    N_("logmonendgroup"),
    N_("logmonendhost"),
    NULL
  };

  static const char  *ident[] = {
    N_("severityreadonly"),
    N_("severitylogfiles"),
    N_("severitygrowinglogs"),
    N_("severityignorenone"),
    N_("severityignoreall"),
    N_("severityattributes"),
    N_("severitydirs"),
    N_("severityfiles"),
    N_("severitynames"),
    N_("severityuser0"),
    N_("severityuser1"),
    N_("severityuser2"),
    N_("severityuser3"),
    N_("severityuser4"),
    N_("severityprelink"),
    NULL
  };

  static int      identnum[] = { 
    SH_ERR_T_RO,    
    SH_ERR_T_LOGS,  
    SH_ERR_T_GLOG,  
    SH_ERR_T_NOIG,  
    SH_ERR_T_ALLIG, 
    SH_ERR_T_ATTR, 
    SH_ERR_T_DIR,   
    SH_ERR_T_FILE, 
    SH_ERR_T_NAME,       
    SH_ERR_T_USER0,       
    SH_ERR_T_USER1,       
    SH_ERR_T_USER2,       
    SH_ERR_T_USER3,       
    SH_ERR_T_USER4,       
    SH_ERR_T_PRELINK,       
  };
    
  SL_ENTER(_("sh_readconf_line"));

  /* convert to lowercase                              */

  tmp = line;
  while (*tmp != '=' && *tmp != '\0')
    {
      *tmp = tolower( (int) *tmp);
      ++tmp;
    }

  key = line;

  /* interpret line                                    */

  value = strchr(line, '=');

  if (value == NULL || (*value) == '\0')
    {
      if (key != NULL)
	{
	  i = 0;
	  while (closing[i] != NULL) 
	    {
	      if (sl_strncmp(key,_(closing[i]),sl_strlen(closing[i])-1) == 0)
		{
		  value = dummy;
		  goto ok_novalue;
		}
	      ++i;
	    }

	  TPT(( 0, FIL__, __LINE__, _("msg=<ConfigFile: not key=value: %s>\n"),
		line));
	}
      SL_RETURN(good_opt, _("sh_readconf_line"));
    }
  else
    ++value;

  /* skip leading whitespace
   */
  while ((*value) == ' ' || (*value) == '\t')
    ++value;

  if ((*value) == '\0')     /* no value                    */
    {
      if (key != NULL)
	{
	  TPT(( 0, FIL__, __LINE__, _("msg=<ConfigFile: not key=value: %s>\n"),
		line));
	}
      SL_RETURN(good_opt, _("sh_readconf_line"));
    }

 ok_novalue:

  if (!sl_is_suid())
    {
      TPT(( 0, FIL__, __LINE__, _("msg=<ConfigFile: %s>\n"), line));
    }

  /* Expand shell expressions. This return allocated memory which we must free.
   * If !defined(SH_EVAL_SHELL), this will reduce to a strdup.
   */
  value = sh_readconf_expand_value(value);

  if (!value || (*value) == '\0')
    {
      TPT(( 0, FIL__, __LINE__, _("msg=<ConfigFile: empty after shell expansion: %s>\n"),
	    line));
      SL_RETURN(good_opt, _("sh_readconf_line"));
    }

#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) 
  if      (read_mode == SH_SECTION_OTHER) 
    {
      for (modnum = 0; modList[modnum].name != NULL; ++modnum) 
	{
	  for (modkey = 0; modList[modnum].conf_table[modkey].the_opt != NULL; 
	       ++modkey) 
	    {
	      if (sl_strncmp (key,
			      _(modList[modnum].conf_table[modkey].the_opt),
			      sl_strlen(modList[modnum].conf_table[modkey].the_opt) ) == 0)
		{
		  good_opt = 0;
		  if (0 != modList[modnum].conf_table[modkey].func(value))
		    sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALS,
				     _(modList[modnum].conf_table[modkey].the_opt), value);
		  if (!sl_is_suid())
		    {
		      TPT(( 0, FIL__, __LINE__, 
			    _("msg=<line = %s, option = %s>\n"), line,
			    _(modList[modnum].conf_table[modkey].the_opt)));
		    }
		  goto outburst;
		}
	    }
	}
    }
  outburst:
#endif


  if (read_mode == SH_SECTION_THRESHOLD) 
    {
      i = 0;
      while (ident[i] != NULL) {
	if (sl_strncmp (key, _(ident[i]), sl_strlen(ident[i])) == 0)
	  {
	    good_opt = 0;
	    sh_error_set_iv (identnum[i], value);
	    break;
	  }
	++i;
      }
    }
  else  
    {
      i = 0;
      while (ext_table[i].optname != NULL)
	{
	  if ((ext_table[i].section == read_mode || 
	       ext_table[i].alt_section == read_mode) &&
	      sl_strncmp (key, _(ext_table[i].optname), 
			  sl_strlen(ext_table[i].optname)) == 0)
	    {
	      good_opt = 0;
	      if (0 != ext_table[i].func (value))
		sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALS,
				 _(ext_table[i].optname), value);
	      break;
	    }
	  ++i;
	}
    }

  SH_FREE((char*)value);

  SL_RETURN(good_opt, _("sh_readconf_line"));
}