⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 user.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
字号:
/*
     This file is part of GNUnet.
     (C) 2006 Christian Grothoff (and other contributing authors)

     GNUnet is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2, or (at your
     option) any later version.

     GNUnet is distributed in the hope that it will be useful, but
     WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with GNUnet; see the file COPYING.  If not, write to the
     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     Boston, MA 02111-1307, USA.
*/

/**
 * @file util/os/user.c
 * @brief wrappers for UID functions
 * @author Christian Grothoff
 */

#include "platform.h"
#include "gnunet_util_os.h"
#include "gnunet_util_string.h"

int
GNUNET_configure_user_account (int testCapability,
                               int doAdd, const char *group_name,
                               const char *user_name)
{
  int haveGroup;

  if (testCapability)
    {
      /* TODO: actually check that group/user
         exists/does not yet exist */
#ifdef WINDOWS
      return IsWinNT ()? GNUNET_OK : GNUNET_SYSERR;
#endif
#ifdef LINUX
      if (geteuid () != 0)
        return GNUNET_SYSERR;
      if (doAdd == GNUNET_YES)
        {
          if (((ACCESS ("/usr/sbin/adduser", X_OK) == 0) ||
               (ACCESS ("/usr/sbin/useradd", X_OK) == 0)) &&
              ((ACCESS ("/usr/sbin/addgroup", X_OK) == 0) ||
               (ACCESS ("/usr/sbin/groupadd", X_OK) == 0)))
            return GNUNET_OK;
          return GNUNET_SYSERR;
        }
      else if (doAdd == GNUNET_NO)
        {
          if ((ACCESS ("/usr/sbin/deluser", X_OK) == 0) ||
              (ACCESS ("/usr/sbin/userdel", X_OK) == 0))
            return GNUNET_OK;
          return GNUNET_SYSERR;
        }
      else if (doAdd == GNUNET_SYSERR)
        {
          if (((ACCESS ("/usr/sbin/dleuser", X_OK) == 0) ||
               (ACCESS ("/usr/sbin/userdel", X_OK) == 0)) &&
              ((ACCESS ("/usr/sbin/delgroup", X_OK) == 0) ||
               (ACCESS ("/usr/sbin/groupdel", X_OK) == 0)))
            return GNUNET_OK;
          return GNUNET_SYSERR;
        }
#endif
      return GNUNET_SYSERR;
    }
  if ((user_name == NULL) || (0 == strlen (user_name)))
    return 0;

#ifdef WINDOWS
  if (IsWinNT ())
    return CreateServiceAccount (user_name, "GNUnet service account");
#elif OSX
  return GNUNET_SYSERR;         /* TODO */
#else
  if (ACCESS ("/usr/sbin/adduser", X_OK) == 0)
    {
      /* Debian */
      /* TODO: FreeBSD? http://www.freebsd.org/cgi/man.cgi?query=adduser&sektion=8 */
      char *cmd;
      int ret;

      haveGroup = group_name && strlen (group_name) > 0;
      cmd =
        GNUNET_malloc (256 + (haveGroup ? strlen (group_name) : 0) +
                       strlen (user_name));

      if (haveGroup)
        {
          sprintf (cmd, "/usr/sbin/addgroup --quiet --system %s", group_name);
          ret = system (cmd);
	  if (ret == -1)
	    GNUNET_GE_LOG_STRERROR(NULL,
				   GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_ADMIN,
				   "system");
	  else if (WEXITSTATUS(ret) != 0)
	    GNUNET_GE_LOG(NULL,
			  GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_ADMIN,
			  _("`%s' returned with error code %u"),
			  "addgroup",
			  WEXITSTATUS(ret));	    
        }

      sprintf (cmd,
               "/usr/sbin/adduser --quiet --system %s %s "
               "--no-create-home %s",
               haveGroup ? "--ingroup" : "",
               haveGroup ? group_name : "", user_name);
      ret = system (cmd);
      if (ret == -1)
	GNUNET_GE_LOG_STRERROR(NULL,
			       GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_ADMIN,
			       "system");     
      else if (WEXITSTATUS(ret) != 0)
	GNUNET_GE_LOG(NULL,
		      GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_ADMIN,
		      _("`%s' returned with error code %u"),
		      "adduser",
		      WEXITSTATUS(ret));
      GNUNET_free (cmd);
      return GNUNET_OK;
    }
  /* TODO: useradd */
  else
    return GNUNET_SYSERR;
#endif
  return GNUNET_SYSERR;
}



/**
 * @brief Change user ID
 */
int
GNUNET_change_user (struct GNUNET_GE_Context *ectx, const char *user)
{
#ifndef MINGW
  struct passwd *pws;

  errno = 0;
  pws = getpwnam (user);
  if (pws == NULL)
    {
      GNUNET_GE_LOG (ectx,
                     GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_ADMIN |
                     GNUNET_GE_IMMEDIATE,
                     _("Cannot obtain information about user `%s': %s\n"),
                     user, errno == 0 ? _("No such user") : STRERROR (errno));
      return GNUNET_SYSERR;
    }
  if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
#if HAVE_INITGROUPS
      (0 != initgroups (user, pws->pw_gid)) ||
#endif
      (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
    {
      if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
          (0 != setreuid (pws->pw_uid, pws->pw_uid)))
        {
          GNUNET_GE_LOG (ectx,
                         GNUNET_GE_FATAL | GNUNET_GE_USER | GNUNET_GE_ADMIN |
                         GNUNET_GE_IMMEDIATE,
                         _("Cannot change user/group to `%s': %s\n"), user,
                         STRERROR (errno));
          return GNUNET_SYSERR;
        }
    }
#endif

  return GNUNET_OK;
}



/**
 * @brief Change owner of a file
 */
int
GNUNET_file_change_owner (struct GNUNET_GE_Context *ectx,
                          const char *filename, const char *user)
{
#ifndef MINGW
  struct passwd *pws;

  pws = getpwnam (user);
  if (pws == NULL)
    {
      if (NULL != ectx)
        GNUNET_GE_LOG (ectx,
                       GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_ADMIN |
                       GNUNET_GE_IMMEDIATE,
                       _("Cannot obtain information about user `%s': %s\n"),
                       user, STRERROR (errno));
      return GNUNET_SYSERR;
    }
  if ((0 != chown (filename, pws->pw_uid, pws->pw_gid)) && (NULL != ectx))
    GNUNET_GE_LOG_STRERROR_FILE (ectx,
                                 GNUNET_GE_ERROR | GNUNET_GE_USER |
                                 GNUNET_GE_ADMIN | GNUNET_GE_IMMEDIATE,
                                 "chown", filename);
#endif
  return GNUNET_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -