+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>
* sec_auth.cc (get_server_groups): Call get_logon_server only for
}
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);
}
CW_ENDENT,
CW_GETNSSSEP,
CW_GETPWSID,
- CW_GETGRSID
+ CW_GETGRSID,
+ CW_CYGNAME_FROM_WINNAME
} cygwin_getinfo_types;
#define CW_LOCK_PINFO CW_LOCK_PINFO
#define CW_GETNSSSEP CW_GETNSSSEP
#define CW_GETPWSID CW_GETPWSID
#define CW_GETGRSID CW_GETGRSID
+#define CW_CYGNAME_FROM_WINNAME CW_CYGNAME_FROM_WINNAME
/* Token type for CW_SET_EXTERNAL_TOKEN */
enum