I can be able to let people login with root credentials to my gui in php?
Se você quer dizer que o processo da GUI tem credenciais raiz, então sim. Esse é um requisito. passwd
e outras coisas que fazem isso < o setuid bit definido e é de propriedade do root. Para obter instruções sobre como fazer isso com o php veja aqui .
Primeiro, certifique-se de que um fato básico sobre senhas seja claro - acho que você provavelmente já sabe disso, mas: As senhas não estão armazenadas no sistema. Um deles é um deles. Um hash unidirecional é uma string que pode ser criada usando um algoritmo de criptografia de uma string de origem (por exemplo, uma senha real), mas a origem não pode ser recriada a partir do hash .
Isso significa que, mesmo que alguém consiga /etc/shadow
, não é possível reconstruir as senhas dos usuários. A criptografia é unidirecional, não pode ser revertida. No entanto, você pode pegar uma string, criptografá-la da mesma maneira e compará-la ao hash. É assim que a autenticação por senha acontece.
A estrutura da string hash em /etc/shadow
é explicada em a boa resposta de Anthon . Abaixo está o processo básico de autenticação demonstrado em C. O PHP tem um wrapper para getpwnam()
ou você poderia analisar e armazenar /etc/shadow
. Para entender o que o crypt()
faz com a string (como Anthon menciona, ele inclui uma indicação do algoritmo usado e o "salt" para criar o hash), veja NOTES - > Glibc observa em man 3 crypt
. O crypt()
do PHP parece funcionar da mesma maneira, embora o documento seja menos claro.
As únicas funções significativas são getpwnam()
e crypt()
, todo o resto é apenas uma entrada básica, saída e manipulação de string.
#define _XOPEN_SOURCE // Important.
#include <errno.h>
#include <crypt.h>
#include <shadow.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main (int argc, const char *argv[]) {
if (argc < 2) {
puts("Username required.");
return 1;
}
// Get shadow password.
struct spwd *spw = getspnam(argv[1]);
if (!spw) {
if (errno == EACCES) puts("Permission denied.");
else if (!errno) puts("No such user.");
else puts(strerror(errno));
return 1;
}
// Read password from user.
fprintf(stderr, "%s> ", argv[1]);
char buffer[4096];
int len = read(0, buffer, 4095);
// Ditch the newline.
buffer[len - 1] = 'gcc --std=c99 whatever.c -o testpw -lcrypt
';
// Hash and report.
char *hashed = crypt(buffer, spw->sp_pwdp);
printf("%s\n%s\n", spw->sp_pwdp, hashed);
if (!strcmp(spw->sp_pwdp, hashed)) puts("Password matched.");
else puts("Password DID NOT match.");
return 0;
}
Você pode compilar isso:
./testpw me
Você precisa executá-lo como root ou receberá "Permissão negada". Você precisa especificar um nome de usuário real:
#define _XOPEN_SOURCE // Important.
#include <errno.h>
#include <crypt.h>
#include <shadow.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main (int argc, const char *argv[]) {
if (argc < 2) {
puts("Username required.");
return 1;
}
// Get shadow password.
struct spwd *spw = getspnam(argv[1]);
if (!spw) {
if (errno == EACCES) puts("Permission denied.");
else if (!errno) puts("No such user.");
else puts(strerror(errno));
return 1;
}
// Read password from user.
fprintf(stderr, "%s> ", argv[1]);
char buffer[4096];
int len = read(0, buffer, 4095);
// Ditch the newline.
buffer[len - 1] = 'gcc --std=c99 whatever.c -o testpw -lcrypt
';
// Hash and report.
char *hashed = crypt(buffer, spw->sp_pwdp);
printf("%s\n%s\n", spw->sp_pwdp, hashed);
if (!strcmp(spw->sp_pwdp, hashed)) puts("Password matched.");
else puts("Password DID NOT match.");
return 0;
}
Nota: o eco não está desativado, portanto, a senha ficará visível quando você digitá-lo.