在 Linux 上我应该调用什么 API 来设置用户密码?
我了解 passwd(1)
和 crypt(3)
。 我正在寻找的是一个要调用的 C API,它将在 passwd/shadow 文件中设置用户的密码,而无需以编程方式遍历文件并覆盖相关用户的条目。 应用程序以 root 身份运行。
这样的API存在吗?
编辑:我想我应该指定,密码在不同系统之间同步,所以我们不能简单地调用 system("passwd") 并允许用户在 passwd 提示时输入他们想要的任何密码。 我们需要知道密码,以便能够以编程方式使用相同的密码更新其他系统。
I know about passwd(1)
and crypt(3)
. What I'm looking for is a C API to call which will set the user's password in the passwd/shadow files, without having to programatically walk the files and overwrite the entry for the user in question. Application runs as root.
Does such an API exist?
EDIT: Guess I should specify, the password is being synced between different systems, so we cannot simply call system("passwd") and allow the user to enter whatever password they want when passwd prompts them. We need to know the password so we can programatically update the other systems with the same password.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
正如 8jean 上面评论的那样,看起来 /usr/sbin/chpasswd 可能是最简单的方法。 否则,我会接受 noha 的评论,即使用 fgetpwent() 或 fgetspent() 等函数来处理影子文件,以遍历用户列表并修改我需要更改的记录。 感谢大家!
As 8jean commented above, looks like /usr/sbin/chpasswd might be the easiest way. Otherwise I'd have gone with noha's comment of using functions like fgetpwent() -- or fgetspent() for dealing with the shadow file -- to walk the list of users and modify the record(s) I need to change. Thanks, everyone!
这很可能会有所不同,具体取决于所讨论的系统使用的机制......
这给我带来了另一个建议,使用现有工具让不同的系统针对公共存储对用户进行身份验证 - 例如 LDAP 或任何目录或主目录系统可在您的站点上使用。 或者设置一个。 最好不是 NIS+ ^^
不要重新发明轮子,正如他们所说的那样。
您从哪里开始获取明文密码? 如果它在那里,为什么还要费心去设置密码呢? (是的,我知道我在这些事情上是个混蛋,抱歉——让反对票开始吧;)
This would most likely vary depending on what mechanism the system in question uses...
...which brings me to another suggestion, use existing tools to have the different systems authenticate users against a common store instead - like LDAP or whatever directory or master system is available at your site. Or set one up. Preferably not NIS+ ^^
Do not reinvent the wheel, as they supposedly say.
Where would you get the clear text password from to begin with? If it's out there, why even bother having passwords? (Yeah, I know I'm a prick when it comes to these things, sorry - let the downvotes begin ;)
使用 /etc/passwd 和 /etc/shadow 存储密码? 系统之间的 UID 是否同步? 您可以简单地复制/覆盖特定用户的 /etc/shadow 文件中的行。
“不要这样做”的答案是使用 NIS 服务器并仅更改密码一次。
Using /etc/passwd and /etc/shadow for password storage? Are the UIDs in sync between systems? You could simply copy/overwrite the line in the /etc/shadow file for the particular user.
And the "don't do it" answer would be to use a NIS server and change the password only once.
也许 putpwent 电话就是您正在寻找的。 尝试男人 putpwent。 在快速搜索中,我找到了一个包含一些示例的页面。 这可能有帮助。
http://linux.omnipot.net/article.php?article_id=10935
检查 getpwnam 进行查找而不是更改条目并使用 putpwent。
Maybe the putpwent call is what you are looking for. Try man putpwent. On a quicks search I find a page with some examples. It might help.
http://linux.omnipotent.net/article.php?article_id=10935
Check getpwnam for looking up than changing the entry and utilizing putpwent.
也许您想要PAM? 不确定,但大多数发行版都使用它...
添加:看起来 Mac OS X 使用
openssl
来管理其密码散列。 在 Linux 下也许可以做类似的事情,但是根据您的需要,您必须与操作系统使用的身份验证层兼容。Perhaps you want PAM? Not sure, but most distributions use it...
Added: It looks like Mac OS X uses
openssl
to manage it's password hashing. It may be possible to do something similar under linux, but for your needs you have to be compatible with the authentication layer used by the OS.您可以查看 passwd 源代码,但我首先尝试一种更简单、更懒的方法:我只是 strace passwd 并看看会发生什么。
You could have a look at passwd source, but I'd first try an easier and lazier way: I'd just strace passwd and see what happens.
最好的办法是使用适当的参数执行 passwd 命令,并让它担心文件处理、加密和文件锁定问题。 在某种程度上,无论如何,都必须“以编程方式遍历文件”。 除非您确实遇到了很大的性能问题,否则您最好依赖现有的代码和经验,而不是尝试复制现有的代码。
The best bet is to exec the passwd command with the appropriate arguments and let it worry about the file handling, crypt, and file locking issues. At some level, something is going to have to "programmatically walk the files" no matter what. Unless you really have a big performance problem with this, you're better off relying on the existing code and experience rather than trying to duplicate the existing code.