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

Commit35e2e35

Browse files
committed
Add authentication parameters compat_realm and upn_usename for SSPI
These parameters are available for SSPI authentication only, to makeit possible to make it behave more like "normal gssapi", whilemaking it possible to maintain compatibility.compat_realm is on by default, but can be turned off to make theauthentication use the full Kerberos realm instead of the NetBIOS name.upn_username is off by default, and can be turned on to return the usersKerberos UPN rather than the SAM-compatible name (a user in ActiveDirectory can have both a legacy SAM-compatible username and a newKerberos one. Normally they are the same, but not always)Author: Christian UllrichReviewed by: Robbie Harwood, Alvaro Herrera, me
1 parentcb0c8cb commit35e2e35

File tree

4 files changed

+178
-0
lines changed

4 files changed

+178
-0
lines changed

‎doc/src/sgml/client-auth.sgml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,43 @@ omicron bryanh guest1
11061106
</listitem>
11071107
</varlistentry>
11081108

1109+
<varlistentry>
1110+
<term><literal>compat_realm</literal></term>
1111+
<listitem>
1112+
<para>
1113+
If set to 1, the domain's SAM-compatible name (also known as the
1114+
NetBIOS name) is used for the <literal>include_realm</literal>
1115+
option. This is the default. If set to 0, the true realm name from
1116+
the Kerberos user principal name is used.
1117+
</para>
1118+
<para>
1119+
Do not enable this option unless your server runs under a domain
1120+
account (this includes virtual service accounts on a domain member
1121+
system) and all clients authenticating through SSPI are also using
1122+
domain accounts, or authentication will fail.
1123+
</para>
1124+
</listitem>
1125+
</varlistentry>
1126+
1127+
<varlistentry>
1128+
<term><literal>upn_username</literal></term>
1129+
<listitem>
1130+
<para>
1131+
If this option is enabled along with <literal>compat_realm</literal>,
1132+
the user name from the Kerberos UPN is used for authentication. If
1133+
it is disabled (the default), the SAM-compatible user name is used.
1134+
By default, these two names are identical for new user accounts.
1135+
</para>
1136+
<para>
1137+
Note that <application>libpq</> uses the SAM-compatible name if no
1138+
explicit user name is specified. If you use
1139+
<application>libpq</> or a driver based on it, you should
1140+
leave this option disabled or explicitly specify user name in the
1141+
connection string.
1142+
</para>
1143+
</listitem>
1144+
</varlistentry>
1145+
11091146
<varlistentry>
11101147
<term><literal>map</literal></term>
11111148
<listitem>

‎src/backend/libpq/auth.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ typedef SECURITY_STATUS
166166
(WINAPI*QUERY_SECURITY_CONTEXT_TOKEN_FN) (
167167
PCtxtHandle,void**);
168168
staticintpg_SSPI_recvauth(Port*port);
169+
staticintpg_SSPI_make_upn(char*accountname,
170+
size_taccountnamesize,
171+
char*domainname,
172+
size_tdomainnamesize,
173+
boolupdate_accountname);
169174
#endif
170175

