Beispiel #1
0
int
main(int argc, char *argv[])
{
	int		 c;
	char		*interface;
	struct passwd	*pw;

	extern char version[];

	while ((c = getopt(argc, argv, "34adfv")) != -1)
		switch (c) {
		case '3':
			Not3Flag = 1;
			break;
		case '4':
			Not4Flag = 1;
			break;
		case 'a':
			AllFlag = 1;
			break;
		case 'd':
			DebugFlag++;
			break;
		case 'f':
			ForegroundFlag = 1;
			break;
		case 'v':
			VersionFlag = 1;
			break;
		default:
			Usage();
			/* NOTREACHED */
		}

	if (VersionFlag) {
		fprintf(stdout,"%s: version %s\n", __progname, version);
		exit(0);
	}

	interface = argv[optind++];

	if ((AllFlag && interface) || (!AllFlag && interface == 0) ||
	    (argc > optind) || (Not3Flag && Not4Flag))
		Usage();

	/* All error reporting is done through syslogs. */
	openlog(__progname, LOG_PID | LOG_CONS, LOG_DAEMON);
	tzset();

	if ((pw = getpwnam("_mopd")) == NULL)
		err(1, "getpwnam");

	if ((!ForegroundFlag) && DebugFlag)
		fprintf(stdout, "%s: not running as daemon, -d given.\n",
		    __progname);

	if ((!ForegroundFlag) && (!DebugFlag))
		if (daemon(0, 0) == -1)
			err(1, NULL);

	syslog(LOG_INFO, "%s %s started.", __progname, version);

	if (AllFlag)
		deviceInitAll();
	else
		deviceInitOne(interface);

	if (chroot(MOP_FILE_PATH) == -1) {
		syslog(LOG_CRIT, "chroot %s: %m", MOP_FILE_PATH);
		exit(1);
	}
	if (chdir("/") == -1) {
		syslog(LOG_CRIT, "chdir(\"/\"): %m");
		exit(1);
	}
	if (setgroups(1, &pw->pw_gid) ||
	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) {
		syslog(LOG_CRIT, "can't drop privileges: %m");
		exit(1);
	}
	endpwent();

	Loop();
	/* NOTREACHED */
}
Beispiel #2
0
int yaz_daemon(const char *progname,
               unsigned int flags,
               void (*work)(void *data), void *data,
               const char *pidfile, const char *uid)
{
#if HAVE_PWD_H
    int pid_fd = -1;

    /* open pidfile .. defer write until in child and after setuid */
    if (pidfile)
    {
        pid_fd = open(pidfile, O_CREAT|O_RDWR, 0666);
        if (pid_fd == -1)
        {
            yaz_log(YLOG_FATAL|YLOG_ERRNO, "open %s", pidfile);
            exit(1);
        }
    }

    if (flags & YAZ_DAEMON_DEBUG)
    {
        /* in debug mode.. it's quite simple */
        write_pidfile(pid_fd);
        work(data);
        exit(0);
    }

    /* running in production mode. */
    if (uid)
    {
        /* OK to use the non-thread version here */
        struct passwd *pw = getpwnam(uid);
        if (!pw)
        {
            yaz_log(YLOG_FATAL, "%s: Unknown user", uid);
            exit(1);
        }
        if (setuid(pw->pw_uid) < 0)
        {
            yaz_log(YLOG_FATAL|YLOG_ERRNO, "setuid");
            exit(1);
        }
    }

    if (flags & YAZ_DAEMON_FORK)
    {
        /* create pipe so that parent waits until child has created
           PID (or failed) */
        static int hand[2]; /* hand shake for child */
        if (pipe(hand) < 0)
        {
            yaz_log(YLOG_FATAL|YLOG_ERRNO, "pipe");
            return 1;
        }
        switch (fork())
        {
        case 0: 
            break;
        case -1:
            return 1;
        default:
            close(hand[1]);
            while(1)
            {
                char dummy[1];
                int res = read(hand[0], dummy, 1);
                if (res < 0 && errno != EINTR)
                {
                    yaz_log(YLOG_FATAL|YLOG_ERRNO, "read fork handshake");
                    break;
                }
                else if (res >= 0)
                    break;
            }
            close(hand[0]);
            _exit(0);
        }
        /* child */
        close(hand[0]);
        if (setsid() < 0)
            return 1;
        
        close(0);
        close(1);
        close(2);
        open("/dev/null", O_RDWR);
        if (dup(0) == -1)
            return 1;
        if (dup(0) == -1)
            return 1;
        close(hand[1]);
    }

    write_pidfile(pid_fd);

    if (flags & YAZ_DAEMON_KEEPALIVE)
    {
        keepalive(work, data);
    }
    else
    {
        work(data);
    }
    return 0;
#else
    work(data);
    return 0;
#endif
}
Beispiel #3
0
static void
godaemon (char *rundir, char *pidfile)
{
  char str[10];
  pid_t pid,sid,parent;
  int lfp = -1;

  // Check if parent process id is set 
  if (getppid() == 1){
    fprintf(stderr,"PPID exists, therefore we are already a daemon ");
    exit(EXIT_FAILURE);
  }

  /* Create the lock file as the current user */
  if ( pidfile && pidfile[0] ) {
    lfp = open(pidfile,O_RDWR|O_CREAT,0640);
    if ( lfp < 0 ) {
      log_err("unable to create pid file %s, code=%d (%s)",
              pidfile, errno, strerror(errno) );
      exit(EXIT_FAILURE);
    }
    /* Get and format PID */
    sprintf(str,"%d\n",getpid());
    int res = write(lfp, str, strlen(str));
    if(res != strlen(str)){
      log_err("Unable to write pid to file\n");
      exit(EXIT_FAILURE);
    }
  }

  /* create the directory for temp data if need be */
  mode_t process_mask = umask(0);
  char dirname[FILENAME_MAX_CHARS];
  sprintf(dirname,"%s/%s",rundir,"bgpmon");
  int result_code = mkdir(dirname, S_IRWXU | S_IRWXG | S_IRWXO);
  if(result_code && errno != EEXIST){
    log_err("Unable to create scratch dir %s\n",dirname);
    exit(EXIT_FAILURE);
  }
  result_code = umask(process_mask);
  if(result_code){
    log_err("Unable to set mask\n");
    exit(EXIT_FAILURE);
  }

  /* Drop user if there is one, and we were run as root */
  if ( getuid() == 0 || geteuid() == 0 ) {
    struct passwd *pw = getpwnam(RUN_AS_USER);
    if ( pw ) {
      result_code = chown(dirname,pw->pw_uid,pw->pw_gid);
      if(result_code){
        log_err("Unable to create scratch dir %s\n",dirname);
        exit(EXIT_FAILURE);
      }
      syslog( LOG_NOTICE, "setting user to " RUN_AS_USER );
      setuid( pw->pw_uid );
    }
  }
  /* Trap signals that we expect to recieve */
  signal(SIGCHLD,child_handler);
  signal(SIGUSR1,child_handler);
  signal(SIGALRM,child_handler);

  /* Fork*/
  pid = fork ();
  if (pid < 0) {
    log_err ("fork failed: %s", strerror(errno));
    exit(EXIT_FAILURE);
  }
  /* In case of this is parent process. */
  if (pid > 0){
     // Wait for confirmation from the child via SIGTERM or SIGCHLD, or
     // for two seconds to elapse (SIGALRM).  pause() should not return. 
     alarm(2);
     pause();
     exit(EXIT_FAILURE);
  }

  // we are now the parent process
  parent = getppid();

  /* Cancel certain signals */
  signal(SIGCHLD,SIG_DFL); /* A child process dies */
  signal(SIGTSTP,SIG_IGN); /* Various TTY signals */
  signal(SIGTTOU,SIG_IGN);
  signal(SIGTTIN,SIG_IGN);
  signal(SIGHUP, SIG_IGN); /* Ignore hangup signal */
  signal(SIGTERM,SIG_DFL); /* Die on SIGTERM */

  /* Change the file mode mask */
  umask(0);

  /* Become session leader and get pid. */
  sid = setsid();
  if (sid < 0)
  {
    log_err ("setsid failed: %s", strerror(errno));
    exit(EXIT_FAILURE);
  }

  /* Change the current working directory.  This prevents the current
     directory from being locked; hence not being able to remove it. */
  if ((chdir("/")) < 0) {
    syslog( LOG_ERR, "unable to change directory to %s, code %d (%s)",
           "/", errno, strerror(errno) );
    exit(EXIT_FAILURE);
  }

  /* Redirect standard files to /dev/null */
  FILE* res;
  res = freopen( "/dev/null", "r", stdin);
  if(res == NULL){
    log_err("unable to redirect stdin\n");
    exit(EXIT_FAILURE);
  }
  res = freopen( "/dev/null", "w", stdout);
  if(res == NULL){
    log_err("unable to redirect stdout\n");
    exit(EXIT_FAILURE);
  }
  res = freopen( "/dev/null", "w", stderr);
  if(res == NULL){
    log_err("unable to redirect stderr\n");
    exit(EXIT_FAILURE);
  }

  // let the parent know that all is good
  kill( parent, SIGUSR1 );
}
Beispiel #4
0
/*
 * Parse the argument to the -R or --owner flag.
 *
 * The format is one of the following:
 *   <username|uid>    - Override user but not group
 *   <username>:   - Override both, group is user's default group
 *   <uid>:    - Override user but not group
 *   <username|uid>:<groupname|gid> - Override both
 *   :<groupname|gid>  - Override group but not user
 *
 * Where uid/gid are decimal representations and groupname/username
 * are names to be looked up in system database.  Note that we try
 * to look up an argument as a name first, then try numeric parsing.
 *
 * A period can be used instead of the colon.
 *
 * Sets uid/gid return as appropriate, -1 indicates uid/gid not specified.
 * TODO: If the spec uses uname/gname, then return those to the caller
 * as well.  If the spec provides uid/gid, just return names as NULL.
 *
 * Returns NULL if no error, otherwise returns error string for display.
 *
 */
const char *
owner_parse(const char *spec, int *uid, int *gid)
{
	static char errbuff[128];
	const char *u, *ue, *g;

	*uid = -1;
	*gid = -1;

	if (spec[0] == '\0')
		return ("Invalid empty user/group spec");

	/*
	 * Split spec into [user][:.][group]
	 *  u -> first char of username, NULL if no username
	 *  ue -> first char after username (colon, period, or \0)
	 *  g -> first char of group name
	 */
	if (*spec == ':' || *spec == '.') {
		/* If spec starts with ':' or '.', then just group. */
		ue = u = NULL;
		g = spec + 1;
	} else {
		/* Otherwise, [user] or [user][:] or [user][:][group] */
		ue = u = spec;
		while (*ue != ':' && *ue != '.' && *ue != '\0')
			++ue;
		g = ue;
		if (*g != '\0') /* Skip : or . to find first char of group. */
			++g;
	}

	if (u != NULL) {
		/* Look up user: ue is first char after end of user. */
		char *user;
		struct passwd *pwent;

		user = (char *)malloc(ue - u + 1);
		if (user == NULL)
			return ("Couldn't allocate memory");
		memcpy(user, u, ue - u);
		user[ue - u] = '\0';
		if ((pwent = getpwnam(user)) != NULL) {
			*uid = pwent->pw_uid;
			if (*ue != '\0')
				*gid = pwent->pw_gid;
		} else {
			char *end;
			errno = 0;
			*uid = (int)strtoul(user, &end, 10);
			if (errno || *end != '\0') {
				snprintf(errbuff, sizeof(errbuff),
				    "Couldn't lookup user ``%s''", user);
				errbuff[sizeof(errbuff) - 1] = '\0';
				free(user);
				return (errbuff);
			}
		}
		free(user);
	}

	if (*g != '\0') {
		struct group *grp;
		if ((grp = getgrnam(g)) != NULL) {
			*gid = grp->gr_gid;
		} else {
			char *end;
			errno = 0;
			*gid = (int)strtoul(g, &end, 10);
			if (errno || *end != '\0') {
				snprintf(errbuff, sizeof(errbuff),
				    "Couldn't lookup group ``%s''", g);
				errbuff[sizeof(errbuff) - 1] = '\0';
				return (errbuff);
			}
		}
	}
	return (NULL);
}
/**
 * thunar_util_expand_filename:
 * @filename          : a local filename.
 * @working_directory : #GFile of the current working directory.
 * @error             : return location for errors or %NULL.
 *
 * Takes a user-typed @filename and expands a tilde at the
 * beginning of the @filename. It also resolves paths prefixed with
 * '.' using the current working directory.
 *
 * The caller is responsible to free the returned string using
 * g_free() when no longer needed.
 *
 * Return value: the expanded @filename or %NULL on error.
 **/
gchar *
thunar_util_expand_filename (const gchar  *filename,
                             GFile        *working_directory,
                             GError      **error)
{
  struct passwd *passwd;
  const gchar   *replacement;
  const gchar   *remainder;
  const gchar   *slash;
  gchar         *username;
  gchar         *pwd;
  gchar         *result = NULL;

  g_return_val_if_fail (filename != NULL, NULL);

  /* check if we have a valid (non-empty!) filename */
  if (G_UNLIKELY (*filename == '\0'))
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Invalid path"));
      return NULL;
    }

  /* check if we start with a '~' */
  if (*filename == '~')
    {
      /* examine the remainder of the filename */
      remainder = filename + 1;

      /* if we have only the slash, then we want the home dir */
      if (G_UNLIKELY (*remainder == '\0'))
        return g_strdup (xfce_get_homedir ());

      /* lookup the slash */
      for (slash = remainder; *slash != '\0' && *slash != G_DIR_SEPARATOR; ++slash);

      /* check if a username was given after the '~' */
      if (G_LIKELY (slash == remainder))
        {
          /* replace the tilde with the home dir */
          replacement = xfce_get_homedir ();
        }
      else
        {
          /* lookup the pwd entry for the username */
          username = g_strndup (remainder, slash - remainder);
          passwd = getpwnam (username);
          g_free (username);

          /* check if we have a valid entry */
          if (G_UNLIKELY (passwd == NULL))
            {
              username = g_strndup (remainder, slash - remainder);
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Unknown user \"%s\""), username);
              g_free (username);
              return NULL;
            }

          /* use the homedir of the specified user */
          replacement = passwd->pw_dir;
        }
    
      /* generate the filename */
      return g_build_filename (replacement, slash, NULL);
    }
  else if (*filename == '.')
    {
      /* examine the remainder of the filename */
      remainder = filename + 1;
      
      /* transform working directory into a filename string */
      if (G_LIKELY (working_directory != NULL))
        {
          pwd = g_file_get_path (working_directory);
    
          /* if we only have the slash then we want the working directory only */
          if (G_UNLIKELY (*remainder == '\0'))
            return pwd;

          /* concatenate working directory and remainder */
          result = g_build_filename (pwd, remainder, G_DIR_SEPARATOR_S, NULL);

          /* free the working directory string */
          g_free (pwd);
        }
      else
        result = g_strdup (filename);

      /* return the resulting path string */
      return result;
    }

  return g_strdup (filename);
}
Beispiel #6
0
static char *
ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
#if (NGX_WIN32)

    ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                       "\"user\" is not supported, ignored");

    return NGX_CONF_OK;

#else

    ngx_core_conf_t  *ccf = conf;

    char             *group;
    struct passwd    *pwd;
    struct group     *grp;
    ngx_str_t        *value;

    if (ccf->user != (uid_t) NGX_CONF_UNSET_UINT) {
        return "is duplicate";
    }

    if (geteuid() != 0) {
        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                           "the \"user\" directive makes sense only "
                           "if the master process runs "
                           "with super-user privileges, ignored");
        return NGX_CONF_OK;
    }

    value = (ngx_str_t *) cf->args->elts;

    ccf->username = (char *) value[1].data;

    ngx_set_errno(0);
    pwd = getpwnam((const char *) value[1].data);
    if (pwd == NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
                           "getpwnam(\"%s\") failed", value[1].data);
        return NGX_CONF_ERROR;
    }

    ccf->user = pwd->pw_uid;

    group = (char *) ((cf->args->nelts == 2) ? value[1].data : value[2].data);

    ngx_set_errno(0);
    grp = getgrnam(group);
    if (grp == NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
                           "getgrnam(\"%s\") failed", group);
        return NGX_CONF_ERROR;
    }

    ccf->group = grp->gr_gid;

    return NGX_CONF_OK;

#endif
}
Beispiel #7
0
/*
 * main - userdel command
 */
