OSDN Git Service

* cygheap.cc (cygheap_user::set_saved_sid): Rename from set_orig_sid.
[pf3gnuchains/sourceware.git] / winsup / cygwin / cygheap.h
1 /* cygheap.h: Cygwin heap manager.
2
3    Copyright 2000, 2001, 2002, 2003 Red Hat, Inc.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #undef cfree
12
13 enum cygheap_types
14 {
15   HEAP_FHANDLER,
16   HEAP_STR,
17   HEAP_ARGV,
18   HEAP_BUF,
19   HEAP_MOUNT,
20   HEAP_SIGS,
21   HEAP_1_START,
22   HEAP_1_STR,
23   HEAP_1_ARGV,
24   HEAP_1_BUF,
25   HEAP_1_EXEC,
26   HEAP_1_MAX = 100,
27   HEAP_MMAP = 200
28 };
29
30 #define incygheap(s) (cygheap && ((char *) (s) >= (char *) cygheap) && ((char *) (s) <= ((char *) cygheap_max)))
31
32 struct _cmalloc_entry
33 {
34   union
35   {
36     DWORD b;
37     char *ptr;
38   };
39   struct _cmalloc_entry *prev;
40   char data[0];
41 };
42
43 struct cygheap_root_mount_info
44 {
45   char posix_path[MAX_PATH];
46   unsigned posix_pathlen;
47   char native_path[MAX_PATH];
48   unsigned native_pathlen;
49 };
50
51 /* CGF: FIXME This doesn't belong here */
52
53 class cygheap_root
54 {
55   /* Root directory information.
56      This is used after a chroot is called. */
57   struct cygheap_root_mount_info *m;
58
59 public:
60   bool posix_ok (const char *path)
61   {
62     if (!m)
63       return 1;
64     return path_prefix_p (m->posix_path, path, m->posix_pathlen);
65   }
66   bool ischroot_native (const char *path)
67   {
68     if (!m)
69       return 1;
70     return strncasematch (m->native_path, path, m->native_pathlen)
71             && (path[m->native_pathlen] == '\\' || !path[m->native_pathlen]);
72   }
73   const char *unchroot (const char *path)
74   {
75     if (!m)
76       return path;
77     const char *p = path + m->posix_pathlen;
78     if (!*p)
79       p = "/";
80     return p;
81   }
82   bool exists () {return !!m;}
83   void set (const char *posix, const char *native);
84   size_t posix_length () const { return m->posix_pathlen; }
85   const char *posix_path () const { return m->posix_path; }
86   size_t native_length () const { return m->native_pathlen; }
87   const char *native_path () const { return m->native_path; }
88 };
89
90 enum homebodies
91 {
92   CH_HOMEDRIVE,
93   CH_HOMEPATH,
94   CH_HOME
95 };
96
97 class cygheap_user
98 {
99   /* Extendend user information.
100      The information is derived from the internal_getlogin call
101      when on a NT system. */
102   char  *pname;         /* user's name */
103   char  *plogsrv;       /* Logon server, may be FQDN */
104   char  *pdomain;       /* Logon domain of the user */
105   char  *homedrive;     /* User's home drive */
106   char  *homepath;      /* User's home path */
107   char  *pwinname;      /* User's name as far as Windows knows it */
108   char  *puserprof;     /* User profile */
109   PSID   psid;          /* buffer for user's SID */
110   PSID   saved_psid;    /* Remains intact even after impersonation */
111 public:
112   __uid32_t saved_uid;     /* Remains intact even after impersonation */
113   __gid32_t saved_gid;     /* Ditto */
114   __uid32_t real_uid;      /* Remains intact on seteuid, replaced by setuid */
115   __gid32_t real_gid;      /* Ditto */
116   user_groups groups;      /* Primary and supp SIDs */
117
118   /* token is needed if set(e)uid should be called. It can be set by a call
119      to `set_impersonation_token()'. */
120   HANDLE external_token;
121   HANDLE internal_token;
122   HANDLE current_token;
123
124   /* CGF 2002-06-27.  I removed the initializaton from this constructor
125      since this class is always allocated statically.  That means that everything
126      is zero anyway so there is no need to initialize it to zero.  Since the
127      token initialization is always handled during process startup as well,
128      I've removed the constructor entirely.  Please reinstate this f this
129      situation ever changes.
130   cygheap_user () : pname (NULL), plogsrv (NULL), pdomain (NULL),
131                     homedrive (NULL), homepath (NULL),
132                     token (INVALID_HANDLE_VALUE) {}
133   */
134
135   ~cygheap_user ();
136
137   void init ();
138   void set_name (const char *new_name);
139   const char *name () const { return pname; }
140
141   const char *env_logsrv (const char *, size_t);
142   const char *env_homepath (const char *, size_t);
143   const char *env_homedrive (const char *, size_t);
144   const char *env_userprofile (const char *, size_t);
145   const char *env_domain (const char *, size_t);
146   const char *env_name (const char *, size_t);
147
148   const char *logsrv ()
149   {
150     const char *p = env_logsrv ("LOGONSERVER=", sizeof ("LOGONSERVER=") - 1);
151     return (p == almost_null) ? NULL : p;
152   }
153   const char *winname ()
154   {
155     const char *p = env_name ("USERNAME=", sizeof ("USERNAME=") - 1);
156     return (p == almost_null) ? NULL : p;
157   }
158   const char *domain ()
159   {
160     const char *p = env_domain ("USERDOMAIN=", sizeof ("USERDOMAIN=") - 1);
161     return (p == almost_null) ? NULL : p;
162   }
163   BOOL set_sid (PSID new_sid);
164   BOOL set_saved_sid ();
165   PSID sid () const { return psid; }
166   PSID saved_sid () const { return saved_psid; }
167   const char *ontherange (homebodies what, struct passwd * = NULL);
168   bool issetuid () const { return current_token != INVALID_HANDLE_VALUE; }
169   HANDLE token () { return current_token; }
170   void deimpersonate ()
171   {
172     if (issetuid ())
173       RevertToSelf ();
174   }
175   void reimpersonate ()
176   {
177     if (issetuid ()
178         && !ImpersonateLoggedOnUser (token ()))
179       system_printf ("ImpersonateLoggedOnUser: %E");
180   }
181   bool has_impersonation_tokens ()
182     { return external_token != INVALID_HANDLE_VALUE
183              || internal_token != INVALID_HANDLE_VALUE
184              || current_token != INVALID_HANDLE_VALUE; }
185   void close_impersonation_tokens ()
186   {
187     if (current_token != INVALID_HANDLE_VALUE)
188       {
189         if( current_token != external_token && current_token != internal_token)
190           CloseHandle (current_token);
191         current_token = INVALID_HANDLE_VALUE;
192       }
193     if (external_token != INVALID_HANDLE_VALUE)
194       {
195         CloseHandle (external_token);
196         external_token = INVALID_HANDLE_VALUE;
197       }
198     if (internal_token != INVALID_HANDLE_VALUE)
199       {
200         CloseHandle (internal_token);
201         internal_token = INVALID_HANDLE_VALUE;
202       }
203   }
204   const char *cygheap_user::test_uid (char *&, const char *, size_t)
205     __attribute__ ((regparm (3)));
206 };
207
208 /* cwd cache stuff.  */
209
210 class muto;
211
212 struct cwdstuff
213 {
214   char *posix;
215   char *win32;
216   DWORD hash;
217   muto *cwd_lock;
218   char *get (char *buf, int need_posix = 1, int with_chroot = 0, unsigned ulen = MAX_PATH);
219   DWORD get_hash ();
220   void init ();
221   void fixup_after_exec (char *win32, char *posix, DWORD hash);
222   bool get_initial ();
223   void set (const char *win32_cwd, const char *posix_cwd = NULL);
224 };
225
226 #ifdef DEBUGGING
227 struct cygheap_debug
228 {
229   handle_list starth;
230   handle_list *endh;
231   handle_list freeh[500];
232 };
233 #endif
234
235 struct user_heap_info
236 {
237   void *base;
238   void *ptr;
239   void *top;
240   void *max;
241   unsigned chunk;
242 };
243
244 struct init_cygheap
245 {
246   _cmalloc_entry *chain;
247   char *buckets[32];
248   cygheap_root root;
249   cygheap_user user;
250   user_heap_info user_heap;
251   mode_t umask;
252   HANDLE shared_h;
253   HANDLE console_h;
254   char *cygwin_regname;
255   cwdstuff cwd;
256   dtable fdtab;
257 #ifdef DEBUGGING
258   cygheap_debug debug;
259 #endif
260   struct sigaction *sigs;
261 };
262
263 #define CYGHEAPSIZE (sizeof (init_cygheap) + (20000 * sizeof (fhandler_union)) + (5 * 65536))
264
265 extern init_cygheap *cygheap;
266 extern void *cygheap_max;
267
268 class cygheap_fdmanip
269 {
270  protected:
271   int fd;
272   fhandler_base **fh;
273   bool locked;
274  public:
275   cygheap_fdmanip (): fh (NULL) {}
276   virtual ~cygheap_fdmanip ()
277   {
278     if (locked)
279       ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdmanip");
280   }
281   void release ()
282   {
283     cygheap->fdtab.release (fd);
284   }
285   operator int &() {return fd;}
286   operator fhandler_base* &() {return *fh;}
287   void operator = (fhandler_base *fh) {*this->fh = fh;}
288   fhandler_base *operator -> () const {return *fh;}
289   bool isopen () const
290   {
291     if (*fh)
292       return true;
293     set_errno (EBADF);
294     return false;
295   }
296 };
297
298 class cygheap_fdnew : public cygheap_fdmanip
299 {
300  public:
301   cygheap_fdnew (int seed_fd = -1, bool lockit = true)
302   {
303     if (lockit)
304       SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew");
305     if (seed_fd < 0)
306       fd = cygheap->fdtab.find_unused_handle ();
307     else
308       fd = cygheap->fdtab.find_unused_handle (seed_fd + 1);
309     if (fd >= 0)
310       {
311         locked = lockit;
312         fh = cygheap->fdtab + fd;
313       }
314     else
315       {
316         set_errno (EMFILE);
317         if (lockit)
318           ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew");
319         locked = false;
320       }
321   }
322   void operator = (fhandler_base *fh) {*this->fh = fh;}
323 };
324
325 class cygheap_fdget : public cygheap_fdmanip
326 {
327  public:
328   cygheap_fdget (int fd, bool lockit = false, bool do_set_errno = true)
329   {
330     if (lockit)
331       SetResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget");
332     if (fd >= 0 && fd < (int) cygheap->fdtab.size
333         && *(fh = cygheap->fdtab + fd) != NULL)
334       {
335         this->fd = fd;
336         locked = lockit;
337       }
338     else
339       {
340         this->fd = -1;
341         if (do_set_errno)
342           set_errno (EBADF);
343         if (lockit)
344           ReleaseResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget");
345         locked = false;
346       }
347   }
348 };
349
350 class child_info;
351 void *__stdcall cygheap_setup_for_child (child_info *ci, bool dup_later) __attribute__ ((regparm(2)));
352 void __stdcall cygheap_setup_for_child_cleanup (void *, child_info *, bool) __attribute__ ((regparm(3)));
353 void __stdcall cygheap_fixup_in_child (bool);
354 extern "C" {
355 void __stdcall cfree (void *) __attribute__ ((regparm(1)));
356 void *__stdcall cmalloc (cygheap_types, DWORD) __attribute__ ((regparm(2)));
357 void *__stdcall crealloc (void *, DWORD) __attribute__ ((regparm(2)));
358 void *__stdcall ccalloc (cygheap_types, DWORD, DWORD) __attribute__ ((regparm(3)));
359 char *__stdcall cstrdup (const char *) __attribute__ ((regparm(1)));
360 char *__stdcall cstrdup1 (const char *) __attribute__ ((regparm(1)));
361 void __stdcall cfree_and_set (char *&, char * = NULL) __attribute__ ((regparm(2)));
362 void __stdcall cygheap_init ();
363 extern DWORD _cygheap_start;
364 }