Exemplo n.º 1
0
int DirNode::mkdir(const char *plaintextPath, mode_t mode, uid_t uid,
                   gid_t gid) {
  string cyName = rootDir + naming->encodePath(plaintextPath);
  rAssert(!cyName.empty());

  VLOG(1) << "mkdir on " << cyName;

  // if uid or gid are set, then that should be the directory owner
#if 0
  int olduid = -1;
  int oldgid = -1;
  if (uid != 0) olduid = setfsuid(uid);
  if (gid != 0) oldgid = setfsgid(gid);
#endif

  int res = unix::mkdir(cyName.c_str(), mode);

#if 0
  if (olduid >= 0) setfsuid(olduid);
  if (oldgid >= 0) setfsgid(oldgid);
#endif

  if (res == -1) {
    int eno = errno;
    RLOG(WARNING) << "mkdir error on " << cyName << " mode " << mode << ": "
                  << strerror(eno);
    res = -eno;
  } else
    res = 0;

  return res;
}
Exemplo n.º 2
0
   Result<bool> ChangeFileOrDirOwnershipToUser(const std::string& path, const std::string& username) {

      std::lock_guard<std::mutex> lock(mPermissionsMutex);
      auto previuousuid = setfsuid(-1);
      auto previuousgid = setfsgid(-1);
      setfsuid(0);
      setfsgid(0);
      struct passwd* pwd = GetUserFromPasswordFile(username);
      auto returnVal = chown(path.c_str(), pwd->pw_uid, pwd->pw_gid);
      free(pwd);

      if (returnVal < 0) {
         std::string error{"Cannot chown dir/file: "};
         error.append(path);
         error.append(" error number: ");
         error.append(std::to_string(errno));
         error.append(" current fs permissions are for uid: ");
         error.append(std::to_string(setfsuid(-1)));
         setfsuid(previuousuid);
         setfsgid(previuousgid);
         return Result<bool>{false, error};
      }
      setfsuid(previuousuid);
      setfsgid(previuousgid);
      return Result<bool>{true};
   }
Exemplo n.º 3
0
gid_t setgroup(gid_t gid)
{
	gid_t orig_gid = setfsgid(gid);
	if (gid != setfsgid(gid))
		LogCrit(COMPONENT_FSAL, "Could not set group identity");

	return orig_gid;
}
Exemplo n.º 4
0
int main(int argc, char **argv)
{
	int ret, verbose = 0, c, opt_index, bypass = 0, decimal = 0;
	char *file = NULL;

	setfsuid(getuid());
	setfsgid(getgid());

	if (argc == 1)
		help();

	while ((c = getopt_long(argc, argv, short_options,
			        long_options, &opt_index)) != EOF) {
		switch (c) {
		case 'h':
			help();
			break;
		case 'v':
			version();
			break;
		case 'V':
			verbose = 1;
			break;
		case 'D':
			decimal = 1;
			break;
		case 'b':
			bypass = 1;
			break;
		case 'd':
			bpf_dump_op_table();
			die();
		case 'i':
			file = xstrdup(optarg);
			break;
		case '?':
			switch (optopt) {
			case 'i':
				panic("Option -%c requires an argument!\n",
				      optopt);
			default:
				if (isprint(optopt))
					printf("Unknown option character `0x%X\'!\n", optopt);
				die();
			}
		default:
			break;
		}
	}

	if (argc == 2)
		file = xstrdup(argv[1]);
	if (!file)
		panic("No Berkeley Packet Filter program specified!\n");

	ret = compile_filter(file, verbose, bypass, decimal);

	xfree(file);
	return ret;
}
Exemplo n.º 5
0
static void restore_privs(void)
{
    if (getuid() != 0) {
        setfsuid(oldfsuid);
        setfsgid(oldfsgid);
    }
}
Exemplo n.º 6
0
static void drop_privs(void)
{
    if (getuid() != 0) {
        oldfsuid = setfsuid(getuid());
        oldfsgid = setfsgid(getgid());
    }
}
Exemplo n.º 7
0
static int drop_privs()
{
    int res;
    struct __user_cap_header_struct head;
    struct __user_cap_data_struct newcaps;

    head.version = _LINUX_CAPABILITY_VERSION;
    head.pid = 0;
    res = capget(&head, &oldcaps);
    if(res == -1) {
        fprintf(stderr, "%s: failed to get capabilities: %s\n", progname,
                strerror(errno));
        return -1;
    }

    oldfsuid = setfsuid(getuid());
    oldfsgid = setfsgid(getgid());
    newcaps = oldcaps;
    /* Keep CAP_SYS_ADMIN for mount */
    newcaps.effective &= (1 << CAP_SYS_ADMIN);

    head.version = _LINUX_CAPABILITY_VERSION;
    head.pid = 0;
    res = capset(&head, &newcaps);
    if(res == -1) {
        fprintf(stderr, "%s: failed to set capabilities: %s\n", progname,
                strerror(errno));
        return -1;
    }
    return 0;
}
Exemplo n.º 8
0
static void
setfsids(uid_t cred_uid, gid_t cred_gid, gid_t * cred_gids, int cred_len)
{
	setfsuid(cred_uid);
	setfsgid(cred_gid);

	/* First, set the user ID. */
	if (auth_uid != cred_uid) {
		if (setfsuid(cred_uid) < 0)
			dbg_printf(__FILE__, __LINE__, L_ERROR,
				   "Unable to setfsuid %d: %s\n", cred_uid,
				   strerror(errno));
		else
			auth_uid = cred_uid;
	}

	/* Next, the group ID. */
	if (auth_gid != cred_gid) {
		if (setfsgid(cred_gid) < 0)
			dbg_printf(__FILE__, __LINE__, L_ERROR,
				   "Unable to setfsgid %d: %s\n", cred_gid,
				   strerror(errno));
		else
			auth_gid = cred_gid;
	}
#ifdef HAVE_SETGROUPS
	/* Finally, set the supplementary group IDs if possible. */
	if (cred_len < 0 || cred_len > NGRPS)
		dbg_printf(__FILE__, __LINE__, L_ERROR,
			   "Negative or huge cred_len: %d\n", cred_len);
	else if (cred_len != auth_gidlen
		 || memcmp(cred_gids, auth_gids,
			   auth_gidlen * sizeof(gid_t))) {
		if (setgroups(cred_len, cred_gids) < 0)
			dbg_printf(__FILE__, __LINE__, L_ERROR,
				   "Unable to setgroups: %s\n",
				   strerror(errno));
		else {
			memcpy(auth_gids, cred_gids,
			       cred_len * sizeof(gid_t));
			auth_gidlen = cred_len;
		}
	}
#endif /* HAVE_SETGROUPS */

}
Exemplo n.º 9
0
void testValues() {
    f = 2;
    
    setfsgid(anyint());

    //@ assert f == 2;
    //@ assert vacuous: \false;
}
Exemplo n.º 10
0
   /*
    * When running as root, change the file system access to a user.
    */
   void SetUserFileSystemAccess(const std::string& username) {
      struct passwd* pwd = GetUserFromPasswordFile(username);

      setfsuid(pwd->pw_uid);
      setfsgid(pwd->pw_gid);

      free(pwd);

   }
