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会话中执行此操作.
以下是一些其他注意事项:
setuid
root用户起初我无法sudo
从SBCL中获得(实际程序本身):
(inferior-shell:run/ss '("sudo" "ls" ".")) ;; how can I pass sudo a password?
现在看起来可以使用sudo
's -S
选项(谢谢JustAnotherCurious).我想我可能会走这条路; 这绝对是我现在所倾向的.
无论如何,谢谢大家!我从你们所有人那里学到了很多东西.
如果您在进程中需要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命令.