passwd help/version patch
Joshua Daniel Franklin
joshuadfranklin@yahoo.com
Thu May 30 19:13:00 GMT 2002
--- Corinna Vinschen <cygwin-patches@cygwin.com> wrote:
> > > Or perhaps change passwd to take the Cygwin name and
> > > convert it to the windows name???
> > >
> > > Corinna
> >
> > Maybe I'm missing something, but there doesn't seem to be any Win32
> > function to get a username from a uid other than NetUserEnum, but
> > I really don't think people running 'passwd bob' are wanting to enum
> > all users. The code to do it wouldn't be that hard, but it wouldn't
> > work for those people with domains (unless they specify a domain like
> > for mkpasswd).
> >
> > Maybe mkpasswd should cache the info somewhere other than just /etc/passwd
> > for this purpose? Or use the GECOS field?
>
> I'm sorry if my mail wasn't clear but I just asked for getting the
> Win32 name from the cygwin name. The cygwin name is the one given
> on the command line or what is returned by getlogin(). The information
> about the Win32 name is then returned in the pw_gecos field by
> getpwnam(). Either a U-DOMAIN\NAME or a S-1-5-xxx sid. If the
> U- field is given, it contains the name, otherwise a LookupAccountSid()
> gives the Win32 name from the SID. If neither is given, the Cygwin
> username is equal to the Win32 name.
>
> There is already a function `extract_nt_dom_user()' in Cygwin, file
> security.cc which contains this functionality. Unfortunately it
> isn't exported so it would have to be copied to passwd.c (and
> transformed to plain c).
>
> Or we export that function. I think it is a useful functionality for
> Cygwin tools. Perhaps with the "cygwin_" prefix.
>
> Corinna
Thanks very much for the pointers. However,
After working on it a while, I think that exporting a
cygwin_extract_nt_dom_user() would be best. The attached patch is a
halfway solution that just copies most of extract_nt_dom_user()
other than the SID code. It will get the correct username in the case of
a U-DOMAIN type of GECOS, but if only a ':S-1-5-xxx:' is in the GECOS
it fails with the old 'passwd: unknown user boalhg' message.
If a Win32 username is found, a line like: 'Windows username : bob'
is output.
I tried to build up the structures necessary for LookupAccountSid()
with the sec* stuff in winsup/cygwin as a guide, but it looks like
reinventing a C wheel from C++ spare parts. It'd be a lot better to
be able to just put cygwin_extract_nt_dom_user(pw, domain, (char *) user)
right in passwd.c IMHO.
Caveat: I don't have a real domain that I'm testing with.
2002-05-30 Joshua Daniel Franklin <joshuadfranklin@yahoo.com>
* passwd.c (extract_nt_dom_user): New function.
(GetPW): Try to look up Win32 username in case of NERR_UserNotFound.
-------------- next part --------------
--- passwd.c-orig Thu May 30 20:05:05 2002
+++ passwd.c Thu May 30 20:54:10 2002
@@ -28,6 +28,7 @@ details. */
#define USER_PRIV_ADMIN 2
#define UF_LOCKOUT 0x00010
+#define INTERNET_MAX_HOST_NAME_LENGTH 256
static const char version[] = "$Revision: 1.4 $";
static char *prog_name;
@@ -101,15 +102,66 @@ EvalRet (int ret, const char *user)
return 1;
}
+void
+extract_nt_dom_user (const struct passwd *pw, char *domain, char *user)
+{
+ char buf[INTERNET_MAX_HOST_NAME_LENGTH + UNLEN + 2];
+ char *c;
+
+ strcpy (domain, "");
+ strcpy (buf, pw->pw_name);
+
+ if ((pw && pw->pw_gecos) && (strrchr (pw->pw_gecos, ',') == NULL))
+ {
+ return;
+ }
+
+ if (pw->pw_gecos)
+ {
+ if ((c = strstr (pw->pw_gecos, "U-")) != NULL &&
+ (c == pw->pw_gecos || c[-1] == ','))
+ {
+ buf[0] = '\0';
+ strncat (buf, c + 2, INTERNET_MAX_HOST_NAME_LENGTH + UNLEN + 1);
+ if ((c = strchr (buf, ',')) != NULL)
+ *c = '\0';
+ }
+ }
+ if ((c = strchr (buf, '\\')) != NULL)
+ {
+ *c++ = '\0';
+ strcpy (domain, buf);
+ strcpy (user, c);
+ }
+ else
+ {
+ strcpy (domain, "");
+ strcpy (user, buf);
+ }
+}
+
PUSER_INFO_3
GetPW (const char *user)
{
WCHAR name[512];
DWORD ret;
PUSER_INFO_3 ui;
-
+ struct passwd *pw;
+ char *domain = (char *) malloc (MAX_PATH + 1);
+
MultiByteToWideChar (CP_ACP, 0, user, -1, name, 512);
ret = NetUserGetInfo (NULL, name, 3, (LPBYTE *) &ui);
+ /* Try getting a Win32 username in case the user edited /etc/passwd */
+ if (ret == NERR_UserNotFound)
+ {
+ if ((pw = getpwnam (user)))
+ extract_nt_dom_user (pw, domain, (char *) user);
+ MultiByteToWideChar (CP_ACP, 0, user, -1, name, 512);
+ ret = NetUserGetInfo (NULL, name, 3, (LPBYTE *) &ui);
+ if (ret == (int) NULL)
+ printf ("Windows username : %s\n", user);
+ }
+
return EvalRet (ret, user) ? NULL : ui;
}
More information about the Cygwin-patches
mailing list