我想使用C ++更改任何Linux用户密码,任何解决方案都会很棒。
我需要手动完成,这意味着打开文件(不能使用system()):
似乎我还需要锁定这些文件。有c代码样本用于打开.txt文件和阅读内容,但无法读取大内容,这也是问题。
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/file.h>
#include <stdlib.h>
#include <string>
const char* path = "/tmp/log.txt";
void read_file()
{
int fd;
char buf[1000];
int i;
fd = open(path, O_RDONLY);
flock(fd, LOCK_SH);
for(i=0; i < 255 ; i++) {
read(fd, &buf[i], 1);
usleep(10 * 10); // 10 ms
}
flock(fd, LOCK_UN);
close(fd);
printf("reader: %#x: %s\n", getpid(), buf);
usleep(10 * 10); // 10 ms
}
void reader()
{
read_file();
exit(0);
}
int main()
{
setlinebuf(stdout);
reader();
return 0;
}
在理想的解决方案中,它必须像这样工作:
有人可以解释我需要使用哪个文件来更改密码以及如何正确打开它以免损坏系统?如何准确编辑那一行是密码?
目前我正在使用Ubuntu 16.04。
修改
我在评论中看到普通用户无法访问这些文件。一条评论是为每个用户授予更改任何用户密码的权限。
那么如果一个用户有权编辑这些文件并将密码更改为任何用户呢?这样就可以安全地打开和编辑系统文件shadow
,保存并关闭它。我需要以某种方式锁定它或如何访问它?
There是shadow
文件结构,因为所有人都可以看到密码有特殊的哈希或密码,所以如果正确更改并保存文件,密码必须更改。
使用用户名获取用户数据的代码:
#include <stdio.h>
#include <pwd.h>
#include <iostream>
using namespace std;
int main()
{
struct passwd *p_entry1, *p_entry2;
char* username;
cout<<"Insert username: ";
cin>>username;
/* Find user data by entered username */
p_entry1 = getpwnam(username);
printf("username = %s = %s"
" userid = %d group id = %d"
" real name = %s directory = %s"
" primary shell = %s",
p_entry1->pw_name, p_entry1->pw_passwd,
p_entry1->pw_uid, p_entry1->pw_gid,
p_entry1->pw_gecos, p_entry1->pw_dir,
p_entry1->pw_shell);
}
答案 0 :(得分:3)
要更改用户密码,您可以使用<pwd.h>
和<shadow.h>
中的 putpwent 和 putspent 功能分别。这样您就不需要显式读取,解析和写入passwd和shadow文件。
关于权限:
如果您不愿意以root用户身份运行程序,则可以选择 setuid 对您的可执行文件授予权限,就像passwd
可执行文件本身一样。
chown root.root <executable>
chmod u+s <executable>
setuid
程序在其所有者的权限/权限下执行(在本例中为root
),因此您被授予二进制所有者的权限/权限。
如果您的二进制文件归root
所有并且具有suid
权限,则可以更改/etc/passwd
以及只有root
有权访问的任何其他文件。这非常方便,但与此同时它可能非常危险。例如,如果您的程序存在错误或无法预料的情况,恶意用户可能会利用它来获取系统中的root权限/访问权限。
编写安全程序似乎很简单,但它有各种各样的问题。祝你好运!
答案 1 :(得分:2)
当然,您无法直接访问这些文件,因为它们是root拥有的特权文件。毕竟,如果任何进程可以随机乱写这些文件并更改任何人的密码,那么安全性就会不高。
因此,无法避免权限升级以更新系统密码。这是一个基本的,基本的安全原则。
所以,无论你如何处理它,在某些时候,在某个地方,必须system()
- 执行特权二进制文件。 /usr/bin/passwd
是一个setuid-root二进制文件是有原因的。
因此,如果您无法使用system()
,则无法执行此操作。这是基本的。
这里可以做的最多的事情就是让一个单独的守护进程以root身份运行,并让你的应用程序连接并与之通信,将适当的凭据传递给它,并让守护进程负责更改密码。这样可以避免由应用程序直接使用system()
。
就实际更改密码的任务而言,一旦您拥有足够的root权限,通常不会通过自己对文件进行涂鸦来完成。 Linux PAM library提供了用于验证和更新系统密码的API。有关更多信息,请参阅Linux PAM库文档。
答案 2 :(得分:0)
一切皆有可能 - &gt;制作改变密码的c ++代码我做了这个:
$6$:SHA-512
哈希。/etc/shadow
文件,阅读,按用户名查找用户并更改密码。 There您可以阅读shadow
文件结构。要打开文件使用的fstream,要查找和更改使用std::getline
和std::vector
的行。
要运行.cpp文件,需要在终端root,运行g++ fileName.cpp -o excqFileName -lcrypt
和./excqFileName
命令。这对我而言。
所有人,我完成了我的任务,这是可能的。不会共享代码,但我解释得足够了解它是如何工作的。