int main (int argc, char **argv)
{
	int errors = 0; /* Error in the removal of the home directory */

#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
	pam_handle_t *pamh = NULL;
	int retval;
#endif				/* USE_PAM */
#endif				/* ACCT_TOOLS_SETUID */

#ifdef WITH_AUDIT
	audit_help_open ();
#endif

	/*
	 * Get my name so that I can use it to report errors.
	 */
	Prog = Basename (argv[0]);
	(void) setlocale (LC_ALL, "");
	(void) bindtextdomain (PACKAGE, LOCALEDIR);
	(void) textdomain (PACKAGE);

	{
		/*
		 * Parse the command line options.
		 */
		int c;
		static struct option long_options[] = {
			{"force", no_argument, NULL, 'f'},
			{"help", no_argument, NULL, 'h'},
			{"remove", no_argument, NULL, 'r'},
			{NULL, 0, NULL, '\0'}
		};
		while ((c = getopt_long (argc, argv, "fhr",
		                         long_options, NULL)) != -1) {
			switch (c) {
			case 'f':	/* force remove even if not owned by user */
				fflg = true;
				break;
			case 'r':	/* remove home dir and mailbox */
				rflg = true;
				break;
			default:
				usage ();
			}
		}
	}

	if ((optind + 1) != argc) {
		usage ();
	}

	OPENLOG ("userdel");

#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
	{
		struct passwd *pampw;
		pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
		if (pampw == NULL) {
			fprintf (stderr,
			         _("%s: Cannot determine your user name.\n"),
			         Prog);
			exit (E_PW_UPDATE);
		}

		retval = pam_start ("userdel", pampw->pw_name, &conv, &pamh);
	}

	if (PAM_SUCCESS == retval) {
		retval = pam_authenticate (pamh, 0);
	}

	if (PAM_SUCCESS == retval) {
		retval = pam_acct_mgmt (pamh, 0);
	}

	if (NULL != pamh) {
		(void) pam_end (pamh, retval);
	}
	if (PAM_SUCCESS != retval) {
		fprintf (stderr, _("%s: PAM authentication failed\n"), Prog);
		exit (E_PW_UPDATE);
	}
#endif				/* USE_PAM */
#endif				/* ACCT_TOOLS_SETUID */

	is_shadow_pwd = spw_file_present ();
#ifdef SHADOWGRP
	is_shadow_grp = sgr_file_present ();
#endif

	/*
	 * Start with a quick check to see if the user exists.
	 */
	user_name = argv[argc - 1];
	{
		struct passwd *pwd;
		pwd = getpwnam (user_name); /* local, no need for xgetpwnam */
		if (NULL == pwd) {
			fprintf (stderr, _("%s: user '%s' does not exist\n"),
				 Prog, user_name);
#ifdef WITH_AUDIT
			audit_logger (AUDIT_DEL_USER, Prog,
			              "deleting user not found",
			              user_name, AUDIT_NO_ID,
			              SHADOW_AUDIT_FAILURE);
#endif
			exit (E_NOTFOUND);
		}
		user_id = pwd->pw_uid;
		user_home = xstrdup (pwd->pw_dir);
	}
#ifdef	USE_NIS

	/*
	 * Now make sure it isn't an NIS user.
	 */
	if (__ispwNIS ()) {
		char *nis_domain;
		char *nis_master;

		fprintf (stderr,
			 _("%s: user %s is a NIS user\n"), Prog, user_name);
		if (   !yp_get_default_domain (&nis_domain)
		    && !yp_master (nis_domain, "passwd.byname", &nis_master)) {
			fprintf (stderr,
				 _("%s: %s is the NIS master\n"),
				 Prog, nis_master);
		}
		exit (E_NOTFOUND);
	}
#endif
	/*
	 * Check to make certain the user isn't logged in.
	 * Note: This is a best effort basis. The user may log in between,
	 * a cron job may be started on her behalf, etc.
	 */
	if (user_busy (user_name, user_id) != 0) {
		fprintf (stderr,
		         _("%s: user %s is currently logged in\n"),
		         Prog, user_name);
		if (!fflg) {
#ifdef WITH_AUDIT
			audit_logger (AUDIT_DEL_USER, Prog,
			              "deleting user logged in",
			              user_name, AUDIT_NO_ID,
			              SHADOW_AUDIT_FAILURE);
#endif
			exit (E_USER_BUSY);
		}
	}

	/*
	 * Do the hard stuff - open the files, create the user entries,
	 * create the home directory, then close and update the files.
	 */
	open_files ();
	update_user ();
	update_groups ();

	if (rflg) {
		errors += remove_mailbox ();
	}
	if (rflg) {
		int home_owned = is_owner (user_id, user_home);
		if (-1 == home_owned) {
			fprintf (stderr,
			         _("%s: %s home directory (%s) not found\n"),
			         Prog, user_name, user_home);
			rflg = 0;
		} else if ((0 == home_owned) && !fflg) {
			fprintf (stderr,
			         _("%s: %s not owned by %s, not removing\n"),
			         Prog, user_home, user_name);
			rflg = 0;
			errors++;
			/* continue */
		}
	}

#ifdef EXTRA_CHECK_HOME_DIR
	/* This may be slow, the above should be good enough. */
	if (rflg && !fflg) {
		struct passwd *pwd;
		/*
		 * For safety, refuse to remove the home directory if it
		 * would result in removing some other user's home
		 * directory. Still not perfect so be careful, but should
		 * prevent accidents if someone has /home or / as home
		 * directory...  --marekm
		 */
		setpwent ();
		while ((pwd = getpwent ())) {
			if (strcmp (pwd->pw_name, user_name) == 0) {
				continue;
			}
			if (path_prefix (user_home, pwd->pw_dir)) {
				fprintf (stderr,
					 _
					 ("%s: not removing directory %s (would remove home of user %s)\n"),
					 Prog, user_home, pwd->pw_name);
				rflg = false;
				errors++;
				/* continue */
				break;
			}
		}
		endpwent ();
	}
#endif

	if (rflg) {
		if (remove_tree (user_home) != 0) {
			fprintf (stderr,
				 _("%s: error removing directory %s\n"),
				 Prog, user_home);
			errors++;
			/* continue */
		}
#ifdef WITH_AUDIT
		else
		{
			audit_logger (AUDIT_DEL_USER, Prog,
			              "deleting home directory",
			              user_name, (unsigned int) user_id,
			              SHADOW_AUDIT_SUCCESS);
		}
#endif
	}
#ifdef WITH_AUDIT
	if (0 != errors) {
		audit_logger (AUDIT_DEL_USER, Prog,
		              "deleting home directory",
		              user_name, AUDIT_NO_ID,
		              SHADOW_AUDIT_FAILURE);
	}
#endif

#ifdef WITH_SELINUX
	if (is_selinux_enabled () > 0) {
		const char *args[5];
		args[0] = "/usr/sbin/semanage";
		args[1] = "login";
		args[2] = "-d";
		args[3] = user_name;
		args[4] = NULL;
		safe_system (args[0], args, NULL, 1);
	}
#endif

	/*
	 * Cancel any crontabs or at jobs. Have to do this before we remove
	 * the entry from /etc/passwd.
	 */
	user_cancel (user_name);
	close_files ();

	nscd_flush_cache ("passwd");
	nscd_flush_cache ("group");

	return ((0 != errors) ? E_HOMEDIR : E_SUCCESS);
}
int main(int argc, char **argv)
{
	struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
	bool rm_xdp_prog = false;
	struct passwd *pwd = NULL;
	__u32 xdp_flags = 0;
	char filename[256];
	int longindex = 0;
	uid_t owner = -1; /* -1 result in no-change of owner */
	gid_t group = -1;
	int opt;

	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);

	/* Parse commands line args */
	while ((opt = getopt_long(argc, argv, "hSrqd:",
				  long_options, &longindex)) != -1) {
		switch (opt) {
		case 'q':
			verbose = 0;
			break;
		case 'r':
			rm_xdp_prog = true;
			break;
		case 'o': /* extract owner and group from username */
			if (!(pwd = getpwnam(optarg))) {
				fprintf(stderr,
					"ERR: unknown owner:%s err(%d):%s\n",
					optarg, errno, strerror(errno));
				goto error;
			}
			owner = pwd->pw_uid;
			group = pwd->pw_gid;
			break;
		case 'd':
			if (strlen(optarg) >= IF_NAMESIZE) {
				fprintf(stderr, "ERR: --dev name too long\n");
				goto error;
			}
			ifname = (char *)&ifname_buf;
			strncpy(ifname, optarg, IF_NAMESIZE);
			ifindex = if_nametoindex(ifname);
			if (ifindex == 0) {
				fprintf(stderr,
					"ERR: --dev name unknown err(%d):%s\n",
					errno, strerror(errno));
				goto error;
			}
			break;
		case 'S':
			xdp_flags |= XDP_FLAGS_SKB_MODE;
			break;
		case 'h':
		error:
		default:
			usage(argv);
			return EXIT_FAIL_OPTION;
		}
	}
	/* Required options */
	if (ifindex == -1) {
		printf("ERR: required option --dev missing");
		usage(argv);
		return EXIT_FAIL_OPTION;
	}
	if (rm_xdp_prog) {
		remove_xdp_program(ifindex, ifname, xdp_flags);
		return EXIT_OK;
	}
	if (verbose) {
		printf("Documentation:\n%s\n", __doc__);
		printf(" - Attached to device:%s (ifindex:%d)\n",
		       ifname, ifindex);
	}

	/* Increase resource limits */
	if (setrlimit(RLIMIT_MEMLOCK, &r)) {
		perror("setrlimit(RLIMIT_MEMLOCK, RLIM_INFINITY)");
		return 1;
	}

	/* Load bpf-ELF file with callback for loading maps via filesystem */
	if (load_bpf_file_fixup_map(filename, pre_load_maps_via_fs)) {
		fprintf(stderr, "ERR in load_bpf_file(): %s", bpf_log_buf);
		return EXIT_FAIL;
	}

	if (!prog_fd[0]) {
		printf("load_bpf_file: %s\n", strerror(errno));
		return 1;
	}

	/* Export maps that were not loaded from filesystem */
	export_maps();

	if (owner >= 0)
		chown_maps(owner, group);

	if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
		printf("link set xdp fd failed\n");
		return EXIT_FAIL_XDP;
	}

	/* Add something to the map as a test */
	blacklist_modify(map_fd[0], "198.18.50.3", ACTION_ADD);
	blacklist_port_modify(map_fd[2], map_fd[4], 80, ACTION_ADD, IPPROTO_UDP);

	return EXIT_OK;
}
Beispiel #9
0
/*===========================================================================*
 *		            sef_cb_init_fresh                                *
 *===========================================================================*/
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the inet server. */
	int r;
	int timerand, fd;
	u8_t randbits[32];
	struct timeval tv;
	struct passwd *pw;

#if DEBUG
	printf("Starting inet...\n");
	printf("%s\n", version);
#endif

#if HZ_DYNAMIC
	system_hz = sys_hz();
#endif

	/* Read configuration. */
	nw_conf();

	/* Get a random number */
	timerand= 1;
	fd= open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK);
	if (fd != -1)
	{
		r= read(fd, randbits, sizeof(randbits));
		if (r == sizeof(randbits))
			timerand= 0;
		else
		{
			printf("inet: unable to read random data from %s: %s\n",
				RANDOM_DEV_NAME, r == -1 ? strerror(errno) :
				r == 0 ? "EOF" : "not enough data");
		}
		close(fd);
	}
	else
	{
		printf("inet: unable to open random device %s: %s\n",
			RANDOM_DEV_NAME, strerror(errno));
	}
	if (timerand)
	{
		printf("inet: using current time for random-number seed\n");
		r= gettimeofday(&tv, NULL);
		if (r == -1)
		{
			printf("sysutime failed: %s\n", strerror(errno));
			exit(1);
		}
		memcpy(randbits, &tv, sizeof(tv));
	}
	init_rand256(randbits);

	/* Our new identity as a server. */
	this_proc= info->endpoint;

#ifdef BUF_CONSISTENCY_CHECK
	inet_buf_debug= (getenv("inetbufdebug") && 
		(strcmp(getenv("inetbufdebug"), "on") == 0));
	inet_buf_debug= 100;
	if (inet_buf_debug)
	{
		ip_warning(( "buffer consistency check enabled" ));
	}
