Exemplo n.º 1
0
void procfs_kill_addgrpid(gid_t add_grp_id, int sig, tShepherd_trace shepherd_trace)
{
   char procnam[128];
   int i;
   int groups=0;
   u_long32 max_groups;
   gid_t *list;
#if defined(SOLARIS) || defined(ALPHA)
   int fd;
   prcred_t proc_cred;
#elif defined(LINUX)
   FILE *fp;
   char buffer[1024];
   uid_t uids[4] = {0,0,0,0};
   gid_t gids[4] = {0,0,0,0};
#endif

   DENTER(TOP_LAYER, "procfs_kill_addgrpid");

   /* quick return in case of invalid add. group id */
   if (add_grp_id == 0) {
      DEXIT;
      return;
   }

   max_groups = sge_sysconf(SGE_SYSCONF_NGROUPS_MAX);
   if (max_groups <= 0)
      if (shepherd_trace) {
         shepherd_trace(MSG_SGE_NGROUPS_MAXOSRECONFIGURATIONNECESSARY);
      }
/*
 * INSURE detects a WRITE_OVERFLOW when getgroups was invoked (LINUX).
 * Is this a bug in the kernel or in INSURE?
 */
#if defined(LINUX)
   list = (gid_t*) malloc(2*max_groups*sizeof(gid_t));
#else
   list = (gid_t*) malloc(max_groups*sizeof(gid_t));
#endif
   if (list == NULL)
      if (shepherd_trace) {
         shepherd_trace(MSG_SGE_PROCFSKILLADDGRPIDMALLOCFAILED);
      }

   pt_open();

   /* find next valid entry in procfs  */
   while ((dent = readdir(cwd))) {
      if (!dent->d_name)
         continue;
      if (!dent->d_name[0])
         continue;

      if (!strcmp(dent->d_name, "..") || !strcmp(dent->d_name, "."))
         continue;

      if (atoi(dent->d_name) == 0)
         continue;

#if defined(SOLARIS) || defined(ALPHA)
      sprintf(procnam, "%s/%s", PROC_DIR, dent->d_name);
      if ((fd = open(procnam, O_RDONLY, 0)) == -1) {
         DPRINTF(("open(%s) failed: %s\n", procnam, strerror(errno)));
         continue;
      }
#elif defined(LINUX)
      if (!strcmp(dent->d_name, "self"))
         continue;

      sprintf(procnam, PROC_DIR "/%s/status", dent->d_name);
      if (!(fp = fopen(procnam, "r")))
         continue;
#endif

#if defined(SOLARIS) || defined(ALPHA)
      /* get number of groups */
      if (ioctl(fd, PIOCCRED, &proc_cred) == -1) {
         close(fd);
         continue;
      }

      /* get list of supplementary groups */
      groups = proc_cred.pr_ngroups;
      if (ioctl(fd, PIOCGROUPS, list) == -1) {
         close(fd);
         continue;
      }

#elif defined(LINUX)
      /* get number of groups and current uids, gids
       * uids[0], gids[0] => UID and GID
       * uids[1], gids[1] => EUID and EGID
       * uids[2], gids[2] => SUID and SGID
       * uids[3], gids[3] => FSUID and FSGID
       */
      groups = 0;
      while (fgets(buffer, sizeof(buffer), fp)) {
         char *label = NULL;
         char *token = NULL;

         label = strtok(buffer, " \t\n");
         if (label) {
            if (!strcmp("Groups:", label)) {
               while ((token = strtok((char*) NULL, " \t\n"))) {
                  list[groups]=(gid_t) atol(token);
                  groups++;
               }
            } else if (!strcmp("Uid:", label)) {
               int i = 0;

               while ((i < 4) && (token = strtok((char*) NULL, " \t\n"))) {
                  uids[i]=(uid_t) atol(token);
                  i++;
               }
            } else if (!strcmp("Gid:", label)) {
               int i = 0;

               while ((i < 4) && (token = strtok((char*) NULL, " \t\n"))) {
                  gids[i]=(gid_t) atol(token);
                  i++;
               }
            }
         }
      }
#endif

#if defined(SOLARIS) || defined(ALPHA)
      close(fd);
#elif defined(LINUX)
      FCLOSE(fp);
FCLOSE_ERROR:
#endif

      /* send each process a signal which belongs to add_grg_id */
      for (i = 0; i < groups; i++) {
         if (list[i] == add_grp_id) {
            pid_t pid;
            pid = (pid_t) atol(dent->d_name);

#if defined(LINUX)
            /* if UID, GID, EUID and EGID == 0
             *  don't kill the process!!! - it could be the rpc.nfs-deamon
             */
            if (!(uids[0] == 0 && gids[0] == 0 &&
                  uids[1] == 0 && gids[1] == 0)) {
#elif defined(SOLARIS) || defined(ALPHA)
            if (!(proc_cred.pr_ruid == 0 && proc_cred.pr_rgid == 0 &&
                  proc_cred.pr_euid == 0 && proc_cred.pr_egid == 0)) {
#endif

               if (shepherd_trace) {
                  char err_str[256];

                  sprintf(err_str, MSG_SGE_KILLINGPIDXY_UI , sge_u32c(pid), groups);
                  shepherd_trace(err_str);
               }

               kill(pid, sig);

            } else {
               if (shepherd_trace) {
                  char err_str[256];

                  sprintf(err_str, MSG_SGE_DONOTKILLROOTPROCESSXY_UI ,
                     sge_u32c(atol(dent->d_name)), groups);
                  shepherd_trace(err_str);
               }
            }

            break;
         }
      }
   }
   pt_close();
   sge_free(&list);
   DEXIT;
}

int pt_open(void)
{
   cwd = opendir(PROC_DIR);
   return !cwd;
}
Exemplo n.º 2
0
/**
 * FSAL_lookup :
 * Looks up for an object into a directory.
 *
 * Note : if parent handle and filename are NULL,
 *        this retrieves root's handle.
 *
 * \param parent_directory_handle (input)
 *        Handle of the parent directory to search the object in.
 * \param filename (input)
 *        The name of the object to find.
 * \param p_context (input)
 *        Authentication context for the operation (user,...).
 * \param object_handle (output)
 *        The handle of the object corresponding to filename.
 * \param object_attributes (optional input/output)
 *        Pointer to the attributes of the object we found.
 *        As input, it defines the attributes that the caller
 *        wants to retrieve (by positioning flags into this structure)
 *        and the output is built considering this input
 *        (it fills the structure according to the flags it contains).
 *        It can be NULL (increases performances).
 *
 * \return - ERR_FSAL_NO_ERROR, if no error.
 *         - Another error code else.
 *
 */
fsal_status_t PTFSAL_lookup(const struct req_op_context *p_context,
			    struct fsal_obj_handle *parent,
			    const char *p_filename,
			    struct attrlist *p_object_attr,
			    ptfsal_handle_t *fh)
{
	fsal_status_t status;
	int parent_fd;
	struct attrlist *parent_dir_attrs;
	fsi_stat_struct buffstat;
	int rc;
	struct pt_fsal_obj_handle *parent_hdl;

	FSI_TRACE(FSI_DEBUG, "Begin##################################\n");
	if (p_filename != NULL)
		FSI_TRACE(FSI_DEBUG, "FSI - fsal_lookup file [%s]\n",
			  p_filename);

	if (parent != NULL)
		FSI_TRACE(FSI_DEBUG, "FSI - fsal_lookup parent dir\n");

	if (!parent || !p_filename)
		return fsalstat(ERR_FSAL_FAULT, 0);

	parent_hdl =
	    container_of(parent, struct pt_fsal_obj_handle, obj_handle);

	parent_dir_attrs = &parent_hdl->obj_handle.attributes;

	/* get directory metadata */
	parent_dir_attrs->mask = p_context->fsal_export->exp_ops.
			fs_supported_attrs(p_context->fsal_export);
	status =
	    fsal_internal_handle2fd_at(p_context, parent_hdl, &parent_fd,
				       O_RDONLY);

	if (FSAL_IS_ERROR(status))
		return status;

	FSI_TRACE(FSI_DEBUG, "FSI - lookup parent directory type = %d\n",
		  parent_dir_attrs->type);

	/* Be careful about junction crossing, symlinks, hardlinks,... */
	switch (parent_dir_attrs->type) {
	case DIRECTORY:
		/* OK */
		break;

	case REGULAR_FILE:
	case SYMBOLIC_LINK:
		/* not a directory */
		pt_close(parent);
		return fsalstat(ERR_FSAL_NOTDIR, 0);

	default:
		return fsalstat(ERR_FSAL_SERVERFAULT, 0);
	}

	/* get file handle, it it exists */
	/* This might be a race, but it's the best we can currently do */
	rc = ptfsal_stat_by_parent_name(p_context, parent_hdl, p_filename,
					&buffstat);
	if (rc < 0) {
		ptfsal_closedir_fd(p_context, p_context->fsal_export,
				   parent_fd);
		return fsalstat(ERR_FSAL_NOENT, errno);
	}
	memset(fh->data.handle.f_handle, 0, sizeof(fh->data.handle.f_handle));
	memcpy(&fh->data.handle.f_handle, &buffstat.st_persistentHandle.handle,
	       FSI_CCL_PERSISTENT_HANDLE_N_BYTES);
	fh->data.handle.handle_size = FSI_CCL_PERSISTENT_HANDLE_N_BYTES;
	fh->data.handle.handle_key_size = OPENHANDLE_KEY_LEN;
	fh->data.handle.handle_version = OPENHANDLE_VERSION;
	fh->data.handle.handle_type = posix2fsal_type(buffstat.st_mode);

	/* get object attributes */
	if (p_object_attr) {
		p_object_attr->mask = p_context->fsal_export->exp_ops.
				fs_supported_attrs(p_context->fsal_export);
		status = PTFSAL_getattrs(p_context->fsal_export, p_context,
					 fh, p_object_attr);
		if (FSAL_IS_ERROR(status)) {
			FSAL_CLEAR_MASK(p_object_attr->mask);
			FSAL_SET_MASK(p_object_attr->mask, ATTR_RDATTR_ERR);
		}
	}

	ptfsal_closedir_fd(p_context, p_context->fsal_export, parent_fd);

	FSI_TRACE(FSI_DEBUG, "End##################################\n");
	/* lookup complete ! */
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

}