Hi!
Every possible way would be good, I just want to make /etc/passwd
and /etc/smbpasswd-entrys out of my two c-strings for username & password.
Some time ago I used the following function to modify user passwords from a
C program. I do not remember where I found these lines of code.
Dirk
---------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ETC_SHADOW "/etc/shadow"
#define SHADOW_TMP "/etc/shadow.tmp"
#define SHADOW_OLD "/etc/shadow.old"
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
int setpass ( char *user, char *pass ) {
char salt[2];
struct stat passwd_stat;
struct spwd *sp; /* shadow struct obtained from fgetspent() */
FILE *oldpf = NULL, *newpf = NULL;
int gotit;
int ret;
time_t tm;
time (&tm);
salt[0] = bin_to_ascii (tm & 0x3f);
salt[1] = bin_to_ascii ((tm >> 6) & 0x3f);
/* Open the shadow file for reading. We can't use getspent and
friends here, because they go through the YP maps, too. */
if ((oldpf = fopen ( ETC_SHADOW, "r")) == NULL) {
return 1;
}
if (fstat (fileno (oldpf), &passwd_stat) < 0) {
fclose (oldpf);
return 1;
}
/* Open a temp shadow file */
if ((newpf = fopen ( SHADOW_TMP, "w+")) == NULL) {
fclose (oldpf);
return 1;
}
chmod ( SHADOW_TMP, passwd_stat.st_mode);
chown ( SHADOW_TMP, passwd_stat.st_uid, passwd_stat.st_gid);
gotit = 0;
/* Loop over all passwd entries */
while ((sp = fgetspent (oldpf)) != NULL) {
/* check if this is the uid we want to change. A few
sanity checks added for consistency. */
if (!gotit && strcmp (user, sp->sp_namp) == 0) {
time_t now;
time(&now);
/* set the new passwd */
sp->sp_pwdp = crypt (pass, salt);
sp->sp_lstchg = (long int)now / (24L*3600L);
gotit = 1;
}
/* write the passwd entry to tmp file */
if (putspent (sp, newpf) < 0) {
unlink ( SHADOW_TMP );
fclose(oldpf);
fclose(newpf);
return 1;
}
}
unlink ( SHADOW_OLD );
link ( ETC_SHADOW, SHADOW_OLD );
ret = rename ( SHADOW_TMP, ETC_SHADOW );
unlink ( SHADOW_TMP );
fclose (oldpf);
fclose (newpf);
return ret;
}