#endif

	if (getenv("killerinet"))
	{
		ip_warning(( "killer inet active" ));
		killer_inet= 1;
	}

	nw_init();

	/* Subscribe to driver events for network drivers. */
	r = ds_subscribe("drv\\.net\\..*", DSF_INITIAL | DSF_OVERWRITE);
	if(r != OK) {
		ip_panic(("inet: can't subscribe to driver events"));
	}

	/* Drop root privileges */
	if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) {
		printf("inet: unable to retrieve uid of SERVICE_LOGIN, "
			"still running as root");
	} else if (setuid(pw->pw_uid) != 0) {
		ip_panic(("inet: unable to drop privileges"));
	}

	/* Announce we are up. INET announces its presence to VFS just like
	 * any other character driver.
	 */
	chardriver_announce();

	return(OK);
}
Beispiel #10
0
int
packing_append_file_attr(struct packing *pack, const char *filepath,
    const char *newpath, const char *uname, const char *gname, mode_t perm)
{
	int fd;
	char *map;
	int retcode = EPKG_OK;
	int ret;
	struct stat st;
	struct archive_entry *entry, *sparse_entry;
	bool unset_timestamp;

	entry = archive_entry_new();
	archive_entry_copy_sourcepath(entry, filepath);

	pkg_debug(2, "Packing file '%s'", filepath);

	if (lstat(filepath, &st) != 0) {
		pkg_emit_errno("lstat", filepath);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	ret = archive_read_disk_entry_from_file(pack->aread, entry, -1,
			&st);
	if (ret != ARCHIVE_OK) {
		pkg_emit_error("%s: %s", filepath,
				archive_error_string(pack->aread));
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (newpath != NULL)
		archive_entry_set_pathname(entry, newpath);

	if (archive_entry_filetype(entry) != AE_IFREG) {
		archive_entry_set_size(entry, 0);
	}

	if (uname != NULL && uname[0] != '\0') {
		if (pack->pass) {
			struct passwd* pw = getpwnam(uname);
			if (pw == NULL) {
				pkg_emit_error("Unknown user: '******'", uname);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
			archive_entry_set_uid(entry, pw->pw_uid);
		}
		archive_entry_set_uname(entry, uname);
	}

	if (gname != NULL && gname[0] != '\0') {
		if (pack->pass) {
			struct group *gr = (getgrnam(gname));
			if (gr == NULL) {
				pkg_emit_error("Unknown group: '%s'", gname);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
			archive_entry_set_gid(entry, gr->gr_gid);
		}
		archive_entry_set_gname(entry, gname);
	}

	if (perm != 0)
		archive_entry_set_perm(entry, perm);

	pkg_config_bool(PKG_CONFIG_UNSET_TIMESTAMP, &unset_timestamp);

	if (unset_timestamp) {
		archive_entry_unset_atime(entry);
		archive_entry_unset_ctime(entry);
		archive_entry_unset_mtime(entry);
		archive_entry_unset_birthtime(entry);
	}

	archive_entry_linkify(pack->resolver, &entry, &sparse_entry);

	if (sparse_entry != NULL && entry == NULL)
		entry = sparse_entry;

	archive_write_header(pack->awrite, entry);

	if (archive_entry_size(entry) > 0) {
		if ((fd = open(filepath, O_RDONLY)) < 0) {
			pkg_emit_errno("open", filepath);
			retcode = EPKG_FATAL;
			goto cleanup;
		}
		if (st.st_size > SSIZE_MAX) {
			char buf[BUFSIZ];
			int len;

			while ((len = read(fd, buf, sizeof(buf))) > 0)
				if (archive_write_data(pack->awrite, buf, len) == -1) {
					pkg_emit_errno("archive_write_data", "archive write error");
					retcode = EPKG_FATAL;
					break;
				}

			if (len == -1) {
				pkg_emit_errno("read", "file read error");
				retcode = EPKG_FATAL;
			}
			close(fd);
		}
		else {
			if ((map = mmap(NULL, st.st_size, PROT_READ,
					MAP_SHARED, fd, 0)) != MAP_FAILED) {
				close(fd);
				if (archive_write_data(pack->awrite, map, st.st_size) == -1) {
					pkg_emit_errno("archive_write_data", "archive write error");
					retcode = EPKG_FATAL;
				}
				munmap(map, st.st_size);
			}
			else {
				close(fd);
				pkg_emit_errno("open", filepath);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}
	}

	cleanup:
	archive_entry_free(entry);
	return (retcode);
}
Beispiel #11
0
/** daemonize, drop user priviliges and chroot if needed */
static void
perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
	const char** cfgfile)
{
#ifdef HAVE_KILL
	int pidinchroot;
#endif
#ifdef HAVE_GETPWNAM
	struct passwd *pwd = NULL;

	if(cfg->username && cfg->username[0]) {
		if((pwd = getpwnam(cfg->username)) == NULL)
			fatal_exit("user '%s' does not exist.", cfg->username);
		/* endpwent below, in case we need pwd for setusercontext */
	}
#endif
#ifdef UB_ON_WINDOWS
	w_config_adjust_directory(cfg);
#endif

	/* init syslog (as root) if needed, before daemonize, otherwise
	 * a fork error could not be printed since daemonize closed stderr.*/
	if(cfg->use_syslog) {
		log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
	}
	/* if using a logfile, we cannot open it because the logfile would
	 * be created with the wrong permissions, we cannot chown it because
	 * we cannot chown system logfiles, so we do not open at all.
	 * So, using a logfile, the user does not see errors unless -d is
	 * given to unbound on the commandline. */

	/* read ssl keys while superuser and outside chroot */
#ifdef HAVE_SSL
	if(!(daemon->rc = daemon_remote_create(cfg)))
		fatal_exit("could not set up remote-control");
	if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
		if(!(daemon->listen_sslctx = listen_sslctx_create(
			cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
			fatal_exit("could not set up listen SSL_CTX");
	}
	if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, NULL)))
		fatal_exit("could not set up connect SSL_CTX");
#endif

#ifdef HAVE_KILL
	/* true if pidfile is inside chrootdir, or nochroot */
	pidinchroot = !(cfg->chrootdir && cfg->chrootdir[0]) ||
				(cfg->chrootdir && cfg->chrootdir[0] &&
				strncmp(cfg->pidfile, cfg->chrootdir,
				strlen(cfg->chrootdir))==0);

	/* check old pid file before forking */
	if(cfg->pidfile && cfg->pidfile[0]) {
		/* calculate position of pidfile */
		if(cfg->pidfile[0] == '/')
			daemon->pidfile = strdup(cfg->pidfile);
		else	daemon->pidfile = fname_after_chroot(cfg->pidfile, 
				cfg, 1);
		if(!daemon->pidfile)
			fatal_exit("pidfile alloc: out of memory");
		checkoldpid(daemon->pidfile, pidinchroot);
	}
#endif

	/* daemonize because pid is needed by the writepid func */
	if(!debug_mode && cfg->do_daemonize) {
		detach();
	}

	/* write new pidfile (while still root, so can be outside chroot) */
#ifdef HAVE_KILL
	if(cfg->pidfile && cfg->pidfile[0]) {
		writepid(daemon->pidfile, getpid());
		if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
			pidinchroot) {
#  ifdef HAVE_CHOWN
			if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
				verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
					(unsigned)cfg_uid, (unsigned)cfg_gid,
					daemon->pidfile, strerror(errno));
			}
#  endif /* HAVE_CHOWN */
		}
	}
#else
	(void)daemon;
#endif /* HAVE_KILL */

	/* Set user context */
#ifdef HAVE_GETPWNAM
	if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1) {
#ifdef HAVE_SETUSERCONTEXT
		/* setusercontext does initgroups, setuid, setgid, and
		 * also resource limits from login config, but we
		 * still call setresuid, setresgid to be sure to set all uid*/
		if(setusercontext(NULL, pwd, cfg_uid, (unsigned)
			LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
			log_warn("unable to setusercontext %s: %s",
				cfg->username, strerror(errno));
#endif /* HAVE_SETUSERCONTEXT */
	}
#endif /* HAVE_GETPWNAM */

	/* box into the chroot */
#ifdef HAVE_CHROOT
	if(cfg->chrootdir && cfg->chrootdir[0]) {
		if(chdir(cfg->chrootdir)) {
			fatal_exit("unable to chdir to chroot %s: %s",
				cfg->chrootdir, strerror(errno));
		}
		verbose(VERB_QUERY, "chdir to %s", cfg->chrootdir);
		if(chroot(cfg->chrootdir))
			fatal_exit("unable to chroot to %s: %s", 
				cfg->chrootdir, strerror(errno));
		if(chdir("/"))
			fatal_exit("unable to chdir to / in chroot %s: %s",
				cfg->chrootdir, strerror(errno));
		verbose(VERB_QUERY, "chroot to %s", cfg->chrootdir);
		if(strncmp(*cfgfile, cfg->chrootdir, 
			strlen(cfg->chrootdir)) == 0) 
			(*cfgfile) += strlen(cfg->chrootdir);

		/* adjust stored pidfile for chroot */
		if(daemon->pidfile && daemon->pidfile[0] && 
			strncmp(daemon->pidfile, cfg->chrootdir,
			strlen(cfg->chrootdir))==0) {
			char* old = daemon->pidfile;
			daemon->pidfile = strdup(old+strlen(cfg->chrootdir));
			free(old);
			if(!daemon->pidfile)
				log_err("out of memory in pidfile adjust");
		}
		daemon->chroot = strdup(cfg->chrootdir);
		if(!daemon->chroot)
			log_err("out of memory in daemon chroot dir storage");
	}
#else
	(void)cfgfile;
#endif
	/* change to working directory inside chroot */
	if(cfg->directory && cfg->directory[0]) {
		char* dir = cfg->directory;
		if(cfg->chrootdir && cfg->chrootdir[0] &&
			strncmp(dir, cfg->chrootdir, 
			strlen(cfg->chrootdir)) == 0)
			dir += strlen(cfg->chrootdir);
		if(dir[0]) {
			if(chdir(dir)) {
				fatal_exit("Could not chdir to %s: %s",
					dir, strerror(errno));
			}
			verbose(VERB_QUERY, "chdir to %s", dir);
		}
	}

	/* drop permissions after chroot, getpwnam, pidfile, syslog done*/
#ifdef HAVE_GETPWNAM
	if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1) {
#  ifdef HAVE_INITGROUPS
		if(initgroups(cfg->username, cfg_gid) != 0)
			log_warn("unable to initgroups %s: %s",
				cfg->username, strerror(errno));
#  endif /* HAVE_INITGROUPS */
#  ifdef HAVE_ENDPWENT
		endpwent();
#  endif

#ifdef HAVE_SETRESGID
		if(setresgid(cfg_gid,cfg_gid,cfg_gid) != 0)
#elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID)
		if(setregid(cfg_gid,cfg_gid) != 0)
#else /* use setgid */
		if(setgid(cfg_gid) != 0)
#endif /* HAVE_SETRESGID */
			fatal_exit("unable to set group id of %s: %s", 
				cfg->username, strerror(errno));
#ifdef HAVE_SETRESUID
		if(setresuid(cfg_uid,cfg_uid,cfg_uid) != 0)
#elif defined(HAVE_SETREUID) && !defined(DARWIN_BROKEN_SETREUID)
		if(setreuid(cfg_uid,cfg_uid) != 0)
#else /* use setuid */
		if(setuid(cfg_uid) != 0)
#endif /* HAVE_SETRESUID */
			fatal_exit("unable to set user id of %s: %s", 
				cfg->username, strerror(errno));
		verbose(VERB_QUERY, "drop user privileges, run as %s", 
			cfg->username);
	}
#endif /* HAVE_GETPWNAM */
	/* file logging inited after chroot,chdir,setuid is done so that 
	 * it would succeed on SIGHUP as well */
	if(!cfg->use_syslog)
		log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
}
Beispiel #12
0
/*
 * expand tilde from the passwd file.
 */
static const Char *
globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
{
	struct passwd *pwd;
	char *h;
	const Char *p;
	Char *b, *eb;

	if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
		return pattern;

	/* Copy up to the end of the string or / */
	eb = &patbuf[patbuf_len - 1];
	for (p = pattern + 1, h = (char *) patbuf;
	    h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
		;

	*h = EOS;

#if 0
	if (h == (char *)eb)
		return what;
#endif

	if (((char *) patbuf)[0] == EOS) {
		/*
		 * handle a plain ~ or ~/ by expanding $HOME
		 * first and then trying the password file
		 */
#if 0
		if (issetugid() != 0 || (h = getenv("HOME")) == NULL) {
#endif
		if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) {
			if ((pwd = getpwuid(getuid())) == NULL)
				return pattern;
			else
				h = pwd->pw_dir;
		}
	} else {
		/*
		 * Expand a ~user
		 */
		if ((pwd = getpwnam((char*) patbuf)) == NULL)
			return pattern;
		else
			h = pwd->pw_dir;
	}

	/* Copy the home directory */
	for (b = patbuf; b < eb && *h; *b++ = *h++)
		;

	/* Append the rest of the pattern */
	while (b < eb && (*b++ = *p++) != EOS)
		;
	*b = EOS;

	return patbuf;
}

static int
g_strncmp(const Char *s1, const char *s2, size_t n)
{
	int rv = 0;

	while (n--) {
		rv = *(Char *)s1 - *(const unsigned char *)s2++;
		if (rv)
			break;
		if (*s1++ == '\0')
			break;
	}
	return rv;
}
void Pass(char *param)
{
    struct passwd *pw;
    struct spwd *spw;
    char *passwd, salt[13];

    if (!input_user) {
        outs("%d Login with USER first.", ACK_503);
        return;
    }

    /* judge and chdir to its home directory */
    if (!anonymous_login) {
        if (system_uid != 0) {
            outs("%d Login incorrect.", ACK_530);
            input_user = 0;
            return;
        }

        if ((pw = getpwnam(username)) == NULL) {
            outs("%d Login incorrect.", ACK_530);
            input_user = 0;
            return;
        }

        passwd = pw->pw_passwd;
        if (passwd == NULL || strcmp(passwd, "x") == 0) {
            spw = getspnam(username);
            if (spw == NULL || (passwd = spw->sp_pwdp) == NULL) {
                outs("%d Login incorrect.", ACK_530);
                input_user = 0;
                return;
            }
        }
        strncpy(salt, passwd, 12);
        if (strcmp(passwd, crypto((const char *)param, (const char *)salt)) != 0) {
            outs("%d Login incorrect.", ACK_530);
            input_user = 0;
            return;
        }
        strcpy(path, "");
        setuid(pw->pw_uid);
        if (pw->pw_dir)
            strncpy(path, pw->pw_dir, PATH_MAX);
        else
            strcpy(path, "/");
        outs("%d User %s logged in.", ACK_230, username);
        chdir(path);
        getcwd(path, PATH_MAX);
        user_valid = 1;

    } else {
        if ((pw = getpwuid(system_uid)) == NULL) {
            outs("%d Login incorrect.", ACK_530);
            input_user = 0;
            return;
        }
        if (pw->pw_dir)
            strncpy(basedir, pw->pw_dir, PATH_MAX);
        else
            strcpy(basedir, "");

        strcpy(path, "/");
        chdir(basedir);
        getcwd(basedir, PATH_MAX);
        user_valid = 1;
        outs("%d Anonymous access granted, restrictions apply.", ACK_230);
    }
    user_valid = 1;
    outs("%d Anonymous access granted, restrictions apply.", ACK_230);
}
Beispiel #14
0
int
main (int argc, char *argv[])
{
  const char *globfile[] = { "one", "two", "three", NULL };
  char tmpdir[32];
  struct passwd *pw;
  const char *cwd;
  int test;
  int fail = 0;
  int i;

  if (argc > 1)
    {
      command_line_test (argv[1]);
      return 0;
    }

  cwd = getcwd (NULL, 0);

  /* Set up arena for pathname expansion */
  tmpnam (tmpdir);
  if (mkdir (tmpdir, S_IRWXU) || chdir (tmpdir))
    return -1;
  else
    {
      int fd;

      for (i = 0; globfile[i]; ++i)
	if ((fd = creat (globfile[i], S_IRUSR | S_IWUSR)) == -1
	    || close (fd))
	  return -1;
    }

  for (test = 0; test_case[test].retval != -1; test++)
    if (testit (&test_case[test]))
      ++fail;

  pw = getpwnam ("root");
  if (pw != NULL)
    {
      struct test_case_struct ts;

      ts.retval = 0;
      ts.env = NULL;
      ts.words = "~root";
      ts.flags = 0;
      ts.wordc = 1;
      ts.wordv[0] = pw->pw_dir;
      ts.ifs = IFS;

      if (testit (&ts))
	++fail;
    }

  puts ("tests completed, now cleaning up");

  /* Clean up */
  for (i = 0; globfile[i]; ++i)
    remove (globfile[i]);

  if (cwd == NULL)
    cwd = "..";

  chdir (cwd);
  rmdir (tmpdir);

  printf ("tests failed: %d\n", fail);

  return fail != 0;
}
main(int argc, char *argv[])
#endif
{
    char            options[128] = "aAc:CdD::fhHI:l:L:m:M:n:p:P:qrsS:UvV-:Y:";
    int             arg, i, ret;
    int             dont_fork = 0, do_help = 0;
    int             log_set = 0;
    int             uid = 0, gid = 0;
    int             agent_mode = -1;
    char           *cptr, **argvptr;
    char           *pid_file = NULL;
    char            option_compatability[] = "-Le";
#if HAVE_GETPID
    int fd;
    FILE           *PID;
#endif

#ifndef WIN32
    /*
     * close all non-standard file descriptors we may have
     * inherited from the shell.
     */
    for (i = getdtablesize() - 1; i > 2; --i) {
        (void) close(i);
    }
#endif /* #WIN32 */
    
    /*
     * register signals ASAP to prevent default action (usually core)
     * for signals during startup...
     */
#ifdef SIGTERM
    DEBUGMSGTL(("signal", "registering SIGTERM signal handler\n"));
    signal(SIGTERM, SnmpdShutDown);
#endif
#ifdef SIGINT
    DEBUGMSGTL(("signal", "registering SIGINT signal handler\n"));
    signal(SIGINT, SnmpdShutDown);
#endif
#ifdef SIGHUP
    signal(SIGHUP, SIG_IGN);   /* do not terminate on early SIGHUP */
#endif
#ifdef SIGUSR1
    DEBUGMSGTL(("signal", "registering SIGUSR1 signal handler\n"));
    signal(SIGUSR1, SnmpdDump);
#endif
#ifdef SIGPIPE
    DEBUGMSGTL(("signal", "registering SIGPIPE signal handler\n"));
    signal(SIGPIPE, SIG_IGN);   /* 'Inline' failure of wayward readers */
#endif
#ifdef SIGXFSZ
    signal(SIGXFSZ, SnmpdCatchRandomSignal);
#endif

#ifdef NETSNMP_NO_ROOT_ACCESS
    /*
     * Default to no.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
#endif
    /*
     * Default to NOT running an AgentX master.  
     */
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			   NETSNMP_DS_AGENT_AGENTX_MASTER, 0);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_TIMEOUT, -1);
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_AGENTX_RETRIES, -1);

    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                       NETSNMP_DS_AGENT_CACHE_TIMEOUT, 5);
    /*
     * Add some options if they are available.  
     */
#if HAVE_UNISTD_H
    strcat(options, "g:u:");
#endif
#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
    strcat(options, "x:");
#endif
#ifdef USING_AGENTX_SUBAGENT_MODULE
    strcat(options, "X");
#endif

    /*
     * This is incredibly ugly, but it's probably the simplest way
     *  to handle the old '-L' option as well as the new '-Lx' style
     */
    for (i=0; i<argc; i++) {
        if (!strcmp(argv[i], "-L"))
            argv[i] = option_compatability;            
    }

#ifdef WIN32
    snmp_log_syslogname(app_name_long);
#else
    snmp_log_syslogname(app_name);
#endif
    netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                          NETSNMP_DS_LIB_APPTYPE, app_name);

    /*
     * Now process options normally.  
     */
    while ((arg = getopt(argc, argv, options)) != EOF) {
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                usage(argv[0]);
            }
            if (strcasecmp(optarg, "version") == 0) {
                version();
            }

            handle_long_opt(optarg);
            break;

        case 'a':
            log_addresses++;
            break;

        case 'A':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                                   NETSNMP_DS_LIB_APPEND_LOGFILES, 1);
            break;

        case 'c':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
				      NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
            } else {
                usage(argv[0]);
            }
            break;

        case 'C':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
				   NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1);
            break;

        case 'd':
            snmp_set_dump_packet(++snmp_dump_packet);
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;

        case 'f':
            dont_fork = 1;
            break;

#if HAVE_UNISTD_H
        case 'g':
            if (optarg != NULL) {
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_GROUPID, atoi(optarg));
            } else {
                usage(argv[0]);
            }
            break;