Exemplo n.º 11
0
   Result<std::string> ReadAsciiFileContentAsRoot(const std::string& filename) {

      std::lock_guard<std::mutex> lock(mPermissionsMutex);
      auto previuousuid = setfsuid(-1);
      auto previuousgid = setfsgid(-1);

      // RAII resource cleanup; de-escalate privileges from root to previous: 
      std::shared_ptr<void> resetPreviousPermisions(nullptr, [&](void*) {
         setfsuid(previuousuid);
         setfsgid(previuousgid);
      });

      setfsuid(0);
      setfsgid(0);
      auto result = ReadAsciiFileContent(filename);

      return result;
   }
static int mate_score_child(int infileno, int outfileno)
{
	struct command cmd;
	gchar* level;
	gchar* realname;
	gint retval;

	#ifdef HAVE_SETFSGID
	   gid_t gid;

	   gid = getegid();
	   setgid(getgid());
	   setfsgid(gid);
	#endif

	realname = g_strdup(g_get_real_name());

	if (strcmp(realname, "Unknown") == 0)
	{
		g_free(realname);
		realname = g_strdup(g_get_user_name());
	}

	while (read(infileno, &cmd, sizeof cmd) == sizeof(cmd))
	{
		level = g_new (char, cmd.level);

		if (read(infileno, level, cmd.level) != cmd.level)
		{
			g_free(realname);

			return EXIT_FAILURE;
		}

		if (!*level)
		{
			g_free(level);
			level = NULL;
		}

		retval = log_score(defgamename, level, realname, cmd.score, cmd.ordering);

		if (write(outfileno, &retval, sizeof retval) != sizeof retval)
		{
			g_free(realname);
			return EXIT_FAILURE;
		}

		g_free(level);
	}

	g_free(realname);

	return EXIT_SUCCESS;
}
Exemplo n.º 13
0
static void restore_privs(void)
{
	if (getuid() != 0) {
#ifdef HAVE_SET_FSID
		setfsuid(oldfsuid);
		setfsgid(oldfsgid);
#else
		fprintf(stderr, "%s: Implement alternative setfsuid/gid \n", progname);
#endif
	}
}
Exemplo n.º 14
0
static void drop_privs(void)
{
	if (getuid() != 0) {
#ifdef HAVE_SET_FSID
		oldfsuid = setfsuid(getuid());
		oldfsgid = setfsgid(getgid());
#else
		fprintf(stderr, "%s: Implement alternative setfsuid/gid \n", progname);
#endif
	}
}
Exemplo n.º 15
0
   Result<bool> RemoveFileAsRoot(const std::string& filename) {

      std::lock_guard<std::mutex> lock(mPermissionsMutex);
      auto previuousuid = setfsuid(-1);
      auto previuousgid = setfsgid(-1);

      // RAII resource cleanup; de-escalate privileges from root to previous: 
      std::shared_ptr<void> resetPreviousPermisions(nullptr, [&](void*) {
         setfsuid(previuousuid);
         setfsgid(previuousgid);
      });

      setfsuid(0);
      setfsgid(0);
      int rc = unlink(filename.c_str());

      if (rc == -1) {
         return Result<bool>{false, "Unable to unlink file"};
      }
      return Result<bool>{true};
   }
Exemplo n.º 16
0
/**
 * Create a symbolic link pointing to "to" named "from"
 */
