Easycluster recently requires users to be created and a user account can be created on Linux. It is natural that the background program calls the useradd command line, passwords are troublesome. Check the useradd manual. You can specify a password when creating the-P password option. However, the password here must have been encrypted, this requires encryption using the crypt function and then placing it in the command line. I tested it and wrote a test code to generate a password:
-
Code: select all
-
#define _XOPEN_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
char key[] = "666666";
printf("encrypted password is: %s\n", crypt(key, "3a"));
return 0;
}
In this case, you can generate a 666666 password. Note that _ xopen_source must be defined first, which is required in the crypt manual. Second, the first parameter of the crypt function is the plaintext password, and the second parameter is "salt ", in fact is an encrypted key, consists of two characters, the value of the character can be "a-zA-Z0-9. /". For more information, see the manual.
Then, use useradd-P <encrypted password> <username> to generate an account with the specified password.
Caution: User logon is the opposite of the above process, but the difficulty lies in not knowing salt. Different encryption methods have different rules. For example, in some encryption methods, the first two letters of the encrypted ciphertext are salt, and some are not. In all the confidential methods, glibc provides the crypt call, shielding the complexity of multiple encryption algorithms. This should be the PAM mechanism in Linux. Therefore, when a user logs on, he must first retrieve the salt in the password Based on the encryption method, then call crypt to generate the ciphertext, and then compare it! One encryption method does not work. Try the second one. Here we have the easycluster User Login background Verification Code. In RedHat and Suse (the encryption methods for SuSE and RedHat are different, but they are the same for password creation, all of them call crypt, as described above). All the tests passed:
-
Code: select all
-
#define _XOPEN_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>#include "easy_s.h"
#include "common.h"
// you need link your object file like this:
// gcc -o xx xxx.c -lcrypt
//int authenticate_user(char *username, char *key);
int authenticate_user(char *username, char *key)
{
const int buffer_len = 512;
const char filename[50] = "/etc/shadow";
char *dataline = (char *)malloc(buffer_len);
if (dataline == NULL){
message_log("authenticate_user() error: failed to allocate space for user data buffer.");
return -2;
}
FILE *fp = fopen(filename, "r");
if (fp == NULL){
free(dataline);
//fprintf(stderr, "failed to open user account file.\n");
return -1;
}
while (fgets(dataline, buffer_len, fp)){
if (strstr(dataline, username)){
/*
char *crypt(const char *key, const char *salt).
If salt is a character string starting with the three characters "$1$"
followed by at most eight characters, and optionally terminated
by "$", then instead of using the DES machine, the glibc crypt
function uses an MD5-based algorithm, and outputs up to 34 bytes,
namely "$1$<string>$", where "<string>" stands for the up to 8 charac-
ters following "$1$" in the salt, followed by 22 bytes chosen from the
set [a-zA-Z0-9./].
*/
char *line = strstr(dataline, "$1$");
char *t;
/*if ((line == NULL) || (strlen(line) < 4)){
free(dataline);
fclose(fp);
return -4;
}
*/
if (line == NULL ){
line = strchr(dataline, ':');
if (line == NULL){
free(dataline);
fclose(fp);
return -4;
}
t = strchr((line+1), ':');
if (t == NULL){
free(dataline);
fclose(fp);
return -4;
}
*t = '\0';
char salt_1[16];
salt_1[0] = line[1];salt_1[1] = line[2];salt_1[2] = '\0';
char *pass = crypt(key, salt_1);
if (pass == NULL){
free(dataline);
fclose(fp);
return -4;
}
if (strcmp((line+1), pass) == 0){
free(dataline);
fclose(fp);
return 0;
}else{
free(dataline);
fclose(fp);
return -5;
}
}
if (strlen(line) < 4){
free(dataline);
fclose(fp);
return -4;
}
t =strstr((line+3), ":");
if (t == NULL){
free(dataline);
fclose(fp);
return -4;
}
t[0] = '\0';
t = strstr((line+3), "$");
if (t == NULL){
free(dataline);
fclose(fp);
return -4;
}
char salt[50];
memcpy(salt, line, t-line+1);
char *encrypt_str = crypt(key, salt);
if (encrypt_str == NULL){
free(dataline);
fclose(fp);
return -5;
}
if (strcmp(encrypt_str, line) == 0){
free(dataline);
fclose(fp);
return 0;
}
}
}
free(dataline);
fclose(fp);
return -4;
}
Similarly, you can use the-P option of The usermod command to change the user password. For example, usermod-P <encrypted password> username.