// Setup creates udev rules specific to a given snap. // If any of the rules are changed or removed then udev database is reloaded. // // Since udev has no concept of a complain mode, devMode is ignored. // // If the method fails it should be re-tried (with a sensible strategy) by the caller. func (b *Backend) Setup(snapInfo *snap.Info, devMode bool, repo *interfaces.Repository) error { snapName := snapInfo.Name() snippets, err := repo.SecuritySnippetsForSnap(snapInfo.Name(), interfaces.SecurityUDev) if err != nil { return fmt.Errorf("cannot obtain udev security snippets for snap %q: %s", snapName, err) } content, err := b.combineSnippets(snapInfo, snippets) if err != nil { return fmt.Errorf("cannot obtain expected udev rules for snap %q: %s", snapName, err) } glob := fmt.Sprintf("70-%s.rules", interfaces.SecurityTagGlob(snapName)) dir := dirs.SnapUdevRulesDir if err := os.MkdirAll(dir, 0755); err != nil { return fmt.Errorf("cannot create directory for udev rules %q: %s", dir, err) } return ensureDirState(dir, glob, content, snapName) }
// Setup creates dbus configuration files specific to a given snap. // // DBus has no concept of a complain mode so devMode is not supported func (b *Backend) Setup(snapInfo *snap.Info, devMode bool, repo *interfaces.Repository) error { snapName := snapInfo.Name() // Get the snippets that apply to this snap snippets, err := repo.SecuritySnippetsForSnap(snapInfo.Name(), interfaces.SecurityDBus) if err != nil { return fmt.Errorf("cannot obtain DBus security snippets for snap %q: %s", snapName, err) } // Get the files that this snap should have content, err := b.combineSnippets(snapInfo, snippets) if err != nil { return fmt.Errorf("cannot obtain expected DBus configuration files for snap %q: %s", snapName, err) } glob := fmt.Sprintf("%s.conf", interfaces.SecurityTagGlob(snapName)) dir := dirs.SnapBusPolicyDir if err := os.MkdirAll(dir, 0755); err != nil { return fmt.Errorf("cannot create directory for DBus configuration files %q: %s", dir, err) } _, _, err = osutil.EnsureDirState(dir, glob, content) if err != nil { return fmt.Errorf("cannot synchronize DBus configuration files for snap %q: %s", snapName, err) } return nil }
// Setup creates and loads apparmor profiles specific to a given snap. // The snap can be in developer mode to make security violations non-fatal to // the offending application process. // // This method should be called after changing plug, slots, connections between // them or application present in the snap. func (b *Backend) Setup(snapInfo *snap.Info, devMode bool, repo *interfaces.Repository) error { snapName := snapInfo.Name() // Get the snippets that apply to this snap snippets, err := repo.SecuritySnippetsForSnap(snapName, interfaces.SecurityAppArmor) if err != nil { return fmt.Errorf("cannot obtain security snippets for snap %q: %s", snapName, err) } // Get the files that this snap should have content, err := b.combineSnippets(snapInfo, devMode, snippets) if err != nil { return fmt.Errorf("cannot obtain expected security files for snap %q: %s", snapName, err) } glob := interfaces.SecurityTagGlob(snapInfo.Name()) dir := dirs.SnapAppArmorDir if err := os.MkdirAll(dir, 0755); err != nil { return fmt.Errorf("cannot create directory for apparmor profiles %q: %s", dir, err) } _, removed, errEnsure := osutil.EnsureDirState(dir, glob, content) // NOTE: load all profiles instead of just the changed profiles. We're // relying on apparmor cache to make this efficient. This gives us // certainty that each call to Setup ends up with working profiles. all := make([]string, 0, len(content)) for name := range content { all = append(all, name) } sort.Strings(all) errReload := reloadProfiles(all) errUnload := unloadProfiles(removed) if errEnsure != nil { return fmt.Errorf("cannot synchronize security files for snap %q: %s", snapName, errEnsure) } if errReload != nil { return errReload } return errUnload }