src/lib/priv.c
void drop(char *uname, char *gname, bool keep_readall_caps)
{
#if   defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
   struct passwd *passw = NULL;
   struct group *group = NULL;
   gid_t gid;
   uid_t uid;
   char username[1000];

   Dmsg2(900, "uname=%s gname=%s\n", uname?uname:"NONE", gname?gname:"NONE");
   if (!uname && !gname) {
      return;                            /* Nothing to do */
   }

   if (uname) {
      if ((passw = getpwnam(uname)) == NULL) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Could not find userid=%s: ERR=%s\n"), uname,
            be.bstrerror());
      }
   } else {
      if ((passw = getpwuid(getuid())) == NULL) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("Could not find password entry. ERR=%s\n"),
            be.bstrerror());
      } else {
         uname = passw->pw_name;
      }
   }
   /* Any OS uname pointer may get overwritten, so save name, uid, and gid */
   bstrncpy(username, uname, sizeof(username));
   uid = passw->pw_uid;
   gid = passw->pw_gid;
   if (gname) {
      if ((group = getgrnam(gname)) == NULL) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Could not find group=%s: ERR=%s\n"), gname,
            be.bstrerror());
      }
      gid = group->gr_gid;
   }
   if (initgroups(username, gid)) {
      berrno be;
      if (gname) {
         Emsg3(M_ERROR_TERM, 0, _("Could not initgroups for group=%s, userid=%s: ERR=%s\n"),
            gname, username, be.bstrerror());
      } else {
         Emsg2(M_ERROR_TERM, 0, _("Could not initgroups for userid=%s: ERR=%s\n"),
            username, be.bstrerror());
      }
   }
   if (gname) {
      if (setgid(gid)) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Could not set group=%s: ERR=%s\n"), gname,
            be.bstrerror());
      }
   }
   if (keep_readall_caps) {
#ifdef ENABLE_KEEP_READALL_CAPS_SUPPORT
      cap_t caps;

      if (prctl(PR_SET_KEEPCAPS, 1)) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("prctl failed: ERR=%s\n"), be.bstrerror());
      }
      if (setreuid(uid, uid)) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("setreuid failed: ERR=%s\n"), be.bstrerror());
      }
      if (!(caps = cap_from_text("cap_dac_read_search=ep"))) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("cap_from_text failed: ERR=%s\n"), be.bstrerror());
      }
      if (cap_set_proc(caps) < 0) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("cap_set_proc failed: ERR=%s\n"), be.bstrerror());
      }
      cap_free(caps);
#else
      Emsg0(M_ERROR_TERM, 0, _("Keep readall caps not implemented this OS or missing libraries.\n"));
#endif
   } else if (setuid(uid)) {
      berrno be;
      Emsg1(M_ERROR_TERM, 0, _("Could not set specified userid: %s\n"), username);
   }
#endif
}
/*
 * Lower privileges by switching to new UID and GID if non-NULL.
 * If requested, keep readall capabilities after switch.
 */
Lower privileges by switching to new UID and GID if non-NULL.
If requested, keep readall capabilities after switch.
Lower privileges by switching to new UID and GID if non - NULL . If requested keep readall capabilities after switch .
void drop(char *uname, char *gname, bool keep_readall_caps)
{
#if   defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
   struct passwd *passw = NULL;
   struct group *group = NULL;
   gid_t gid;
   uid_t uid;
   char username[1000];
   Dmsg2(900, "uname=%s gname=%s\n", uname?uname:"NONE", gname?gname:"NONE");
   if (!uname && !gname) {
      return;                            
   }
   if (uname) {
      if ((passw = getpwnam(uname)) == NULL) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Could not find userid=%s: ERR=%s\n"), uname,
            be.bstrerror());
      }
   } else {
      if ((passw = getpwuid(getuid())) == NULL) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("Could not find password entry. ERR=%s\n"),
            be.bstrerror());
      } else {
         uname = passw->pw_name;
      }
   }
   bstrncpy(username, uname, sizeof(username));
   uid = passw->pw_uid;
   gid = passw->pw_gid;
   if (gname) {
      if ((group = getgrnam(gname)) == NULL) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Could not find group=%s: ERR=%s\n"), gname,
            be.bstrerror());
      }
      gid = group->gr_gid;
   }
   if (initgroups(username, gid)) {
      berrno be;
      if (gname) {
         Emsg3(M_ERROR_TERM, 0, _("Could not initgroups for group=%s, userid=%s: ERR=%s\n"),
            gname, username, be.bstrerror());
      } else {
         Emsg2(M_ERROR_TERM, 0, _("Could not initgroups for userid=%s: ERR=%s\n"),
            username, be.bstrerror());
      }
   }
   if (gname) {
      if (setgid(gid)) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Could not set group=%s: ERR=%s\n"), gname,
            be.bstrerror());
      }
   }
   if (keep_readall_caps) {
#ifdef ENABLE_KEEP_READALL_CAPS_SUPPORT
      cap_t caps;
      if (prctl(PR_SET_KEEPCAPS, 1)) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("prctl failed: ERR=%s\n"), be.bstrerror());
      }
      if (setreuid(uid, uid)) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("setreuid failed: ERR=%s\n"), be.bstrerror());
      }
      if (!(caps = cap_from_text("cap_dac_read_search=ep"))) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("cap_from_text failed: ERR=%s\n"), be.bstrerror());
      }
      if (cap_set_proc(caps) < 0) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("cap_set_proc failed: ERR=%s\n"), be.bstrerror());
      }
      cap_free(caps);
