接下來要做的事情是變更實際碼, 我們將變更 auth.c 檔。
變更前 auth.c 檔 function 為:
--------------------------------------------------------------------------------
/*
* login - Check the user name and passWord against the system
* password database, and login the user if OK.
*
* returns:
* UPAP_AUTHNAK: Login failed.
* UPAP_AUTHACK: Login sUCceeded.
* In either case, msg points to an apPRopriate message.
*/
static int
login(user, passwd, msg, msglen)
char *user;
char *passwd;
char **msg;
int *msglen;
{
struct passwd *pw;
char *epasswd;
char *tty;
if ((pw = getpwnam(user)) == NULL) {
return (UPAP_AUTHNAK);
}
/*
* XXX If no passwd, let them login without one.
*/
if (pw->pw_passwd == '/0') {
return (UPAP_AUTHACK);
}
epasswd = crypt(passwd, pw->pw_passwd);
if (strcmp(epasswd, pw->pw_passwd)) {
return (UPAP_AUTHNAK);
}
syslog(LOG_INFO, "user %s logged in", user);
/*
* Write a wtmp entry for this user.
*/
tty = strrchr(devname, '/');
if (tty == NULL)
tty = devname;
else
tty++;
logwtmp(tty, user, ""); /* Add wtmp login entry */
logged_in = TRUE;
return (UPAP_AUTHACK);
}
--------------------------------------------------------------------------------
使用者的密碼被放在 pw->pw_passwd,所以我們需新增 getspnam function,這將會把密碼放到 spwd->sp_pwdp。
我們將新增 pwauth function 來表示真正的權限。 這將在 shadow 檔設定時自動產生第二個權限。
變更為可以支援 shadow 後的 auth.c function:
--------------------------------------------------------------------------------
/*
* login - Check the user name and password against the system
* password database, and login the user if OK.
*
* This function has been modified to support the linux Shadow Password
* Suite if USE_SHADOW is defined.
*
* returns:
* UPAP_AUTHNAK: Login failed.
* UPAP_AUTHACK: Login succeeded.
* In either case, msg points to an appropriate message.
*/
static int
login(user, passwd, msg, msglen)
char *user;
char *passwd;
char **msg;
int *msglen;
{
struct passwd *pw;
char *epasswd;
char *tty;
#ifdef USE_SHADOW
struct spwd *spwd;
struct spwd *getspnam();
#endif
if ((pw = getpwnam(user)) == NULL) {
return (UPAP_AUTHNAK);
}
#ifdef USE_SHADOW
spwd = getspnam(user);
if (spwd)
pw->pw_passwd = spwd->sp-pwdp;
#endif
/*
* XXX If no passwd, let NOT them login without one.
*/
if (pw->pw_passwd == '/0') {
return (UPAP_AUTHNAK);
}
#ifdef HAS_SHADOW
if ((pw->pw_passwd && pw->pw_passwd[0] == '@'
&& pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL))
!valid (passwd, pw)) {
return (UPAP_AUTHNAK);
}
#else
epasswd = crypt(passwd, pw->pw_passwd);
if (strcmp(epasswd, pw->pw_passwd)) {
return (UPAP_AUTHNAK);
}
#endif
syslog(LOG_INFO, "user %s logged in", user);
/*
* Write a wtmp entry for this user.
*/
tty = strrchr(devname, '/');
if (tty == NULL)
tty = devname;
else
tty++;
logwtmp(tty, user, ""); /* Add wtmp login entry */
logged_in = TRUE;
return (UPAP_AUTHACK);
}
--------------------------------------------------------------------------------
嚴謹的□例將啟發我們在作其他改變的幫助。
原始的版本假如在 /etc/passwd 檔沒有任何密碼,可答應存取傳回的 UPAP_AUTHACK 。這是不好的,因為簽入的使用是使用一個答應存取 PPP process的帳號,然後檢查帳號密碼,該帳號密碼是由 RAP 、在 /etc/passwd 檔的帳號和 /etc/shadow 檔的密碼供給。
所以假如我們設定原本版本對每個使用者,如 ppp 可以在 shell 執行,然後任何人可以獲得 ppp 鏈結透過設定他們對使用者 ppp 的 PAP 和 null 的密碼。
我們修正 UPAP_AUTHNAK 取代 UPAP_AUTHACK 假如密碼欄位是空的。
有趣的是 pppd-2.2.0 有相同的問題。
接下來我們需要變更 Makefile 以便讓兩件事發生:
USE_SHADOW 必須被重新定義且libshadow.a 需要被新增到鏈結 process。
編輯 Makefile 且新增:
LIBS = -lshadow
然後我們找到這一行:
COMPILE_FLAGS = -I.. -D_linux_=1 -DGIDSET_TYPE=gid_t
然後改變它變成:
COMPILE_FLAGS = -I.. -D_linux_=1 -DGIDSET_TYPE=gid_t -DUSE_SHADOW
現在執行 make 跟 install.