gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/account_control.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package builtin 21 22 import ( 23 "strconv" 24 "strings" 25 26 "gitee.com/mysnapcore/mysnapd/interfaces" 27 "gitee.com/mysnapcore/mysnapd/interfaces/seccomp" 28 "gitee.com/mysnapcore/mysnapd/osutil" 29 ) 30 31 const accountControlSummary = `allows managing non-system user accounts` 32 33 const accountControlBaseDeclarationSlots = ` 34 account-control: 35 allow-installation: 36 slot-snap-type: 37 - core 38 deny-auto-connection: true 39 ` 40 41 const accountControlConnectedPlugAppArmor = ` 42 /{,usr/}sbin/chpasswd ixr, 43 /{,usr/}sbin/user{add,del} ixr, 44 45 # Allow modifying the non-system extrausers NSS database. The extrausers 46 # database is used on Ubuntu Core devices to manage both privileged and 47 # unprivileged users (since /etc/passwd, /etc/group, etc are all read-only). 48 /var/lib/extrausers/ r, 49 /var/lib/extrausers/** rwkl, 50 51 # Needed by useradd 52 /etc/login.defs r, 53 /etc/default/useradd r, 54 /etc/default/nss r, 55 /etc/pam.d/{,*} r, 56 /{,usr/}sbin/pam_tally2 ixr, 57 58 # Needed by chpasswd 59 /{,usr/}lib/@{multiarch}/security/* ixr, 60 61 # Useradd needs netlink 62 network netlink raw, 63 64 # Capabilities needed by useradd 65 capability audit_write, 66 capability chown, 67 capability fsetid, 68 69 # useradd writes the result in the log 70 #include <abstractions/wutmp> 71 /var/log/faillog rwk, 72 ` 73 74 // Needed because useradd uses a netlink socket, {{group}} is used as a 75 // placeholder argument for the actual ID of a group owning /etc/shadow 76 const accountControlConnectedPlugSecCompTemplate = ` 77 # useradd requires chowning to 0:'{{group}}' 78 fchown - u:root {{group}} 79 fchown32 - u:root {{group}} 80 81 # from libaudit1 82 bind 83 socket AF_NETLINK - NETLINK_AUDIT 84 ` 85 86 type accountControlInterface struct { 87 commonInterface 88 secCompSnippet string 89 } 90 91 func makeAccountControlSecCompSnippet() (string, error) { 92 gid, err := osutil.FindGidOwning("/etc/shadow") 93 if err != nil { 94 return "", err 95 } 96 97 snippet := strings.Replace(accountControlConnectedPlugSecCompTemplate, 98 "{{group}}", strconv.FormatUint(gid, 10), -1) 99 100 return snippet, nil 101 } 102 103 func (iface *accountControlInterface) SecCompConnectedPlug(spec *seccomp.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 104 if iface.secCompSnippet == "" { 105 // Cache the snippet after it's successfully computed once 106 snippet, err := makeAccountControlSecCompSnippet() 107 if err != nil { 108 return err 109 } 110 iface.secCompSnippet = snippet 111 } 112 spec.AddSnippet(iface.secCompSnippet) 113 return nil 114 } 115 116 func init() { 117 registerIface(&accountControlInterface{commonInterface: commonInterface{ 118 name: "account-control", 119 summary: accountControlSummary, 120 implicitOnCore: true, 121 implicitOnClassic: true, 122 baseDeclarationSlots: accountControlBaseDeclarationSlots, 123 connectedPlugAppArmor: accountControlConnectedPlugAppArmor, 124 // handled by SecCompConnectedPlug 125 connectedPlugSecComp: "", 126 }}) 127 }