#else
      Emsg0(M_ERROR_TERM, 0, _("Keep readall caps not implemented this OS or missing libraries.\n"));
#endif
   } else if (setuid(uid)) {
      berrno be;
      Emsg1(M_ERROR_TERM, 0, _("Could not set specified userid: %s\n"), username);
   }
#endif
}
void drop ( char * uname , char * gname , bool keep_readall_caps ) { #if defined ( HAVE_PWD_H ) && defined ( HAVE_GRP_H ) struct passwd * passw = NULL ; struct group * group = NULL ; gid_t gid ; uid_t uid ; char username [ 1000 ] ; Dmsg2 ( 900 , " \n " , uname ? uname : " " , gname ? gname : " " ) ; if ( ! uname && ! gname ) { return ; } if ( uname ) { if ( ( passw = getpwnam ( uname ) ) == NULL ) { berrno be ; Emsg2 ( M_ERROR_TERM , 0 , _ ( " \n " ) , uname , be . bstrerror ( ) ) ; } } else { if ( ( passw = getpwuid ( getuid ( ) ) ) == NULL ) { berrno be ; Emsg1 ( M_ERROR_TERM , 0 , _ ( " \n " ) , be . bstrerror ( ) ) ; } else { uname = passw -> pw_name ; } } bstrncpy ( username , uname , sizeof ( username ) ) ; uid = passw -> pw_uid ; gid = passw -> pw_gid ; if ( gname ) { if ( ( group = getgrnam ( gname ) ) == NULL ) { berrno be ; Emsg2 ( M_ERROR_TERM , 0 , _ ( " \n " ) , gname , be . bstrerror ( ) ) ; } gid = group -> gr_gid ; } if ( initgroups ( username , gid ) ) { berrno be ; if ( gname ) { Emsg3 ( M_ERROR_TERM , 0 , _ ( " \n " ) , gname , username , be . bstrerror ( ) ) ; } else { Emsg2 ( M_ERROR_TERM , 0 , _ ( " \n " ) , username , be . bstrerror ( ) ) ; } } if ( gname ) { if ( setgid ( gid ) ) { berrno be ; Emsg2 ( M_ERROR_TERM , 0 , _ ( " \n " ) , gname , be . bstrerror ( ) ) ; } } if ( keep_readall_caps ) { #ifdef ENABLE_KEEP_READALL_CAPS_SUPPORT cap_t caps ; if ( prctl ( PR_SET_KEEPCAPS , 1 ) ) { berrno be ; Emsg1 ( M_ERROR_TERM , 0 , _ ( " \n " ) , be . bstrerror ( ) ) ; } if ( setreuid ( uid , uid ) ) { berrno be ; Emsg1 ( M_ERROR_TERM , 0 , _ ( " \n " ) , be . bstrerror ( ) ) ; } if ( ! ( caps = cap_from_text ( " " ) ) ) { berrno be ; Emsg1 ( M_ERROR_TERM , 0 , _ ( " \n " ) , be . bstrerror ( ) ) ; } if ( cap_set_proc ( caps ) < 0 ) { berrno be ; Emsg1 ( M_ERROR_TERM , 0 , _ ( " \n " ) , be . bstrerror ( ) ) ; } cap_free ( caps ) ; #else Emsg0 ( M_ERROR_TERM , 0 , _ ( " \n " ) ) ; #endif } else if ( setuid ( uid ) ) { berrno be ; Emsg1 ( M_ERROR_TERM , 0 , _ ( " \n " ) , username ) ; } #endif }
Lower privileges by switching to new UID and GID if non-NULL.
Lower privileges by switching to new UID and GID if non - NULL .
/* Nothing to do */ /* Any OS uname pointer may get overwritten, so save name, uid, and gid */