void recv_generator(char *fname,struct file_list *flist,int i,int f_out) { int fd; STRUCT_STAT st; struct map_struct *buf; struct sum_struct *s; int statret; struct file_struct *file = flist->files[i]; char *fnamecmp; char fnamecmpbuf[MAXPATHLEN]; extern char *compare_dest; extern int list_only; if (list_only) return; if (verbose > 2) rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i); statret = link_stat(fname,&st); if (S_ISDIR(file->mode)) { if (dry_run) return; if (statret == 0 && !S_ISDIR(st.st_mode)) { if (robust_unlink(fname) != 0) { rprintf(FERROR,"unlink %s : %s\n",fname,strerror(errno)); return; } statret = -1; } if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) { if (!(relative_paths && errno==ENOENT && create_directory_path(fname)==0 && do_mkdir(fname,file->mode)==0)) { rprintf(FERROR,"mkdir %s : %s (2)\n", fname,strerror(errno)); } } if (set_perms(fname,file,NULL,0) && verbose) rprintf(FINFO,"%s/\n",fname); return; } if (preserve_links && S_ISLNK(file->mode)) { #if SUPPORT_LINKS char lnk[MAXPATHLEN]; int l; extern int safe_symlinks; if (safe_symlinks && unsafe_symlink(file->link, fname)) { if (verbose) { rprintf(FINFO,"ignoring unsafe symlink %s -> %s\n", fname,file->link); } return; } if (statret == 0) { l = readlink(fname,lnk,MAXPATHLEN-1); if (l > 0) { lnk[l] = 0; if (strcmp(lnk,file->link) == 0) { set_perms(fname,file,&st,1); return; } } } delete_file(fname); if (do_symlink(file->link,fname) != 0) { rprintf(FERROR,"link %s -> %s : %s\n", fname,file->link,strerror(errno)); } else { set_perms(fname,file,NULL,0); if (verbose) { rprintf(FINFO,"%s -> %s\n", fname,file->link); } } #endif return; } #ifdef HAVE_MKNOD if (am_root && preserve_devices && IS_DEVICE(file->mode)) { if (statret != 0 || st.st_mode != file->mode || st.st_rdev != file->rdev) { delete_file(fname); if (verbose > 2) rprintf(FINFO,"mknod(%s,0%o,0x%x)\n", fname,(int)file->mode,(int)file->rdev); if (do_mknod(fname,file->mode,file->rdev) != 0) { rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno)); } else { set_perms(fname,file,NULL,0); if (verbose) rprintf(FINFO,"%s\n",fname); } } else { set_perms(fname,file,&st,1); } return; } #endif if (preserve_hard_links && check_hard_link(file)) { if (verbose > 1) rprintf(FINFO,"%s is a hard link\n",f_name(file)); return; } if (!S_ISREG(file->mode)) { rprintf(FINFO,"skipping non-regular file %s\n",fname); return; } fnamecmp = fname; if ((statret == -1) && (compare_dest != NULL)) { /* try the file at compare_dest instead */ int saveerrno = errno; slprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname); statret = link_stat(fnamecmpbuf,&st); if (!S_ISREG(st.st_mode)) statret = -1; if (statret == -1) errno = saveerrno; else fnamecmp = fnamecmpbuf; } if (statret == -1) { if (errno == ENOENT) { write_int(f_out,i); if (!dry_run) send_sums(NULL,f_out); } else { if (verbose > 1) rprintf(FERROR,"recv_generator failed to open %s\n",fname); } return; } if (!S_ISREG(st.st_mode)) { if (delete_file(fname) != 0) { return; } /* now pretend the file didn't exist */ write_int(f_out,i); if (!dry_run) send_sums(NULL,f_out); return; } if (update_only && st.st_mtime > file->modtime && fnamecmp == fname) { if (verbose > 1) rprintf(FINFO,"%s is newer\n",fname); return; } if (skip_file(fname, file, &st)) { if (fnamecmp == fname) set_perms(fname,file,&st,1); return; } if (dry_run) { write_int(f_out,i); return; } if (whole_file) { write_int(f_out,i); send_sums(NULL,f_out); return; } /* open the file */ fd = open(fnamecmp,O_RDONLY); if (fd == -1) { rprintf(FERROR,"failed to open %s : %s\n",fnamecmp,strerror(errno)); rprintf(FERROR,"skipping %s\n",fname); return; } if (st.st_size > 0) { buf = map_file(fd,st.st_size); } else { buf = NULL; } if (verbose > 3) rprintf(FINFO,"gen mapped %s of size %d\n",fnamecmp,(int)st.st_size); s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size)); if (verbose > 2) rprintf(FINFO,"sending sums for %d\n",i); write_int(f_out,i); send_sums(s,f_out); close(fd); if (buf) unmap_file(buf); free_sums(s); }
int main(int argc, char *argv[]) { char path[GPATH_MAX]; int perms; /* full mapset permissions */ int group, other; /* bool. want group/other permission */ struct Option *group_opt, *other_opt; struct GModule *module; /* init the GRASS library */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("general")); G_add_keyword(_("map management")); G_add_keyword(_("permission")); module->label = _("Controls access to the current mapset for other users on the system."); module->description = _("If no option given, prints current status."); group_opt = G_define_option(); group_opt->key = "group"; group_opt->type = TYPE_STRING; group_opt->required = NO; group_opt->options = "grant,revoke"; group_opt->description = _("Access for group"); group_opt->guisection = _("Settings"); other_opt = G_define_option(); other_opt->key = "other"; other_opt->type = TYPE_STRING; other_opt->required = NO; other_opt->options = "grant,revoke"; other_opt->description = _("Access for others"); other_opt->guisection = _("Settings"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); #ifdef __MINGW32__ G_fatal_error(_("UNIX filesystem access controls are not supported by MS-Windows")); #endif /* get the unix file name for the mapset directory */ G_file_name(path, "", "", G_mapset()); /* this part is until PERMANENT no longer holds DEFAULT_WIND and MYNAME */ if (strcmp(G_mapset(), "PERMANENT") == 0) G_fatal_error(_("Access to the PERMANENT mapset must be open, nothing changed")); /* get the current permissions */ if (get_perms(path, &perms, &group, &other) < 0) G_fatal_error(_("Unable to determine mapset permissions")); if (group_opt->answer) { if (group_opt->answer[0] == 'g') group = 1; else group = 0; } if (other_opt->answer) { if (other_opt->answer[0] == 'g') other = 1; else other = 0; } set_perms(path, perms, group, other); exit(EXIT_SUCCESS); }
void x11_xorg(void) { #ifdef HAVE_X11 // destination - create an empty ~/.Xauthotrity file if it doesn't exist already, and use it as a mount point char *dest; if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) errExit("asprintf"); struct stat s; if (stat(dest, &s) == -1) { // create an .Xauthority file touch_file_as_user(dest, getuid(), getgid(), 0600); } // check xauth utility is present in the system if (stat("/usr/bin/xauth", &s) == -1) { fprintf(stderr, "Error: cannot find /usr/bin/xauth executable\n"); exit(1); } // temporarily mount a tempfs on top of /tmp directory if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) errExit("mounting /tmp"); // create a temporary .Xauthority file char tmpfname[] = "/tmp/.tmpXauth-XXXXXX"; int fd = mkstemp(tmpfname); if (fd == -1) { fprintf(stderr, "Error: cannot create .Xauthority file\n"); exit(1); } if (fchown(fd, getuid(), getgid()) == -1) errExit("chown"); close(fd); pid_t child = fork(); if (child < 0) errExit("fork"); if (child == 0) { // generate the new .Xauthority file using xauth utility if (arg_debug) printf("Generating a new .Xauthority file\n"); drop_privs(1); char *display = getenv("DISPLAY"); if (!display) display = ":0.0"; clearenv(); execlp("/usr/bin/xauth", "/usr/bin/xauth", "-f", tmpfname, "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL); #ifdef HAVE_GCOV __gcov_flush(); #endif _exit(0); } // wait for the child to finish waitpid(child, NULL, 0); // check the file was created and set mode and ownership if (stat(tmpfname, &s) == -1) { fprintf(stderr, "Error: cannot create the new .Xauthority file\n"); exit(1); } if (set_perms(tmpfname, getuid(), getgid(), 0600)) errExit("set_perms"); // move the temporary file in RUN_XAUTHORITY_SEC_FILE in order to have it deleted // automatically when the sandbox is closed if (copy_file(tmpfname, RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600)) { // root needed fprintf(stderr, "Error: cannot create the new .Xauthority file\n"); exit(1); } if (set_perms(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600)) errExit("set_perms"); /* coverity[toctou] */ unlink(tmpfname); // mount if (mount(RUN_XAUTHORITY_SEC_FILE, dest, "none", MS_BIND, "mode=0600") == -1) { fprintf(stderr, "Error: cannot mount the new .Xauthority file\n"); exit(1); } if (set_perms(dest, getuid(), getgid(), 0600)) errExit("set_perms"); free(dest); // unmount /tmp umount("/tmp"); #endif }
// disable shm in pulseaudio void pulseaudio_init(void) { struct stat s; // do we have pulseaudio in the system? if (stat("/etc/pulse/client.conf", &s) == -1) { if (arg_debug) printf("/etc/pulse/client.conf not found\n"); return; } // create the new user pulseaudio directory if (mkdir(RUN_PULSE_DIR, 0700) == -1) errExit("mkdir"); // mount it nosuid, noexec, nodev fs_noexec(RUN_PULSE_DIR); // create the new client.conf file char *pulsecfg = NULL; if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1) errExit("asprintf"); if (copy_file("/etc/pulse/client.conf", pulsecfg, -1, -1, 0644)) // root needed errExit("copy_file"); FILE *fp = fopen(pulsecfg, "a"); if (!fp) errExit("fopen"); fprintf(fp, "%s", "\nenable-shm = no\n"); SET_PERMS_STREAM(fp, getuid(), getgid(), 0644); fclose(fp); // hand over the directory to the user if (set_perms(RUN_PULSE_DIR, getuid(), getgid(), 0700)) errExit("set_perms"); // create ~/.config/pulse directory if not present char *homeusercfg; if (asprintf(&homeusercfg, "%s/.config", cfg.homedir) == -1) errExit("asprintf"); if (lstat(homeusercfg, &s) == -1) { if (create_empty_dir_as_user(homeusercfg, 0700)) fs_logger2("create", homeusercfg); } else if (!S_ISDIR(s.st_mode)) { if (S_ISLNK(s.st_mode)) fprintf(stderr, "Error: %s is a symbolic link\n", homeusercfg); else fprintf(stderr, "Error: %s is not a directory\n", homeusercfg); exit(1); } free(homeusercfg); if (asprintf(&homeusercfg, "%s/.config/pulse", cfg.homedir) == -1) errExit("asprintf"); if (lstat(homeusercfg, &s) == -1) { if (create_empty_dir_as_user(homeusercfg, 0700)) fs_logger2("create", homeusercfg); } else if (!S_ISDIR(s.st_mode)) { if (S_ISLNK(s.st_mode)) fprintf(stderr, "Error: %s is a symbolic link\n", homeusercfg); else fprintf(stderr, "Error: %s is not a directory\n", homeusercfg); exit(1); } // if we have ~/.config/pulse mount the new directory, else set environment variable. if (stat(homeusercfg, &s) == 0) { // get a file descriptor for ~/.config/pulse, fails if there is any symlink int fd = safe_fd(homeusercfg, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); if (fd == -1) errExit("safe_fd"); // confirm the actual mount destination is owned by the user if (fstat(fd, &s) == -1) errExit("fstat"); if (s.st_uid != getuid()) { fprintf(stderr, "Error: %s is not owned by the current user\n", homeusercfg); exit(1); } // preserve a read-only mount struct statvfs vfs; if (fstatvfs(fd, &vfs) == -1) errExit("fstatvfs"); if ((vfs.f_flag & MS_RDONLY) == MS_RDONLY) fs_rdonly(RUN_PULSE_DIR); // mount via the link in /proc/self/fd char *proc; if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) errExit("asprintf"); if (mount(RUN_PULSE_DIR, proc, "none", MS_BIND, NULL) < 0) errExit("mount pulseaudio"); fs_logger2("tmpfs", homeusercfg); free(proc); close(fd); // check /proc/self/mountinfo to confirm the mount is ok MountData *mptr = get_last_mount(); if (strcmp(mptr->dir, homeusercfg) != 0 || strcmp(mptr->fstype, "tmpfs") != 0) errLogExit("invalid pulseaudio mount"); char *p; if (asprintf(&p, "%s/client.conf", homeusercfg) == -1) errExit("asprintf"); fs_logger2("create", p); free(p); } else { // set environment if (setenv("PULSE_CLIENTCONFIG", pulsecfg, 1) < 0) errExit("setenv"); } free(pulsecfg); free(homeusercfg); }