#endif

        case 'h':
            usage(argv[0]);
            break;

        case 'H':
            do_help = 1;
            break;

        case 'I':
            if (optarg != NULL) {
                add_to_init_list(optarg);
            } else {
                usage(argv[0]);
            }
            break;

        case 'l':
            printf("Warning: -l option is deprecated, use -Lf <file> instead\n");
            if (optarg != NULL) {
                if (strlen(optarg) > PATH_MAX) {
                    fprintf(stderr,
                            "%s: logfile path too long (limit %d chars)\n",
                            argv[0], PATH_MAX);
                    exit(1);
                }
                snmp_enable_filelog(optarg,
                                    netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                                           NETSNMP_DS_LIB_APPEND_LOGFILES));
                log_set = 1;
            } else {
                usage(argv[0]);
            }
            break;

        case 'L':
	    if  (snmp_log_options( optarg, argc, argv ) < 0 ) {
                usage(argv[0]);
            }
            log_set = 1;
            break;

        case 'm':
            if (optarg != NULL) {
                setenv("MIBS", optarg, 1);
            } else {
                usage(argv[0]);
            }
            break;

        case 'M':
            if (optarg != NULL) {
                setenv("MIBDIRS", optarg, 1);
            } else {
                usage(argv[0]);
            }
            break;

        case 'n':
            if (optarg != NULL) {
                app_name = optarg;
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                                      NETSNMP_DS_LIB_APPTYPE, app_name);
            } else {
                usage(argv[0]);
            }
            break;

        case 'P':
            printf("Warning: -P option is deprecated, use -p instead\n");
        case 'p':
            if (optarg != NULL) {
                pid_file = optarg;
            } else {
                usage(argv[0]);
            }
            break;

        case 'q':
            snmp_set_quick_print(1);
            break;

        case 'r':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
            break;

        case 's':
            printf("Warning: -s option is deprecated, use -Lsd instead\n");
            snmp_enable_syslog();
            log_set = 1;
            break;

        case 'S':
            printf("Warning: -S option is deprecated, use -Ls <facility> instead\n");
            if (optarg != NULL) {
                switch (*optarg) {
                case 'd':
                case 'D':
                    Facility = LOG_DAEMON;
                    break;
                case 'i':
                case 'I':
                    Facility = LOG_INFO;
                    break;
                case '0':
                    Facility = LOG_LOCAL0;
                    break;
                case '1':
                    Facility = LOG_LOCAL1;
                    break;
                case '2':
                    Facility = LOG_LOCAL2;
                    break;
                case '3':
                    Facility = LOG_LOCAL3;
                    break;
                case '4':
                    Facility = LOG_LOCAL4;
                    break;
                case '5':
                    Facility = LOG_LOCAL5;
                    break;
                case '6':
                    Facility = LOG_LOCAL6;
                    break;
                case '7':
                    Facility = LOG_LOCAL7;
                    break;
                default:
                    fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg);
                    usage(argv[0]);
                }
                snmp_enable_syslog_ident(snmp_log_syslogname(NULL), Facility);
                log_set = 1;
            } else {
                fprintf(stderr, "no syslog facility specified\n");
                usage(argv[0]);
            }
            break;

        case 'U':
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_LEAVE_PIDFILE);
            break;

#if HAVE_UNISTD_H
        case 'u':
            if (optarg != NULL) {
                char           *ecp;
                int             uid;

                uid = strtoul(optarg, &ecp, 10);
                if (*ecp) {
#if HAVE_GETPWNAM && HAVE_PWD_H
                    struct passwd  *info;
                    info = getpwnam(optarg);
                    if (info) {
                        uid = info->pw_uid;
                    } else {
#endif
                        fprintf(stderr, "Bad user id: %s\n", optarg);
                        exit(1);
#if HAVE_GETPWNAM && HAVE_PWD_H
                    }
#endif
                }
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_USERID, uid);
            } else {
                usage(argv[0]);
            }
            break;
#endif

        case 'v':
            version();

        case 'V':
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_VERBOSE, 1);
            break;

#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
        case 'x':
            if (optarg != NULL) {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_X_SOCKET, optarg);
            } else {
                usage(argv[0]);
            }
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_AGENTX_MASTER, 1);
            break;
#endif

        case 'X':
#if defined(USING_AGENTX_SUBAGENT_MODULE)
            agent_mode = SUB_AGENT;
#else
            fprintf(stderr, "%s: Illegal argument -X:"
		            "AgentX support not compiled in.\n", argv[0]);
            usage(argv[0]);
            exit(1);
#endif
            break;

        case 'Y':
            netsnmp_config_remember(optarg);
            break;

        default:
            usage(argv[0]);
            break;
        }
    }

    if (do_help) {
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
                               NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
        init_agent(app_name);        /* register our .conf handlers */
        init_mib_modules();
        init_snmp(app_name);
        fprintf(stderr, "Configuration directives understood:\n");
        read_config_print_usage("  ");
        exit(0);
    }

    if (optind < argc) {
        /*
         * There are optional transport addresses on the command line.  
         */
        DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc));
        for (i = optind; i < argc; i++) {
            char *c, *astring;
            if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					   NETSNMP_DS_AGENT_PORTS))) {
                astring = malloc(strlen(c) + 2 + strlen(argv[i]));
                if (astring == NULL) {
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
                    exit(1);
                }
                sprintf(astring, "%s,%s", c, argv[i]);
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, astring);
                SNMP_FREE(astring);
            } else {
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
				      NETSNMP_DS_AGENT_PORTS, argv[i]);
            }
        }
        DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
                    netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
					  NETSNMP_DS_AGENT_PORTS)));
    }

#ifdef NETSNMP_LOGFILE
    if (0 == log_set)
        snmp_enable_filelog(NETSNMP_LOGFILE,
                            netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                                   NETSNMP_DS_LIB_APPEND_LOGFILES));
#endif

    /*
     * Initialize a argv set to the current for restarting the agent.   
     */
    argvrestartp = (char **)malloc((argc + 2) * sizeof(char *));
    argvptr = argvrestartp;
    for (i = 0, ret = 1; i < argc; i++) {
        ret += strlen(argv[i]) + 1;
    }
    argvrestart = (char *) malloc(ret);
    argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
    if (!argvrestartp || !argvrestart || !argvrestartname) {
        fprintf(stderr, "malloc failure processing argvrestart\n");
        exit(1);
    }
    strcpy(argvrestartname, argv[0]);
    if (agent_mode == -1) {
        if (strstr(argvrestartname, "agentxd") != NULL) {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_ROLE, SUB_AGENT);
        } else {
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_ROLE, MASTER_AGENT);
        }
    } else {
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
			       NETSNMP_DS_AGENT_ROLE, agent_mode);
    }

    for (cptr = argvrestart, i = 0; i < argc; i++) {
        strcpy(cptr, argv[i]);
        *(argvptr++) = cptr;
        cptr += strlen(argv[i]) + 1;
    }
    *cptr = 0;
    *argvptr = NULL;

#ifdef BUFSIZ
    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#endif
    /*
     * Initialize the world.  Detach from the shell.  Create initial user.  
     */
    if(!dont_fork) {
        int quit = ! netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                            NETSNMP_DS_AGENT_QUIT_IMMEDIATELY);
        ret = netsnmp_daemonize(quit, snmp_stderrlog_status());
        /*
         * xxx-rks: do we care if fork fails? I think we should...
         */
        if(ret != 0)
            Exit(1);                /*  Exit logs exit val for us  */
    }

    SOCK_STARTUP;
    init_agent(app_name);        /* do what we need to do first. */
    init_mib_modules();

    /*
     * start library 
     */
    init_snmp(app_name);

    if ((ret = init_master_agent()) != 0) {
        /*
         * Some error opening one of the specified agent transports.  
         */
        Exit(1);                /*  Exit logs exit val for us  */
    }

#if HAVE_GETPID
    if (pid_file != NULL) {
        /*
         * unlink the pid_file, if it exists, prior to open.  Without
         * doing this the open will fail if the user specified pid_file
         * already exists.
         */
        unlink(pid_file);
        fd = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 0600);
        if (fd == -1) {
            snmp_log_perror(pid_file);
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
                                        NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        } else {
            if ((PID = fdopen(fd, "w")) == NULL) {
                snmp_log_perror(pid_file);
                exit(1);
            } else {
                fprintf(PID, "%d\n", (int) getpid());
                fclose(PID);
            }
            close(fd);
        }
    }
#endif

#if HAVE_UNISTD_H
    cptr = get_persistent_directory();
    mkdirhier( cptr, NETSNMP_AGENT_DIRECTORY_MODE, 0 );
   
    uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
			     NETSNMP_DS_AGENT_USERID);
    gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
			     NETSNMP_DS_AGENT_GROUPID);
    
#ifdef HAVE_CHOWN
    if ( uid != 0 || gid != 0 )
        chown( cptr, uid, gid );
#endif

#ifdef HAVE_SETGID
    if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_GROUPID)) != 0) {
        DEBUGMSGTL(("snmpd/main", "Changing gid to %d.\n", gid));
        if (setgid(gid) == -1
#ifdef HAVE_SETGROUPS
            || setgroups(1, (gid_t *)&gid) == -1
#endif
            ) {
            snmp_log_perror("setgid failed");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        }
    }
#endif
#ifdef HAVE_SETUID
    if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
				  NETSNMP_DS_AGENT_USERID)) != 0) {
        DEBUGMSGTL(("snmpd/main", "Changing uid to %d.\n", uid));
        if (setuid(uid) == -1) {
            snmp_log_perror("setuid failed");
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                exit(1);
            }
        }
    }
#endif
#endif

    /*
     * Store persistent data immediately in case we crash later.  
     */
    snmp_store(app_name);

#ifdef SIGHUP
    DEBUGMSGTL(("signal", "registering SIGHUP signal handler\n"));
    signal(SIGHUP, SnmpdReconfig);
#endif

    /*
     * Send coldstart trap if possible.  
     */
    send_easy_trap(0, 0);

    /*
     * We're up, log our version number.  
     */
    snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
#ifdef WIN32SERVICE
    agent_status = AGENT_RUNNING;
#endif
    netsnmp_addrcache_initialise();

    /*
     * Forever monitor the dest_port for incoming PDUs.  
     */
    DEBUGMSGTL(("snmpd/main", "We're up.  Starting to process data.\n"));
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_QUIT_IMMEDIATELY))
        receive();
    DEBUGMSGTL(("snmpd/main", "sending shutdown trap\n"));
    SnmpTrapNodeDown();
    DEBUGMSGTL(("snmpd/main", "Bye...\n"));
    snmp_shutdown(app_name);
#ifdef SHUTDOWN_AGENT_CLEANLY /* broken code */
    /* these attempt to free all known memory, but result in double frees */
    shutdown_master_agent();
    shutdown_agent();
#endif

    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				NETSNMP_DS_AGENT_LEAVE_PIDFILE) &&
	(pid_file != NULL)) {
        unlink(pid_file);
    }
#ifdef WIN32SERVICE
    agent_status = AGENT_STOPPED;
