Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit76c09db

Browse files
committed
Rewrite pam_passwd_conv_proc to be more robust: avoid assuming that the
pam_message array contains exactly one PAM_PROMPT_ECHO_OFF message.Instead, deal with however many messages there are, and don't throw errorfor PAM_ERROR_MSG and PAM_TEXT_INFO messages. This logic is borrowed fromopenssh 5.2p1, which hopefully has seen more real-world PAM usage than wehave. Per bug #5121 from Ryan Douglas, which turned out to be caused bythe conv_proc being called with zero messages. Apparently that is normalbehavior given the combination of Linux pam_krb5 with MS Active Directoryas the domain controller.Patch all the way back, since this code has been essentially untouchedsince 7.4. (Surprising we've not heard complaints before.)
1 parentc02350d commit76c09db

File tree

1 file changed

+80
-48
lines changed

1 file changed

+80
-48
lines changed

‎src/backend/libpq/auth.c

Lines changed: 80 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.186 2009/10/14 22:09:46 heikki Exp $
11+
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.187 2009/10/16 22:08:36 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -452,7 +452,6 @@ ClientAuthentication(Port *port)
452452

453453
caseuaPAM:
454454
#ifdefUSE_PAM
455-
pam_port_cludge=port;
456455
status=CheckPAMAuth(port,port->user_name,"");
457456
#else
458457
Assert(false);
@@ -1888,72 +1887,103 @@ static int
18881887
pam_passwd_conv_proc(intnum_msg,conststructpam_message**msg,
18891888
structpam_response**resp,void*appdata_ptr)
18901889
{
1891-
if (num_msg!=1||msg[0]->msg_style!=PAM_PROMPT_ECHO_OFF)
1892-
{
1893-
switch (msg[0]->msg_style)
1894-
{
1895-
casePAM_ERROR_MSG:
1896-
ereport(LOG,
1897-
(errmsg("error from underlying PAM layer: %s",
1898-
msg[0]->msg)));
1899-
returnPAM_CONV_ERR;
1900-
default:
1901-
ereport(LOG,
1902-
(errmsg("unsupported PAM conversation %d/%s",
1903-
msg[0]->msg_style,msg[0]->msg)));
1904-
returnPAM_CONV_ERR;
1905-
}
1906-
}
1890+
char*passwd;
1891+
structpam_response*reply;
1892+
inti;
19071893

1908-
if (!appdata_ptr)
1894+
if (appdata_ptr)
1895+
passwd= (char*)appdata_ptr;
1896+
else
19091897
{
19101898
/*
19111899
* Workaround for Solaris 2.6 where the PAM library is broken and does
19121900
* not pass appdata_ptr to the conversation routine
19131901
*/
1914-
appdata_ptr=pam_passwd;
1902+
passwd=pam_passwd;
19151903
}
19161904

1917-
/*
1918-
* Password wasn't passed to PAM the first time around - let's go ask the
1919-
* client to send a password, which we then stuff into PAM.
1920-
*/
1921-
if (strlen(appdata_ptr)==0)
1922-
{
1923-
char*passwd;
1924-
1925-
sendAuthRequest(pam_port_cludge,AUTH_REQ_PASSWORD);
1926-
passwd=recv_password_packet(pam_port_cludge);
1927-
1928-
if (passwd==NULL)
1929-
returnPAM_CONV_ERR;/* client didn't want to send password */
1905+
*resp=NULL;/* in case of error exit */
19301906

1931-
if (strlen(passwd)==0)
1932-
{
1933-
ereport(LOG,
1934-
(errmsg("empty password returned by client")));
1935-
returnPAM_CONV_ERR;
1936-
}
1937-
appdata_ptr=passwd;
1938-
}
1907+
if (num_msg <=0||num_msg>PAM_MAX_NUM_MSG)
1908+
returnPAM_CONV_ERR;
19391909

19401910
/*
19411911
* Explicitly not using palloc here - PAM will free this memory in
19421912
* pam_end()
19431913
*/
1944-
*resp=calloc(num_msg,sizeof(structpam_response));
1945-
if (!*resp)
1914+
if ((reply=calloc(num_msg,sizeof(structpam_response)))==NULL)
19461915
{
19471916
ereport(LOG,
19481917
(errcode(ERRCODE_OUT_OF_MEMORY),
19491918
errmsg("out of memory")));
19501919
returnPAM_CONV_ERR;
19511920
}
19521921

1953-
(*resp)[0].resp=strdup((char*)appdata_ptr);
1954-
(*resp)[0].resp_retcode=0;
1922+
for (i=0;i<num_msg;i++)
1923+
{
1924+
switch (msg[i]->msg_style)
1925+
{
1926+
casePAM_PROMPT_ECHO_OFF:
1927+
if (strlen(passwd)==0)
1928+
{
1929+
/*
1930+
* Password wasn't passed to PAM the first time around -
1931+
* let's go ask the client to send a password, which we
1932+
* then stuff into PAM.
1933+
*/
1934+
sendAuthRequest(pam_port_cludge,AUTH_REQ_PASSWORD);
1935+
passwd=recv_password_packet(pam_port_cludge);
1936+
if (passwd==NULL)
1937+
{
1938+
/*
1939+
* Client didn't want to send password. We
1940+
* intentionally do not log anything about this.
1941+
*/
1942+
gotofail;
1943+
}
1944+
if (strlen(passwd)==0)
1945+
{
1946+
ereport(LOG,
1947+
(errmsg("empty password returned by client")));
1948+
gotofail;
1949+
}
1950+
}
1951+
if ((reply[i].resp=strdup(passwd))==NULL)
1952+
gotofail;
1953+
reply[i].resp_retcode=PAM_SUCCESS;
1954+
break;
1955+
casePAM_ERROR_MSG:
1956+
ereport(LOG,
1957+
(errmsg("error from underlying PAM layer: %s",
1958+
msg[i]->msg)));
1959+
/* FALL THROUGH */
1960+
casePAM_TEXT_INFO:
1961+
/* we don't bother to log TEXT_INFO messages */
1962+
if ((reply[i].resp=strdup(""))==NULL)
1963+
gotofail;
1964+
reply[i].resp_retcode=PAM_SUCCESS;
1965+
break;
1966+
default:
1967+
elog(LOG,"unsupported PAM conversation %d/\"%s\"",
1968+
msg[i]->msg_style,
1969+
msg[i]->msg ?msg[i]->msg :"(none)");
1970+
gotofail;
1971+
}
1972+
}
1973+
1974+
*resp=reply;
1975+
returnPAM_SUCCESS;
1976+
1977+
fail:
1978+
/* free up whatever we allocated */
1979+
for (i=0;i<num_msg;i++)
1980+
{
1981+
if (reply[i].resp!=NULL)
1982+
free(reply[i].resp);
1983+
}
1984+
free(reply);
19551985

1956-
return((*resp)[0].resp ?PAM_SUCCESS :PAM_CONV_ERR);
1986+
returnPAM_CONV_ERR;
19571987
}
19581988

19591989

@@ -1967,10 +1997,12 @@ CheckPAMAuth(Port *port, char *user, char *password)
19671997
pam_handle_t*pamh=NULL;
19681998

19691999
/*
1970-
* Apparently, Solaris 2.6 is broken, and needs ugly static variable
1971-
* workaround
2000+
* We can't entirely rely on PAM to pass through appdata --- it appears
2001+
* not to work on at least Solaris 2.6. So use these ugly static
2002+
* variables instead.
19722003
*/
19732004
pam_passwd=password;
2005+
pam_port_cludge=port;
19742006

19752007
/*
19762008
* Set the application data portion of the conversation struct This is

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp