如果您需要验证使用阴影密码的系统上的 *真实* Unix 密码,则 PHP 中的 posix_getpwnam() 函数将不起作用(如上所述,密码字段中将是 'x' 或 '*')。
我需要在 PHP 中验证用户/密码(使用 SSL!)。我不知道这是否是最好的方法,但这是我目前正在做的事情(效果很好!)。
首先,您需要操作系统的一些帮助。我编写了一个小型 C 实用程序,它为我执行阴影查找... 它需要 root 权限才能读取 /etc/shadow。因此,在您编译(gcc -O2 -s -o spasswd -lcrypt spasswd.c)之后,您需要使用 sudo 运行它,或者
# chown root spasswd && chmod u+s spasswd
我用于从 PHP 身份验证用户/密码的代码如下所示
function Authenticate($realm)
{
global $PHP_AUTH_USER;
global $PHP_AUTH_PW;
if(!isset($PHP_AUTH_USER))
{
header("WWW-Authenticate: Basic realm=\"$realm\"");
header("HTTP/1.0 401 Unauthorized");
return false;
}
else
{
if(($fh = popen("/usr/sbin/spasswd", "w")))
{
fputs($fh, "$PHP_AUTH_USER $PHP_AUTH_PW");
$r = pclose($fh);
if(!$r)
return true;
}
}
header("WWW-Authenticate: Basic realm=\"$realm\"");
header("HTTP/1.0 401 Unauthorized");
return false;
}
spasswd.c 的 C 源代码
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crypt.h>
#include <shadow.h>
static char salt[12], user[128], pass[128];
void die(void)
{
memset(salt, '\0', 12);
memset(user, '\0', 128);
memset(pass, '\0', 128);
}
int main(int argc, char *argv[])
{
struct spwd *passwd;
atexit(die); die();
if(fscanf(stdin, "%127s %127s", user, pass) != 2)
return 1;
if(!(passwd = getspnam(user)))
return 1;
strncpy(salt, passwd->sp_pwdp, 11);
strncpy(pass, crypt(pass, salt), 127);
if(!strncmp(pass, passwd->sp_pwdp, 127))
return 0;
return 1;
}
希望这对某人有帮助...