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; }
/** * 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); }