Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2014-05-15 15:16:28 +0400
committerCorinna Vinschen <corinna@vinschen.de>2014-05-15 15:16:28 +0400
commit076a61f0d9bf60c6063b1569004c1daa24f9aa0c (patch)
treebc712d6210cd97372cd32711b4733920b663565e /winsup/cygwin/external.cc
parentb9ee0bb0786b270726aad94d40ed602b807ba576 (diff)
* 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.
Diffstat (limited to 'winsup/cygwin/external.cc')
-rw-r--r--winsup/cygwin/external.cc55
1 files changed, 55 insertions, 0 deletions
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index 8eec5b1db..4480375be 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -619,6 +619,61 @@ cygwin_internal (cygwin_getinfo_types t, ...)
}
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:
set_errno (ENOSYS);
}