[gnu.emacs] Editing a file as super user

tjfs@tadtec.uucp (Tim Steele) (09/11/89)

What's the favourite way of getting around the problem where a
sysadmin "lives in Emacs" but wants to edit a privileged file?  At the
moment I do:

^Z (leave Emacs)

su (become root)

emacs /etc/motd (or even vi, as having 2 copies of emacs loaded kills
our system!!)

^X^C (leave superuser Emacs)

^D (leave subshell)

Grubby!  Any better suggestions?  I can't even edit it in place and
save it out easily, like I can with vi, because Emacs notices I'm not
allowed to write it and marks the buffer read only.

Thanks

Tim
-- 
tjfs@tadtec.uucp   ..!uunet!mcvax!ukc!tadtec!tjfs
Tadpole Technology plc, Titan House, Castle Park, CAMBRIDGE, CB3 0AY, UK
Phone: +44-223-461000   Fax: +44-223-460727   Telex: TADTEC G

raulmill@usc.edu (Raul Deluth Rockwell) (09/12/89)

In article <TJFS.89Sep11164320@tadtec.tadtec.uucp> tjfs@tadtec.uucp (Tim Steele) writes:
   What's the favourite way of getting around the problem where a
   sysadmin "lives in Emacs" but wants to edit a privileged file?  At
   the moment I do:
[ . . . icky hack elided . . . ]
   Grubby!  Any better suggestions?  I can't even edit it in place and
   save it out easily, like I can with vi, because Emacs notices I'm
   not allowed to write it and marks the buffer read only.

I don't know if there are any neat tricks to su around in emacs.
Especially on a system which can't support two emacs jobs concurrently
(which I think I remember you saying in the part I elided).

However, you can always use toggle-read-only (bound to C-X C-Q on my
system) to edit the image of the file.

--
Raul Rockwell                                      !
INTERNET:   raulmill@usc.edu                       !
UUCP:       ...uunet!usc!raulmill                  !  55 mph = 82 nc
U.S.SNAIL:  721 E Windsor #4,  GLENDALE CA  91205  !

karl@triceratops.cis.ohio-state.edu (Karl Kleinpaste) (09/12/89)

M-x terminal