int encfs_symlink(const char *to, const char *from) {
  EncFS_Context *ctx = context();

  if (isReadOnly(ctx)) return -EROFS;

  int res = -EIO;
  std::shared_ptr<DirNode> FSRoot = ctx->getRoot(&res);
  if (!FSRoot) return res;

  try {
    string fromCName = FSRoot->cipherPath(from);
    // allow fully qualified names in symbolic links.
    string toCName = FSRoot->relativeCipherPath(to);

    VLOG(1) << "symlink " << fromCName << " -> " << toCName;

    // use setfsuid / setfsgid so that the new link will be owned by the
    // uid/gid provided by the fuse_context.
    int olduid = -1;
    int oldgid = -1;
    if (ctx->publicFilesystem) {
      fuse_context *context = fuse_get_context();
      olduid = setfsuid(context->uid);
      oldgid = setfsgid(context->gid);
    }
    res = ::symlink(toCName.c_str(), fromCName.c_str());
    if (olduid >= 0) setfsuid(olduid);
    if (oldgid >= 0) setfsgid(oldgid);

    if (res == -1)
      res = -errno;
    else
      res = ESUCCESS;
  } catch (encfs::Error &err) {
    RLOG(ERROR) << "error caught in symlink: " << err.what();
  }
  return res;
}
Exemplo n.º 17
0
int main(int ac, char **av)
{
	int lc;			/* loop counter */
	char *msg;		/* message returned from parse_opts */

	gid_t gid;

	/* parse standard options */
	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
	}

	setup();

	/* Check for looping state if -i option is given */
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		/* reset Tst_count in case we are looping */
		Tst_count = 0;

		gid = 1;
		while (!getgrgid(gid)) {
			gid++;
		}

		TEST(setfsgid(gid));

		if (TEST_RETURN == -1) {
			tst_resm(TFAIL, "call failed unexpectedly - errno %d",
				 TEST_ERRNO);
			continue;
		}

		if (!STD_FUNCTIONAL_TEST) {
			tst_resm(TPASS, "call succeeded");
			continue;
		}

		if (TEST_RETURN == gid) {
			tst_resm(TFAIL,
				 "setfsgid() returned %ld, expected anything but %d",
				 TEST_RETURN, gid);
		} else {
			tst_resm(TPASS, "setfsgid() returned expected value : "
				 "%ld", TEST_RETURN);
		}
	}
	cleanup();

	  return EXIT_SUCCESS;
}
Exemplo n.º 18
0
static void restore_privs()
{
    struct __user_cap_header_struct head;
    int res;

    head.version = _LINUX_CAPABILITY_VERSION;
    head.pid = 0;
    res = capset(&head, &oldcaps);
    if(res == -1)
        fprintf(stderr, "%s: failed to restore capabilities: %s\n", progname,
                strerror(errno));

    setfsuid(oldfsuid);
    setfsgid(oldfsgid);
}
Exemplo n.º 19
0
int main(int ac, char **av)
{
	int lc;				/* loop counter */
	char *msg;			/* message returned from parse_opts */

	gid_t gid;
	
	/* parse standard options */
	if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
		tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
	}

	setup();

	/* Check for looping state if -i option is given */
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		/* reset Tst_count in case we are looping */
		Tst_count = 0;

		gid = getegid();

		TEST(setfsgid(gid));

		if (TEST_RETURN == -1) {
			tst_resm(TFAIL, "call failed unexpectedly - errno %d",
				 TEST_ERRNO);
			continue;
		}

		if (!STD_FUNCTIONAL_TEST) {
			tst_resm(TPASS, "call succeeded");
			continue;
		}

		if (TEST_RETURN != gid) {
			tst_resm(TFAIL, "setfsgid() returned %d, expeceted %d",
				 TEST_RETURN, gid);
		} else {
			tst_resm(TPASS, "setfsgid() returned expected value : "
				 "%d", gid);
		}
	}
	cleanup();

	/*NOTREACHED*/ 
	return(0);
}
Exemplo n.º 20
0
/*
 * from man 7 capabilities, section
 * Effect of User ID Changes on Capabilities:
 * 4. If the file system user ID is changed from 0 to nonzero (see setfsuid(2))
 * then the following capabilities are cleared from the effective set:
 * CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH,  CAP_FOWNER, CAP_FSETID,
 * CAP_LINUX_IMMUTABLE  (since  Linux 2.2.30), CAP_MAC_OVERRIDE, and CAP_MKNOD
 * (since Linux 2.2.30). If the file system UID is changed from nonzero to 0,
 * then any of these capabilities that are enabled in the permitted set
 * are enabled in the effective set.
 */
