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:
Diffstat (limited to 'winsup/cygwin/passwd.cc')
-rw-r--r--winsup/cygwin/passwd.cc193
1 files changed, 115 insertions, 78 deletions
diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc
index 2f52473c7..22e8b3e20 100644
--- a/winsup/cygwin/passwd.cc
+++ b/winsup/cygwin/passwd.cc
@@ -1,6 +1,6 @@
/* passwd.cc: getpwnam () and friends
- Copyright 1996, 1997, 1998, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -18,8 +18,6 @@ details. */
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include <sys/termios.h>
@@ -82,19 +80,17 @@ parse_pwd (struct passwd &res, char *buf)
/* Allocate enough room for the passwd struct and all the strings
in it in one go */
size_t len = strlen (buf);
- char *mybuf = (char *) malloc (len + 1);
- (void) memcpy (mybuf, buf, len + 1);
- if (mybuf[--len] == '\n')
- mybuf[len] = '\0';
-
- res.pw_name = grab_string (&mybuf);
- res.pw_passwd = grab_string (&mybuf);
- res.pw_uid = grab_int (&mybuf);
- res.pw_gid = grab_int (&mybuf);
+ if (buf[--len] == '\r')
+ buf[len] = '\0';
+
+ res.pw_name = grab_string (&buf);
+ res.pw_passwd = grab_string (&buf);
+ res.pw_uid = grab_int (&buf);
+ res.pw_gid = grab_int (&buf);
res.pw_comment = 0;
- res.pw_gecos = grab_string (&mybuf);
- res.pw_dir = grab_string (&mybuf);
- res.pw_shell = grab_string (&mybuf);
+ res.pw_gecos = grab_string (&buf);
+ res.pw_dir = grab_string (&buf);
+ res.pw_shell = grab_string (&buf);
}
/* Add one line from /etc/passwd into the password cache */
@@ -111,71 +107,102 @@ add_pwd_line (char *line)
class passwd_lock
{
- pthread_mutex_t mutex;
+ bool armed;
+ static NO_COPY pthread_mutex_t mutex;
public:
- passwd_lock (): mutex ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER) {}
- void arm () {pthread_mutex_lock (&mutex); }
+ passwd_lock (bool doit)
+ {
+ if (doit)
+ pthread_mutex_lock (&mutex);
+ armed = doit;
+ }
~passwd_lock ()
{
- if (mutex != (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)
+ if (armed)
pthread_mutex_unlock (&mutex);
}
};
+pthread_mutex_t NO_COPY passwd_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
+
/* Read in /etc/passwd and save contents in the password cache.
This sets passwd_state to loaded or emulated so functions in this file can
tell that /etc/passwd has been read in or will be emulated. */
void
read_etc_passwd ()
{
- char linebuf[1024];
- /* A mutex is ok for speed here - pthreads will use critical sections not mutex's
- * for non-shared mutexs in the future. Also, this function will at most be called
- * once from each thread, after that the passwd_state test will succeed
- */
- static NO_COPY passwd_lock here;
+ static pwdgrp_read pr;
- if (cygwin_finished_initializing)
- here.arm ();
+ /* A mutex is ok for speed here - pthreads will use critical sections not
+ * mutexes for non-shared mutexes in the future. Also, this function will
+ * at most be called once from each thread, after that the passwd_state
+ * test will succeed */
+ passwd_lock here (cygwin_finished_initializing);
- /* if we got blocked by the mutex, then etc_passwd may have been processed */
- if (passwd_state != uninitialized)
- return;
+ /* if we got blocked by the mutex, then etc_passwd may have been processed */
+ if (passwd_state != uninitialized)
+ return;
- if (passwd_state != initializing)
- {
- passwd_state = initializing;
- if (max_lines) /* When rereading, free allocated memory first. */
- {
- for (int i = 0; i < curr_lines; ++i)
- free (passwd_buf[i].pw_name);
- curr_lines = 0;
- }
-
- FILE *f = fopen ("/etc/passwd", "rt");
-
- if (f)
- {
- while (fgets (linebuf, sizeof (linebuf), f) != NULL)
- {
- if (strlen (linebuf))
- add_pwd_line (linebuf);
- }
-
- passwd_state.set_last_modified (f);
- fclose (f);
- passwd_state = loaded;
- }
- else
- {
- debug_printf ("Emulating /etc/passwd");
- snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh", cygheap->user.name (),
- DEFAULT_UID, DEFAULT_GID, getenv ("HOME") ?: "/");
- add_pwd_line (linebuf);
- passwd_state = emulated;
- }
+ if (passwd_state != initializing)
+ {
+ passwd_state = initializing;
+ if (pr.open ("/etc/passwd"))
+ {
+ char *line;
+ while ((line = pr.gets ()) != NULL)
+ if (strlen (line))
+ add_pwd_line (line);
+
+ passwd_state.set_last_modified (pr.get_fhandle (), pr.get_fname ());
+ passwd_state = loaded;
+ pr.close ();
+ debug_printf ("Read /etc/passwd, %d lines", curr_lines);
+ }
+ else
+ {
+ static char linebuf[1024];
+
+ if (wincap.has_security ())
+ {
+ HANDLE ptok;
+ cygsid tu, tg;
+ DWORD siz;
+
+ if (OpenProcessToken (hMainProc, TOKEN_QUERY, &ptok))
+ {
+ if (GetTokenInformation (ptok, TokenUser, &tu, sizeof tu,
+ &siz)
+ && GetTokenInformation (ptok, TokenPrimaryGroup, &tg,
+ sizeof tg, &siz))
+ {
+ char strbuf[100];
+ snprintf (linebuf, sizeof (linebuf),
+ "%s::%lu:%lu:%s:%s:/bin/sh",
+ cygheap->user.name (),
+ *GetSidSubAuthority (tu,
+ *GetSidSubAuthorityCount(tu) - 1),
+ *GetSidSubAuthority (tg,
+ *GetSidSubAuthorityCount(tg) - 1),
+ tu.string (strbuf), getenv ("HOME") ?: "/");
+ debug_printf ("Emulating /etc/passwd: %s", linebuf);
+ add_pwd_line (linebuf);
+ passwd_state = emulated;
+ }
+ CloseHandle (ptok);
+ }
+ }
+ if (passwd_state != emulated)
+ {
+ snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh",
+ cygheap->user.name (), (unsigned) DEFAULT_UID,
+ (unsigned) DEFAULT_GID, getenv ("HOME") ?: "/");
+ debug_printf ("Emulating /etc/passwd: %s", linebuf);
+ add_pwd_line (linebuf);
+ passwd_state = emulated;
+ }
+ }
- }
+ }
return;
}
@@ -183,7 +210,7 @@ read_etc_passwd ()
/* Cygwin internal */
/* If this ever becomes non-reentrant, update all the getpw*_r functions */
static struct passwd *
-search_for (uid_t uid, const char *name)
+search_for (__uid32_t uid, const char *name)
{
struct passwd *res = 0;
struct passwd *default_pw = 0;
@@ -199,7 +226,7 @@ search_for (uid_t uid, const char *name)
if (strcasematch (name, res->pw_name))
return res;
}
- else if (uid == res->pw_uid)
+ else if (uid == (__uid32_t) res->pw_uid)
return res;
}
@@ -214,18 +241,24 @@ search_for (uid_t uid, const char *name)
}
extern "C" struct passwd *
-getpwuid (uid_t uid)
+getpwuid32 (__uid32_t uid)
{
if (passwd_state <= initializing)
read_etc_passwd ();
- pthread_testcancel();
+ pthread_testcancel ();
return search_for (uid, 0);
}
+extern "C" struct passwd *
+getpwuid (__uid16_t uid)
+{
+ return getpwuid32 (uid16touid32 (uid));
+}
+
extern "C" int
-getpwuid_r (uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result)
+getpwuid_r32 (__uid32_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result)
{
*result = NULL;
@@ -235,7 +268,7 @@ getpwuid_r (uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct
if (passwd_state <= initializing)
read_etc_passwd ();
- pthread_testcancel();
+ pthread_testcancel ();
struct passwd *temppw = search_for (uid, 0);
@@ -266,13 +299,19 @@ getpwuid_r (uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct
return 0;
}
+extern "C" int
+getpwuid_r (__uid16_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result)
+{
+ return getpwuid_r32 (uid16touid32 (uid), pwd, buffer, bufsize, result);
+}
+
extern "C" struct passwd *
getpwnam (const char *name)
{
if (passwd_state <= initializing)
read_etc_passwd ();
- pthread_testcancel();
+ pthread_testcancel ();
return search_for (0, name);
}
@@ -293,7 +332,7 @@ getpwnam_r (const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, s
if (passwd_state <= initializing)
read_etc_passwd ();
- pthread_testcancel();
+ pthread_testcancel ();
struct passwd *temppw = search_for (0, nam);
@@ -337,7 +376,7 @@ getpwent (void)
}
extern "C" struct passwd *
-getpwduid (uid_t)
+getpwduid (__uid16_t)
{
return NULL;
}
@@ -385,14 +424,12 @@ getpass (const char * prompt)
if (passwd_state <= initializing)
read_etc_passwd ();
- if (cygheap->fdtab.not_open (0))
- {
- set_errno (EBADF);
- pass[0] = '\0';
- }
+ cygheap_fdget fhstdin (0);
+
+ if (fhstdin < 0)
+ pass[0] = '\0';
else
{
- fhandler_base *fhstdin = cygheap->fdtab[0];
fhstdin->tcgetattr (&ti);
newti = ti;
newti.c_lflag &= ~ECHO;