* external.cc (cygwin_internal): Implement CW_CYGNAME_FROM_WINNAME.

Add lengthy comment to explain what we do and why.
	* include/sys/cygwin.h (cygwin_getinfo_types): Add
	CW_CYGNAME_FROM_WINNAME.
This commit is contained in:
Corinna Vinschen 2014-05-15 11:16:28 +00:00
parent b9ee0bb078
commit 076a61f0d9
3 changed files with 65 additions and 1 deletions

View File

@ -1,3 +1,10 @@
2014-05-15 Corinna Vinschen <corinna@vinschen.de>
* external.cc (cygwin_internal): Implement CW_CYGNAME_FROM_WINNAME.
Add lengthy comment to explain what we do and why.
* include/sys/cygwin.h (cygwin_getinfo_types): Add
CW_CYGNAME_FROM_WINNAME.
2014-05-14 Corinna Vinschen <corinna@vinschen.de> 2014-05-14 Corinna Vinschen <corinna@vinschen.de>
* sec_auth.cc (get_server_groups): Call get_logon_server only for * sec_auth.cc (get_server_groups): Call get_logon_server only for

View File

@ -619,6 +619,61 @@ cygwin_internal (cygwin_getinfo_types t, ...)
} }
break; break;
case CW_CYGNAME_FROM_WINNAME:
{
/* This functionality has been added mainly for sshd. Sshd
calls getpwnam() with the username of the non-privileged
user used for privilege separation. This is usually a
fixed string "sshd". However, when using usernames from
the Windows DBs, it's no safe bet anymore if the username
is "sshd", it could also be "DOMAIN+sshd". So what we do
here is this:
Sshd calls cygwin_internal (CW_CYGNAME_FROM_WINNAME,
"sshd",
username_buffer,
sizeof username_buffer);
If this call succeeds, sshd expects the correct Cygwin
username of the unprivileged sshd account in username_buffer.
The below code checks for a Windows username matching the
incoming username, and then fetches the Cygwin username with
the matching SID. This is our username used for privsep then.
Of course, other applications with similar needs can use the
same method. */
const char *winname = va_arg (arg, const char *);
char *buffer = va_arg (arg, char *);
size_t buflen = va_arg (arg, size_t);
if (!winname || !buffer || !buflen)
break;
PWCHAR name;
if (!sys_mbstowcs_alloc (&name, HEAP_BUF, winname))
break;
cygsid sid;
DWORD slen = SECURITY_MAX_SID_SIZE;
WCHAR dom[DNLEN + 1];
DWORD dlen = DNLEN + 1;
SID_NAME_USE acc_type;
if (!LookupAccountNameW (NULL, name, sid, &slen, dom, &dlen,
&acc_type))
break;
struct passwd *pw = internal_getpwsid (sid);
if (!pw)
break;
buffer[0] = '\0';
strncat (buffer, pw->pw_name, buflen - 1);
res = 0;
}
break;
default: default:
set_errno (ENOSYS); set_errno (ENOSYS);
} }

View File

@ -149,7 +149,8 @@ typedef enum
CW_ENDENT, CW_ENDENT,
CW_GETNSSSEP, CW_GETNSSSEP,
CW_GETPWSID, CW_GETPWSID,
CW_GETGRSID CW_GETGRSID,
CW_CYGNAME_FROM_WINNAME
} cygwin_getinfo_types; } cygwin_getinfo_types;
#define CW_LOCK_PINFO CW_LOCK_PINFO #define CW_LOCK_PINFO CW_LOCK_PINFO
@ -206,6 +207,7 @@ typedef enum
#define CW_GETNSSSEP CW_GETNSSSEP #define CW_GETNSSSEP CW_GETNSSSEP
#define CW_GETPWSID CW_GETPWSID #define CW_GETPWSID CW_GETPWSID
#define CW_GETGRSID CW_GETGRSID #define CW_GETGRSID CW_GETGRSID
#define CW_CYGNAME_FROM_WINNAME CW_CYGNAME_FROM_WINNAME
/* Token type for CW_SET_EXTERNAL_TOKEN */ /* Token type for CW_SET_EXTERNAL_TOKEN */
enum enum