static int setfsugid(int uid, int gid)
{
    /*
     * We still need DAC_OVERRIDE because  we don't change
     * supplementary group ids, and hence may be subjected DAC rules
     */
    cap_value_t cap_list[] = {
        CAP_DAC_OVERRIDE,
    };

    setfsgid(gid);
    setfsuid(uid);

    if (uid != 0 || gid != 0) {
        return do_cap_set(cap_list, ARRAY_SIZE(cap_list), 0);
    }
    return 0;
}
Exemplo n.º 21
0
nix_uid_t
nix_linux_setfsgid(nix_gid_t gid, nix_env_t *env)
{
#ifdef HAVE_SETFSGID
	int rv;

	errno = 0;
	rv = setfsgid((gid_t)gid);
	if (errno != 0) {
		nix_env_set_errno(env, errno);
		return (-1);
	}

	return (rv);
#else
	nix_gid_t last = g_fsgid;
	g_fsgid = gid;
	return (last);
#endif
}
Exemplo n.º 22
0
static void
change_fsid (uid_t olduid, gid_t oldgid, uid_t uid, gid_t gid)
{
    uid_t u;
    gid_t g;

    if (uid != olduid) {
        u = setfsuid (uid);
        if (u == -1)
            err ("setfsuid");
        else if (u != olduid)
            msg ("setfsuid returned %d (wanted %d)", u, olduid);
    }
    if (gid != oldgid) {
        g = setfsgid (gid);
        if (g == -1)
            err ("setfsgid");
        else if (g != oldgid)
            msg ("setfsgid returned %d (wanted %d)", g, oldgid);
    }
    if (!check_fsid (uid, gid))
        msg_exit ("setfsuid/setfsgid failed");
    msg ("fsid changed to %d:%d", uid, gid);
}
Exemplo n.º 23
0
void runSuccess() {
    setfsgid(anyint());
}
Exemplo n.º 24
0
static void overlay_mknod(fuse_req_t req, struct inode_struct *pinode, struct name_struct *xname, struct call_info_struct *call_info, mode_t mode, dev_t rdev)
{
    struct resource_struct *resource=call_info->object->resource;
    struct localfile_struct *localfile=(struct localfile_struct *) resource->data;
    struct pathinfo_struct *pathinfo=&call_info->pathinfo;
    unsigned int len0=pathinfo->len - call_info->relpath, len1=localfile->pathinfo.len;
    char path[len0 + len1 + 1];
    struct entry_struct *entry=NULL, *parent=pinode->alias;
    struct inode_struct *inode;


    memcpy(path, localfile->pathinfo.path, len1);

    if (len0>0) {

	memcpy(path+len1, pathinfo->path + call_info->relpath, len0);
	len1+=len0;

    }

    path[len1]='\0';

    entry=create_entry(parent, xname);
    inode=create_inode();

    if (entry && inode) {
	struct entry_struct *result=NULL;
	unsigned int error=0;

	entry->inode=inode;
	inode->alias=entry;

	result=insert_entry(entry, &error, _ENTRY_FLAG_TEMP);

	if (result==entry) {
	    uid_t uid_keep=setfsuid(call_info->uid);
	    gid_t gid_keep=setfsgid(call_info->gid);
	    mode_t umask_keep=umask(call_info->umask);

	    mode = (mode & ~call_info->umask);

	    if (mknod(path, mode, rdev)==0) {
    		struct fuse_entry_param e;

		adjust_pathmax(call_info->pathinfo.len);
		add_inode_hashtable(inode, increase_inodes_workspace, (void *) call_info->workspace_mount);

		/* here complete the insert ?? */

		inode->mode=mode;

		inode->nlink=1;
		inode->uid=call_info->uid;
		inode->gid=call_info->gid;
		inode->nlookup=1;

		inode->rdev=rdev;
		inode->size=0;

		get_current_time(&inode->mtim);
		memcpy(&inode->ctim, &inode->mtim, sizeof(struct timespec));

		memset(&e, 0, sizeof(e));

		e.ino = inode->ino;
		e.generation = 1;

		e.attr.st_ino = e.ino;
		e.attr.st_mode = inode->mode;
		e.attr.st_nlink = inode->nlink;
		e.attr.st_dev = 0;
		e.attr.st_uid=inode->uid;
		e.attr.st_gid=inode->gid;
		e.attr.st_size=inode->size;
		e.attr.st_rdev=inode->rdev;

		memcpy(&e.attr.st_mtim, &inode->mtim, sizeof(struct timespec));
		memcpy(&e.attr.st_ctim, &inode->mtim, sizeof(struct timespec));
		memcpy(&e.attr.st_atim, &inode->mtim, sizeof(struct timespec));

		e.attr_timeout = fs_options.attr_timeout;
		e.entry_timeout = fs_options.entry_timeout;

		e.attr.st_blksize=4096;
		e.attr.st_blocks=0;

    		fuse_reply_entry(req, &e);

	    } else {
		unsigned int error_delete=0;

		error=errno;

		remove_entry(entry, &error_delete);

		destroy_entry(entry);
		entry=NULL;

		free(inode);
		inode=NULL;

		fuse_reply_err(req, error);

	    }

	    uid_keep=setfsuid(uid_keep);
	    gid_keep=setfsgid(gid_keep);
	    umask_keep=umask(umask_keep);

	} else {

	    destroy_entry(entry);
	    entry=NULL;

	    free(inode);
	    inode=NULL;

	    if (error==0) error=EEXIST;

	    fuse_reply_err(req, error);

	}

    } else {

	if (entry) {

	    destroy_entry(entry);
	    entry=NULL;

	}

	if (inode) {

	    free(inode);
	    inode=NULL;

	}

	fuse_reply_err(req, ENOMEM);

    }

}
Exemplo n.º 25
0
int main(int argc, char **argv)
{
	int ret = 0, c, udp = 0, ipv4 = -1, daemon = 1, log = 1;
	char *port = NULL, *stun = NULL, *dev = NULL, *home = NULL, *alias = NULL;
	enum working_mode wmode = MODE_UNKNOW;

	setfsuid(getuid());
	setfsgid(getgid());

	home = fetch_home_dir();

	while ((c = getopt_long(argc, argv, short_options, long_options,
				NULL)) != EOF) {
		switch (c) {
		case 'h':
			help();
			break;
		case 'v':
			version();
			break;
		case 'D':
			daemon = 0;
			break;
		case 'N':
			log = 0;
			break;
		case 'C':
			wmode = MODE_DUMPC;
			break;
		case 'S':
			wmode = MODE_DUMPS;
			break;
		case 'c':
			wmode = MODE_CLIENT;
			if (optarg) {
				if (*optarg == '=')
					optarg++;
				alias = xstrdup(optarg);
			}
			break;
		case 'd':
			dev = xstrdup(optarg);
			break;
		case 'k':
			wmode = MODE_KEYGEN;
			break;
		case '4':
			ipv4 = 1;
			break;
		case '6':
			ipv4 = 0;
			break;
		case 'x':
			wmode = MODE_EXPORT;
			break;
		case 's':
			wmode = MODE_SERVER;
			break;
		case 'u':
			udp = 1;
			break;
		case 't':
			stun = xstrdup(optarg);
			break;
		case 'p':
			port = xstrdup(optarg);
			break;
		case '?':
			switch (optopt) {
			case 't':
			case 'd':
			case 'u':
			case 'p':
				panic("Option -%c requires an argument!\n",
				      optopt);
			default:
				if (isprint(optopt))
					printf("Unknown option character `0x%X\'!\n", optopt);
				die();
			}
		default:
			break;
		}
	}

	if (argc < 2)
		help();

	register_signal(SIGINT, signal_handler);
	register_signal(SIGHUP, signal_handler);
	register_signal(SIGTERM, signal_handler);
	register_signal(SIGPIPE, signal_handler);

	curve25519_selftest();

	switch (wmode) {
	case MODE_KEYGEN:
		ret = main_keygen(home);
		break;
	case MODE_EXPORT:
		ret = main_export(home);
		break;
	case MODE_DUMPC:
		ret = main_dumpc(home);
		break;
	case MODE_DUMPS:
		ret = main_dumps(home);
		break;
	case MODE_CLIENT:
		ret = main_client(home, dev, alias, daemon);
		break;
	case MODE_SERVER:
		if (!port)
			panic("No port specified!\n");
		if (stun)
			print_stun_probe(stun, 3478, strtoul(port, NULL, 10));
		ret = main_server(home, dev, port, udp, ipv4, daemon, log);
		break;
	default:
		die();
	}

	free(dev);
	free(stun);
	free(port);
	free(alias);

	return ret;
}
Exemplo n.º 26
0
int main(int argc, char **argv)
{
	int ret, verbose = 0, c, opt_index, bypass = 0, format = 0;
	bool invoke_cpp = false;
	char *file = NULL;

	setfsuid(getuid());
	setfsgid(getgid());

	if (argc == 1)
		help();

	while ((c = getopt_long(argc, argv, short_options,
			        long_options, &opt_index)) != EOF) {
		switch (c) {
		case 'h':
			help();
			break;
		case 'v':
			version();
			break;
		case 'V':
			verbose = 1;
			break;
		case 'p':
			invoke_cpp = true;
			break;
		case 'f':
			if (!strncmp(optarg, "C", 1) ||
			    !strncmp(optarg, "netsniff-ng", 11))
				format = 0;
			else if (!strncmp(optarg, "tcpdump", 7))
				format = 2;
			else if (!strncmp(optarg, "xt_bpf", 6) ||
				 !strncmp(optarg, "tc", 2))
				format = 1;
			else
				help();
			break;
		case 'b':
			bypass = 1;
			break;
		case 'd':
			bpf_dump_op_table();
			die();
		case 'i':
			file = xstrdup(optarg);
			break;
		case '?':
			switch (optopt) {
			case 'i':
			case 'f':
				panic("Option -%c requires an argument!\n",
				      optopt);
			default:
				if (isprint(optopt))
					printf("Unknown option character `0x%X\'!\n", optopt);
				die();
			}
		default:
			break;
		}
	}

	if (argc == 2)
		file = xstrdup(argv[1]);
	if (!file)
		panic("No Berkeley Packet Filter program specified!\n");

	ret = compile_filter(file, verbose, bypass, format, invoke_cpp);

	xfree(file);
	return ret;
}
Exemplo n.º 27
0
int FileNode::mknod(mode_t mode, dev_t rdev, uid_t uid, gid_t gid) {
  Lock _lock(mutex);

  int res;
  int olduid = -1;
  int oldgid = -1;
  if (gid != 0) {
    oldgid = setfsgid(gid);
    if (oldgid == -1) {
      int eno = errno;
      RLOG(DEBUG) << "setfsgid error: " << strerror(eno);
      return -EPERM;
    }
  }
  if (uid != 0) {
    olduid = setfsuid(uid);
    if (olduid == -1) {
      int eno = errno;
      RLOG(DEBUG) << "setfsuid error: " << strerror(eno);
      return -EPERM;
    }
  }

  /*
   * cf. xmp_mknod() in fusexmp.c
   * The regular file stuff could be stripped off if there
   * were a create method (advised to have)
   */
  if (S_ISREG(mode)) {
    res = ::open(_cname.c_str(), O_CREAT | O_EXCL | O_WRONLY, mode);
    if (res >= 0) {
      res = ::close(res);
    }
  } else if (S_ISFIFO(mode)) {
    res = ::mkfifo(_cname.c_str(), mode);
  } else {
    res = ::mknod(_cname.c_str(), mode, rdev);
  }

  if (res == -1) {
    int eno = errno;
    VLOG(1) << "mknod error: " << strerror(eno);
    res = -eno;
  }

  if (olduid >= 0) {
    if(setfsuid(olduid) == -1) {
      int eno = errno;
      RLOG(DEBUG) << "setfsuid back error: " << strerror(eno);
      // does not return error here as initial setfsuid worked
    }
  }
  if (oldgid >= 0) {
    if(setfsgid(oldgid) == -1) {
      int eno = errno;
      RLOG(DEBUG) << "setfsgid back error: " << strerror(eno);
      // does not return error here as initial setfsgid worked
    }
  }

  return res;
}
Exemplo n.º 28
0
/* Note: it is possible for setfsuid/setfsgid to fail silently,
 * e.g. if user doesn't have CAP_SETUID/CAP_SETGID.
 * That should be checked at server startup.
 */
