diff options
Diffstat (limited to 'pam/pam.go')
| -rw-r--r-- | pam/pam.go | 82 |
1 files changed, 54 insertions, 28 deletions
@@ -35,16 +35,14 @@ import ( "unsafe" "github.com/google/fscrypt/security" - "github.com/google/fscrypt/util" ) // Handle wraps the C pam_handle_t type. This is used from within modules. type Handle struct { - handle *C.pam_handle_t - status C.int - // OrigUser is the user who invoked the PAM module (usually root) - OrigUser *user.User - // PamUser is the user who the PAM module is for + handle *C.pam_handle_t + status C.int + origPrivs *security.Privileges + // PamUser is the user for whom the PAM module is running. PamUser *user.User } @@ -58,17 +56,12 @@ func NewHandle(pamh unsafe.Pointer) (*Handle, error) { var pamUsername *C.char h.status = C.pam_get_user(h.handle, &pamUsername, nil) - if err := h.err(); err != nil { + if err = h.err(); err != nil { return nil, err } - if h.PamUser, err = user.Lookup(C.GoString(pamUsername)); err != nil { - return nil, err - } - if h.OrigUser, err = util.EffectiveUser(); err != nil { - return nil, err - } - return h, nil + h.PamUser, err = user.Lookup(C.GoString(pamUsername)) + return h, err } func (h *Handle) setData(name string, data unsafe.Pointer, cleanup C.CleanupFunc) error { @@ -86,7 +79,7 @@ func (h *Handle) getData(name string) (unsafe.Pointer, error) { return data, h.err() } -// ClearData remotes the PAM data with the specified name. +// ClearData removes the PAM data with the specified name. func (h *Handle) ClearData(name string) error { return h.setData(name, unsafe.Pointer(C.CString("")), C.CleanupFunc(C.freeData)) } @@ -99,8 +92,8 @@ func (h *Handle) SetSecret(name string, secret unsafe.Pointer) error { } // GetSecret returns a pointer to the C string PAM data with the specified name. -// This a pointer directory to the data, so it shouldn't be modified. It should -// have been previously set with SetSecret(). +// This is a pointer directly to the data, so it shouldn't be modified. It +// should have been previously set with SetSecret(). func (h *Handle) GetSecret(name string) (unsafe.Pointer, error) { return h.getData(name) } @@ -120,28 +113,54 @@ func (h *Handle) GetString(name string) (string, error) { return C.GoString((*C.char)(data)), nil } -// GetItem retrieves a PAM information item. This a pointer directory to the +// GetItem retrieves a PAM information item. This is a pointer directly to the // data, so it shouldn't be modified. func (h *Handle) GetItem(i Item) (unsafe.Pointer, error) { var data unsafe.Pointer h.status = C.pam_get_item(h.handle, C.int(i), &data) - return data, h.err() + if err := h.err(); err != nil { + return nil, err + } + if data == nil { + return nil, errors.New("item not found") + } + return data, nil +} + +// GetServiceName retrieves the name of the application running the PAM transaction. +func (h *Handle) GetServiceName() string { + data, err := h.GetItem(Service) + if err != nil { + return "[unknown service]" + } + return C.GoString((*C.char)(data)) } -// StartAsPamUser sets the effective privileges to that of the PAM user, and -// configures the PAM user's keyrings to be properly linked. +// StartAsPamUser sets the effective privileges to that of the PAM user. func (h *Handle) StartAsPamUser() error { - if _, err := security.UserKeyringID(h.PamUser, true); err != nil { - log.Printf("Setting up keyrings in PAM: %v", err) + userPrivs, err := security.UserPrivileges(h.PamUser) + if err != nil { + return err + } + origPrivs, err := security.ProcessPrivileges() + if err != nil { + return err } - return security.SetThreadPrivileges(h.PamUser) + if err = security.SetProcessPrivileges(userPrivs); err != nil { + return err + } + h.origPrivs = origPrivs + return nil } // StopAsPamUser restores the original privileges that were running the -// PAM module (this is usually root). As this error is often ignored in a defer -// statement, any error is also logged. +// PAM module (this is usually root). func (h *Handle) StopAsPamUser() error { - err := security.SetThreadPrivileges(h.OrigUser) + if h.origPrivs == nil { + return nil + } + err := security.SetProcessPrivileges(h.origPrivs) + h.origPrivs = nil if err != nil { log.Print(err) } @@ -156,8 +175,15 @@ func (h *Handle) err() error { return errors.New(s) } +// InfoMessage sends a message to the application using pam_info(). +func (h *Handle) InfoMessage(message string) { + cMessage := C.CString(message) + defer C.free(unsafe.Pointer(cMessage)) + C.infoMessage(h.handle, cMessage) +} + // Transaction represents a wrapped pam_handle_t type created with pam_start -// form an application. +// from an application. type Transaction Handle // Start initializes a pam Transaction. End() should be called after the |