如何将需要root权限的功能添加到Common Lisp库中?

Joe*_*lor 2 unix linux macos common-lisp elevated-privileges

原始问题

我正在尝试创建一个Lisp库,除其他外,它可以编辑我的系统/etc/hosts文件和nginx配置.我面临的问题是,因为我的Lisp图像是一个无特权的用户,我的图书馆不能做这些事情.理想情况下,当需要root权限时,我可以为我的库提供密码,以便暂时提升其访问权限以完成任务.唉,我还没找到任何Common Lisp等价的sudo.有吗?我是以错误的方式接近这个吗?我怎么能解决这个问题呢?

在代码中,我希望能够做的基本上是这样的:

(with-sudo (:username "root" :password (securely-read-line))
  (with-open-file (f "/etc/hosts" :direction :output :if-exists :append)
    (format f "127.0.0.1 mywebsite.local~%")))
Run Code Online (Sandbox Code Playgroud)

澄清

我在OS X上使用SBCL.我正在尝试创建一个基本上是网站快速项目专业化的库.目前,每次在本地计算机上设置新的Web项目时,我都必须编辑遍布系统的配置文件.我想尽可能多地自动化,我希望能够在我通常打开并连接到单个SBCL实例的SLIME会话中执行此操作.

以下是一些其他注意事项:

  1. 我不希望我的主要SBCL实例成为setuidroot用户
  2. 我不介意产生一个新的进程,无论是一个小的C程序还是一个SBCL的裸实例,它会加载几行代码然后退出.
  3. 我想尽可能保持Lisp与C的比例.
  4. 某些文本编辑器(如TextMate)在访问需要更高权限查看的文件时会提示用户名和密码,并提供相应的访问权限.我想知道如何让我的Lisp库做同样的事情?
  5. 起初我无法sudo从SBCL中获得(实际程序本身):

    (inferior-shell:run/ss '("sudo" "ls" ".")) ;; how can I pass sudo a password?

    现在看起来可以使用sudo's -S选项(谢谢JustAnotherCurious).我想我可能会走这条路; 这绝对是我现在所倾向的.

无论如何,谢谢大家!我从你们所有人那里学到了很多东西.

han*_*s23 5

如果您在进程中需要root访问权限,则需要最初以root身份启动Lisp进程.通常不可能像回顾一样运行非根进程.

幸运的是,Unix有一种机制允许进程在运行时在根权限和非root权限之间切换.该机制称为有效用户ID.以root身份运行的进程可以使用seteuid系统调用切换到非root有效uid ,也可以通过这种方式切换回"正在"root.

当然,如果你以root身份启动Lisp进程,那么该进程可以完全控制机器,并且根据你正在处理的数据和机器,你需要考虑到你打开的可能的安全漏洞.幸运的是,在Lisp中很难产生缓冲区溢出,所以从这个角度来看,你处于更安全的一面:)

访问系统调用接口是不是在Common Lisp的标准化,但大多数的实现有一个本机接口系统,你也可以使用CFFI如果你打算为你的程序是基于对面的Linux/Unix的Lisp便携.

以下是以root身份运行的SBCL的成绩单,演示了seteuid的使用:

CL-USER> (defun write-file-in-filesystem-root ()
           (handler-case
               (with-open-file (f "/only-root-may-write-to-root"
                                  :direction :output
                                  :if-exists :supersede)
                 (write "hello" :stream f))
             (error (e) (format t "error: ~A~%" e))))
WRITE-FILE-IN-FILESYSTEM-ROOT
CL-USER> (sb-posix:seteuid 0)
0
CL-USER> (write-file-in-filesystem-root)
"hello"
CL-USER> (sb-posix:seteuid 1000)
0
CL-USER> (write-file-in-filesystem-root)
error: error opening #P"/only-root-may-write-to-root": Permission denied
NIL
CL-USER> (sb-posix:seteuid 0)
0
CL-USER> (write-file-in-filesystem-root)
"hello"
CL-USER> (delete-file "/only-root-may-write-to-root")
T
Run Code Online (Sandbox Code Playgroud)

如果您只需要访问受保护的文件,如果保持OSX特定是可接受的,并且您希望用户使用标准身份验证请求程序进行身份验证,则可以使用特定于OSX 的authopen命令.