YourShellPrompt> su
Password:
YourSUPrompt# emacs
[edit to your heart's discontent]
^X^C
YourSUPrompt# 

It is deeply weird to see Emacs running inside Emacs.  It takes some
getting used to.

--Karl

mpf@triplea.cs.umd.edu (Martin Farach) (09/13/89)

In article <KARL.89Sep12082550@triceratops.cis.ohio-state.edu> karl@triceratops.cis.ohio-state.edu (Karl Kleinpaste) writes:

   M-x terminal

   YourShellPrompt> su
   Password:
   YourSUPrompt# emacs
   [edit to your heart's discontent]
   ^X^C
   YourSUPrompt# 

   It is deeply weird to see Emacs running inside Emacs.  It takes some
   getting used to.

   --Karl

Of course, if his system dies with two emacs proccesses running
independently, it will also die with one emacs running within another
emacs.

Martin
--

*******************************************************************************
* Martin Farach				|                                     *
* University of Maryland		|                                     *
* Department of Computer Science	|                                     *
* College Park, Maryland 20742		|                                     *
*					|                                     *
* also know as:				|                                     *
* mpf@brillig.umd.edu			|                                     *
*******************************************************************************

aks%nowhere@hub.ucsb.edu (aks@hub, Alan Stebbens) (09/13/89)

> What's the favourite way of getting around the problem where a
> sysadmin "lives in Emacs" but wants to edit a privileged file? ...
> moment I do:

Place these files, where possible, under group-ownership of a
special group, of which you are a member, and make the files also
group writable.  Alternatively, place yourself in all groups which
own these files, and make the files group-writable.  In either
case, you'll also have to make the parent-directory of these files
group writable, so the Emacs backup files can be created (unless
you don't care about backups); however, the backup files will be
owned by you.

The advantage of the former method is that, since group membership
is limited to NGROUPS (a kernel configuration), you only need one
special group, which may be "wheel" or "daemon", or somesuch.  The
disadvantage is that some files may require a certain kind of
group ownership.

The advantage of the latter method is that each file's current
group ownership doesn't change, but you must be a member of all
such groups, which may be a larger number than NGROUPS and won't
work (this is very unusual though).

I use the latter method.

Alan Stebbens        <aks@hub.ucsb.edu>             (805) 961-3221
     Center for Computational Sciences and Engineering (CCSE)
          University of California, Santa Barbara (UCSB)
           3111 Engineering I, Santa Barbara, CA 93106

jr@bbn.com (John Robinson) (09/22/89)

In article <TJFS.89Sep11164320@tadtec.tadtec.uucp>, tjfs@tadtec (Tim Steele) writes:
>What's the favourite way of getting around the problem where a
>sysadmin "lives in Emacs" but wants to edit a privileged file?  At the
>moment I do:
>
>^Z (leave Emacs)
>
>su (become root)
>
>emacs /etc/motd (or even vi, as having 2 copies of emacs loaded kills
>our system!!)
>
>^X^C (leave superuser Emacs)
>
>^D (leave subshell)
>
>Grubby!  Any better suggestions?  I can't even edit it in place and
>save it out easily, like I can with vi, because Emacs notices I'm not
>allowed to write it and marks the buffer read only.

Mark the buffer modifiable with ^X^Q (as others pointed out).  Edit
it.  Save it somewhere you can write with ^X^W (like ~/ or /tmp/).
Then use su-command (appended below) to move or copy the file over the
old version, perhaps moving the previous one out of the way first if
necessary.  Elisp after my .sig.

(anticipating the nits: yes, I know the password echos as you type it.
However, putting the two arguments in the order they are at least
overwrites the minibuffer as soon as you finish the password.  Anyone
who wants to add the get-a-string-sliently logic to the following is
welcome to do it and repost).
--
/jr, nee John Robinson     Life did not take over the globe by combat,
jr@bbn.com or bbn!jr          but by networking -- Lynn Margulis
====8<----------------------------------------------------------------
(defun su-command (password command)
  "Prompt for root password and a command, then do the latter as root."
  (interactive "sRoot password: \nsCommand: ")
  (let ((buffer (get-buffer-create "*Shell Command Output*"))
        proc)
    (save-excursion
          (set-buffer buffer)
          (erase-buffer))
    (setq proc (start-process "su-emacs" buffer "/bin/su"
                              "-c" command))
    (if (save-excursion
          (set-buffer buffer)
          (goto-char (point-min))
          (while (not (looking-at "Password:"))
            (accept-process-output proc)
            (goto-char (point-min)))
          (erase-buffer)
          (send-string proc (concat password "\n"))
          (while (not (looking-at "\n"))
            (accept-process-output proc)
            (goto-char (point-min)))
          (delete-char 1)
          (while (not (equal (process-status proc) 'exit))
            (accept-process-output))
          (> (buffer-size) 0))
        (set-window-start (display-buffer buffer) 1)
      (message "(Command completed with no output)"))))

;;; suggested binding (# is the prompt when superuser):
;;; (global-set-key "\e#" 'su-command)
====8<----------------------------------------------------------------
/jr, nee John Robinson     Life did not take over the globe by combat,
jr@bbn.com or bbn!jr          but by networking -- Lynn Margulis

tale@pawl.rpi.edu (David C Lawrence) (09/23/89)

In <45953@bbn.COM> jr@bbn.com (John Robinson) writes:
jr> (anticipating the nits: yes, I know the password echos as you type it.
jr> However, putting the two arguments in the order they are at least
jr> overwrites the minibuffer as soon as you finish the password.  Anyone
jr> who wants to add the get-a-string-sliently logic to the following is
jr> welcome to do it and repost).

Here you go; simple blanking.

;; From jr@bbn.com Fri Sep 22 18:15:02 1989
;; added blanking passwd, Sep 22 18:20 -- tale

;;; suggested binding (# is the prompt when superuser):
;;; (global-set-key "\e#" 'su-command)

(defun su-command (password command)
  "Prompt for root password and a command, then do the latter as root."
  (interactive (list (read-passwd "root password: ")
                     (read-string "shell command: ")))
  (let ((buffer (get-buffer-create "*Shell Command Output*"))
        proc)
    (save-excursion
          (set-buffer buffer)
          (erase-buffer))
    (setq proc (start-process "su-emacs" buffer "/bin/su" "-c" command))
    (if (save-excursion
          (set-buffer buffer)
          (goto-char (point-min))
          (while (not (looking-at "Password:"))
            (accept-process-output proc)
            (goto-char (point-min)))
          (erase-buffer)
          (send-string proc (concat password "\n"))
          (while (not (looking-at "\n"))
            (accept-process-output proc)
            (goto-char (point-min)))
          (delete-char 1)
          (while (not (equal (process-status proc) 'exit))
            (accept-process-output))
          (> (buffer-size) 0))
        (set-window-start (display-buffer buffer) 1)
      (message "(Command completed with no output)"))))

(defun read-passwd (&optional prompt)
  "Allow user to type a string without it showing.  Returns string.
If optional PROMPT non-nil, use it as the prompt string in the minibuffer."
  ;; this is based on a similar function in telnet.el
  ;; the major drawback is that while being prompted for a password
  ;; it stays in this routine until C-g, RET or LFD is typed.
  ;; also didn't bother moving the cursor to the minibuffer
  (let ((passwd "") (echo-keystrokes 0) char)
    (if prompt (message prompt))
    (while (not (or (= (setq char (read-char)) 13) (= char 10)))
      ;; naughty bit.  take C-h to mean DEL.
      (if (or (= char 8) (= char 127))
          (if (> (length passwd) 0)
              (setq passwd (substring passwd 0 (1- (length passwd)))))
        (setq passwd (concat passwd (char-to-string char))))
      (if prompt (message (concat prompt (make-string (length passwd) ?*)))))
    (if prompt (message ""))
    passwd))