@@ -74,6 +74,8 @@ type UnprivilegedUser interface {
7474// WARNING: this alters global process state, so you shouldn't be doing anything concurrent.
7575// (at least where the different operations would be bothered by running in different security context)
7676func DropToUnprivilegedUserIfPossible () (PrivilegedWork , error ) {
77+ withErr := func (err error ) (PrivilegedWork , error ) { return nil , FuncWrapErr (err ) }
78+
7779 if _ , err := RequireRoot (); err != nil {
7880 return nil , err
7981 }
@@ -83,10 +85,10 @@ func DropToUnprivilegedUserIfPossible() (PrivilegedWork, error) {
8385 userDetails , err := getInvokingUserUidAndGidIfRunningInSudoWithSupplementary ()
8486 switch {
8587 case err != nil : // should only happen if sudo ENV var numbers fail to parse
86- return nil , ErrorWrap ( "PrivilegesDropTemporarily" , err )
88+ return withErr ( err )
8789 case userDetails != nil :
8890 if err := setEffectiveUIDAndGID (* userDetails ); err != nil {
89- return nil , ErrorWrap ( "PrivilegesDropTemporarily" , err )
91+ return withErr ( err )
9092 }
9193
9294 return & runningUnderSudo {* userDetails }, nil
@@ -138,12 +140,12 @@ func (r *runningUnderSudo) UnprivilegedUser() UserAndGroup {
138140
139141func (r * runningUnderSudo ) AsRoot (work func (ProofOfRunningAsRoot ) error ) error {
140142 if err := regainRoot (); err != nil {
141- return ErrorWrap ("AsRoot" , err )
143+ return fmt . Errorf ("AsRoot: %w " , err )
142144 }
143145
144146 returnAfterDroppingPrivileges := func (errWork error ) error {
145147 if errDrop := setEffectiveUIDAndGID (r .unprivileged ); errDrop != nil {
146- if errDrop != nil {
148+ if errWork != nil {
147149 return fmt .Errorf ("%w; additionally privilege drop failed: %v" , errWork , errDrop )
148150 } else {
149151 return fmt .Errorf ("AsRoot: work succeeded but privilege drop failed: %w" , errDrop )
@@ -188,61 +190,61 @@ func (r *runningUnderSudo) AsRoot(work func(ProofOfRunningAsRoot) error) error {
188190//
189191// After regaining root (seteuid(0) and setegid(0)) the effect is reversed, i.e. back to starting situation.
190192func setEffectiveUIDAndGID (user UserAndGroup ) error {
191- return ErrorWrap ("setEffectiveUIDAndGID" , func () error {
192- // gid has to be set first (otherwise we'd not be authorized to change it)
193- if err := syscall .Setegid (user .gid ); err != nil {
194- return ErrorWrap ("Setegid" , err )
195- }
193+ // gid has to be set first (otherwise we'd not be authorized to change it)
194+ if err := syscall .Setegid (user .gid ); err != nil {
195+ return fmt .Errorf ("Setegid: %w" , err )
196+ }
196197
197- if err := syscall .Setgroups (user .gidsSupplementary ); err != nil {
198- return ErrorWrap ("Setgroups" , err )
199- }
198+ if err := syscall .Setgroups (user .gidsSupplementary ); err != nil {
199+ return fmt . Errorf ("Setgroups: %w " , err )
200+ }
200201
201- if err := syscall .Seteuid (user .uid ); err != nil {
202- return ErrorWrap ("Seteuid" , err )
203- }
202+ if err := syscall .Seteuid (user .uid ); err != nil {
203+ return fmt . Errorf ("Seteuid: %w " , err )
204+ }
204205
205- return nil
206- }())
206+ return nil
207207}
208208
209209func regainRoot () error {
210- return ErrorWrap ("regainRoot" , func () error {
211- // uid has to be set first (otherwise we'd not be authorized to change it)
212- if err := syscall .Seteuid (0 ); err != nil {
213- return fmt .Errorf ("Seteuid root: %w" , err )
214- }
210+ withErr := FuncWrapErr
215211
216- if err := syscall .Setegid (0 ); err != nil {
217- return fmt .Errorf ("Setegid root: %w" , err )
218- }
212+ // uid has to be set first (otherwise we'd not be authorized to change it)
213+ if err := syscall .Seteuid (0 ); err != nil {
214+ return withErr (fmt .Errorf ("Seteuid root: %w" , err ))
215+ }
219216
220- return nil
221- }())
217+ if err := syscall .Setegid (0 ); err != nil {
218+ return withErr (fmt .Errorf ("Setegid root: %w" , err ))
219+ }
220+
221+ return nil
222222}
223223
224224// if running under '$ sudo', return invoking user's uid:gid pair.
225225// returns nil, nil if not running under sudo
226226func getInvokingUserUidAndGidIfRunningInSudoWithSupplementary () (* UserAndGroup , error ) {
227+ withErr := func (err error ) (* UserAndGroup , error ) { return nil , FuncWrapErr (err ) }
228+
227229 // documented in https://www.sudo.ws/docs/man/sudo.man/#SUDO_UID
228230 if os .Getenv ("SUDO_UID" ) == "" { // not running under sudo
229231 return nil , nil
230232 }
231233
232234 uidSudo , err := strconv .Atoi (os .Getenv ("SUDO_UID" ))
233235 if err != nil {
234- return nil , ErrorWrap ( "getInvokingUserUidAndGidIfRunningInSudoWithoutSupplementary" , err )
236+ return withErr ( err )
235237 }
236238
237239 gidSudo , err := strconv .Atoi (os .Getenv ("SUDO_GID" ))
238240 if err != nil {
239- return nil , ErrorWrap ( "getInvokingUserUidAndGidIfRunningInSudoWithoutSupplementary" , err )
241+ return withErr ( err )
240242 }
241243
242244 // resolve also supplementary gids
243245 gidsSupplementarySudo , err := resolveSupplementaryGids (os .Getenv ("SUDO_USER" ))
244246 if err != nil {
245- return nil , ErrorWrap ( "getInvokingUserUidAndGidIfRunningInSudoWithSupplementary" , err )
247+ return withErr ( err )
246248 }
247249
248250 return & UserAndGroup {uidSudo , gidSudo , gidsSupplementarySudo }, nil
0 commit comments