#endif

    SNMP_FREE(argvrestartname);
    SNMP_FREE(argvrestart);
    SNMP_FREE(argvrestartp);
    SOCK_CLEANUP;
    return 0;
}                               /* End main() -- snmpd */
Beispiel #16
0
/*******************************************************
*
*  Main function
*
*******************************************************/
int main(int argc, char *argv[])
{
    int auth_state = AUTH_NONE;
    char cryptobuf[SHA1KEYL*2];
    char buf[256];
    int i, res, nullfd;
    int sock, newsock;
    fd_set active_fd_set, read_fd_set;
    struct sockaddr_in clientaddr;
    size_t size;
    FILE *fd;
    /*  previous balance and limit status  */
    int balance = 0, limit = 0;
    int opt;

    while ((opt = getopt(argc, argv, ":c:p:i:u:h")) != -1) {
	switch (opt) {
	    case 'c':
		conf_name = optarg;
		break;
	    case 'p':
		pid_name = optarg;
		break;
	    case 'i':
		info_name = optarg;
		break;
	    case 'u':
		user_name = optarg;
		break;
	    case ':':
		log_err("wrong parameters");
	    case 'h':
	    default:
		fprintf(stderr,
		    "usage: %s [options]\n"
		    "options:\n"
		    "  -c <conf_file>\n"
		    "  -p <pid_file>\n"
		    "  -c <info_file>\n"
		    "  -u <user_name>\n", DAEMON_NAME);
		exit(EXIT_FAILURE);
	}
    }

    if (!readconfig()) {
        sprintf(buf, "can't read configuration file %s: %s\n", conf_name, strerror(errno));
	fprintf(stderr, buf);
	log_err(buf);
	exit (EXIT_FAILURE);
    }

    /* close standard I/O handles */
    nullfd = open("/dev/null", O_RDWR);
    if (nullfd < 0) {
	perror("/dev/null");
    } else {
	dup2(nullfd,0);
	dup2(nullfd,1);
	dup2(nullfd,2);
	close(nullfd);
    }

    if(fork()) {
	exit(EXIT_SUCCESS);
    }

    /* Daemon is started */

    /* Create the socket and set it up to accept connections */
    sock = make_socket(SERV_TCP_PORT);
    if (listen(sock, 3) < 0) {
	log_err("can't listen to main socket");
	exit(EXIT_FAILURE);
    }

    /* Set stop signal */
    signal(SIGINT, authcli_term);
    signal(SIGTERM, authcli_term);
    signal(SIGQUIT, authcli_term);

    /* Set SIGCHLD */
    signal(SIGCHLD, authcli_child);

    /* Set SIGHUP */
    signal(SIGHUP, authcli_hup);

    log_msg("%s v.%.2f started.", DAEMON_NAME, VERSION/100.);
    log_msg("listening on TCP port %d", SERV_TCP_PORT);

    /*  Write PID file */
    if (pid_name) {
	pid_t pid = getpid();
	if (pid < 0) {
	    log_err("can't get pid");
	    exit(EXIT_FAILURE);
	}
	fd = fopen(pid_name, "w");
	if (fd != NULL) {
	    fprintf(fd, "%d", pid);
	    fclose(fd);
	} else
	    log_err("can't create pid file %s: %s", pid_name, strerror(errno));
    }

    /* Switch to unpriviledged account */
    if (user_name) {
	struct passwd* ppwd;

	ppwd = getpwnam(user_name); 
	if (ppwd) {
	    log_dbg("switching to unprivileged user \'%s\' (UID %d, GID %d)",
		user_name, ppwd->pw_uid, ppwd->pw_gid);
	    setuid(ppwd->pw_uid);
	    setgid(ppwd->pw_gid);
	} else
	    log_dbg("can't switch to unprivileged user \'%s\'", user_name);
    }

    child_pid = fork();
    if (!child_pid) {
	sleep(1);  // wait for parent network init
	request_auth_child();
	exit(EXIT_SUCCESS);
    }

    /* Initialize the set of active sockets */
    FD_ZERO(&active_fd_set);
    FD_SET(sock, &active_fd_set);

    while (loop_flag) {
	/* Block until input arrives on one or more active sockets */
	read_fd_set = active_fd_set;
	if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) {
	    log_dbg("select error: %s", strerror(errno));
	    continue;
	}

	/* Service all the sockets with input pending */
	for (i = 0; i < FD_SETSIZE; i++) {
	    if (FD_ISSET(i, &read_fd_set)) {
		if (i == sock) {  /* New connection request on original socket.  */
		    size = sizeof(clientaddr);
		    if ((newsock = accept(sock, (struct sockaddr*)&clientaddr, (void*)&size)) < 0) {
        		log_err("error accepting connection");
			exit(EXIT_FAILURE);
		    }

		    pstrclientip = inet_ntoa(clientaddr.sin_addr);
		    log_dbg("new connection from %s", pstrclientip);

		    FD_SET(newsock, &active_fd_set);

		} else {  /* Data arriving on an already-connected socket */
		    struct message mr, ms;

		    log_dbg("receiving data");

		    memset((void*)&mr, 0, sizeof(mr)); // clear message structure before recv
		    res = recv_message(i, &mr);
		    if (res < 1) {
			if (res != 0) {
			    #ifndef LOG_INVALID_MESSAGES
			    log_err("error receiving auth message");
			    #endif
			}
        		close(i);
        		FD_CLR(i, &active_fd_set);
			continue;
		    }

		    if(mr.attr == A_KEYSND) {
                	memset((void*)&ms, 0, sizeof(ms)); // clear send buffer
			ms.attr = a_passnd;
			a_passnd = A_PASSND2 | (AUTH_VERSION<<16);

			memcpy(cryptobuf, mr.challenge,  SHA1KEYL);
			memcpy(cryptobuf+SHA1KEYL, NKEY, SHA1KEYL);
			sha1encode_strn((unsigned char*)cryptobuf, SHA1KEYL*2, ms.response);

			if (!send_message(i, &ms)) {
			    #ifndef LOG_INVALID_MESSAGES
			    log_msg("error sending auth message");
			    #endif
			    close(i);
			    FD_CLR(i, &active_fd_set);
			}
			continue;
		    } else

		    if (mr.attr == A_PASASQ) {
			int balance_cur, limit_cur;

			if (mr.auth.result == AUTH_ACCEPT) {
			    balance_cur = mr.auth.balance;
			    limit_cur = mr.auth.limit;

			    /* log balance only if it has been changed or if this is the
			     * first time we've got auth accept message	*/
			    if ((balance_cur != balance) || (limit_cur != limit) || 
				(auth_state != AUTH_ACCEPT)) {
				/* dump info */
				if (info_name) {
				    fd = fopen(info_name, "w");
				    if (fd != NULL) {
					fprintf(fd,
					    "BALANCE=%.2f\n"
					    "LIMIT=%.2f\n",
					    balance_cur/100., limit_cur/100.);
					fclose(fd);
				    } else
					log_err("can't create info file %s: %s", info_name, strerror(errno));
				}
				if (balance_cur < limit_cur) {
				    log_msg("low balance %.2f",balance_cur/100.);
				} else {
				    log_msg("balance %.2f",balance_cur/100.);
				}
				balance = balance_cur;
				limit = limit_cur;
			    }

			    if (auth_state != AUTH_ACCEPT) {
				log_msg("auth key accepted");
				auth_state = AUTH_ACCEPT;
			    }
			}
		    } else

		    if (mr.attr == A_PASNEG) {
			log_msg("invalid password");
                	auth_state = AUTH_REJECT;
                    } else

		    if (mr.attr == A_WRNVER) {
			log_msg("wrong client version");
		    } else

		    if (auth_state != AUTH_REJECT) {
		        log_msg("auth key rejected");
		        auth_state = AUTH_REJECT;
		    }

		    close(i);
		    FD_CLR(i, &active_fd_set);
		}
	    } /* end if */
	} /* end for */
    } /* end while */

    /* Clean up pid and info files
     * Note: Take care of unprivileged user permissions */
    if (info_name)
	unlink(info_name);
    if (pid_name)
	unlink(pid_name);
    return 0;
}
Beispiel #17
0
int _SMERP_posixMain( int argc, char* argv[] )
{
// i18n global stuff
	if ( setlocale( LC_ALL, "" ) == NULL )	{
		std::cerr << "Unable to set locale. Falling back to default." << std::endl;
	}
	else	{
		if ( bindtextdomain( "SMERP", "../po" ) == NULL )	{
			std::cerr << "Not enough memory to bind textdomain" << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
		if ( textdomain( "SMERP" ) == NULL )	{
			std::cerr << "Not enough memory to set textdomain" << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
	}
// end of i18n global stuff

	try	{
		_SMERP::Version		appVersion( MAJOR_VERSION, MINOR_VERSION, REVISION_NUMBER );
		_SMERP::CmdLineConfig	cmdLineCfg;
		const char		*configFile;

// it's just a DUMMY for now
		_SMERP::HandlerConfiguration	handlerConfig;

		if ( !cmdLineCfg.parse( argc, argv ))	{	// there was an error parsing the command line
			std::cerr << cmdLineCfg.errMsg() << std::endl << std::endl;
			cmdLineCfg.usage( std::cerr );
			std::cerr << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
// command line has been parsed successfully
// if cmdLineCfg.errMsg() is not empty than we have a warning
		if ( !cmdLineCfg.errMsg().empty() )	// there was a warning parsing the command line
			std::cerr << "BOO:" << cmdLineCfg.errMsg() << std::endl << std::endl;

// if we have to print the version or the help do it and exit
		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_VERSION )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl << std::endl;
			return _SMERP::ErrorCodes::OK;
		}
		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_HELP )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl;
			cmdLineCfg.usage( std::cout );
			std::cout << std::endl;
			return _SMERP::ErrorCodes::OK;
		}

// decide what configuration file to use
		if ( !cmdLineCfg.cfgFile.empty() )	// if it has been specified than that's The One ! (and only)
			configFile = cmdLineCfg.cfgFile.c_str();
		else
			configFile = _SMERP::CfgFileConfig::chooseFile( DEFAULT_MAIN_CONFIG,
								       DEFAULT_USER_CONFIG,
								       DEFAULT_LOCAL_CONFIG );
		if ( configFile == NULL )	{	// there is no configuration file
			std::cerr << gettext ( "MOMOMO: no configuration file found !" ) << std::endl << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}

		_SMERP::CfgFileConfig	cfgFileCfg;
		if ( !cfgFileCfg.parse( configFile ))	{	// there was an error parsing the configuration file
			std::cerr << cfgFileCfg.errMsg() << std::endl << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
		else if ( !cfgFileCfg.errMsg().empty())
			std::cerr << cfgFileCfg.errMsg() << std::endl;
// configuration file has been parsed successfully
// build the application configuration
		_SMERP::ApplicationConfiguration config( cmdLineCfg, cfgFileCfg);

// now here we know where to log to on stderr
		_SMERP::LogBackend::instance().setConsoleLevel( config.stderrLogLevel );

// Check the configuration
		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::CHECK_CONFIG )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl;
			if ( config.check() )	{
				if ( config.errMsg().empty() )	{
					std::cout << "Configuration OK" << std::endl << std::endl;
					return _SMERP::ErrorCodes::OK;
				}
				else	{
					std::cout << "WARNING: " << config.errMsg() << std::endl << std::endl;
					return _SMERP::ErrorCodes::OK;
				}
			}
			else	{
				std::cout << "ERROR: " << config.errMsg() << std::endl << std::endl;
				return _SMERP::ErrorCodes::OK;
			}
		}

		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_CONFIG )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl;
			config.print( std::cout );
			std::cout << std::endl;
			return _SMERP::ErrorCodes::OK;
		}

		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::TEST_CONFIG )	{
			std::cout << "Not implemented yet" << std::endl << std::endl;
			return _SMERP::ErrorCodes::OK;
		}

		// Daemon stuff
		if( !config.foreground ) {
			// Aba: maybe also in the foreground?
			// try to lock the pidfile, bail out if not possible
			if( boost::filesystem::exists( config.pidFile ) ) {
				boost::interprocess::file_lock lock( config.pidFile.c_str( ) );
				if( lock.try_lock( ) ) {
					std::cerr << "Pidfile is locked, another daemon running?" << std::endl;
					return _SMERP::ErrorCodes::FAILURE;
				}
			}

			// daemonize, lose process group, terminal output, etc.
			if( daemon( 0, 0 ) ) {
				std::cerr << "Daemonizing server failed" << std::endl;
				return _SMERP::ErrorCodes::FAILURE;
			}

			// now here we lost constrol over the console, we should
			// create a temporary logger which at least tells what's
			// going on in the syslog
			_SMERP::LogBackend::instance().setSyslogLevel( config.syslogLogLevel );
			_SMERP::LogBackend::instance().setSyslogFacility( config.syslogFacility );
			_SMERP::LogBackend::instance().setSyslogIdent( config.syslogIdent );

			// if we are root we can drop privileges now
			struct group *groupent;
			struct passwd *passwdent;

			groupent = getgrnam( config.group.c_str( ) );
			passwdent = getpwnam( config.user.c_str( ) );
			if( groupent == NULL || passwdent == NULL ) {
				LOG_CRITICAL << "Illegal group '" << config.group << "' or user '" << config.user << "'";
				return _SMERP::ErrorCodes::FAILURE;
			}

			if( setgid( groupent->gr_gid ) < 0 ) {
				LOG_CRITICAL << "setgid for group '" << config.group << "' failed!";
				return _SMERP::ErrorCodes::FAILURE;
			}

			if( setuid( passwdent->pw_uid ) < 0 ) {
				LOG_CRITICAL << "setgid for user '" << config.user << "' failed!";
				return _SMERP::ErrorCodes::FAILURE;
			}

			// create a pid file and lock id
			std::ofstream pidFile( config.pidFile.c_str( ), std::ios_base::trunc );
			if( !pidFile.good( ) ) {
				LOG_CRITICAL << "Unable to create PID file '" << config.pidFile << "'!";
				return _SMERP::ErrorCodes::FAILURE;
			}
			pidFile << getpid( ) << std::endl;
			pidFile.close( );

			// Create the final logger based on the configuration
			// file logger only here to get the right permissions
			_SMERP::LogBackend::instance().setLogfileLevel( config.logFileLogLevel );
			_SMERP::LogBackend::instance().setLogfileName( config.logFile );
		}

		// Block all signals for background thread.
		sigset_t new_mask;
		sigfillset( &new_mask );
		sigset_t old_mask;
		pthread_sigmask( SIG_BLOCK, &new_mask, &old_mask );

		LOG_NOTICE << "Starting server";

		// Run server in background thread(s).
		_SMERP::ServerHandler	handler( handlerConfig );
		_SMERP::Network::server s( config.address, config.SSLaddress, handler,
					   config.threads, config.maxConnections );
		boost::thread t( boost::bind( &_SMERP::Network::server::run, &s ));

		// Restore previous signals.
		pthread_sigmask( SIG_SETMASK, &old_mask, 0 );

		// Wait for signal indicating time to shut down.
		sigset_t wait_mask;
		sigemptyset( &wait_mask );
		sigaddset( &wait_mask, SIGINT );
		sigaddset( &wait_mask, SIGQUIT );
		sigaddset( &wait_mask, SIGTERM );
		pthread_sigmask( SIG_BLOCK, &wait_mask, 0 );
		int sig = 0;
		sigwait( &wait_mask, &sig );

		// Stop the server.
		LOG_INFO << "Stopping server";
		s.stop();
		t.join();
		LOG_NOTICE << "Server stopped";

		// Daemon stuff
		if( !config.foreground ) {
			(void)remove( config.pidFile.c_str( ) );
		}
	}
	catch (std::exception& e)	{
		// Aba: how to delete the pid file here?
		LOG_ERROR << "posixMain: exception: " << e.what() << "\n";
		return _SMERP::ErrorCodes::FAILURE;
	}

	return _SMERP::ErrorCodes::OK;
}
Beispiel #18
0
void SettingsParseCommandLine(int argc, char *argv[])
{
int i;

if (argc < 2) return;
if (strcmp("-user", argv[1])==0) SettingsParseUserCommandLine(argc, argv);
else
{
for (i=1; i < argc; i++)
{
	if (strcmp("-?",argv[i])==0) SettingsPrintUsage();
	else if (strcmp("-help",argv[i])==0) SettingsPrintUsage();
	else if (strcmp("--help",argv[i])==0) SettingsPrintUsage();
	else if (strcmp("-version",argv[i])==0) PrintVersion();
	else if (strcmp("--version",argv[i])==0) PrintVersion();
	else if (strcmp("-chroot",argv[i])==0) 
	{
		Settings.Flags |= FLAG_CHROOT;
		Settings.ChDir=CopyStr(Settings.ChDir,argv[++i]);
	}
	else if (strcmp("-dynhome",argv[i])==0) 
	{
		Settings.Flags |= FLAG_DYNHOME | FLAG_UNMOUNT;
		Settings.DynamicHomeDir=CopyStr(Settings.DynamicHomeDir,argv[++i]);
	}
	else if (strcmp("-debug", argv[i])==0) Settings.Flags |= FLAG_DEBUG;
	else if (strcmp("-honeypot", argv[i])==0) 
	{
			Settings.Flags |= FLAG_DENYAUTH | FLAG_HONEYPOT;
			Settings.AuthMethods=CopyStr(Settings.AuthMethods,"");
			Settings.AuthFile=CopyStr(Settings.AuthFile,"");
			Settings.InfoLogLevel=LOG_CRIT;
			Settings.ErrorLogLevel=LOG_CRIT;
	}
	else if (strcmp("-chhome", argv[i])==0) Settings.Flags |= FLAG_CHHOME;
	else if (strcmp("-banner", argv[i])==0) Settings.Banner=CopyStr(Settings.Banner,argv[++i]);
	else if (strcmp("-env", argv[i])==0) Settings.Environment=CopyStr(Settings.Environment,argv[++i]);
	else if (strcmp("-a", argv[i])==0) Settings.AuthFile=CopyStr(Settings.AuthFile,argv[++i]);
	else if (strcmp("-A", argv[i])==0) Settings.AuthMethods=CopyStr(Settings.AuthMethods,argv[++i]);
	else if (strcmp("-auth-methods", argv[i])==0) Settings.AuthMethods=CopyStr(Settings.AuthMethods,argv[++i]);
	else if (strcmp("-auth-file", argv[i])==0) Settings.AuthFile=CopyStr(Settings.AuthFile,argv[++i]);
	else if (strcmp("-pid-file", argv[i])==0) Settings.PidFile=CopyStr(Settings.PidFile,argv[++i]);
	else if (strcmp("-auth-tries", argv[i])==0) Settings.AuthTries=atoi(argv[++i]);
	else if (strcmp("-auth-delay", argv[i])==0) Settings.AuthDelay=atoi(argv[++i]);
	else if (strcmp("-allow", argv[i])==0) Settings.AllowUsers=CopyStr(Settings.AllowUsers,argv[++i]);
	else if (strcmp("-deny", argv[i])==0) Settings.DenyUsers=CopyStr(Settings.DenyUsers,argv[++i]);
	else if (strcmp("-allow-users", argv[i])==0) Settings.AllowUsers=CopyStr(Settings.AllowUsers,argv[++i]);
	else if (strcmp("-deny-users", argv[i])==0) Settings.DenyUsers=CopyStr(Settings.DenyUsers,argv[++i]);
	else if (strcmp("-allow-ips", argv[i])==0) Settings.AllowIPs=CopyStr(Settings.AllowIPs,argv[++i]);
	else if (strcmp("-deny-ips", argv[i])==0) Settings.DenyIPs=CopyStr(Settings.DenyIPs,argv[++i]);
	else if (strcmp("-allow-macs", argv[i])==0) Settings.AllowMACs=CopyStr(Settings.AllowMACs,argv[++i]);
	else if (strcmp("-deny-macs", argv[i])==0) Settings.DenyMACs=CopyStr(Settings.DenyMACs,argv[++i]);
	else if (strcmp("-local", argv[i])==0) Settings.Flags |= FLAG_LOCALONLY;
	else if (strcmp("-m", argv[i])==0) Settings.BindMounts=CopyStr(Settings.BindMounts,argv[++i]);
	else if (strcmp("-mounts", argv[i])==0) Settings.BindMounts=CopyStr(Settings.BindMounts,argv[++i]);
	else if (strcmp("-i", argv[i])==0) Settings.Interface=CopyStr(Settings.Interface,argv[++i]);
	else if (strcmp("-p", argv[i])==0) Settings.Port=atoi(argv[++i]);
	else if (strcmp("-port", argv[i])==0) Settings.Port=atoi(argv[++i]);
	else if (strcmp("-inetd", argv[i])==0) Settings.Flags |= FLAG_INETD;
	else if (strcmp("-D", argv[i])==0) Settings.Flags |= FLAG_NODEMON;
	else if (strcmp("-nodemon", argv[i])==0) Settings.Flags |= FLAG_NODEMON;
	else if (strcmp("-idle", argv[i])==0) Settings.IdleTimeout=atoi(argv[++i]);
	else if (strcmp("-shell", argv[i])==0)
	{
		Settings.DefaultShell=CopyStr(Settings.DefaultShell,argv[++i]);
		Settings.Flags |= FLAG_FORCE_SHELL;
	}
	else if (strcmp("-error-log-level", argv[i])==0) Settings.ErrorLogLevel=SettingsParseLogLevel(argv[++i]);
	else if (strcmp("-info-log-level", argv[i])==0) Settings.InfoLogLevel=SettingsParseLogLevel(argv[++i]);
	else if (strcmp("-shell", argv[i])==0) Settings.DefaultShell=CopyStr(Settings.DefaultShell,argv[++i]);
	else if (strcmp("-login-script", argv[i])==0) Settings.LoginScript=CopyStr(Settings.LoginScript,argv[++i]);
	else if (strcmp("-logout-script", argv[i])==0) Settings.LogoutScript=CopyStr(Settings.LogoutScript,argv[++i]);
	else if (strcmp("-real-user", argv[i])==0) 
	{
		i++;
		if (getpwnam(argv[i])) Settings.RealUser=CopyStr(Settings.RealUser,argv[i]);
		else
		{
			printf("ERROR: No such user: %s\n",argv[i]);
			exit(1);
		}
		Settings.Flags |= FLAG_FORCE_REALUSER;
	}
	else 
	{
			printf("ERROR: Unknown option '%s'\n",argv[i]);
			Settings.Flags |= FLAG_ERROR;
	}
}
}

if (Settings.Flags & FLAG_ERROR)
{
	printf("%s -? for help\n",argv[0]);
	exit(1);
}
}
Beispiel #19
0
static char *
ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_core_conf_t  *ccf = conf;

    ngx_conf_init_value(ccf->daemon, 1);
    ngx_conf_init_value(ccf->master, 1);
    ngx_conf_init_msec_value(ccf->timer_resolution, 0);

    ngx_conf_init_value(ccf->worker_processes, 1);
    ngx_conf_init_value(ccf->debug_points, 0);