171176
/*----------------------------------------------------------------
@@ -1287,6 +1292,17 @@ pg_SSPI_recvauth(Port *port)
12871292

12881293
free(tokenuser);
12891294

1295+
if (!port->hba->compat_realm)
1296+
{
1297+
intstatus=pg_SSPI_make_upn(accountname,sizeof(accountname),
1298+
domainname,sizeof(domainname),
1299+
port->hba->upn_username);
1300+
1301+
if (status!=STATUS_OK)
1302+
/* Error already reported from pg_SSPI_make_upn */
1303+
returnstatus;
1304+
}
1305+
12901306
/*
12911307
* Compare realm/domain if requested. In SSPI, always compare case
12921308
* insensitive.
@@ -1322,6 +1338,100 @@ pg_SSPI_recvauth(Port *port)
13221338
else
13231339
returncheck_usermap(port->hba->usermap,port->user_name,accountname, true);
13241340
}
1341+
1342+
/*
1343+
* Replaces the domainname with the Kerberos realm name,
1344+
* and optionally the accountname with the Kerberos user name.
1345+
*/
1346+
staticint
1347+
pg_SSPI_make_upn(char*accountname,
1348+
size_taccountnamesize,
1349+
char*domainname,
1350+
size_tdomainnamesize,
1351+
boolupdate_accountname)
1352+
{
1353+
char*samname;
1354+
char*upname=NULL;
1355+
char*p=NULL;
1356+
ULONGupnamesize=0;
1357+
size_tupnamerealmsize;
1358+
BOOLEANres;
1359+
1360+
/*
1361+
* Build SAM name (DOMAIN\user), then translate to UPN
1362+
* (user@kerberos.realm). The realm name is returned in lower case, but
1363+
* that is fine because in SSPI auth, string comparisons are always
1364+
* case-insensitive.
1365+
*/
1366+
1367+
samname=psprintf("%s\\%s",domainname,accountname);
1368+
res=TranslateName(samname,NameSamCompatible,NameUserPrincipal,
1369+
NULL,&upnamesize);
1370+
1371+
if ((!res&&GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
1372+
||upnamesize==0)
1373+
{
1374+
pfree(samname);
1375+
ereport(LOG,
1376+
(errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1377+
errmsg("could not translate name")));
1378+
returnSTATUS_ERROR;
1379+
}
1380+
1381+
/* upnamesize includes the terminating NUL. */
1382+
upname=palloc(upnamesize);
1383+
1384+
res=TranslateName(samname,NameSamCompatible,NameUserPrincipal,
1385+
upname,&upnamesize);
1386+
1387+
pfree(samname);
1388+
if (res)
1389+
p=strchr(upname,'@');
1390+
1391+
if (!res||p==NULL)
1392+
{
1393+
pfree(upname);
1394+
ereport(LOG,
1395+
(errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1396+
errmsg("could not translate name")));
1397+
returnSTATUS_ERROR;
1398+
}
1399+
1400+
/* Length of realm name after the '@', including the NUL. */
1401+
upnamerealmsize=upnamesize- (p-upname+1);
1402+
1403+
/* Replace domainname with realm name. */
1404+
if (upnamerealmsize>domainnamesize)
1405+
{
1406+
pfree(upname);
1407+
ereport(LOG,
1408+
(errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1409+
errmsg("realm name too long")));
1410+
returnSTATUS_ERROR;
1411+
}
1412+
1413+
/* Length is now safe. */
1414+
strcpy(domainname,p+1);
1415+
1416+
/* Replace account name as well (in case UPN != SAM)? */
1417+
if (update_accountname)
1418+
{
1419+
if ((p-upname+1)>accountnamesize)
1420+
{
1421+
pfree(upname);
1422+
ereport(LOG,
1423+
(errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1424+
errmsg("translated account name too long")));
1425+
returnSTATUS_ERROR;
1426+
}
1427+
1428+
*p=0;
1429+
strcpy(accountname,upname);
1430+
}
1431+
1432+
pfree(upname);
1433+
returnSTATUS_OK;
1434+
}
13251435
#endif/* ENABLE_SSPI */
13261436

13271437

‎src/backend/libpq/hba.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,17 @@ parse_hba_line(List *line, int line_num, char *raw_line)
12931293
parsedline->auth_method==uaSSPI)
12941294
parsedline->include_realm= true;
12951295

1296+
/*
1297+
* For SSPI, include_realm defaults to the SAM-compatible domain (aka
1298+
* NetBIOS name) and user names instead of the Kerberos principal name for
1299+
* compatibility.
1300+
*/
1301+
if (parsedline->auth_method==uaSSPI)
1302+
{
1303+
parsedline->compat_realm= true;
1304+
parsedline->upn_username= false;
1305+
}
1306+
12961307
/* Parse remaining arguments */
12971308
while ((field=lnext(field))!=NULL)
12981309
{
@@ -1585,6 +1596,24 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num)
15851596
else
15861597
hbaline->include_realm= false;
15871598
}
1599+
elseif (strcmp(name,"compat_realm")==0)
1600+
{
1601+
if (hbaline->auth_method!=uaSSPI)
1602+
INVALID_AUTH_OPTION("compat_realm",gettext_noop("sspi"));
1603+
if (strcmp(val,"1")==0)
1604+
hbaline->compat_realm= true;
1605+
else
1606+
hbaline->compat_realm= false;
1607+
}
1608+
elseif (strcmp(name,"upn_username")==0)
1609+
{
1610+
if (hbaline->auth_method!=uaSSPI)
1611+
INVALID_AUTH_OPTION("upn_username",gettext_noop("sspi"));
1612+
if (strcmp(val,"1")==0)
1613+
hbaline->upn_username= true;
1614+
else
1615+
hbaline->upn_username= false;
1616+
}
15881617
elseif (strcmp(name,"radiusserver")==0)
15891618
{
15901619
structaddrinfo*gai_result;

‎src/include/libpq/hba.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ typedef struct HbaLine
7979
boolclientcert;
8080
char*krb_realm;
8181
boolinclude_realm;
82+
boolcompat_realm;
83+
boolupn_username;
8284
char*radiusserver;
8385
char*radiussecret;
8486
char*radiusidentifier;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp