"Fossies" - the Fresh Open Source Software Archive

Member "gvm-libs-11.0.1/base/drop_privileges.c" (12 May 2020, 3700 Bytes) of package /linux/misc/openvas/gvm-libs-11.0.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "drop_privileges.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.0-beta2_vs_1.0.0.

    1 /* Copyright (C) 2010-2019 Greenbone Networks GmbH
    2  *
    3  * SPDX-License-Identifier: GPL-2.0-or-later
    4  *
    5  * This program is free software; you can redistribute it and/or
    6  * modify it under the terms of the GNU General Public License
    7  * as published by the Free Software Foundation; either version 2
    8  * of the License, or (at your option) any later version.
    9  *
   10  * This program is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  * GNU General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU General Public License
   16  * along with this program; if not, write to the Free Software
   17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18  */
   19 
   20 /**
   21  * @file
   22  * @brief Basic support to drop privileges.
   23  */
   24 
   25 #include "drop_privileges.h"
   26 
   27 #include <grp.h> /* for initgroups */
   28 #include <pwd.h> /* for passwd, getpwnam */
   29 #include <sys/types.h>
   30 #include <unistd.h> /* for geteuid, setgid, setuid */
   31 
   32 /**
   33  * @brief Sets an error and return \p errorcode
   34  *
   35  * @param error     Error to set.
   36  * @param errorcode Errorcode (possible values defined in drop_privileges.h),
   37  *                  will be returned.
   38  * @param message   Message to attach to the error.
   39  *
   40  * @return \p errorcode
   41  */
   42 static gint
   43 drop_privileges_error (GError **error, gint errorcode, const gchar *message)
   44 {
   45   g_set_error (error, GVM_DROP_PRIVILEGES, errorcode, "%s", message);
   46   return errorcode;
   47 }
   48 
   49 /**
   50  * @brief Drop privileges.
   51  *
   52  * We try to drop our (root) privileges and setuid to \p username to
   53  * minimize the risk of privilege escalation.
   54  * The current implementation is linux-specific and may not work on other
   55  * platforms.
   56  *
   57  * @param[in]  username The user to become. Its safe to pass "NULL", in which
   58  *                      case it will default to "nobody".
   59  * @param[out] error    Return location for errors or NULL if not interested
   60  *                      in errors.
   61  *
   62  * @return GVM_DROP_PRIVILEGES_OK in case of success. Sets \p error
   63  *         otherwise and returns the error code.
   64  */
   65 int
   66 drop_privileges (gchar *username, GError **error)
   67 {
   68   g_return_val_if_fail (*error == NULL, GVM_DROP_PRIVILEGES_ERROR_ALREADY_SET);
   69 
   70   if (username == NULL)
   71     username = "nobody";
   72 
   73   if (geteuid () == 0)
   74     {
   75       struct passwd *user_pw = NULL;
   76 
   77       if ((user_pw = getpwnam (username)))
   78         {
   79           if (initgroups (username, user_pw->pw_gid) != 0)
   80             return drop_privileges_error (
   81               error, GVM_DROP_PRIVILEGES_FAIL_SUPPLEMENTARY,
   82               "Failed to drop supplementary groups privileges!\n");
   83           if (setgid (user_pw->pw_gid) != 0)
   84             return drop_privileges_error (error,
   85                                           GVM_DROP_PRIVILEGES_FAIL_DROP_GID,
   86                                           "Failed to drop group privileges!\n");
   87           if (setuid (user_pw->pw_uid) != 0)
   88             return drop_privileges_error (error,
   89                                           GVM_DROP_PRIVILEGES_FAIL_DROP_UID,
   90                                           "Failed to drop user privileges!\n");
   91         }
   92       else
   93         {
   94           g_set_error (error, GVM_DROP_PRIVILEGES,
   95                        GVM_DROP_PRIVILEGES_FAIL_UNKNOWN_USER,
   96                        "Failed to get gid and uid for user %s.", username);
   97           return GVM_DROP_PRIVILEGES_FAIL_UNKNOWN_USER;
   98         }
   99       return GVM_DROP_PRIVILEGES_OK;
  100     }
  101   else
  102     {
  103       return drop_privileges_error (error, GVM_DROP_PRIVILEGES_FAIL_NOT_ROOT,
  104                                     "Only root can drop its privileges.");
  105     }
  106 }