#if (NGX_HAVE_CPU_AFFINITY)

    if (ccf->cpu_affinity_n
        && ccf->cpu_affinity_n != 1
        && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
    {
        ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
                      "the number of \"worker_processes\" is not equal to "
                      "the number of \"worker_cpu_affinity\" masks, "
                      "using last mask for remaining worker processes");
    }

#endif


    if (ccf->pid.len == 0) {
        ngx_str_set(&ccf->pid, NGX_PID_PATH);
    }

    if (ngx_conf_full_name(cycle, &ccf->pid, 0) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT);

    ccf->oldpid.data = ngx_pnalloc(cycle->pool, ccf->oldpid.len);
    if (ccf->oldpid.data == NULL) {
        return NGX_CONF_ERROR;
    }

    ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len),
               NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT));


#if !(NGX_WIN32)

    if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
        struct group   *grp;
        struct passwd  *pwd;

        ngx_set_errno(0);
        pwd = getpwnam(NGX_USER);
        if (pwd == NULL) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "getpwnam(\"" NGX_USER "\") failed");
            return NGX_CONF_ERROR;
        }

        ccf->username = NGX_USER;
        ccf->user = pwd->pw_uid;

        ngx_set_errno(0);
        grp = getgrnam(NGX_GROUP);
        if (grp == NULL) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "getgrnam(\"" NGX_GROUP "\") failed");
            return NGX_CONF_ERROR;
        }

        ccf->group = grp->gr_gid;
    }


    if (ccf->lock_file.len == 0) {
        ngx_str_set(&ccf->lock_file, NGX_LOCK_PATH);
    }

    if (ngx_conf_full_name(cycle, &ccf->lock_file, 0) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    {
    ngx_str_t  lock_file;

    lock_file = cycle->old_cycle->lock_file;

    if (lock_file.len) {
        lock_file.len--;

        if (ccf->lock_file.len != lock_file.len
            || ngx_strncmp(ccf->lock_file.data, lock_file.data, lock_file.len)
               != 0)
        {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                          "\"lock_file\" could not be changed, ignored");
        }

        cycle->lock_file.len = lock_file.len + 1;
        lock_file.len += sizeof(".accept");

        cycle->lock_file.data = ngx_pstrdup(cycle->pool, &lock_file);
        if (cycle->lock_file.data == NULL) {
            return NGX_CONF_ERROR;
        }

    } else {
        cycle->lock_file.len = ccf->lock_file.len + 1;
        cycle->lock_file.data = ngx_pnalloc(cycle->pool,
                                      ccf->lock_file.len + sizeof(".accept"));
        if (cycle->lock_file.data == NULL) {
            return NGX_CONF_ERROR;
        }

        ngx_memcpy(ngx_cpymem(cycle->lock_file.data, ccf->lock_file.data,
                              ccf->lock_file.len),
                   ".accept", sizeof(".accept"));
    }
    }

