* grp.cc (etc_group): Removed.
(parse_grp): Make line parameter nonconst. Don't copy data into new allocated memory. Check for CR instead of LF to accomodate new read method. (add_grp_line): Make line parameter nonconst. (read_etc_group): Rearrange using new pwdgrp_read class. * passwd.cc (parse_pwd): Don't copy data into new allocated memory. Check for CR instead of LF to accomodate new read method. (read_etc_passwd): Rearrange using new pwdgrp_read class. * pwdgrp.h (pwdgrp_check::set_last_modified): Use different parameters. (class pwdgrp_read): New class for opening and reading passwd and group files.
This commit is contained in:
		| @@ -1,3 +1,19 @@ | |||||||
|  | 2002-06-05  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* grp.cc (etc_group): Removed. | ||||||
|  | 	(parse_grp): Make line parameter nonconst.  Don't copy data into new | ||||||
|  | 	allocated memory.  Check for CR instead of LF to accomodate new | ||||||
|  | 	read method. | ||||||
|  | 	(add_grp_line): Make line parameter nonconst. | ||||||
|  | 	(read_etc_group): Rearrange using new pwdgrp_read class. | ||||||
|  | 	* passwd.cc (parse_pwd): Don't copy data into new allocated memory. | ||||||
|  | 	Check for CR instead of LF to accomodate new read method. | ||||||
|  | 	(read_etc_passwd): Rearrange using new pwdgrp_read class. | ||||||
|  | 	* pwdgrp.h (pwdgrp_check::set_last_modified):  Use different | ||||||
|  | 	parameters. | ||||||
|  | 	(class pwdgrp_read): New class for opening and reading passwd and | ||||||
|  | 	group files. | ||||||
|  |  | ||||||
| 2002-06-04  Christopher Faylor  <cgf@redhat.com> | 2002-06-04  Christopher Faylor  <cgf@redhat.com> | ||||||
|  |  | ||||||
| 	* dtable.cc (handle_to_fn): Attempt to handle "raw" accesses to remote | 	* dtable.cc (handle_to_fn): Attempt to handle "raw" accesses to remote | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ details. */ | |||||||
| /* Read /etc/group only once for better performance.  This is done | /* Read /etc/group only once for better performance.  This is done | ||||||
|    on the first call that needs information from it. */ |    on the first call that needs information from it. */ | ||||||
|  |  | ||||||
| static const char *etc_group NO_COPY = "/etc/group"; |  | ||||||
| static struct __group32 *group_buf;		/* group contents in memory */ | static struct __group32 *group_buf;		/* group contents in memory */ | ||||||
| static int curr_lines; | static int curr_lines; | ||||||
| static int max_lines; | static int max_lines; | ||||||
| @@ -44,22 +43,19 @@ static int grp_pos = 0; | |||||||
| static pwdgrp_check group_state; | static pwdgrp_check group_state; | ||||||
|  |  | ||||||
| static int | static int | ||||||
| parse_grp (struct __group32 &grp, const char *line) | parse_grp (struct __group32 &grp, char *line) | ||||||
| { | { | ||||||
|   int len = strlen(line); |   int len = strlen(line); | ||||||
|   char *newline = (char *) malloc (len + 1); |   if (line[--len] == '\r') | ||||||
|   (void) memcpy (newline, line, len + 1); |     line[len] = '\0'; | ||||||
|  |  | ||||||
|   if (newline[--len] == '\n') |   char *dp = strchr (line, ':'); | ||||||
|     newline[len] = '\0'; |  | ||||||
|  |  | ||||||
|   char *dp = strchr (newline, ':'); |  | ||||||
|  |  | ||||||
|   if (!dp) |   if (!dp) | ||||||
|     return 0; |     return 0; | ||||||
|  |  | ||||||
|   *dp++ = '\0'; |   *dp++ = '\0'; | ||||||
|   grp.gr_name = newline; |   grp.gr_name = line; | ||||||
|  |  | ||||||
|   grp.gr_passwd = dp; |   grp.gr_passwd = dp; | ||||||
|   dp = strchr (grp.gr_passwd, ':'); |   dp = strchr (grp.gr_passwd, ':'); | ||||||
| @@ -104,7 +100,7 @@ parse_grp (struct __group32 &grp, const char *line) | |||||||
|  |  | ||||||
| /* Read one line from /etc/group into the group cache */ | /* Read one line from /etc/group into the group cache */ | ||||||
| static void | static void | ||||||
| add_grp_line (const char *line) | add_grp_line (char *line) | ||||||
| { | { | ||||||
|     if (curr_lines == max_lines) |     if (curr_lines == max_lines) | ||||||
|     { |     { | ||||||
| @@ -143,11 +139,7 @@ pthread_mutex_t NO_COPY group_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INIT | |||||||
| void | void | ||||||
| read_etc_group () | read_etc_group () | ||||||
| { | { | ||||||
|   char linebuf [200]; |   static pwdgrp_read gr; | ||||||
|   char group_name [UNLEN + 1]; |  | ||||||
|   DWORD group_name_len = UNLEN + 1; |  | ||||||
|  |  | ||||||
|   strncpy (group_name, "Administrators", sizeof (group_name)); |  | ||||||
|  |  | ||||||
|   group_lock here (cygwin_finished_initializing); |   group_lock here (cygwin_finished_initializing); | ||||||
|  |  | ||||||
| @@ -158,49 +150,38 @@ read_etc_group () | |||||||
|   if (group_state != initializing) |   if (group_state != initializing) | ||||||
|     { |     { | ||||||
|       group_state = initializing; |       group_state = initializing; | ||||||
|       if (max_lines) /* When rereading, free allocated memory first. */ |       if (gr.open ("/etc/group")) | ||||||
| 	{ | 	{ | ||||||
| 	  for (int i = 0; i < curr_lines; ++i) | 	  char *line; | ||||||
| 	    { | 	  while ((line = gr.gets ()) != NULL) | ||||||
| 	      free (group_buf[i].gr_name); | 	    if (strlen (line)) | ||||||
| 	      free (group_buf[i].gr_mem); | 	      add_grp_line (line); | ||||||
| 	    } |  | ||||||
| 	  curr_lines = 0; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|       FILE *f = fopen (etc_group, "rt"); | 	  group_state.set_last_modified (gr.get_fhandle(), gr.get_fname ()); | ||||||
|  |  | ||||||
|       if (f) |  | ||||||
| 	{ |  | ||||||
| 	  while (fgets (linebuf, sizeof (linebuf), f) != NULL) |  | ||||||
| 	    { |  | ||||||
| 	      if (strlen (linebuf)) |  | ||||||
| 		add_grp_line (linebuf); |  | ||||||
| 	    } |  | ||||||
|  |  | ||||||
| 	  group_state.set_last_modified (f); |  | ||||||
| 	  fclose (f); |  | ||||||
| 	  group_state = loaded; | 	  group_state = loaded; | ||||||
|  | 	  gr.close (); | ||||||
|  | 	  debug_printf ("Read /etc/group, %d lines", curr_lines); | ||||||
| 	} | 	} | ||||||
|       else /* /etc/group doesn't exist -- create default one in memory */ |       else /* /etc/group doesn't exist -- create default one in memory */ | ||||||
| 	{ | 	{ | ||||||
|  | 	  char group_name [UNLEN + 1]; | ||||||
|  | 	  DWORD group_name_len = UNLEN + 1; | ||||||
| 	  char domain_name [INTERNET_MAX_HOST_NAME_LENGTH + 1]; | 	  char domain_name [INTERNET_MAX_HOST_NAME_LENGTH + 1]; | ||||||
| 	  DWORD domain_name_len = INTERNET_MAX_HOST_NAME_LENGTH + 1; | 	  DWORD domain_name_len = INTERNET_MAX_HOST_NAME_LENGTH + 1; | ||||||
| 	  SID_NAME_USE acType; | 	  SID_NAME_USE acType; | ||||||
|  | 	  static char linebuf [200]; | ||||||
|  |  | ||||||
| 	  debug_printf ("Emulating /etc/group"); | 	  debug_printf ("Emulating /etc/group"); | ||||||
| 	  if (! LookupAccountSidA (NULL , | 	  strncpy (group_name, "Administrators", sizeof (group_name)); | ||||||
| 				    well_known_admins_sid, | 	  if (! LookupAccountSidA (NULL, well_known_admins_sid, group_name, | ||||||
| 				    group_name, | 				   &group_name_len, domain_name, | ||||||
| 				    &group_name_len, | 				   &domain_name_len, &acType)) | ||||||
| 				    domain_name, |  | ||||||
| 				    &domain_name_len, |  | ||||||
| 				    &acType)) |  | ||||||
| 	    { | 	    { | ||||||
| 	      strcpy (group_name, "unknown"); | 	      strcpy (group_name, "unknown"); | ||||||
| 	      debug_printf ("Failed to get local admins group name. %E"); | 	      debug_printf ("Failed to get local admins group name. %E"); | ||||||
| 	    } | 	    } | ||||||
|  | 	  snprintf (linebuf, sizeof (linebuf), "%s::%u:\n", group_name, | ||||||
| 	  snprintf (linebuf, sizeof (linebuf), "%s::%u:\n", group_name, (unsigned) DEFAULT_GID); | 		    (unsigned) DEFAULT_GID); | ||||||
| 	  add_grp_line (linebuf); | 	  add_grp_line (linebuf); | ||||||
| 	  group_state = emulated; | 	  group_state = emulated; | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -80,19 +80,17 @@ parse_pwd (struct passwd &res, char *buf) | |||||||
|   /* Allocate enough room for the passwd struct and all the strings |   /* Allocate enough room for the passwd struct and all the strings | ||||||
|      in it in one go */ |      in it in one go */ | ||||||
|   size_t len = strlen (buf); |   size_t len = strlen (buf); | ||||||
|   char *mybuf = (char *) malloc (len + 1); |   if (buf[--len] == '\r') | ||||||
|   (void) memcpy (mybuf, buf, len + 1); |     buf[len] = '\0'; | ||||||
|   if (mybuf[--len] == '\n') |  | ||||||
|     mybuf[len] = '\0'; |  | ||||||
|  |  | ||||||
|   res.pw_name = grab_string (&mybuf); |   res.pw_name = grab_string (&buf); | ||||||
|   res.pw_passwd = grab_string (&mybuf); |   res.pw_passwd = grab_string (&buf); | ||||||
|   res.pw_uid = grab_int (&mybuf); |   res.pw_uid = grab_int (&buf); | ||||||
|   res.pw_gid = grab_int (&mybuf); |   res.pw_gid = grab_int (&buf); | ||||||
|   res.pw_comment = 0; |   res.pw_comment = 0; | ||||||
|   res.pw_gecos = grab_string (&mybuf); |   res.pw_gecos = grab_string (&buf); | ||||||
|   res.pw_dir =  grab_string (&mybuf); |   res.pw_dir =  grab_string (&buf); | ||||||
|   res.pw_shell = grab_string (&mybuf); |   res.pw_shell = grab_string (&buf); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Add one line from /etc/passwd into the password cache */ | /* Add one line from /etc/passwd into the password cache */ | ||||||
| @@ -133,51 +131,46 @@ pthread_mutex_t NO_COPY passwd_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INI | |||||||
| void | void | ||||||
| read_etc_passwd () | read_etc_passwd () | ||||||
| { | { | ||||||
|     char linebuf[1024]; |   static pwdgrp_read pr; | ||||||
|     /* 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 |  | ||||||
|      */ |  | ||||||
|     passwd_lock here (cygwin_finished_initializing); |  | ||||||
|  |  | ||||||
|     /* if we got blocked by the mutex, then etc_passwd may have been processed */ |   /* A mutex is ok for speed here - pthreads will use critical sections not | ||||||
|     if (passwd_state != uninitialized) |    * mutexes for non-shared mutexes in the future. Also, this function will | ||||||
|       return; |    * at most be called once from each thread, after that the passwd_state | ||||||
|  |    * test will succeed */ | ||||||
|  |   passwd_lock here (cygwin_finished_initializing); | ||||||
|  |  | ||||||
|     if (passwd_state != initializing) |   /* if we got blocked by the mutex, then etc_passwd may have been processed */ | ||||||
|       { |   if (passwd_state != uninitialized) | ||||||
| 	passwd_state = initializing; |     return; | ||||||
| 	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 (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); | ||||||
|  |  | ||||||
| 	if (f) | 	  passwd_state.set_last_modified (pr.get_fhandle(), pr.get_fname ()); | ||||||
| 	  { | 	  passwd_state = loaded; | ||||||
| 	    while (fgets (linebuf, sizeof (linebuf), f) != NULL) | 	  pr.close (); | ||||||
| 	      { | 	  debug_printf ("Read /etc/passwd, %d lines", curr_lines); | ||||||
| 		if (strlen (linebuf)) | 	} | ||||||
| 		  add_pwd_line (linebuf); |       else | ||||||
| 	      } | 	{ | ||||||
|  | 	  static char linebuf[400]; | ||||||
|  |  | ||||||
| 	    passwd_state.set_last_modified (f); | 	  debug_printf ("Emulating /etc/passwd"); | ||||||
| 	    fclose (f); | 	  snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh", | ||||||
| 	    passwd_state = loaded; | 	  	    cygheap->user.name (), (unsigned) DEFAULT_UID, | ||||||
| 	  } | 		    (unsigned) DEFAULT_GID, getenv ("HOME") ?: "/"); | ||||||
| 	else | 	  add_pwd_line (linebuf); | ||||||
| 	  { | 	  passwd_state = emulated; | ||||||
| 	    debug_printf ("Emulating /etc/passwd"); | 	} | ||||||
| 	    snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh", cygheap->user.name (), |  | ||||||
| 		      (unsigned) DEFAULT_UID, (unsigned) DEFAULT_GID, getenv ("HOME") ?: "/"); |  | ||||||
| 	    add_pwd_line (linebuf); |  | ||||||
| 	    passwd_state = emulated; |  | ||||||
| 	  } |  | ||||||
|  |  | ||||||
|       } |     } | ||||||
|  |  | ||||||
|   return; |   return; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -44,12 +44,81 @@ public: | |||||||
|     { |     { | ||||||
|       state = nstate; |       state = nstate; | ||||||
|     } |     } | ||||||
|   void set_last_modified (FILE *f) |   void set_last_modified (HANDLE fh, const char *name) | ||||||
|     { |     { | ||||||
|       if (!file_w32[0]) |       if (!file_w32[0]) | ||||||
| 	strcpy (file_w32, cygheap->fdtab[fileno (f)]->get_win32_name ()); | 	strcpy (file_w32, name); | ||||||
|  |       GetFileTime (fh, NULL, NULL, &last_modified); | ||||||
|       GetFileTime (cygheap->fdtab[fileno (f)]->get_handle (), |  | ||||||
| 		   NULL, NULL, &last_modified); |  | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | class pwdgrp_read { | ||||||
|  |   path_conv pc; | ||||||
|  |   HANDLE fh; | ||||||
|  |   char *buf; | ||||||
|  |   char *lptr, *eptr; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |   pwdgrp_read () | ||||||
|  |   : fh (INVALID_HANDLE_VALUE), buf (NULL), lptr (NULL), eptr (NULL) {} | ||||||
|  |   virtual ~pwdgrp_read () | ||||||
|  |   { | ||||||
|  |     close (); | ||||||
|  |     if (buf) | ||||||
|  |       free (buf); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   bool open (const char *posix_fname) | ||||||
|  |   { | ||||||
|  |     if (buf) | ||||||
|  |       free (buf); | ||||||
|  |     buf = lptr = eptr = NULL; | ||||||
|  |  | ||||||
|  |     pc.check (posix_fname); | ||||||
|  |     if (pc.error || !pc.exists () || !pc.isdisk () || pc.isdir ()) | ||||||
|  |       return false; | ||||||
|  |  | ||||||
|  |     fh = CreateFile (pc, GENERIC_READ, wincap.shared (), NULL, OPEN_EXISTING, | ||||||
|  | 		     FILE_ATTRIBUTE_NORMAL, 0); | ||||||
|  |     if (fh) | ||||||
|  |       { | ||||||
|  | 	DWORD size = GetFileSize (fh, NULL), read_bytes; | ||||||
|  | 	buf = (char *) malloc (size + 1); | ||||||
|  | 	if (!ReadFile (fh, buf, size, &read_bytes, NULL)) | ||||||
|  | 	  { | ||||||
|  | 	    if (buf) | ||||||
|  | 	      free (buf); | ||||||
|  | 	    buf = NULL; | ||||||
|  | 	    CloseHandle (fh); | ||||||
|  | 	    fh = INVALID_HANDLE_VALUE; | ||||||
|  | 	    return false; | ||||||
|  | 	  } | ||||||
|  |         buf[read_bytes] = '\0'; | ||||||
|  | 	return true; | ||||||
|  |       } | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   char *gets () | ||||||
|  |   { | ||||||
|  |     if (!buf) | ||||||
|  |       return NULL; | ||||||
|  |     if (!lptr) | ||||||
|  |       lptr = buf; | ||||||
|  |     else if (!eptr) | ||||||
|  |       return lptr = NULL; | ||||||
|  |     else | ||||||
|  |       lptr = eptr; | ||||||
|  |     eptr = strchr (lptr, '\n'); | ||||||
|  |     if (eptr) | ||||||
|  |       *eptr++ = '\0'; | ||||||
|  |     return lptr; | ||||||
|  |   } | ||||||
|  |   inline HANDLE get_fhandle () { return fh; } | ||||||
|  |   inline const char *get_fname () { return pc; } | ||||||
|  |   void close () | ||||||
|  |   { | ||||||
|  |     if (fh != INVALID_HANDLE_VALUE) | ||||||
|  |       CloseHandle (fh); | ||||||
|  |     fh = INVALID_HANDLE_VALUE; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user