]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/uinfo.cc
Throughout, update copyrights to reflect dates which correspond to main-branch
[newlib-cygwin.git] / winsup / cygwin / uinfo.cc
CommitLineData
1fd5e000
CF
1/* uinfo.cc: user info (uid, gid, etc...)
2
bc837d22
CF
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
1fd5e000
CF
5
6This file is part of Cygwin.
7
8This software is a copyrighted work licensed under the terms of the
9Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10details. */
11
1fd5e000 12#include "winsup.h"
84c7d409 13#include <unistd.h>
17db1105 14#include <wininet.h>
1fd5e000 15#include <stdlib.h>
520fcc97 16#include <wchar.h>
1fd5e000 17#include <lm.h>
9a512577 18#include <iptypes.h>
eb79d041 19#include <sys/cygwin.h>
169c465a 20#include "cygerrno.h"
e2ebe117 21#include "pinfo.h"
47063f00 22#include "path.h"
7ac61736 23#include "fhandler.h"
0381fec6 24#include "dtable.h"
1f0f8e12 25#include "cygheap.h"
520fcc97 26#include "shared_info.h"
f0338f54 27#include "registry.h"
9a771b29 28#include "child_info.h"
094d5193 29#include "environ.h"
d6ffc075 30#include "pwdgrp.h"
edab6053 31#include "tls_pbuf.h"
5f9c8e2a 32#include "ntdll.h"
1fd5e000 33
0efafbfb
CF
34/* Initialize the part of cygheap_user that does not depend on files.
35 The information is used in shared.cc for the user shared.
36 Final initialization occurs in uinfo_init */
9a771b29 37void
9a4d574b 38cygheap_user::init ()
1fd5e000 39{
ebdc75d9 40 WCHAR user_name[UNLEN + 1];
2a9b4b7a 41 DWORD user_name_len = UNLEN + 1;
0efafbfb 42
3f74d8d5
CV
43 /* This code is only run if a Cygwin process gets started by a native
44 Win32 process. We try to get the username from the environment,
45 first USERNAME (Win32), then USER (POSIX). If that fails (which is
46 very unlikely), it only has an impact if we don't have an entry in
47 /etc/passwd for this user either. In that case the username sticks
48 to "unknown". Since this is called early in initialization, and
49 since we don't want pull in a dependency to any other DLL except
50 ntdll and kernel32 at this early stage, don't call GetUserName,
51 GetUserNameEx, NetWkstaUserGetInfo, etc. */
52 if (GetEnvironmentVariableW (L"USERNAME", user_name, user_name_len)
53 || GetEnvironmentVariableW (L"USER", user_name, user_name_len))
54 {
55 char mb_user_name[user_name_len = sys_wcstombs (NULL, 0, user_name)];
56 sys_wcstombs (mb_user_name, user_name_len, user_name);
57 set_name (mb_user_name);
58 }
59 else
60 set_name ("unknown");
1f0f8e12 61
12eac211
CV
62 NTSTATUS status;
63 ULONG size;
043878df 64 PSECURITY_DESCRIPTOR psd;
6806a8b5 65
12eac211
CV
66 status = NtQueryInformationToken (hProcToken, TokenPrimaryGroup,
67 &groups.pgsid, sizeof (cygsid), &size);
68 if (!NT_SUCCESS (status))
69 system_printf ("NtQueryInformationToken (TokenPrimaryGroup), %p", status);
6806a8b5
PH
70
71 /* Get the SID from current process and store it in effec_cygsid */
12eac211
CV
72 status = NtQueryInformationToken (hProcToken, TokenUser, &effec_cygsid,
73 sizeof (cygsid), &size);
74 if (!NT_SUCCESS (status))
6806a8b5 75 {
12eac211 76 system_printf ("NtQueryInformationToken (TokenUser), %p", status);
f4a1f8a1 77 return;
6806a8b5
PH
78 }
79
80 /* Set token owner to the same value as token user */
12eac211
CV
81 status = NtSetInformationToken (hProcToken, TokenOwner, &effec_cygsid,
82 sizeof (cygsid));
83 if (!NT_SUCCESS (status))
84 debug_printf ("NtSetInformationToken(TokenOwner), %p", status);
6806a8b5 85
043878df 86 /* Standard way to build a security descriptor with the usual DACL */
7311cc1f 87 PSECURITY_ATTRIBUTES sa_buf = (PSECURITY_ATTRIBUTES) alloca (1024);
f4a1f8a1 88 psd = (PSECURITY_DESCRIPTOR)
b86f999a 89 (sec_user_nih (sa_buf, sid()))->lpSecurityDescriptor;
6806a8b5 90
1838d97b 91 BOOLEAN acl_exists, dummy;
043878df 92 TOKEN_DEFAULT_DACL dacl;
1838d97b
CV
93
94 status = RtlGetDaclSecurityDescriptor (psd, &acl_exists, &dacl.DefaultDacl,
95 &dummy);
96 if (NT_SUCCESS (status) && acl_exists && dacl.DefaultDacl)
043878df 97 {
5f9c8e2a 98
043878df 99 /* Set the default DACL and the process DACL */
12eac211
CV
100 status = NtSetInformationToken (hProcToken, TokenDefaultDacl, &dacl,
101 sizeof (dacl));
102 if (!NT_SUCCESS (status))
103 system_printf ("NtSetInformationToken (TokenDefaultDacl), %p", status);
f16706de
CV
104 if ((status = NtSetSecurityObject (NtCurrentProcess (),
105 DACL_SECURITY_INFORMATION, psd)))
5f9c8e2a 106 system_printf ("NtSetSecurityObject, %lx", status);
0efafbfb 107 }
043878df 108 else
0cd9f74f 109 system_printf("Cannot get dacl, %E");
0efafbfb
CF
110}
111
112void
113internal_getlogin (cygheap_user &user)
114{
115 struct passwd *pw = NULL;
116
2a9b4b7a
CV
117 cygpsid psid = user.sid ();
118 pw = internal_getpwsid (psid);
39b553b8 119
2a9b4b7a 120 if (!pw && !(pw = internal_getpwnam (user.name ()))
d6ffc075 121 && !(pw = internal_getpwuid (DEFAULT_UID)))
9a4d574b 122 debug_printf ("user not found in augmented /etc/passwd");
647b92a7 123 else
9a771b29 124 {
a76877e9
CV
125 cygsid gsid;
126
1fd072b6
CV
127 myself->uid = pw->pw_uid;
128 myself->gid = pw->pw_gid;
efcaf042 129 user.set_name (pw->pw_name);
a76877e9 130 if (gsid.getfromgr (internal_getgrgid (pw->pw_gid)))
eb6d2e2f 131 {
a76877e9 132 if (gsid != user.groups.pgsid)
647b92a7 133 {
a76877e9 134 /* Set primary group to the group in /etc/passwd. */
12eac211
CV
135 NTSTATUS status = NtSetInformationToken (hProcToken,
136 TokenPrimaryGroup,
137 &gsid, sizeof gsid);
138 if (!NT_SUCCESS (status))
139 debug_printf ("NtSetInformationToken (TokenPrimaryGroup), %p",
140 status);
a76877e9
CV
141 else
142 user.groups.pgsid = gsid;
143 clear_procimptoken ();
647b92a7 144 }
647b92a7 145 }
a76877e9
CV
146 else
147 debug_printf ("gsid not found in augmented /etc/group");
9a771b29 148 }
0c55f6ed 149 cygheap->user.ontherange (CH_HOME, pw);
1fd5e000
CF
150}
151
152void
153uinfo_init ()
154{
70249d56 155 if (child_proc_info && !cygheap->user.has_impersonation_tokens ())
271c1935
CV
156 return;
157
158 if (!child_proc_info)
159 internal_getlogin (cygheap->user); /* Set the cygheap->user. */
160 /* Conditions must match those in spawn to allow starting child
161 processes with ruid != euid and rgid != egid. */
162 else if (cygheap->user.issetuid ()
e3778517 163 && cygheap->user.saved_uid == cygheap->user.real_uid
1498189c 164 && cygheap->user.saved_gid == cygheap->user.real_gid
0191627a
CV
165 && !cygheap->user.groups.issetgroups ()
166 && !cygheap->user.setuid_to_restricted)
4f7e12dd 167 {
70249d56 168 cygheap->user.reimpersonate ();
271c1935 169 return;
4f7e12dd 170 }
271c1935 171 else
70249d56 172 cygheap->user.close_impersonation_tokens ();
271c1935 173
1498189c
CV
174 cygheap->user.saved_uid = cygheap->user.real_uid = myself->uid;
175 cygheap->user.saved_gid = cygheap->user.real_gid = myself->gid;
53197923
PH
176 cygheap->user.external_token = NO_IMPERSONATION;
177 cygheap->user.internal_token = NO_IMPERSONATION;
f4a1f8a1 178 cygheap->user.curr_primary_token = NO_IMPERSONATION;
77ee8805 179 cygheap->user.curr_imp_token = NO_IMPERSONATION;
0191627a
CV
180 cygheap->user.ext_token_is_restricted = false;
181 cygheap->user.curr_token_is_restricted = false;
182 cygheap->user.setuid_to_restricted = false;
1498189c 183 cygheap->user.set_saved_sid (); /* Update the original sid */
a6f3658d 184 cygheap->user.deimpersonate ();
1fd5e000
CF
185}
186
68509b30
CV
187extern "C" int
188getlogin_r (char *name, size_t namesize)
189{
553f0805 190 const char *login = cygheap->user.name ();
68509b30
CV
191 size_t len = strlen (login) + 1;
192 if (len > namesize)
193 return ERANGE;
893ac8e0
CF
194 myfault efault;
195 if (efault.faulted ())
196 return EFAULT;
68509b30
CV
197 strncpy (name, login, len);
198 return 0;
199}
200
1fd5e000
CF
201extern "C" char *
202getlogin (void)
203{
553f0805
CV
204 static char username[UNLEN];
205 int ret = getlogin_r (username, UNLEN);
206 if (ret)
207 {
208 set_errno (ret);
209 return NULL;
210 }
211 return username;
1fd5e000
CF
212}
213
a8d7ae61
CV
214extern "C" __uid32_t
215getuid32 (void)
216{
217 return cygheap->user.real_uid;
218}
219
de4e0d30 220extern "C" __uid16_t
1fd5e000
CF
221getuid (void)
222{
1f0f8e12 223 return cygheap->user.real_uid;
1fd5e000
CF
224}
225
57196405
CV
226extern "C" __gid32_t
227getgid32 (void)
228{
229 return cygheap->user.real_gid;
230}
231
de4e0d30 232extern "C" __gid16_t
1fd5e000
CF
233getgid (void)
234{
1f0f8e12 235 return cygheap->user.real_gid;
1fd5e000
CF
236}
237
a8d7ae61
CV
238extern "C" __uid32_t
239geteuid32 (void)
240{
241 return myself->uid;
242}
243
de4e0d30 244extern "C" __uid16_t
1fd5e000
CF
245geteuid (void)
246{
64b30629 247 return myself->uid;
1fd5e000
CF
248}
249
57196405
CV
250extern "C" __gid32_t
251getegid32 (void)
252{
253 return myself->gid;
254}
255
de4e0d30 256extern "C" __gid16_t
1fd5e000
CF
257getegid (void)
258{
64b30629 259 return myself->gid;
1fd5e000
CF
260}
261
262/* Not quite right - cuserid can change, getlogin can't */
263extern "C" char *
264cuserid (char *src)
265{
da086d02
CF
266 if (!src)
267 return getlogin ();
268
269 strcpy (src, getlogin ());
270 return src;
271}
272
273const char *
274cygheap_user::ontherange (homebodies what, struct passwd *pw)
275{
da086d02
CF
276 LPUSER_INFO_3 ui = NULL;
277 WCHAR wuser[UNLEN + 1];
278 NET_API_STATUS ret;
179cae11
CF
279 char homedrive_env_buf[3];
280 char *newhomedrive = NULL;
281 char *newhomepath = NULL;
edab6053 282 tmp_pathbuf tp;
da086d02 283
094d5193 284 debug_printf ("what %d, pw %p", what, pw);
da086d02
CF
285 if (what == CH_HOME)
286 {
287 char *p;
5f25e1d1 288
da086d02
CF
289 if ((p = getenv ("HOME")))
290 debug_printf ("HOME is already in the environment %s", p);
291 else
292 {
da086d02
CF
293 if (pw && pw->pw_dir && *pw->pw_dir)
294 {
da086d02 295 debug_printf ("Set HOME (from /etc/passwd) to %s", pw->pw_dir);
8297bda0 296 setenv ("HOME", pw->pw_dir, 1);
da086d02 297 }
8297bda0 298 else
da086d02 299 {
764d88e4
CV
300 char home[strlen (name ()) + 8];
301
302 debug_printf ("Set HOME to default /home/USER");
303 __small_sprintf (home, "/home/%s", name ());
8297bda0 304 setenv ("HOME", home, 1);
da086d02
CF
305 }
306 }
307 }
308
094d5193 309 if (what != CH_HOME && homepath == NULL && newhomepath == NULL)
1fd5e000 310 {
edab6053 311 char *homepath_env_buf = tp.c_get ();
da086d02 312 if (!pw)
d6ffc075 313 pw = internal_getpwnam (name ());
da086d02 314 if (pw && pw->pw_dir && *pw->pw_dir)
edab6053
CV
315 cygwin_conv_path (CCP_POSIX_TO_WIN_A, pw->pw_dir, homepath_env_buf,
316 NT_MAX_PATH);
da086d02
CF
317 else
318 {
179cae11 319 homepath_env_buf[0] = homepath_env_buf[1] = '\0';
094d5193 320 if (logsrv ())
da086d02 321 {
834224ab 322 WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
5ab0b5cf
CV
323 sys_mbstowcs (wlogsrv, sizeof (wlogsrv) / sizeof (*wlogsrv),
324 logsrv ());
325 sys_mbstowcs (wuser, sizeof (wuser) / sizeof (*wuser), winname ());
9a4d574b 326 if (!(ret = NetUserGetInfo (wlogsrv, wuser, 3, (LPBYTE *) &ui)))
da086d02 327 {
edab6053 328 sys_wcstombs (homepath_env_buf, NT_MAX_PATH,
b86f999a 329 ui->usri3_home_dir);
834224ab
CV
330 if (!homepath_env_buf[0])
331 {
edab6053 332 sys_wcstombs (homepath_env_buf, NT_MAX_PATH,
03a49a00 333 ui->usri3_home_dir_drive);
834224ab
CV
334 if (homepath_env_buf[0])
335 strcat (homepath_env_buf, "\\");
db57a363 336 else
edab6053
CV
337 cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE,
338 "/", homepath_env_buf, NT_MAX_PATH);
834224ab 339 }
da086d02
CF
340 }
341 }
342 if (ui)
343 NetApiBufferFree (ui);
344 }
345
a77d35f7 346 if (homepath_env_buf[1] != ':')
da086d02 347 {
179cae11
CF
348 newhomedrive = almost_null;
349 newhomepath = homepath_env_buf;
da086d02
CF
350 }
351 else
352 {
a77d35f7
CF
353 homedrive_env_buf[0] = homepath_env_buf[0];
354 homedrive_env_buf[1] = homepath_env_buf[1];
179cae11
CF
355 homedrive_env_buf[2] = '\0';
356 newhomedrive = homedrive_env_buf;
357 newhomepath = homepath_env_buf + 2;
da086d02 358 }
1fd5e000 359 }
da086d02 360
8297bda0 361 if (newhomedrive && newhomedrive != homedrive)
179cae11 362 cfree_and_set (homedrive, (newhomedrive == almost_null)
5bf785a0 363 ? almost_null : cstrdup (newhomedrive));
179cae11 364
8297bda0 365 if (newhomepath && newhomepath != homepath)
179cae11
CF
366 cfree_and_set (homepath, cstrdup (newhomepath));
367
da086d02 368 switch (what)
1fd5e000 369 {
da086d02
CF
370 case CH_HOMEDRIVE:
371 return homedrive;
372 case CH_HOMEPATH:
373 return homepath;
374 default:
375 return homepath;
1fd5e000
CF
376 }
377}
da086d02
CF
378
379const char *
094d5193 380cygheap_user::test_uid (char *&what, const char *name, size_t namelen)
da086d02 381{
8297bda0 382 if (!what && !issetuid ())
38bc1196 383 what = getwinenveq (name, namelen, HEAP_STR);
094d5193
CF
384 return what;
385}
386
387const char *
388cygheap_user::env_logsrv (const char *name, size_t namelen)
389{
390 if (test_uid (plogsrv, name, namelen))
9a771b29 391 return plogsrv;
da086d02 392
efc1575e
CF
393 const char *mydomain = domain ();
394 const char *myname = winname ();
c69d873f 395 if (!mydomain || ascii_strcasematch (myname, "SYSTEM"))
e97962b9 396 return almost_null;
5f25e1d1 397
9a512577 398 WCHAR wdomain[MAX_DOMAIN_NAME_LEN + 1];
5558de95 399 WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
9a512577 400 sys_mbstowcs (wdomain, MAX_DOMAIN_NAME_LEN + 1, mydomain);
179cae11 401 cfree_and_set (plogsrv, almost_null);
5558de95
CV
402 if (get_logon_server (wdomain, wlogsrv, false))
403 sys_wcstombs_alloc (&plogsrv, HEAP_STR, wlogsrv);
179cae11 404 return plogsrv;
9a771b29
CF
405}
406
407const char *
094d5193 408cygheap_user::env_domain (const char *name, size_t namelen)
9a771b29 409{
38bc1196 410 if (pwinname && test_uid (pdomain, name, namelen))
9a771b29
CF
411 return pdomain;
412
91d30570
CV
413 DWORD ulen = UNLEN + 1;
414 WCHAR username[ulen];
3f74d8d5 415 DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
91d30570 416 WCHAR userdomain[dlen];
9a771b29
CF
417 SID_NAME_USE use;
418
094d5193 419 cfree_and_set (pwinname, almost_null);
179cae11 420 cfree_and_set (pdomain, almost_null);
91d30570
CV
421 if (!LookupAccountSidW (NULL, sid (), username, &ulen,
422 userdomain, &dlen, &use))
179cae11
CF
423 __seterrno ();
424 else
9a771b29 425 {
91d30570
CV
426 sys_wcstombs_alloc (&pwinname, HEAP_STR, username);
427 sys_wcstombs_alloc (&pdomain, HEAP_STR, userdomain);
9a771b29 428 }
179cae11 429 return pdomain;
da086d02
CF
430}
431
432const char *
094d5193 433cygheap_user::env_userprofile (const char *name, size_t namelen)
da086d02 434{
094d5193
CF
435 if (test_uid (puserprof, name, namelen))
436 return puserprof;
437
793371f5
CV
438 /* User hive path is never longer than MAX_PATH. */
439 WCHAR userprofile_env_buf[MAX_PATH];
7b4b41ab 440 WCHAR win_id[UNLEN + 1]; /* Large enough for SID */
e70bea19 441
179cae11 442 cfree_and_set (puserprof, almost_null);
e70bea19 443 if (get_registry_hive_path (get_windows_id (win_id), userprofile_env_buf))
793371f5 444 sys_wcstombs_alloc (&puserprof, HEAP_STR, userprofile_env_buf);
5f25e1d1 445
179cae11 446 return puserprof;
da086d02
CF
447}
448
449const char *
094d5193 450cygheap_user::env_homepath (const char *name, size_t namelen)
da086d02
CF
451{
452 return ontherange (CH_HOMEPATH);
453}
454
455const char *
094d5193 456cygheap_user::env_homedrive (const char *name, size_t namelen)
da086d02
CF
457{
458 return ontherange (CH_HOMEDRIVE);
459}
9a771b29
CF
460
461const char *
094d5193 462cygheap_user::env_name (const char *name, size_t namelen)
9a771b29 463{
094d5193 464 if (!test_uid (pwinname, name, namelen))
0c55f6ed 465 domain ();
094d5193 466 return pwinname;
9a771b29 467}
14ea5029 468
60cb120f
CV
469const char *
470cygheap_user::env_systemroot (const char *name, size_t namelen)
471{
472 if (!psystemroot)
473 {
ba6aad1d 474 int size = GetSystemWindowsDirectoryW (NULL, 0);
60cb120f 475 if (size > 0)
05726ddd 476 {
ba6aad1d
CV
477 WCHAR wsystemroot[size];
478 size = GetSystemWindowsDirectoryW (wsystemroot, size);
479 if (size > 0)
480 sys_wcstombs_alloc (&psystemroot, HEAP_STR, wsystemroot);
60cb120f
CV
481 }
482 if (size <= 0)
ba6aad1d 483 debug_printf ("GetSystemWindowsDirectoryW(), %E");
60cb120f
CV
484 }
485 return psystemroot;
486}
487
7905c4f1 488char *
ac413374 489pwdgrp::next_str (char c)
14ea5029 490{
ac413374 491 char *res = lptr;
f71f133b 492 lptr = strchrnul (lptr, c);
fea48988
CF
493 if (*lptr)
494 *lptr++ = '\0';
ac413374 495 return res;
7905c4f1 496}
14ea5029 497
65037056
CF
498bool
499pwdgrp::next_num (unsigned long& n)
ac413374 500{
fea48988 501 char *p = next_str (':');
ac413374 502 char *cp;
65037056
CF
503 n = strtoul (p, &cp, 10);
504 return p != cp && !*cp;
ac413374
CF
505}
506
507char *
508pwdgrp::add_line (char *eptr)
7905c4f1 509{
ac413374 510 if (eptr)
7905c4f1 511 {
ac413374 512 lptr = eptr;
03dba1de
CF
513 eptr = strchr (lptr, '\n');
514 if (eptr)
ac413374
CF
515 {
516 if (eptr > lptr && eptr[-1] == '\r')
fea48988
CF
517 eptr[-1] = '\0';
518 else
519 *eptr = '\0';
ac413374
CF
520 eptr++;
521 }
522 if (curr_lines >= max_lines)
523 {
524 max_lines += 10;
525 *pwdgrp_buf = realloc (*pwdgrp_buf, max_lines * pwdgrp_buf_elem_size);
526 }
65037056
CF
527 if ((this->*parse) ())
528 curr_lines++;
7905c4f1 529 }
ac413374 530 return eptr;
14ea5029
CF
531}
532
65037056 533void
520fcc97 534pwdgrp::load (const wchar_t *rel_path)
14ea5029 535{
65037056
CF
536 static const char failed[] = "failed";
537 static const char succeeded[] = "succeeded";
e1e4b104
CV
538 const char *res = failed;
539 HANDLE fh = NULL;
e1e4b104
CV
540
541 NTSTATUS status;
542 OBJECT_ATTRIBUTES attr;
543 IO_STATUS_BLOCK io;
544 FILE_STANDARD_INFORMATION fsi;
65037056 545
7905c4f1
CF
546 if (buf)
547 free (buf);
548 buf = NULL;
981f9625 549 curr_lines = 0;
7905c4f1 550
520fcc97 551 if (!path &&
8895d962 552 !(path = (PWCHAR) malloc ((wcslen (cygheap->installation_root)
520fcc97 553 + wcslen (rel_path) + 1) * sizeof (WCHAR))))
65037056 554 {
520fcc97 555 paranoid_printf ("malloc (%W) failed", rel_path);
e1e4b104 556 goto out;
65037056 557 }
8895d962 558 wcpcpy (wcpcpy (path, cygheap->installation_root), rel_path);
520fcc97
CV
559 RtlInitUnicodeString (&upath, path);
560
561 InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
562 etc_ix = etc::init (etc_ix, &attr);
563
564 paranoid_printf ("%S", &upath);
565
e9982f2a 566 status = NtOpenFile (&fh, SYNCHRONIZE | FILE_READ_DATA, &attr, &io,
93e88498
CV
567 FILE_SHARE_VALID_FLAGS,
568 FILE_SYNCHRONOUS_IO_NONALERT
569 | FILE_OPEN_FOR_BACKUP_INTENT);
e1e4b104 570 if (!NT_SUCCESS (status))
7905c4f1 571 {
520fcc97 572 paranoid_printf ("NtOpenFile(%S) failed, status %p", &upath, status);
e1e4b104 573 goto out;
14ea5029 574 }
e1e4b104
CV
575 status = NtQueryInformationFile (fh, &io, &fsi, sizeof fsi,
576 FileStandardInformation);
577 if (!NT_SUCCESS (status))
578 {
579 paranoid_printf ("NtQueryInformationFile(%S) failed, status %p",
520fcc97 580 &upath, status);
e1e4b104
CV
581 goto out;
582 }
583 /* FIXME: Should we test for HighPart set? If so, the
584 passwd or group file is way beyond what we can handle. */
585 /* FIXME 2: It's still ugly that we keep the file in memory.
586 Big organizations have naturally large passwd files. */
587 buf = (char *) malloc (fsi.EndOfFile.LowPart + 1);
588 if (!buf)
589 {
590 paranoid_printf ("malloc (%d) failed", fsi.EndOfFile.LowPart);
591 goto out;
592 }
e9982f2a
CV
593 status = NtReadFile (fh, NULL, NULL, NULL, &io, buf, fsi.EndOfFile.LowPart,
594 NULL, NULL);
e1e4b104
CV
595 if (!NT_SUCCESS (status))
596 {
520fcc97 597 paranoid_printf ("NtReadFile(%S) failed, status %p", &upath, status);
e1e4b104
CV
598 free (buf);
599 goto out;
600 }
601 buf[fsi.EndOfFile.LowPart] = '\0';
7b9e380f 602 for (char *eptr = buf; (eptr = add_line (eptr)); )
e1e4b104 603 continue;
520fcc97 604 debug_printf ("%W curr_lines %d", rel_path, curr_lines);
e1e4b104
CV
605 res = succeeded;
606
607out:
608 if (fh)
609 NtClose (fh);
520fcc97 610 debug_printf ("%W load %s", rel_path, res);
57394495 611 initialized = true;
14ea5029 612}
This page took 0.523898 seconds and 5 git commands to generate.