#endif

    return NGX_CONF_OK;
}
Beispiel #20
0
static void daemonize (const char *lockfile, char *tty, char *name)
{
	pid_t pid, sid, parent;
	int lfp = -1;
	FILE * pFile;
	char const *pidprefix = "/var/run/";
	char const *pidsuffix = ".pid";
	char pidfile[PIDFILE_LENGTH];

	snprintf(pidfile, PIDFILE_LENGTH, "%s%s-%s%s", pidprefix, DAEMON_NAME, tty, pidsuffix);

	/* already a daemon */
	if (getppid () == 1)
		return;

	/* Create the lock file as the current user */
	if (lockfile && lockfile[0])
	{
		lfp = open (lockfile, O_RDWR | O_CREAT, 0640);
		if (lfp < 0)
		{
			syslog (LOG_ERR, "unable to create lock file %s, code=%d (%s)",
				lockfile, errno, strerror (errno));
			exit (EXIT_FAILURE);
		}
	}

	/* Drop user if there is one, and we were run as root */
	if (getuid () == 0 || geteuid () == 0)
	{
		struct passwd *pw = getpwnam (RUN_AS_USER);
		if (pw)
		{
			//syslog (LOG_NOTICE, "setting user to " RUN_AS_USER);
			setuid (pw->pw_uid);
		}
	}

	/* Trap signals that we expect to receive */
	signal (SIGCHLD, child_handler);
	signal (SIGUSR1, child_handler);
	signal (SIGALRM, child_handler);

	/* Fork off the parent process */
	pid = fork ();
	if (pid < 0)
	{
		syslog (LOG_ERR, "unable to fork daemon, code=%d (%s)",
			errno, strerror (errno));
		exit (EXIT_FAILURE);
	}
	/* If we got a good PID, then we can exit the parent process. */
	if (pid > 0)
	{

		/* Wait for confirmation from the child via SIGTERM or SIGCHLD, or
		   for two seconds to elapse (SIGALRM).  pause() should not return. */
		alarm (2);
		pause ();

		exit (EXIT_FAILURE);
	}

	/* At this point we are executing as the child process */
	parent = getppid ();

	/* Cancel certain signals */
	signal (SIGCHLD, SIG_DFL);	/* A child process dies */
	signal (SIGTSTP, SIG_IGN);	/* Various TTY signals */
	signal (SIGTTOU, SIG_IGN);
	signal (SIGTTIN, SIG_IGN);
	signal (SIGHUP, SIG_IGN);	/* Ignore hangup signal */
	signal (SIGTERM, SIG_DFL);	/* Die on SIGTERM */

	/* Change the file mode mask */
	umask (0);

	/* Create a new SID for the child process */
	sid = setsid ();
	if (sid < 0)
	{
		syslog (LOG_ERR, "unable to create a new session, code %d (%s)",
			errno, strerror (errno));
		exit (EXIT_FAILURE);
	}

	pFile = fopen (pidfile,"w");
	if (pFile < 0)
	{
		syslog (LOG_ERR, "unable to create pid file %s, code=%d (%s)",
			pidfile, errno, strerror (errno));
		exit (EXIT_FAILURE);
	}
	fprintf (pFile, "%d\n", sid);
	fclose (pFile);

	/* Change the current working directory.  This prevents the current
	   directory from being locked; hence not being able to remove it. */
	if ((chdir ("/")) < 0)
	{
		syslog (LOG_ERR, "unable to change directory to %s, code %d (%s)",
			"/", errno, strerror (errno));
		exit (EXIT_FAILURE);
	}

	/* Redirect standard files to /dev/null */
	freopen ("/dev/null", "r", stdin);
	freopen ("/dev/null", "w", stdout);
	freopen ("/dev/null", "w", stderr);

	/* Tell the parent process that we are A-okay */
	kill (parent, SIGUSR1);
}
Beispiel #21
0
int main(int argc, char* argv[], char* envp[])
{
	if(argc < 7)
		usage(argv);

	char* root = argv[1];
	char* thumbnail_root = argv[2];
	char* listen_addr = argv[3];
	num_workers = atoi(argv[6]);

	if(num_workers < 1)
		usage(argv);

	struct passwd* pwd = getpwnam(argv[4]);
	if (pwd == NULL)
			error_errno("getpwnam_r failed", EXIT_FAILURE);

	struct group* grp = getgrnam(argv[5]);
	if (grp == NULL)
			error_errno("getgrnam_r failed", EXIT_FAILURE);

	int userid = pwd->pw_uid;
	int groupid = grp->gr_gid;

	if(root[strlen(root) - 1] != '/' || thumbnail_root[strlen(thumbnail_root) - 1] != '/')
		error("Did you forget the ending slash in the (thumbnail) root directory path?", EXIT_FAILURE);

	// TODO Some more error checking

	// Initialize syslog
	syslog(LOG_INFO, "Starting up\n");
	#if defined(DEBUG)
		setlogmask(LOG_UPTO(LOG_DEBUG));
		openlog("fastresize", LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
	#else
		setlogmask(LOG_UPTO(LOG_INFO));
		openlog("fastresize", LOG_CONS, LOG_USER);
	#endif

	// Change the working directory
	if((chdir(root)) < 0)
		error("Couldn't change working directory\n", EXIT_FAILURE);

	// Initialize FastCGI
	syslog(LOG_INFO, "Initializing FastCGI\n");
	if(FCGX_Init())
		error("Could not initialize FastCGI (during FCGX_Init())", EXIT_FAILURE);

	int listen_socket = FCGX_OpenSocket(listen_addr, 400);
	if(listen_socket < 0)
		error("Couldn't bind to FastCGI socket", EXIT_FAILURE);

	// Now that we've got our socket, drop root privileges
	if (getuid() == 0) {
		if (setgid(groupid) != 0)
			error_errno("setgid: Unable to drop group privileges", EXIT_FAILURE);
		if (setuid(userid) != 0)
			error_errno("setuid: Unable to drop user privileges", EXIT_FAILURE);
	}

	FCGX_Request request;
	if(FCGX_InitRequest(&request, listen_socket, 0))
		error("Couldn't initialize FastCGI request handler", EXIT_FAILURE);

	// Initialize ImageMagick
	syslog(LOG_INFO, "Initializing ImageMagick\n");
	MagickWandGenesis();
	atexit(MagickWandTerminus);

	/* Fork a new master process to daemonize and exit the old one. We use
	 * _Exit here to not trigger the atexit that terminates ImageMagick.
	 */
	if(fork())
		_Exit(EXIT_SUCCESS);

	// Fork worker processes
	syslog(LOG_INFO, "Forking workers\n");

	worker_pids = calloc(num_workers, sizeof(pid_t));
	if(!worker_pids)
		error_errno("worker_pids: Could not allocate", 1);

	for(worker_id = 0; worker_id <= num_workers; worker_id++)
	{
		worker_pids[worker_id] = fork();

		// Exit the loop if we're the forked process
		if(worker_pids[worker_id] == 0)
			break;

		syslog(LOG_INFO, "Forked worker with PID %d\n", worker_pids[worker_id]);
	}

	// The following code is only executed in the master process.
	if(worker_id > num_workers)
	{
		syslog(LOG_INFO, "master (PID %d): Sleeping until I receive a signal.\n", getpid());

		/* Sleep a little until we get a SIG{TERM,HUP,INT} or one of our
		 * workers died (not cool).
		 */
		struct sigaction exit_action;
		exit_action.sa_handler = &exit_signal;
		exit_action.sa_sigaction = &exit_signal;

		struct sigaction worker_died_action;
		worker_died_action.sa_handler = &worker_died;
		worker_died_action.sa_sigaction = &worker_died;

		sigaction(SIGTERM, &exit_action, NULL);
		sigaction(SIGHUP, &exit_action, NULL);
		sigaction(SIGINT, &exit_action, NULL);
		sigaction(SIGCHLD, &worker_died_action, NULL);
		pause();

		// This should never™ be reached unless something funny happens.
		exit(EXIT_FAILURE);
	}

	syslog(LOG_INFO, "Worker #%d is now listening for requests on 127.0.0.1:9000\n", worker_id);

	while(FCGX_Accept_r(&request) == 0)
		handle_request(&request, root, thumbnail_root);

	// Exit
	exit(EXIT_SUCCESS);
}
Beispiel #22
0
static void
cups_finalize_client_conf(
    _cups_client_conf_t *cc)		/* I - client.conf values */
{
  const char	*value;			/* Environment variable */


  if ((value = getenv("CUPS_TRUSTFIRST")) != NULL)
    cc->trust_first = cups_boolean_value(value);

  if ((value = getenv("CUPS_ANYROOT")) != NULL)
    cc->any_root = cups_boolean_value(value);

  if ((value = getenv("CUPS_ENCRYPTION")) != NULL)
    cups_set_encryption(cc, value);

  if ((value = getenv("CUPS_EXPIREDCERTS")) != NULL)
    cc->expired_certs = cups_boolean_value(value);

#ifdef HAVE_GSSAPI
  if ((value = getenv("CUPS_GSSSERVICENAME")) != NULL)
    cups_set_gss_service_name(cc, value);
#endif /* HAVE_GSSAPI */

  if ((value = getenv("CUPS_SERVER")) != NULL)
    cups_set_server_name(cc, value);

  if ((value = getenv("CUPS_USER")) != NULL)
    cups_set_user(cc, value);

  if ((value = getenv("CUPS_VALIDATECERTS")) != NULL)
    cc->validate_certs = cups_boolean_value(value);

 /*
  * Then apply defaults for those values that haven't been set...
  */

  if (cc->trust_first < 0)
    cc->trust_first = 1;

  if (cc->any_root < 0)
    cc->any_root = 1;

  if (cc->encryption == (http_encryption_t)-1)
    cc->encryption = HTTP_ENCRYPTION_IF_REQUESTED;

  if (cc->expired_certs < 0)
    cc->expired_certs = 0;

#ifdef HAVE_GSSAPI
  if (!cc->gss_service_name[0])
    cups_set_gss_service_name(cc, CUPS_DEFAULT_GSSSERVICENAME);
#endif /* HAVE_GSSAPI */

  if (!cc->server_name[0])
  {
#ifdef CUPS_DEFAULT_DOMAINSOCKET
   /*
    * If we are compiled with domain socket support, only use the
    * domain socket if it exists and has the right permissions...
    */

    if (!access(CUPS_DEFAULT_DOMAINSOCKET, R_OK))
      cups_set_server_name(cc, CUPS_DEFAULT_DOMAINSOCKET);
    else
#endif /* CUPS_DEFAULT_DOMAINSOCKET */
      cups_set_server_name(cc, "localhost");
  }

  if (!cc->user[0])
  {
#ifdef WIN32
   /*
    * Get the current user name from the OS...
    */

    DWORD	size;			/* Size of string */

    size = sizeof(cc->user);
    if (!GetUserName(cc->user, &size))
#else
   /*
    * Try the USER environment variable as the default username...
    */

    const char *envuser = getenv("USER");
					/* Default username */
    struct passwd *pw = NULL;		/* Account information */

    if (envuser)
    {
     /*
      * Validate USER matches the current UID, otherwise don't allow it to
      * override things...  This makes sure that printing after doing su
      * or sudo records the correct username.
      */

      if ((pw = getpwnam(envuser)) != NULL && pw->pw_uid != getuid())
	pw = NULL;
    }

    if (!pw)
      pw = getpwuid(getuid());

    if (pw)
      strlcpy(cc->user, pw->pw_name, sizeof(cc->user));
    else
#endif /* WIN32 */
    {
     /*
      * Use the default "unknown" user name...
      */

      strlcpy(cc->user, "unknown", sizeof(cc->user));
    }
  }

  if (cc->validate_certs < 0)
    cc->validate_certs = 0;
}
Beispiel #23
0
static void get_service_attr(PIPE_ATTR *attr, char **argv)
{
    const char *myname = "get_service_attr";
    struct passwd *pwd;
    struct group *grp;
    char   *user;			/* user name */
    char   *group;			/* group name */
    char   *size;			/* max message size */
    char   *cp;

    /*
     * Initialize.
     */
    user = 0;
    group = 0;
    attr->command = 0;
    attr->flags = 0;
    attr->exec_dir = 0;
    attr->chroot_dir = 0;
    attr->eol = vstring_strcpy(vstring_alloc(1), "\n");
    attr->null_sender = vstring_strcpy(vstring_alloc(1), MAIL_ADDR_MAIL_DAEMON);
    attr->size_limit = 0;

    /*
     * Iterate over the command-line attribute list.
     */
    for ( /* void */ ; *argv != 0; argv++) {

	/*
	 * flags=stuff
	 */
	if (strncasecmp("flags=", *argv, sizeof("flags=") - 1) == 0) {
	    for (cp = *argv + sizeof("flags=") - 1; *cp; cp++) {
		switch (*cp) {
		case 'B':
		    attr->flags |= MAIL_COPY_BLANK;
		    break;
		case 'D':
		    attr->flags |= MAIL_COPY_DELIVERED;
		    break;
		case 'F':
		    attr->flags |= MAIL_COPY_FROM;
		    break;
		case 'O':
		    attr->flags |= MAIL_COPY_ORIG_RCPT;
		    break;
		case 'R':
		    attr->flags |= MAIL_COPY_RETURN_PATH;
		    break;
		case 'X':
		    attr->flags |= PIPE_OPT_FINAL_DELIVERY;
		    break;
		case '.':
		    attr->flags |= MAIL_COPY_DOT;
		    break;
		case '>':
		    attr->flags |= MAIL_COPY_QUOTE;
		    break;
		case 'h':
		    attr->flags |= PIPE_OPT_FOLD_HOST;
		    break;
		case 'q':
		    attr->flags |= PIPE_OPT_QUOTE_LOCAL;
		    break;
		case 'u':
		    attr->flags |= PIPE_OPT_FOLD_USER;
		    break;
		default:
		    msg_fatal("unknown flag: %c (ignored)", *cp);
		    break;
		}
	    }
	}

	/*
	 * user=username[:groupname]
	 */
	else if (strncasecmp("user="******"user="******"user="******"%s: unknown username: %s", myname, user);
	    attr->uid = pwd->pw_uid;
	    if (group != 0) {
		if ((grp = getgrnam(group)) == 0)
		    msg_fatal("%s: unknown group: %s", myname, group);
		attr->gid = grp->gr_gid;
	    } else {
		attr->gid = pwd->pw_gid;
	    }
	}

	/*
	 * directory=string
	 */
	else if (strncasecmp("directory=", *argv, sizeof("directory=") - 1) == 0) {
	    attr->exec_dir = mystrdup(*argv + sizeof("directory=") - 1);
	}

	/*
	 * chroot=string
	 */
	else if (strncasecmp("chroot=", *argv, sizeof("chroot=") - 1) == 0) {
	    attr->chroot_dir = mystrdup(*argv + sizeof("chroot=") - 1);
	}

	/*
	 * eol=string
	 */
	else if (strncasecmp("eol=", *argv, sizeof("eol=") - 1) == 0) {
	    unescape(attr->eol, *argv + sizeof("eol=") - 1);
	}

	/*
	 * null_sender=string
	 */
	else if (strncasecmp("null_sender=", *argv, sizeof("null_sender=") - 1) == 0) {
	    vstring_strcpy(attr->null_sender, *argv + sizeof("null_sender=") - 1);
	}

	/*
	 * size=max_message_size (in bytes)
	 */
	else if (strncasecmp("size=", *argv, sizeof("size=") - 1) == 0) {
	    size = *argv + sizeof("size=") - 1;
	    if ((attr->size_limit = off_cvt_string(size)) < 0)
		msg_fatal("%s: bad size= value: %s", myname, size);
	}

	/*
	 * argv=command...
	 */
	else if (strncasecmp("argv=", *argv, sizeof("argv=") - 1) == 0) {
	    *argv += sizeof("argv=") - 1;	/* XXX clobbers argv */
	    attr->command = argv;
	    break;
	}

	/*
	 * Bad.
	 */
	else
	    msg_fatal("unknown attribute name: %s", *argv);
    }

    /*
     * Sanity checks. Verify that every member has an acceptable value.
     */
    if (user == 0)
	msg_fatal("missing user= command-line attribute");
    if (attr->command == 0)
	msg_fatal("missing argv= command-line attribute");
    if (attr->uid == 0)
	msg_fatal("user= command-line attribute specifies root privileges");
    if (attr->uid == var_owner_uid)
	msg_fatal("user= command-line attribute specifies mail system owner %s",
		  var_mail_owner);
    if (attr->gid == 0)
	msg_fatal("user= command-line attribute specifies privileged group id 0");
    if (attr->gid == var_owner_gid)
	msg_fatal("user= command-line attribute specifies mail system owner %s group id %ld",
		  var_mail_owner, (long) attr->gid);
    if (attr->gid == var_sgid_gid)
	msg_fatal("user= command-line attribute specifies mail system %s group id %ld",
		  var_sgid_group, (long) attr->gid);

    /*
     * Give the poor tester a clue of what is going on.
     */
    if (msg_verbose)
	msg_info("%s: uid %ld, gid %ld, flags %d, size %ld",
		 myname, (long) attr->uid, (long) attr->gid,
		 attr->flags, (long) attr->size_limit);
}
Beispiel #24
0
void edit_value(int curr)
{
    struct passwd *pw = NULL;
    char ctdluidname[256];
    char buf[SIZ];
    char *default_value = NULL;
    int ctdluid = 0;
    int portnum = 0;
    int auth = 0;
    int lportnum = 0;

    if (setup_type == UI_SILENT)
    {
        default_value = getenv(EnvNames[curr]);
    }
    if (default_value == NULL) {
        default_value = "";
    }

    switch (curr) {

    case eSysAdminName:
        getconf_str(admin_name, "c_sysadm");
        set_str_val(curr, admin_name, default_value);
        setconf_str("c_sysadm", admin_name);
        break;

    case eSysAdminPW:
        set_str_val(curr, admin_pass, default_value);
        break;

    case eUID:

        if (setup_type == UI_SILENT)
        {
            if (default_value) {
                ctdluid = atoi(default_value);
            }
        }
        else
        {
#ifdef __CYGWIN__
            ctdluid = 0;	/* work-around for Windows */
#else
            pw = getpwuid(ctdluid);
            if (pw == NULL) {
                set_int_val(curr, &ctdluid, default_value);
            }
            else {
                strcpy(ctdluidname, pw->pw_name);
                set_str_val(curr, ctdluidname, default_value);
                pw = getpwnam(ctdluidname);
                if (pw != NULL) {
                    ctdluid = pw->pw_uid;
                }
                else if (atoi(ctdluidname) > 0) {
                    ctdluid = atoi(ctdluidname);
                }
            }
#endif
        }
        setconf_int("c_ctdluid", ctdluid);
        break;

    case eIP_ADDR:
        getconf_str(buf, "c_ip_addr");
        set_str_val(curr, buf, default_value);
        setconf_str("c_ip_addr", buf);
        break;

    case eCTDL_Port:
        portnum = getconf_int("c_port_number");
        set_int_val(curr, &portnum, default_value);
        setconf_int("c_port_number", portnum);
        break;

    case eAuthType:
        auth = getconf_int("c_auth_mode");
        if (setup_type == UI_SILENT)
        {
            if ( (default_value) && (!strcasecmp(default_value, "yes")) ) auth = AUTHMODE_HOST;
            if ( (default_value) && (!strcasecmp(default_value, "host")) ) auth = AUTHMODE_HOST;
            if ( (default_value) && (!strcasecmp(default_value, "ldap")) ) auth = AUTHMODE_LDAP;
            if ( (default_value) && (!strcasecmp(default_value, "ldap_ad")) ) auth = AUTHMODE_LDAP_AD;
            if ( (default_value) && (!strcasecmp(default_value, "active directory")) ) auth = AUTHMODE_LDAP_AD;
        }
        else {
            set_int_val(curr, &auth, default_value);
        }
        setconf_int("c_auth_mode", auth);
        break;

    case eLDAP_Host:
        getconf_str(buf, "c_ldap_host");
        if (IsEmptyStr(buf)) {
            strcpy(buf, "localhost");
        }
        set_str_val(curr, buf, default_value);
        setconf_str("c_ldap_host", buf);
        break;

    case eLDAP_Port:
        lportnum = getconf_int("c_ldap_port");
        if (lportnum == 0) {
            lportnum = 389;
        }
        set_int_val(curr, &lportnum, default_value);
        setconf_int("c_ldap_port", lportnum);
        break;

    case eLDAP_Base_DN:
        getconf_str(buf, "c_ldap_base_dn");
        set_str_val(curr, buf, default_value);
        setconf_str("c_ldap_base_dn", buf);
        break;

    case eLDAP_Bind_DN:
        getconf_str(buf, "c_ldap_bind_dn");
        set_str_val(curr, buf, default_value);
        setconf_str("c_ldap_bind_dn", buf);
        break;

    case eLDAP_Bind_PW:
        getconf_str(buf, "c_ldap_bind_pw");
        set_str_val(curr, buf, default_value);
        setconf_str("c_ldap_bind_pw", buf);
        break;
    }
}
Beispiel #25
0
static  DEFPORT(WhoPort)
{
    char    *argv[] = {"/usr/tycho/sys/userlist", NULL};
    int     fd[2];
    char    *p;
    FILE    *fp;
    char    **list;
    char    *item;
    SELECT  opts = (SELECT)vu->vuoptions;
    static  char    buf[18];
    char    lbuf[128];
    VU              child;
    int     pid;
    char    *oldstat;
    int     oldcolor;

    switch(event) {
    case VU_DESTROY:
        list = (char **)vu->vupaint;
        while(*list)
            free(*(list++));
        free(vu->vupaint);
        break;
    case VU_BUTTON:
        list = (char **)vu->vupaint;
        strncpy(buf, list[opts->sel_mark], 16);
        buf[17] = 0;
        strtok(buf, " ");
        child = NULL;

        switch(p1) {
        case VU_MESSAGE:
            child = VUCreateQ(SendNotice, NULL, -1, -1, buf);
            break;
        case VU_FINGER:
            if(!strchr(buf, '@'))
                child = finger(getpwnam(buf));
            else
                child = netfinger(buf);
            endpwent();
            break;
        }
        if(child) {
            child->vuparent = vu->vuparent;
            vu->vuparent = child;
        }
        break;

    case VU_CREATE:
        oldstat = (char *)front->vustatline;
        oldcolor = front->vustatcolor;
        front->vustatline = (STRING)MSG_LOADING;
        front->vustatcolor = STAT_BUSY;
        fixcursor();
        front->vustatline = (STRING)oldstat;
        front->vustatcolor = oldcolor;

        if(!USEPORT(VUSelectPort))
            return FALSE;


        vu->vupaint = (char *)malloc(128 * sizeof(char *));
        list = (char **)vu->vupaint;
        list[0] = 0;
        pipe(fd);
        pid = fork();
        if(pid < 0)
            return FALSE;
        if(pid == 0) {
            dup2(fd[1], 1);
            close(fd[1]);
            close(fd[0]);
            write(1, "USERLIST\n", 9);
            execvp(*argv, argv);
            exit(-1);
        }

        close(fd[1]);
        fp = fdopen(fd[0], "r");
        fgets(lbuf, sizeof(lbuf) - 1, fp);
        while(!feof(fp)) {
            fgets(lbuf, sizeof(lbuf) - 1, fp);
            if(feof(fp))
                break;
            p = strchr(lbuf, '\n');
            *p = 0;
            item = (char *)malloc(strlen(lbuf) + 1);
            strcpy(item, lbuf);
            VUSelectInsert(vu, VUSelectLocate(vu, item, (int(*)(const char *s1, const char *s2)) VUStricmp), item);
        }
        fclose(fp);
        waitpid(pid, NULL, 0);
        opts->sel_mark = opts->sel_base = 0;
        return TRUE;
    default:
        break;
    }
    return USEPORT(VUSelectPort);
}
Beispiel #26
0
PAM_EXTERN int
pam_sm_authenticate(pam_handle_t *pamh, int flags,
	int argc, const char *argv[])
{
#ifndef OPENPAM
	struct pam_conv *conv;
	struct pam_message msg;
	const struct pam_message *msgp;
	struct pam_response *resp;
#endif
	struct passwd *pwd;
	const char *user;
	const char *crypt_password, *password;
	int pam_err, retry;

	(void)argc;
	(void)argv;

	/* identify user */
	if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
		return (pam_err);
	if ((pwd = getpwnam(user)) == NULL)
		return (PAM_USER_UNKNOWN);

	/* get password */
#ifndef OPENPAM
	pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
	if (pam_err != PAM_SUCCESS)
		return (PAM_SYSTEM_ERR);
	msg.msg_style = PAM_PROMPT_ECHO_OFF;
	msg.msg = password_prompt;
	msgp = &msg;
#endif
	for (retry = 0; retry < 3; ++retry) {
#ifdef OPENPAM
		pam_err = pam_get_authtok(pamh, PAM_AUTHTOK,
		    &password, NULL);
#else
		resp = NULL;
		pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr);
		if (resp != NULL) {
			if (pam_err == PAM_SUCCESS)
				password = resp->resp;
			else
				free(resp->resp);
			free(resp);
		}
#endif
		if (pam_err == PAM_SUCCESS)
			break;
	}
	if (pam_err == PAM_CONV_ERR)
		return (pam_err);
	if (pam_err != PAM_SUCCESS)
		return (PAM_AUTH_ERR);

	/* compare passwords */
	if ((!pwd->pw_passwd[0] && (flags & PAM_DISALLOW_NULL_AUTHTOK)) ||
	    (crypt_password = crypt(password, pwd->pw_passwd)) == NULL ||
	    strcmp(crypt_password, pwd->pw_passwd) != 0)
		pam_err = PAM_AUTH_ERR;
	else
		pam_err = PAM_SUCCESS;
#ifndef OPENPAM
	free(password);
#endif
	return (pam_err);
}
Beispiel #27
0
void
agentx_parse_agentx_perms(const char *token, char *cptr)
{
    char *socket_perm, *dir_perm, *socket_user, *socket_group;
    int uid = -1;
    int gid = -1;
    int s_perm = -1;
    int d_perm = -1;
    char *st;
#if HAVE_GETPWNAM && HAVE_PWD_H
    struct passwd *pwd;
#endif
#if HAVE_GETGRNAM && HAVE_GRP_H
    struct group  *grp;
#endif

    DEBUGMSGTL(("agentx/config", "port permissions: %s\n", cptr));
    socket_perm = strtok_r(cptr, " \t", &st);
    dir_perm    = strtok_r(NULL, " \t", &st);
    socket_user = strtok_r(NULL, " \t", &st);
    socket_group = strtok_r(NULL, " \t", &st);

    if (socket_perm) {
        s_perm = strtol(socket_perm, NULL, 8);
        netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_X_SOCK_PERM, s_perm);
        DEBUGMSGTL(("agentx/config", "socket permissions: %o (%d)\n",
                    s_perm, s_perm));
    }
    if (dir_perm) {
        d_perm = strtol(dir_perm, NULL, 8);
        netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_X_DIR_PERM, d_perm);
        DEBUGMSGTL(("agentx/config", "directory permissions: %o (%d)\n",
                    d_perm, d_perm));
    }

    /*
     * Try to handle numeric UIDs or user names for the socket owner
     */
    if (socket_user) {
        uid = atoi(socket_user);
        if ( uid == 0 ) {
#if HAVE_GETPWNAM && HAVE_PWD_H
            pwd = getpwnam( socket_user );
            if (pwd)
                uid = pwd->pw_uid;
            else
#endif
                snmp_log(LOG_WARNING, "Can't identify AgentX socket user (%s).\n", socket_user);
        }
        if ( uid != 0 )
            netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_AGENT_X_SOCK_USER, uid);
        DEBUGMSGTL(("agentx/config", "socket owner: %s (%d)\n",
                    socket_user, uid));
    }

    /*
     * and similarly for the socket group ownership
     */
    if (socket_group) {
        gid = atoi(socket_group);
        if ( gid == 0 ) {
#if HAVE_GETGRNAM && HAVE_GRP_H
            grp = getgrnam( socket_group );
            if (grp)
                gid = grp->gr_gid;
            else
#endif
                snmp_log(LOG_WARNING, "Can't identify AgentX socket group (%s).\n", socket_group);
        }
        if ( gid != 0 )
            netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_AGENT_X_SOCK_GROUP, gid);
        DEBUGMSGTL(("agentx/config", "socket group: %s (%d)\n",
                    socket_group, gid));
    }
}
Beispiel #28
0
void
init_editfns ()
{
  char *user_name;
  register unsigned char *p, *q;
  struct passwd *pw;		/* password entry for the current user */
  Lisp_Object tem;
  extern char *index ();

  /* Set up system_name even when dumping.  */

  Vsystem_name = build_string (get_system_name ());
  p = XSTRING (Vsystem_name)->data;
  while (*p)
    {
      if (*p == ' ' || *p == '\t')
	*p = '-';
      p++;
    }

#ifndef CANNOT_DUMP
  /* Don't bother with this on initial start when just dumping out */
  if (!initialized)
    return;
#endif				/* not CANNOT_DUMP */

  pw = (struct passwd *) getpwuid (getuid ());
  Vuser_real_name = build_string (pw ? pw->pw_name : "unknown");

  user_name = (char *) getenv ("USER");
  if (!user_name)
    user_name = (char *) getenv ("LOGNAME"); /* USG equivalent */
  if (user_name)
    Vuser_name = build_string (user_name);
  else
    Vuser_name = Vuser_real_name;

  tem = Fstring_equal (Vuser_name, Vuser_real_name);
  if (!NULL (tem))
    pw = (struct passwd *) getpwnam (user_name);
  
  p = (unsigned char *) (pw ? USER_FULL_NAME : "unknown");
  q = (unsigned char *) index (p, ',');
  Vuser_full_name = make_string (p, q ? q - p : strlen (p));

#ifdef AMPERSAND_FULL_NAME
  p = XSTRING (Vuser_full_name)->data;
  q = (unsigned char *) index (p, '&');
  /* Substitute the login name for the &, upcasing the first character.  */
  if (q)
    {
      char *r
	= (char *) alloca (strlen (p) + XSTRING (Vuser_name)->size + 1);
      bcopy (p, r, q - p);
      r[q - p] = 0;
      strcat (r, XSTRING (Vuser_real_name)->data);
      r[q - p] = UPCASE (r[q - p]);
      strcat (r, q + 1);
      Vuser_full_name = build_string (r);
    }
#endif				/* AMPERSAND_FULL_NAME */
}
Beispiel #29
0
Server::Server() :
    m_lockFileName(Config::Instance()->lockFileName),
    m_pidFileName(Config::Instance()->pidFileName)
{
	pid_t pid, sid, parent;
	int lfp = -1;
	struct stat sb;

	/* already a daemon */
	if(getppid() == 1) return;

	if(m_lockFileName.size())
	{
	    if (stat(m_lockFileName.c_str(), &sb) != -1)
	    {
			syslog(LOG_INFO, "another process running?");
			if( getProcIdByName(__progname) > 0)
            {
                syslog(LOG_ERR, "exit");
                exit(EXIT_FAILURE);
            }
            else
            {
                ::remove(m_lockFileName.c_str());
            }
        }

		lfp = open(m_lockFileName.c_str(),O_RDWR|O_CREAT,0640);

		if(lfp < 0)
		{
			syslog(LOG_ERR, "unable to create lock file %s, code=%d (%s). exit",
			       m_lockFileName.c_str(), errno, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	if(getuid() == 0 || geteuid() == 0)
	{
		struct passwd *pw = getpwnam(Config::Instance()->asUser.c_str());

		if(pw)
		{
			syslog(LOG_NOTICE, "setting user to %s",Config::Instance()->asUser.c_str());
      if(setuid(pw->pw_uid))
        syslog(LOG_ERR,"error set uid");
		}
	}

	signal(SIGCHLD,child_handler);
	signal(SIGUSR1,child_handler);
	signal(SIGALRM,child_handler);

	pid = fork();

	if(pid < 0)
	{
		syslog(LOG_ERR, "unable to fork daemon, code=%d (%s). exit", errno, strerror(errno));
		exit(EXIT_FAILURE);
	}

	if(pid > 0)
	{
		alarm(2);
		pause();
		exit(EXIT_FAILURE);
	}

	parent = getppid();

	signal(SIGCHLD,SIG_DFL);
	signal(SIGTSTP,SIG_IGN);
	signal(SIGTTOU,SIG_IGN);
	signal(SIGTTIN,SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGTERM,SIG_DFL);
	signal(SIGPIPE,SIG_IGN);
	signal(SIGRTMIN,SIG_DFL);

	umask(007);

	sid = setsid();

	if(sid < 0)
	{
		syslog(LOG_ERR, "unable to create a new session, code %d (%s)",
		       errno, strerror(errno));
//		exit(EXIT_FAILURE);
	}

	if((chdir("/")) < 0)
	{
		syslog(LOG_ERR, "unable to change directory to %s, code %d (%s). exit",
		       "/", errno, strerror(errno));
//		exit(EXIT_FAILURE);
	}

	if(!freopen("/dev/null", "r", stdin))
		syslog(LOG_ERR, "unable to change stdin");

  if(Config::Instance()->debug)
  {
	  if(freopen(Config::Instance()->debug_file.c_str(), "w", stdout))
		  syslog(LOG_ERR, "unable to change stdout to:%s",Config::Instance()->debug_file.c_str());
	  if(!freopen(Config::Instance()->debug_file.c_str(), "w", stderr))
	  	syslog(LOG_ERR, "unable to change stdin %s",Config::Instance()->debug_file.c_str());
    printf("start\n");
  }
  else
  {
	  if(freopen("/dev/null", "w", stdout))
		  syslog(LOG_ERR, "unable to change stdout");
	  if(!freopen("/dev/null", "w", stderr))
	  	syslog(LOG_ERR, "unable to change stderr");
	  kill(parent, SIGUSR1);
  }
    struct sched_param param;
    param.sched_priority = 49;

    if(sched_setscheduler(0, SCHED_FIFO, &param) == -1)
    {
        syslog(LOG_ERR,"sched_setscheduler failed");
        //exit(-1);
    }

    if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1)
    {
        syslog(LOG_ERR,"mlockall failed");
        //exit(-2);
    }

	writePid(m_pidFileName);

	syslog(LOG_NOTICE, "staring: done");
}
Beispiel #30
0
int main(int argc, char ** argv)
{
	int c;
	int flags = MS_MANDLOCK; /* no need to set legacy MS_MGC_VAL */
	char * orgoptions = NULL;
	char * share_name = NULL;
	char * ipaddr = NULL;
	char * uuid = NULL;
	char * mountpoint = NULL;
	char * options = NULL;
	char * resolved_path = NULL;
	char * temp;
	int rc;
	int rsize = 0;
	int wsize = 0;
	int nomtab = 0;
	int uid = 0;
	int gid = 0;
	int optlen = 0;
	int orgoptlen = 0;
	size_t options_size = 0;
	int retry = 0; /* set when we have to retry mount with uppercase */
	struct stat statbuf;
	struct utsname sysinfo;
	struct mntent mountent;
	FILE * pmntfile;

	/* setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE); */

	if(argc && argv) {
		thisprogram = argv[0];
	} else {
		mount_cifs_usage();
		exit(1);
	}

	if(thisprogram == NULL)
		thisprogram = "mount.cifs";

	uname(&sysinfo);
	/* BB add workstation name and domain and pass down */

/* #ifdef _GNU_SOURCE
	printf(" node: %s machine: %s sysname %s domain %s\n", sysinfo.nodename,sysinfo.machine,sysinfo.sysname,sysinfo.domainname);
#endif */
	if(argc > 2) {
		share_name = argv[1];
		mountpoint = argv[2];
	}

	/* add sharename in opts string as unc= parm */

	while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsSU:vVwt:",
			 longopts, NULL)) != -1) {
		switch (c) {
/* No code to do the following  options yet */
/*	case 'l':
		list_with_volumelabel = 1;
		break;
	case 'L':
		volumelabel = optarg;
		break; */
/*	case 'a':	       
		++mount_all;
		break; */

		case '?':
		case 'h':	 /* help */
			mount_cifs_usage ();
			exit(1);
		case 'n':
		    ++nomtab;
		    break;
		case 'b':
#ifdef MS_BIND
			flags |= MS_BIND;
#else
			fprintf(stderr,
				"option 'b' (MS_BIND) not supported\n");
#endif
			break;
		case 'm':
#ifdef MS_MOVE		      
			flags |= MS_MOVE;
#else
			fprintf(stderr,
				"option 'm' (MS_MOVE) not supported\n");
#endif
			break;
		case 'o':
			orgoptions = strdup(optarg);
		    break;
		case 'r':  /* mount readonly */
			flags |= MS_RDONLY;
			break;
		case 'U':
			uuid = optarg;
			break;
		case 'v':
			++verboseflag;
			break;
		case 'V':	   
			printf ("mount.cifs version: %s.%s%s\n",
			MOUNT_CIFS_VERSION_MAJOR,
			MOUNT_CIFS_VERSION_MINOR,
			MOUNT_CIFS_VENDOR_SUFFIX);
			if(mountpassword) {
				memset(mountpassword,0,64);
			}
			exit (0);
		case 'w':
			flags &= ~MS_RDONLY;
			break;
		case 'R':
			rsize = atoi(optarg) ;
			break;
		case 'W':
			wsize = atoi(optarg);
			break;
		case '1':
			if (isdigit(*optarg)) {
				char *ep;

				uid = strtoul(optarg, &ep, 10);
				if (*ep) {
					printf("bad uid value \"%s\"\n", optarg);
					exit(1);
				}
			} else {
				struct passwd *pw;

				if (!(pw = getpwnam(optarg))) {
					printf("bad user name \"%s\"\n", optarg);
					exit(1);
				}
				uid = pw->pw_uid;
				endpwent();
			}
			break;
		case '2':
			if (isdigit(*optarg)) {
				char *ep;

				gid = strtoul(optarg, &ep, 10);
				if (*ep) {
					printf("bad gid value \"%s\"\n", optarg);
					exit(1);
				}
			} else {
				struct group *gr;

				if (!(gr = getgrnam(optarg))) {
					printf("bad user name \"%s\"\n", optarg);
					exit(1);
				}
				gid = gr->gr_gid;
				endpwent();
			}
			break;
		case 'u':
			got_user = 1;
			user_name = optarg;
			break;
		case 'd':
			domain_name = optarg; /* BB fix this - currently ignored */
			got_domain = 1;
			break;
		case 'p':
			if(mountpassword == NULL)
				mountpassword = (char *)calloc(65,1);
			if(mountpassword) {
				got_password = 1;
				strncpy(mountpassword,optarg,64);
			}
			break;
		case 'S':
			get_password_from_file(0 /* stdin */,NULL);
			break;
		case 't':
			break;
		default:
			printf("unknown mount option %c\n",c);
			mount_cifs_usage();
			exit(1);
		}
	}

	if((argc < 3) || (share_name == NULL) || (mountpoint == NULL)) {
		mount_cifs_usage();
		exit(1);
	}

	if (getenv("PASSWD")) {
		if(mountpassword == NULL)
			mountpassword = (char *)calloc(65,1);
		if(mountpassword) {
			strncpy(mountpassword,getenv("PASSWD"),64);
			got_password = 1;
		}
	} else if (getenv("PASSWD_FD")) {
		get_password_from_file(atoi(getenv("PASSWD_FD")),NULL);
	} else if (getenv("PASSWD_FILE")) {
		get_password_from_file(0, getenv("PASSWD_FILE"));
	}

        if (orgoptions && parse_options(&orgoptions, &flags)) {
                rc = -1;
		goto mount_exit;
	}
	ipaddr = parse_server(&share_name);
	if((ipaddr == NULL) && (got_ip == 0)) {
		printf("No ip address specified and hostname not found\n");
		rc = -1;
		goto mount_exit;
	}
	
	/* BB save off path and pop after mount returns? */
	resolved_path = (char *)malloc(PATH_MAX+1);
	if(resolved_path) {
		/* Note that if we can not canonicalize the name, we get
		another chance to see if it is valid when we chdir to it */
		if (realpath(mountpoint, resolved_path)) {
			mountpoint = resolved_path; 
		}
	}
	if(chdir(mountpoint)) {
		printf("mount error: can not change directory into mount target %s\n",mountpoint);
		rc = -1;
		goto mount_exit;
	}

	if(stat (".", &statbuf)) {
		printf("mount error: mount point %s does not exist\n",mountpoint);
		rc = -1;
		goto mount_exit;
	}

	if (S_ISDIR(statbuf.st_mode) == 0) {
		printf("mount error: mount point %s is not a directory\n",mountpoint);
		rc = -1;
		goto mount_exit;
	}

	if((getuid() != 0) && (geteuid() == 0)) {
		if((statbuf.st_uid == getuid()) && (S_IRWXU == (statbuf.st_mode & S_IRWXU))) {
#ifndef CIFS_ALLOW_USR_SUID
			/* Do not allow user mounts to control suid flag
			for mount unless explicitly built that way */
			flags |= MS_NOSUID | MS_NODEV;
#endif						
		} else {
			printf("mount error: permission denied or not superuser and mount.cifs not installed SUID\n"); 
			return -1;
		}
	}

	if(got_user == 0) {
		user_name = getusername();
		got_user = 1;
	}
       
	if(got_password == 0) {
		char *tmp_pass;
		tmp_pass = getpass("Password: "******"Password not entered, exiting.\n");
			return -1;
		}
		strncpy(mountpassword, tmp_pass, 64);
						 
		got_password = 1;
	}
	/* FIXME launch daemon (handles dfs name resolution and credential change) 
	   remember to clear parms and overwrite password field before launching */
