在PHP中调用CHPASSWD来修改客户的密码: echo "account:password"|/usr/sbin/chpasswd,非常简单,但这种 方法却有一个大问题:用这种方法生成的密码只有前八位有效!但如 果用PASSWD来修改密码,则没有此限制。为什么呢? 原来Linux中的密码用两种加密算法加密:DES和MD5,查看你 的/etc/shadow文件,密码栏以$1$开头的是用MD5算法加密的。而用 chpasswd生成的用户密码是用DES算法加密的,它的有效位只有前八 位,而MD5则无此限制。 我们知道用crypt函数可以生成MD5密码,只需要把salt值设为$1 $********$(*为八位任意字符)生成的就是MD5密码。不按此格式则 生成DES密码。 下面是我写的md5passwd程序,可以用 md5passwd 用户名 密码 来生成不限长度的用户密码。 注意特殊字符要用''转义引用,如'|', '!'等,如密码中有 字符'',则要写成'\\'!! #include #include #include int main(int argc, char * * argv) { FILE * oldfp, * newfp; char username[50], password[100], shcmd[200], line_buf[1024]; char * encryptpass, * fpart, * passwd, * part3, * part4, * part5, * char * part7, * part8; char * buf; char salt[12], pass_tmp[256]; int j, i; memset(username, 0, sizeof(username)); memset(password, 0, sizeof(password)); memset(pass_tmp, 0, sizeof(pass_tmp)); memset(salt, 0, sizeof(salt)); memset(shcmd, 0, sizeof(shcmd)); memcpy(username, argv[1], strlen(argv[1])); memcpy(password, argv[2], strlen(argv[2])); /* 处理转义字符 */ j=0; for(i=0;i{ if( password == '\' ) { if( password[i+1] == '\' ) { pass_tmp[j]=password; j++; i=i+1; } else continue; } else { pass_tmp[j]=password; j++; } } memset(password, 0, sizeof(password)); memcpy(password, pass_tmp, strlen(pass_tmp)); /* 用PID作为SALT值 */ sprintf(salt, "$1$%08d$", getpid()); encryptpass=crypt(password, salt); if( (oldfp=fopen("/etc/shadow", "r")) == NULL ) exit(-1); if( (newfp=fopen("/tmp/shadow", "w")) == NULL ) exit(-1); rewind(oldfp); while(!feof(oldfp)) { memset(line_buf, 0, sizeof(line_buf)); fgets(line_buf, 1024, oldfp); buf=line_buf; if( strlen(line_buf) == 0 ) break; fpart=strsep(&buf, ":"); if( fpart != NULL ) fwrite(fpart, strlen(fpart), 1, newfp); fwrite(":", 1, 1, newfp); passwd=strsep(&buf, ":"); if( memcmp(argv[1], fpart, strlen(argv[1])) == 0 ) { passwd=encryptpass; } if( passwd != NULL ) fwrite(passwd, strlen(passwd), 1, newfp); fwrite(":", 1, 1, newfp); part3=strsep(&buf, ":"); if( part3 != NULL ) fwrite(part3, strlen(part3), 1, newfp); fwrite(":", 1, 1, newfp); part4=strsep(&buf, ":"); if( part4 != NULL ) fwrite(part4, strlen(part4), 1, newfp); fwrite(":", 1, 1, newfp); part5=strsep(&buf, ":"); if( part5 != NULL ) fwrite(part5, strlen(part5), 1, newfp); fwrite(":", 1, 1, newfp); part6=strsep(&buf, ":"); if( part6 != NULL ) fwrite(part6, strlen(part6), 1, newfp); fwrite(":", 1, 1, newfp); part7=strsep(&buf, ":"); if( part7 != NULL ) fwrite(part7, strlen(part7), 1, newfp); fwrite(":", 1, 1, newfp); part8=strsep(&buf, ":"); if( part8 != NULL ) fwrite(part8, strlen(part8), 1, newfp); fwrite(":", 1, 1, newfp); fwrite("n", 1, 1, newfp); } fclose(oldfp); fclose(newfp); system("/usr/local/bin/super amv /tmp/shadow /etc/shadow"); } 注:因为要用非root用户来执行,所以用到了super命令。 摘自:LinuxForum phpfans.net收集整理 |