int
np_setfsid (Npreq *req, Npuser *u, u32 gid_override)
{
    Npwthread *wt = req->wthread;
    Npsrv *srv = req->conn->srv;
    int i, n, ret = -1;
    u32 gid;
    uid_t authuid;
    int dumpable = prctl (PR_GET_DUMPABLE, 0, 0, 0, 0);
    int dumpclrd = 0;

    if (np_conn_get_authuser(req->conn, &authuid) < 0)
        authuid = P9_NONUNAME;

    if ((srv->flags & SRV_FLAGS_SETFSID)) {
        /* gid_override must be one of user's suppl. groups unless
         * connection was originally authed as root (trusted).
         */
        if (gid_override != -1 && u->uid != 0 && authuid != 0
                && !(srv->flags & SRV_FLAGS_NOUSERDB)) {
            for (i = 0; i < u->nsg; i++) {
                if (u->sg[i] == gid_override)
                    break;
            }
            if (i == u->nsg) {
                np_uerror (EPERM);
                np_logerr (srv, "np_setfsid(%s): gid_override "
                           "%d not in user's sg list",
                           u->uname, gid_override);
                goto done;
            }
        }
        gid = (gid_override == -1 ? u->gid : gid_override);
        if (wt->fsgid != gid) {
            dumpclrd = 1;
            if ((n = setfsgid (gid)) < 0) {
                np_uerror (errno);
                np_logerr (srv, "setfsgid(%s) gid=%d failed",
                           u->uname, gid);
                wt->fsgid = P9_NONUNAME;
                goto done;
            }
            if (n != wt->fsgid) {
                np_uerror (errno);
                np_logerr (srv, "setfsgid(%s) gid=%d failed"
                           "returned %d, expected %d",
                           u->uname, gid, n, wt->fsgid);
                wt->fsgid = P9_NONUNAME;
                goto done;
            }
            wt->fsgid = gid;
        }
        if (wt->fsuid != u->uid) {
            dumpclrd = 1;
            if ((n = setfsuid (u->uid)) < 0) {
                np_uerror (errno);
                np_logerr (srv, "setfsuid(%s) uid=%d failed",
                           u->uname, u->uid);
                wt->fsuid = P9_NONUNAME;
                goto done;
            }
            if (n != wt->fsuid) {
                np_uerror (EPERM);
                np_logerr (srv, "setfsuid(%s) uid=%d failed: "
                           "returned %d, expected %d",
                           u->uname, u->uid, n, wt->fsuid);
                wt->fsuid = P9_NONUNAME;
                goto done;
            }
            /* Track CAP side effects of setfsuid.
             */
            if (u->uid == 0)
                wt->privcap = 1; /* transiton to 0 sets caps */
            else if (wt->fsuid == 0)
                wt->privcap = 0; /* trans from 0 clears caps */

            /* Suppl groups need to be part of cred for NFS
             * forwarding even with DAC_BYPASS.  However only
             * do it if kernel treats sg's per-thread not process.
             * Addendum: late model glibc attempts to make this
             * per-process, so for now bypass glibc. See issue 53.
             */
            if ((srv->flags & SRV_FLAGS_SETGROUPS)) {
                if (syscall(SYS_setgroups, u->nsg, u->sg) < 0) {
                    np_uerror (errno);
                    np_logerr (srv, "setgroups(%s) nsg=%d failed",
                               u->uname, u->nsg);
                    wt->fsuid = P9_NONUNAME;
                    goto done;
                }
            }
            wt->fsuid = u->uid;
        }
    }
#if HAVE_LIBCAP
    if ((srv->flags & SRV_FLAGS_DAC_BYPASS) && wt->fsuid != 0) {
        if (!wt->privcap && authuid == 0) {
            if (_chg_privcap (srv, CAP_SET) < 0)
                goto done;
            wt->privcap = 1;
            dumpclrd = 1;
        } else if (wt->privcap && authuid != 0) {
            if (_chg_privcap (srv, CAP_CLEAR) < 0)
                goto done;
            wt->privcap = 0;
            dumpclrd = 1;
        }
    }
#endif
    ret = 0;
done:
    if (dumpable && dumpclrd && prctl (PR_SET_DUMPABLE, 1, 0, 0, 0) < 0)
        np_logerr (srv, "prctl PR_SET_DUMPABLE failed");
    return ret;
}
Exemplo n.º 29
0
int main(int argc, char **argv)
{
	int pid, s_p[2], f_p[2], r_p[3];
	const __uid_t w_ruid = 1, w_euid = 2, w_suid = 3, w_fsuid = w_euid;
	const __uid_t w_rgid = 5, w_egid = 6, w_sgid = 7, w_fsgid = 8;
	__uid_t rid, eid, sid, fsid;
	char res = 'x';

	test_init(argc, argv);

	pipe(s_p);
	pipe(f_p);
	pipe(r_p);

	pid = fork();
	if (pid == 0) {
		close(s_p[0]);
		close(f_p[1]);
		close(r_p[0]);

		setresgid(w_rgid, w_egid, w_sgid);
		setfsgid(w_fsgid);
		setresuid(w_ruid, w_euid, w_suid);
		/* fsuid change is impossible after above */

		close(s_p[1]);

		read(f_p[0], &res, 1);
		close(f_p[0]);

#define CHECK_ID(__t, __w, __e)	do {			\
		if (__t##id != w_##__t##__w##id) {	\
			res = __e;			\
			goto bad;			\
		}					\
	} while (0)

		rid = eid = sid = fsid = 0;
		getresuid(&rid, &eid, &sid);
		fsid = setfsuid(w_euid);
		CHECK_ID(r, u, '1');
		CHECK_ID(e, u, '2');
		CHECK_ID(s, u, '3');
		CHECK_ID(s, u, '3');
		CHECK_ID(fs, u, '4');

		rid = eid = sid = fsid = 0;
		getresgid(&rid, &eid, &sid);
		fsid = setfsgid(w_fsgid);
		CHECK_ID(r, g, '5');
		CHECK_ID(e, g, '6');
		CHECK_ID(s, g, '7');
		CHECK_ID(fs, g, '8');

		res = '0';
bad:
		write(r_p[1], &res, 1);
		close(r_p[1]);
		_exit(0);
	}

	close(f_p[0]);
	close(s_p[1]);
	close(r_p[1]);

	read(s_p[0], &res, 1);
	close(s_p[0]);

	test_daemon();
	test_waitsig();

	close(f_p[1]);

	read(r_p[0], &res, 1);
	if (res == '0')
		pass();
	else
		fail("Fail: %c", res);

	return 0;
}
Exemplo n.º 30
0
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
                                int argc, const char **argv)
{
    int opt_in = 1, i;
    struct passwd pwbuf, *findUser = &pwbuf;
    const char *currentUser;
    char randBufAscii[16] = {0};
    uid_t oldUID;
    gid_t oldGID;
    char *CHAP, *RESP;
    
    char line[275];
    
    FILE *tfa_file = NULL;
    char *tfa_filename = "";
    struct stat tfa_stat;
    
    for( i = 0; i < argc; ++i ){
        if( strcmp("debug", argv[i]) == 0 )
            debug = 1;
        if( strcmp("noopt", argv[i]) == 0 )
            opt_in = 0;
    }
    
    if(pam_get_user(pamh, &currentUser, NULL) != PAM_SUCCESS ||
       currentUser == NULL || strlen(currentUser) == 0)
    {
        pam_syslog(pamh, LOG_ERR, "Unable to determine target user.");
        clearParams();
        return PAM_SYSTEM_ERR;
    }

    if(debug) pam_syslog(pamh, LOG_DEBUG, "TwoFactor for %s", currentUser);

    // gett pwentry
    
    if( getPwEntryByName(currentUser, findUser) != 0 )
    {
        if( debug )
        {
            pam_syslog(pamh, LOG_DEBUG, "Error while using getpwent");
        }
        clearParams();
        return PAM_SYSTEM_ERR;
    }

    /// now we have the correct user - allocate strlen pwdir, strlen tfa_config and 1 terminating null byte
    tfa_filename = (char*)malloc(strlen(findUser->pw_dir)+strlen(TFA_CONFIG)+1);
    if( !tfa_filename )
    {
        pam_syslog(pamh, LOG_ERR, "Unable to alloc memory");
        clearParams();
        return PAM_SYSTEM_ERR;
    }

    *tfa_filename = 0; // set first byte to nil for favorable str* fn interaction

    // this should be okay, we used pw_dir to make the dest long
    // HOWEVER, we should probably figure out a 'safe' mechanism
    strcpy(tfa_filename, findUser->pw_dir);
    strcat(tfa_filename, TFA_CONFIG);
    
    ///
    if(0 != stat(tfa_filename, &tfa_stat) )
    {
        release_pwbuf_structs(findUser);
        if( opt_in )
        {
            pam_syslog(pamh, LOG_WARNING, "User '%s' not opted in for file '%s', allowing",
                       currentUser, tfa_filename);
            free(tfa_filename);
            clearParams();
            return PAM_SUCCESS;
        }
        
        //@todo: is it safe to print this name this way? I guess so since
        // the root user would have set this up... still... shiver?
        pam_syslog(pamh, LOG_ERR, "Unable to stat '%s'", tfa_filename);
        free(tfa_filename);
        clearParams();
        return PAM_SYSTEM_ERR;
    }
    
    if( tfa_stat.st_mode & (S_IRWXG | S_IRWXO) )
    {
        pam_syslog(pamh, LOG_ERR, "G/O are allowed to manipulate the secret seed on '%s'.", tfa_filename);
        request_random(pamh, PAM_ERROR_MSG, "G/O permissions on ~/.tfa_config are incorrect.");
        free(tfa_filename);
        // explicit denial here
        clearParams();
        return PAM_PERM_DENIED;
    }

    oldUID = setfsuid(findUser->pw_uid);
    oldGID = setfsgid(findUser->pw_gid);

    release_pwbuf_structs(findUser); // give it up!
    
    tfa_file = fopen(tfa_filename, "r");
    if( tfa_file == NULL )
    {
        pam_syslog(pamh, LOG_ERR, "Unable to open '%s'", tfa_filename);
        free(tfa_filename);

        setfsgid(oldGID); setfsuid(oldUID);
        clearParams();

        if( !opt_in )
            return PAM_PERM_DENIED; // if we can stat but can't open for reading
        // there is some kind of hack afoot - explicit deny
        return PAM_SUCCESS;
    }

    if( debug ) pam_syslog(pamh, LOG_DEBUG, "Opened '%s' for reading.", tfa_filename);
    free(tfa_filename);

    while(fgets(line, sizeof(line), tfa_file) != NULL)
    {
        int iws = 0, iparam, found=0;;
        while(iws < sizeof(line) && (line[iws] == ' ' || line[iws] == '\r' || line[iws] == '\t')) ++iws;
        if( iws == sizeof(line) ) continue;
        if ( line[iws] == '#' || line[iws] == '\n' ) continue;

        for(iparam = 0; iparam < sizeof(file_params) / sizeof(file_params[0]); ++iparam)
        {
            if( strncmp(file_params[iparam].param_name, line+iws, strlen(file_params[iparam].param_name)) ) continue;
            found = 1;
            // skip more ws until =
            iws += strlen(file_params[iparam].param_name);
            while(line[iws] == ' ' || line[iws] == '\t') ++iws;
            if(iws == sizeof(line) || line[iws] != '=')
            {
                pam_syslog(pamh, LOG_ERR, "Invalid format for '%s'",
                           file_params[iparam].param_name);
                fclose(tfa_file);
                setfsgid(oldGID); setfsuid(oldUID);
                clearParams();
                return PAM_SYSTEM_ERR;
            }
            ++iws;
            while(line[iws] == ' ' || line[iws] == '\t') ++iws;
            if(iws == sizeof(line))
            {
                pam_syslog(pamh, LOG_ERR, "Invalid format for '%s'",
                           file_params[iparam].param_name);
                fclose(tfa_file);
                setfsgid(oldGID); setfsuid(oldUID);
                clearParams();
                return PAM_SYSTEM_ERR;
            }
            strncpy(file_params[iparam].output_variable,
                    line+iws, MIN(file_params[iparam].length_of_output,
                                  sizeof(line)-(iws)));
            file_params[iparam].output_variable[file_params[iparam].length_of_output-1] = 0;
            
            iws = 0;
            while( file_params[iparam].output_variable[iws] != ' ' &&
                   file_params[iparam].output_variable[iws] != '\t' &&
                   file_params[iparam].output_variable[iws] != '\r' &&
                   file_params[iparam].output_variable[iws] != '\n' ) iws++;
            file_params[iparam].output_variable[iws] = 0; // nuke any
                                                          // trailing whitespace
        }

        if(!found)
        {
            pam_syslog(pamh, LOG_WARNING, "Unknown element '%s' is being ignored.", line+iws);
        }
    }
    fclose(tfa_file); // later
    memset(line, 0, sizeof(line));
    
    if( debug )
    {
        pam_syslog(pamh, LOG_DEBUG, "Email to: %s", emailToAddr);
        pam_syslog(pamh, LOG_DEBUG, "Email from: %s", emailFromAddr);
        pam_syslog(pamh, LOG_DEBUG, "Email server: %s", emailServer);
        pam_syslog(pamh, LOG_DEBUG, "Email port: %s", emailPort);
        pam_syslog(pamh, LOG_DEBUG, "Email username: %s", emailUser);
    }

    // get the random data as acii
    snprintf(randBufAscii, sizeof(randBufAscii), "%08x", getRandomInt32(pamh));

    CHAP = base64_encode(randBufAscii, strlen(randBufAscii));
    *(CHAP+8) = 0;
    
    if( publish_email(pamh, currentUser, CHAP) < 0 )
    {
        
        pam_syslog(pamh, LOG_ERR, "Unable to send email!!");
        free(CHAP);
        setfsgid(oldGID); setfsuid(oldUID);

        if( !strcmp(failPolicy, "pass") )
        {
            clearParams();
            return PAM_SUCCESS;
        }
        clearParams();
        return PAM_PERM_DENIED;
    }

    if(debug) pam_syslog(pamh, LOG_DEBUG, "Sent email... awaiting response");
    
    //
    RESP = request_random(pamh, PAM_PROMPT_ECHO_ON, "Challenge: ");
    
    if(debug) pam_syslog(pamh, LOG_DEBUG, "Response '%s' received, comparing with '%s'", RESP, CHAP);
    
    i = strcmp(RESP, CHAP);
    free(CHAP);
    free(RESP);
    setfsgid(oldGID); setfsuid(oldUID);
    clearParams();

    if( i )
    {
        //fputs("Failed - try again.", stdout);
        return PAM_PERM_DENIED;
    }
    
    return PAM_SUCCESS;
}