mount_retry:
	if(orgoptions) {
		optlen = strlen(orgoptions);
		orgoptlen = optlen;
	} else
		optlen = 0;
	if(share_name)
		optlen += strlen(share_name) + 4;
	else {
		printf("No server share name specified\n");
		printf("\nMounting the DFS root for server not implemented yet\n");
                exit(1);
	}
	if(user_name)
		optlen += strlen(user_name) + 6;
	if(ipaddr)
		optlen += strlen(ipaddr) + 4;
	if(mountpassword)
		optlen += strlen(mountpassword) + 6;
	if(options) {
		free(options);
		options = NULL;
	}
	options_size = optlen + 10 + 64;
	options = (char *)malloc(options_size /* space for commas in password */ + 8 /* space for domain=  , domain name itself was counted as part of the length username string above */);

	if(options == NULL) {
		printf("Could not allocate memory for mount options\n");
		return -1;
	}

	options[0] = 0;
	strlcpy(options,"unc=",options_size);
	strlcat(options,share_name,options_size);
	/* scan backwards and reverse direction of slash */
	temp = strrchr(options, '/');
	if(temp > options + 6)
		*temp = '\\';
	if(ipaddr) {
		strlcat(options,",ip=",options_size);
		strlcat(options,ipaddr,options_size);
	}

	if(user_name) {
		/* check for syntax like user=domain\user */
		if(got_domain == 0)
			domain_name = check_for_domain(&user_name);
		strlcat(options,",user="******",domain=",options_size);
			strlcat(options,domain_name,options_size);
		}
	}
	if(mountpassword) {
		/* Commas have to be doubled, or else they will
		look like the parameter separator */
/*		if(sep is not set)*/
		if(retry == 0)
			check_for_comma(&mountpassword);
		strlcat(options,",pass="******",ver=",options_size);
	strlcat(options,MOUNT_CIFS_VERSION_MAJOR,options_size);

	if(orgoptions) {
		strlcat(options,",",options_size);
		strlcat(options,orgoptions,options_size);
	}
	if(prefixpath) {
		strlcat(options,",prefixpath=",options_size);
		strlcat(options,prefixpath,options_size); /* no need to cat the / */
	}
	if(verboseflag)
		printf("\nmount.cifs kernel mount options %s \n",options);
	if(mount(share_name, mountpoint, "cifs", flags, options)) {
	/* remember to kill daemon on error */
		char * tmp;

		switch (errno) {
		case 0:
			printf("mount failed but no error number set\n");
			break;
		case ENODEV:
			printf("mount error: cifs filesystem not supported by the system\n");
			break;
		case ENXIO:
			if(retry == 0) {
				retry = 1;
				tmp = share_name;
				while (*tmp && !(((unsigned char)tmp[0]) & 0x80)) {
					*tmp = toupper((unsigned char)*tmp);
		        		tmp++;
				}
				if(!*tmp) {
					printf("retrying with upper case share name\n");
					goto mount_retry;
				}
			}
		default:
			printf("mount error %d = %s\n",errno,strerror(errno));
		}
		printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n");
		rc = -1;
		goto mount_exit;
	} else {
		pmntfile = setmntent(MOUNTED, "a+");
		if(pmntfile) {
			mountent.mnt_fsname = share_name;
			mountent.mnt_dir = mountpoint; 
			mountent.mnt_type = CONST_DISCARD(char *,"cifs"); 
			mountent.mnt_opts = (char *)malloc(220);
			if(mountent.mnt_opts) {
				char * mount_user = getusername();
				memset(mountent.mnt_opts,0,200);
				if(flags & MS_RDONLY)
					strlcat(mountent.mnt_opts,"ro",220);
				else
					strlcat(mountent.mnt_opts,"rw",220);
				if(flags & MS_MANDLOCK)
					strlcat(mountent.mnt_opts,",mand",220);
				if(flags & MS_NOEXEC)
					strlcat(mountent.mnt_opts,",noexec",220);
				if(flags & MS_NOSUID)
					strlcat(mountent.mnt_opts,",nosuid",220);
				if(flags & MS_NODEV)
					strlcat(mountent.mnt_opts,",nodev",220);
				if(flags & MS_SYNCHRONOUS)
					strlcat(mountent.mnt_opts,",synch",220);
				if(mount_user) {
					if(getuid() != 0) {
						strlcat(mountent.mnt_opts,",user="******"could not update mount table\n");
		}
	}