static void clone_spawn(void) { l r; if(ps_n<ps_max){ r=clone(SIGCHLD,0,0,0,0); if(ISERR(r)){ PERR("FATAL:error cloning %ld\n",r); kill(0,SIGTERM); exit(-1); } if(r==0) goto clone_entry_setup; ++ps_n; } return; clone_entry_setup: do r=close(0); while(r==-EINTR);//for the connexion socket do r=close(1); while(r==-EINTR);//for the connexion socket //keep stderr do r=close(sigs_fd); while(r==-EINTR);//don't care of parent signal do r=close(epfd); while(r==-EINTR);//don't use parent epoll clone_entry(); return; }
MateVFSResult file_set_acl (const char *path, const MateVFSFileInfo *info, MateVFSContext *context) { #ifdef HAVE_SOLARIS_ACL GList *acls; GList *entry; guint len; MateVFSResult re; aclent_t *new_aclp; aclent_t *taclp; guint aclp_i; gboolean changed; if (info->acl == NULL) return MATE_VFS_ERROR_BAD_PARAMETERS; acls = mate_vfs_acl_get_ace_list (info->acl); if (acls == NULL) return MATE_VFS_OK; changed = fixup_acl (info->acl, acls); if (changed) { mate_vfs_acl_free_ace_list (acls); acls = mate_vfs_acl_get_ace_list (info->acl); if (acls == NULL) return MATE_VFS_OK; } len = g_list_length (acls); if (len <= 0) return MATE_VFS_OK; new_aclp = (aclent_t *) malloc (len * sizeof(aclent_t)); if (new_aclp == NULL) return MATE_VFS_ERROR_NO_MEMORY; memset (new_aclp, 0, len * sizeof(aclent_t)); aclp_i = 0; taclp = new_aclp; for (entry=acls; entry != NULL; entry = entry->next) { MateVFSACE *ace = MATE_VFS_ACE(entry->data); re = translate_ace_into_aclent (ace, taclp); if (re != MATE_VFS_OK) continue; aclp_i++; taclp++; } /* Sort it out */ re = aclsort (aclp_i, 0, (aclent_t *)new_aclp); if (re == -1) { g_free (new_aclp); return MATE_VFS_ERROR_INTERNAL; } /* Commit it to the file system */ re = acl (path, SETACL, aclp_i, (aclent_t *)new_aclp); if (re < 0) { int err = errno; g_free (new_aclp); return aclerrno_to_vfserror(err); } g_free (new_aclp); return MATE_VFS_OK; #elif defined(HAVE_POSIX_ACL) GList *acls; GList *entry; acl_t acl_obj; acl_t acl_obj_default; if (info->acl == NULL) return MATE_VFS_ERROR_BAD_PARAMETERS; /* POSIX ACL object */ acl_obj_default = acl_get_file (path, ACL_TYPE_DEFAULT); acl_obj = acl_get_file (path, ACL_TYPE_ACCESS); if (acl_obj == NULL) return MATE_VFS_ERROR_GENERIC; /* Parse stored information */ acls = mate_vfs_acl_get_ace_list (info->acl); if (acls == NULL) return MATE_VFS_OK; for (entry=acls; entry != NULL; entry = entry->next) { MateVFSACE *ace = MATE_VFS_ACE(entry->data); gboolean is_default = FALSE; const char *id_str; MateVFSACLKind kind; int id; int re; acl_tag_t type; mode_t perms = 0; acl_entry_t new_entry = NULL; acl_permset_t permset = NULL; id_str = mate_vfs_ace_get_id (ace); kind = mate_vfs_ace_get_kind (ace); is_default = mate_vfs_ace_get_inherit (ace); /* Perms */ if (mate_vfs_ace_check_perm (ace, MATE_VFS_ACL_READ)) perms |= CMD_PERM_READ; else if (mate_vfs_ace_check_perm (ace, MATE_VFS_ACL_WRITE)) perms |= CMD_PERM_WRITE; else if (mate_vfs_ace_check_perm (ace, MATE_VFS_ACL_EXECUTE)) perms |= CMD_PERM_EXECUTE; /* Type */ switch (kind) { case MATE_VFS_ACL_USER: id = string_to_uid (id_str); type = ACL_USER; break; case MATE_VFS_ACL_GROUP: id = string_to_gid (id_str); type = ACL_GROUP; break; case MATE_VFS_ACL_OTHER: type = ACL_OTHER; break; default: return MATE_VFS_ERROR_NOT_SUPPORTED; } /* Add the entry */ new_entry = find_entry (acl_obj, type, id); if (new_entry == NULL) { /* new */ if (is_default) re = acl_create_entry (&acl_obj_default, &new_entry); else re = acl_create_entry (&acl_obj, &new_entry); if (re != 0) return aclerrno_to_vfserror (errno); /* e_tag */ re = acl_set_tag_type (new_entry, type); if (re != 0) return aclerrno_to_vfserror (errno); /* e_id */ re = acl_set_qualifier (new_entry, &id); if (re != 0) return aclerrno_to_vfserror (errno); } /* e_perm */ re = acl_get_permset (new_entry, &permset); if (re != 0) return aclerrno_to_vfserror (errno); set_permset (permset, perms); /* Fix it up */ if (is_default && (acl_obj_default != NULL)) { if (! find_entry (acl_obj_default, ACL_USER_OBJ, ACL_UNDEFINED_ID)) { clone_entry (acl_obj, ACL_USER_OBJ, &acl_obj_default, ACL_USER_OBJ); } if (! find_entry (acl_obj_default, ACL_GROUP_OBJ, ACL_UNDEFINED_ID)) { clone_entry (acl_obj, ACL_GROUP_OBJ, &acl_obj_default, ACL_GROUP_OBJ); } if (! find_entry (acl_obj_default, ACL_OTHER, ACL_UNDEFINED_ID)) { clone_entry (acl_obj, ACL_OTHER, &acl_obj_default, ACL_OTHER); } } if (acl_equiv_mode (acl_obj, NULL) != 0) { if (! find_entry (acl_obj, ACL_MASK, ACL_UNDEFINED_ID)) { clone_entry (acl_obj, ACL_GROUP_OBJ, &acl_obj, ACL_MASK); } if (is_default) re = acl_calc_mask (&acl_obj_default); else re = acl_calc_mask (&acl_obj); if (re != 0) return aclerrno_to_vfserror (errno); } } mate_vfs_acl_free_ace_list (acls); return MATE_VFS_OK; #else return MATE_VFS_ERROR_NOT_SUPPORTED; #endif }
int do_set( const char *path_p, const struct stat *st, const seq_t seq) { acl_t old_acl = NULL, old_default_acl = NULL; acl_t acl = NULL, default_acl = NULL; acl_t *xacl, *old_xacl; acl_entry_t ent; cmd_t cmd; int which_entry; int errors = 0, error; char *acl_text; int acl_modified = 0, default_acl_modified = 0; int acl_mask_provided = 0, default_acl_mask_provided = 0; /* Execute the commands in seq (read ACLs on demand) */ error = seq_get_cmd(seq, SEQ_FIRST_CMD, &cmd); if (error == 0) return 0; while (error == 1) { if (cmd->c_type == ACL_TYPE_ACCESS) { xacl = &acl; old_xacl = &old_acl; acl_modified = 1; if (cmd->c_tag == ACL_MASK) acl_mask_provided = 1; } else { xacl = &default_acl; old_xacl = &old_default_acl; default_acl_modified = 1; if (cmd->c_tag == ACL_MASK) default_acl_mask_provided = 1; } RETRIEVE_ACL(cmd->c_type); /* Check for `X', and replace with `x' as appropriate. */ if (cmd->c_perm & CMD_PERM_COND_EXECUTE) { cmd->c_perm &= ~CMD_PERM_COND_EXECUTE; if (S_ISDIR(st->st_mode) || has_execute_perms(*xacl)) cmd->c_perm |= CMD_PERM_EXECUTE; } switch(cmd->c_cmd) { case CMD_ENTRY_REPLACE: ent = find_entry(*xacl, cmd->c_tag, cmd->c_id); if (!ent) { if (acl_create_entry(xacl, &ent) != 0) goto fail; acl_set_tag_type(ent, cmd->c_tag); if (cmd->c_id != ACL_UNDEFINED_ID) acl_set_qualifier(ent, &cmd->c_id); } set_perm(ent, cmd->c_perm, ~cmd->c_perm); break; case CMD_ENTRY_ADD: ent = find_entry(*xacl, cmd->c_tag, cmd->c_id); if (ent) set_perm(ent, cmd->c_perm, 0); break; case CMD_ENTRY_SUBTRACT: ent = find_entry(*xacl, cmd->c_tag, cmd->c_id); if (ent) set_perm(ent, 0, cmd->c_perm); break; case CMD_REMOVE_ENTRY: ent = find_entry(*xacl, cmd->c_tag, cmd->c_id); if (ent) acl_delete_entry(*xacl, ent); else /* ignore */; break; case CMD_REMOVE_EXTENDED_ACL: remove_extended_entries(acl); break; case CMD_REMOVE_ACL: acl_free(*xacl); *xacl = acl_init(5); if (!*xacl) goto fail; break; default: errno = EINVAL; goto fail; } error = seq_get_cmd(seq, SEQ_NEXT_CMD, &cmd); } if (error < 0) goto fail; /* Try to fill in missing entries */ if (default_acl && acl_entries(default_acl) != 0) { xacl = &acl; old_xacl = &old_acl; if (!find_entry(default_acl, ACL_USER_OBJ, ACL_UNDEFINED_ID)) { if (!acl) RETRIEVE_ACL(ACL_TYPE_ACCESS); clone_entry(acl, ACL_USER_OBJ, &default_acl, ACL_USER_OBJ); } if (!find_entry(default_acl, ACL_GROUP_OBJ, ACL_UNDEFINED_ID)) { if (!acl) RETRIEVE_ACL(ACL_TYPE_ACCESS); clone_entry(acl, ACL_GROUP_OBJ, &default_acl, ACL_GROUP_OBJ); } if (!find_entry(default_acl, ACL_OTHER, ACL_UNDEFINED_ID)) { if (!acl) RETRIEVE_ACL(ACL_TYPE_ACCESS); clone_entry(acl, ACL_OTHER, &default_acl, ACL_OTHER); } } /* update mask entries and check if ACLs are valid */ if (acl && acl_modified) { if (acl_equiv_mode(acl, NULL) != 0) { if (!acl_mask_provided && !find_entry(acl, ACL_MASK, ACL_UNDEFINED_ID)) clone_entry(acl, ACL_GROUP_OBJ, &acl, ACL_MASK); if (opt_recalculate != -1 && (!acl_mask_provided || opt_recalculate == 1)) acl_calc_mask(&acl); } error = acl_check(acl, &which_entry); if (error < 0) goto fail; if (error > 0) { acl_text = acl_to_any_text(acl, NULL, ',', 0); fprintf(stderr, gettext("%s: %s: Malformed access ACL " "`%s': %s at entry %d\n"), progname, path_p, acl_text, acl_error(error), which_entry+1); acl_free(acl_text); errors++; goto cleanup; } } if (default_acl && acl_entries(default_acl) != 0 && default_acl_modified) { if (acl_equiv_mode(default_acl, NULL) != 0) { if (!default_acl_mask_provided && !find_entry(default_acl,ACL_MASK,ACL_UNDEFINED_ID)) clone_entry(default_acl, ACL_GROUP_OBJ, &default_acl, ACL_MASK); if (opt_recalculate != -1 && (!default_acl_mask_provided || opt_recalculate == 1)) acl_calc_mask(&default_acl); } error = acl_check(default_acl, &which_entry); if (error < 0) goto fail; if (error > 0) { acl_text = acl_to_any_text(default_acl, NULL, ',', 0); fprintf(stderr, gettext("%s: %s: Malformed default ACL " "`%s': %s at entry %d\n"), progname, path_p, acl_text, acl_error(error), which_entry+1); acl_free(acl_text); errors++; goto cleanup; } } /* Only directores can have default ACLs */ if (default_acl && !S_ISDIR(st->st_mode) && opt_recursive) { /* In recursive mode, ignore default ACLs for files */ acl_free(default_acl); default_acl = NULL; } /* check which ACLs have changed */ if (acl && old_acl && acl_cmp(old_acl, acl) == 0) { acl_free(acl); acl = NULL; } if ((default_acl && old_default_acl && acl_cmp(old_default_acl, default_acl) == 0)) { acl_free(default_acl); default_acl = NULL; } /* update the file system */ if (opt_test) { print_test(stdout, path_p, st, acl, default_acl); goto cleanup; } if (acl) { if (acl_set_file(path_p, ACL_TYPE_ACCESS, acl) != 0) { if (errno == ENOSYS || errno == ENOTSUP) { int saved_errno = errno; mode_t mode; if (acl_equiv_mode(acl, &mode) != 0) { errno = saved_errno; goto fail; } else if (chmod(path_p, mode) != 0) goto fail; } else goto fail; } } if (default_acl) { if (S_ISDIR(st->st_mode)) { if (acl_entries(default_acl) == 0) { if (acl_delete_def_file(path_p) != 0 && errno != ENOSYS && errno != ENOTSUP) goto fail; } else { if (acl_set_file(path_p, ACL_TYPE_DEFAULT, default_acl) != 0) goto fail; } } else { if (acl_entries(default_acl) != 0) { fprintf(stderr, gettext( "%s: %s: Only directories " "can have default ACLs\n"), progname, path_p); errors++; goto cleanup; } } } error = 0; cleanup: if (acl) acl_free(acl); if (old_acl) acl_free(old_acl); if (default_acl) acl_free(default_acl); if (old_default_acl) acl_free(old_default_acl); return errors; fail: fprintf(stderr, "%s: %s: %s\n", progname, path_p, strerror(errno)); errors++; goto cleanup; }