]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/uinfo.cc
* Merge in cygwin-64bit-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))
61522196 69 system_printf ("NtQueryInformationToken (TokenPrimaryGroup), %y", 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 {
61522196 76 system_printf ("NtQueryInformationToken (TokenUser), %y", 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))
61522196 84 debug_printf ("NtSetInformationToken(TokenOwner), %y", 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))
61522196 103 system_printf ("NtSetInformationToken (TokenDefaultDacl), %y", status);
f16706de
CV
104 if ((status = NtSetSecurityObject (NtCurrentProcess (),
105 DACL_SECURITY_INFORMATION, psd)))
61522196 106 system_printf ("NtSetSecurityObject, %y", 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))
61522196 139 debug_printf ("NtSetInformationToken (TokenPrimaryGroup), %y",
12eac211 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
61522196 214extern "C" uid_t
a8d7ae61
CV
215getuid32 (void)
216{
217 return cygheap->user.real_uid;
218}
219
61522196
CV
220#ifdef __x86_64__
221EXPORT_ALIAS (getuid32, getuid)
222#else
de4e0d30 223extern "C" __uid16_t
1fd5e000
CF
224getuid (void)
225{
1f0f8e12 226 return cygheap->user.real_uid;
1fd5e000 227}
61522196 228#endif
1fd5e000 229
61522196 230extern "C" gid_t
57196405
CV
231getgid32 (void)
232{
233 return cygheap->user.real_gid;
234}
235
61522196
CV
236#ifdef __x86_64__
237EXPORT_ALIAS (getgid32, getgid)
238#else
de4e0d30 239extern "C" __gid16_t
1fd5e000
CF
240getgid (void)
241{
1f0f8e12 242 return cygheap->user.real_gid;
1fd5e000 243}
61522196 244#endif
1fd5e000 245
61522196 246extern "C" uid_t
a8d7ae61
CV
247geteuid32 (void)
248{
249 return myself->uid;
250}
251
61522196
CV
252#ifdef __x86_64__
253EXPORT_ALIAS (geteuid32, geteuid)
254#else
255extern "C" uid_t
1fd5e000
CF
256geteuid (void)
257{
64b30629 258 return myself->uid;
1fd5e000 259}
61522196 260#endif
1fd5e000 261
61522196 262extern "C" gid_t
57196405
CV
263getegid32 (void)
264{
265 return myself->gid;
266}
267
61522196
CV
268#ifdef __x86_64__
269EXPORT_ALIAS (getegid32, getegid)
270#else
de4e0d30 271extern "C" __gid16_t
1fd5e000
CF
272getegid (void)
273{
64b30629 274 return myself->gid;
1fd5e000 275}
61522196 276#endif
1fd5e000
CF
277
278/* Not quite right - cuserid can change, getlogin can't */
279extern "C" char *
280cuserid (char *src)
281{
da086d02
CF
282 if (!src)
283 return getlogin ();
284
285 strcpy (src, getlogin ());
286 return src;
287}
288
289const char *
290cygheap_user::ontherange (homebodies what, struct passwd *pw)
291{
da086d02
CF
292 LPUSER_INFO_3 ui = NULL;
293 WCHAR wuser[UNLEN + 1];
294 NET_API_STATUS ret;
179cae11
CF
295 char homedrive_env_buf[3];
296 char *newhomedrive = NULL;
297 char *newhomepath = NULL;
edab6053 298 tmp_pathbuf tp;
da086d02 299
094d5193 300 debug_printf ("what %d, pw %p", what, pw);
da086d02
CF
301 if (what == CH_HOME)
302 {
303 char *p;
5f25e1d1 304
da086d02
CF
305 if ((p = getenv ("HOME")))
306 debug_printf ("HOME is already in the environment %s", p);
307 else
308 {
da086d02
CF
309 if (pw && pw->pw_dir && *pw->pw_dir)
310 {
da086d02 311 debug_printf ("Set HOME (from /etc/passwd) to %s", pw->pw_dir);
8297bda0 312 setenv ("HOME", pw->pw_dir, 1);
da086d02 313 }
8297bda0 314 else
da086d02 315 {
764d88e4
CV
316 char home[strlen (name ()) + 8];
317
318 debug_printf ("Set HOME to default /home/USER");
319 __small_sprintf (home, "/home/%s", name ());
8297bda0 320 setenv ("HOME", home, 1);
da086d02
CF
321 }
322 }
323 }
324
094d5193 325 if (what != CH_HOME && homepath == NULL && newhomepath == NULL)
1fd5e000 326 {
edab6053 327 char *homepath_env_buf = tp.c_get ();
da086d02 328 if (!pw)
d6ffc075 329 pw = internal_getpwnam (name ());
da086d02 330 if (pw && pw->pw_dir && *pw->pw_dir)
edab6053
CV
331 cygwin_conv_path (CCP_POSIX_TO_WIN_A, pw->pw_dir, homepath_env_buf,
332 NT_MAX_PATH);
da086d02
CF
333 else
334 {
179cae11 335 homepath_env_buf[0] = homepath_env_buf[1] = '\0';
094d5193 336 if (logsrv ())
da086d02 337 {
834224ab 338 WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
5ab0b5cf
CV
339 sys_mbstowcs (wlogsrv, sizeof (wlogsrv) / sizeof (*wlogsrv),
340 logsrv ());
341 sys_mbstowcs (wuser, sizeof (wuser) / sizeof (*wuser), winname ());
9a4d574b 342 if (!(ret = NetUserGetInfo (wlogsrv, wuser, 3, (LPBYTE *) &ui)))
da086d02 343 {
edab6053 344 sys_wcstombs (homepath_env_buf, NT_MAX_PATH,
b86f999a 345 ui->usri3_home_dir);
834224ab
CV
346 if (!homepath_env_buf[0])
347 {
edab6053 348 sys_wcstombs (homepath_env_buf, NT_MAX_PATH,
03a49a00 349 ui->usri3_home_dir_drive);
834224ab
CV
350 if (homepath_env_buf[0])
351 strcat (homepath_env_buf, "\\");
db57a363 352 else
edab6053
CV
353 cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE,
354 "/", homepath_env_buf, NT_MAX_PATH);
834224ab 355 }
da086d02
CF
356 }
357 }
358 if (ui)
359 NetApiBufferFree (ui);
360 }
361
a77d35f7 362 if (homepath_env_buf[1] != ':')
da086d02 363 {
179cae11
CF
364 newhomedrive = almost_null;
365 newhomepath = homepath_env_buf;
da086d02
CF
366 }
367 else
368 {
a77d35f7
CF
369 homedrive_env_buf[0] = homepath_env_buf[0];
370 homedrive_env_buf[1] = homepath_env_buf[1];
179cae11
CF
371 homedrive_env_buf[2] = '\0';
372 newhomedrive = homedrive_env_buf;
373 newhomepath = homepath_env_buf + 2;
da086d02 374 }
1fd5e000 375 }
da086d02 376
8297bda0 377 if (newhomedrive && newhomedrive != homedrive)
179cae11 378 cfree_and_set (homedrive, (newhomedrive == almost_null)
5bf785a0 379 ? almost_null : cstrdup (newhomedrive));
179cae11 380
8297bda0 381 if (newhomepath && newhomepath != homepath)
179cae11
CF
382 cfree_and_set (homepath, cstrdup (newhomepath));
383
da086d02 384 switch (what)
1fd5e000 385 {
da086d02
CF
386 case CH_HOMEDRIVE:
387 return homedrive;
388 case CH_HOMEPATH:
389 return homepath;
390 default:
391 return homepath;
1fd5e000
CF
392 }
393}
da086d02
CF
394
395const char *
094d5193 396cygheap_user::test_uid (char *&what, const char *name, size_t namelen)
da086d02 397{
8297bda0 398 if (!what && !issetuid ())
38bc1196 399 what = getwinenveq (name, namelen, HEAP_STR);
094d5193
CF
400 return what;
401}
402
403const char *
404cygheap_user::env_logsrv (const char *name, size_t namelen)
405{
406 if (test_uid (plogsrv, name, namelen))
9a771b29 407 return plogsrv;
da086d02 408
efc1575e
CF
409 const char *mydomain = domain ();
410 const char *myname = winname ();
c69d873f 411 if (!mydomain || ascii_strcasematch (myname, "SYSTEM"))
e97962b9 412 return almost_null;
5f25e1d1 413
9a512577 414 WCHAR wdomain[MAX_DOMAIN_NAME_LEN + 1];
5558de95 415 WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
9a512577 416 sys_mbstowcs (wdomain, MAX_DOMAIN_NAME_LEN + 1, mydomain);
179cae11 417 cfree_and_set (plogsrv, almost_null);
5558de95
CV
418 if (get_logon_server (wdomain, wlogsrv, false))
419 sys_wcstombs_alloc (&plogsrv, HEAP_STR, wlogsrv);
179cae11 420 return plogsrv;
9a771b29
CF
421}
422
423const char *
094d5193 424cygheap_user::env_domain (const char *name, size_t namelen)
9a771b29 425{
38bc1196 426 if (pwinname && test_uid (pdomain, name, namelen))
9a771b29
CF
427 return pdomain;
428
91d30570
CV
429 DWORD ulen = UNLEN + 1;
430 WCHAR username[ulen];
3f74d8d5 431 DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
91d30570 432 WCHAR userdomain[dlen];
9a771b29
CF
433 SID_NAME_USE use;
434
094d5193 435 cfree_and_set (pwinname, almost_null);
179cae11 436 cfree_and_set (pdomain, almost_null);
91d30570
CV
437 if (!LookupAccountSidW (NULL, sid (), username, &ulen,
438 userdomain, &dlen, &use))
179cae11
CF
439 __seterrno ();
440 else
9a771b29 441 {
91d30570
CV
442 sys_wcstombs_alloc (&pwinname, HEAP_STR, username);
443 sys_wcstombs_alloc (&pdomain, HEAP_STR, userdomain);
9a771b29 444 }
179cae11 445 return pdomain;
da086d02
CF
446}
447
448const char *
094d5193 449cygheap_user::env_userprofile (const char *name, size_t namelen)
da086d02 450{
094d5193
CF
451 if (test_uid (puserprof, name, namelen))
452 return puserprof;
453
793371f5
CV
454 /* User hive path is never longer than MAX_PATH. */
455 WCHAR userprofile_env_buf[MAX_PATH];
7b4b41ab 456 WCHAR win_id[UNLEN + 1]; /* Large enough for SID */
e70bea19 457
179cae11 458 cfree_and_set (puserprof, almost_null);
e70bea19 459 if (get_registry_hive_path (get_windows_id (win_id), userprofile_env_buf))
793371f5 460 sys_wcstombs_alloc (&puserprof, HEAP_STR, userprofile_env_buf);
5f25e1d1 461
179cae11 462 return puserprof;
da086d02
CF
463}
464
465const char *
094d5193 466cygheap_user::env_homepath (const char *name, size_t namelen)
da086d02
CF
467{
468 return ontherange (CH_HOMEPATH);
469}
470
471const char *
094d5193 472cygheap_user::env_homedrive (const char *name, size_t namelen)
da086d02
CF
473{
474 return ontherange (CH_HOMEDRIVE);
475}
9a771b29
CF
476
477const char *
094d5193 478cygheap_user::env_name (const char *name, size_t namelen)
9a771b29 479{
094d5193 480 if (!test_uid (pwinname, name, namelen))
0c55f6ed 481 domain ();
094d5193 482 return pwinname;
9a771b29 483}
14ea5029 484
60cb120f
CV
485const char *
486cygheap_user::env_systemroot (const char *name, size_t namelen)
487{
488 if (!psystemroot)
489 {
ba6aad1d 490 int size = GetSystemWindowsDirectoryW (NULL, 0);
60cb120f 491 if (size > 0)
05726ddd 492 {
ba6aad1d
CV
493 WCHAR wsystemroot[size];
494 size = GetSystemWindowsDirectoryW (wsystemroot, size);
495 if (size > 0)
496 sys_wcstombs_alloc (&psystemroot, HEAP_STR, wsystemroot);
60cb120f
CV
497 }
498 if (size <= 0)
ba6aad1d 499 debug_printf ("GetSystemWindowsDirectoryW(), %E");
60cb120f
CV
500 }
501 return psystemroot;
502}
503
7905c4f1 504char *
ac413374 505pwdgrp::next_str (char c)
14ea5029 506{
ac413374 507 char *res = lptr;
f71f133b 508 lptr = strchrnul (lptr, c);
fea48988
CF
509 if (*lptr)
510 *lptr++ = '\0';
ac413374 511 return res;
7905c4f1 512}
14ea5029 513
65037056
CF
514bool
515pwdgrp::next_num (unsigned long& n)
ac413374 516{
fea48988 517 char *p = next_str (':');
ac413374 518 char *cp;
65037056
CF
519 n = strtoul (p, &cp, 10);
520 return p != cp && !*cp;
ac413374
CF
521}
522
523char *
524pwdgrp::add_line (char *eptr)
7905c4f1 525{
ac413374 526 if (eptr)
7905c4f1 527 {
ac413374 528 lptr = eptr;
03dba1de
CF
529 eptr = strchr (lptr, '\n');
530 if (eptr)
ac413374
CF
531 {
532 if (eptr > lptr && eptr[-1] == '\r')
fea48988
CF
533 eptr[-1] = '\0';
534 else
535 *eptr = '\0';
ac413374
CF
536 eptr++;
537 }
538 if (curr_lines >= max_lines)
539 {
540 max_lines += 10;
541 *pwdgrp_buf = realloc (*pwdgrp_buf, max_lines * pwdgrp_buf_elem_size);
542 }
65037056
CF
543 if ((this->*parse) ())
544 curr_lines++;
7905c4f1 545 }
ac413374 546 return eptr;
14ea5029
CF
547}
548
65037056 549void
520fcc97 550pwdgrp::load (const wchar_t *rel_path)
14ea5029 551{
65037056
CF
552 static const char failed[] = "failed";
553 static const char succeeded[] = "succeeded";
e1e4b104
CV
554 const char *res = failed;
555 HANDLE fh = NULL;
e1e4b104
CV
556
557 NTSTATUS status;
558 OBJECT_ATTRIBUTES attr;
559 IO_STATUS_BLOCK io;
560 FILE_STANDARD_INFORMATION fsi;
65037056 561
7905c4f1
CF
562 if (buf)
563 free (buf);
564 buf = NULL;
981f9625 565 curr_lines = 0;
7905c4f1 566
520fcc97 567 if (!path &&
8895d962 568 !(path = (PWCHAR) malloc ((wcslen (cygheap->installation_root)
520fcc97 569 + wcslen (rel_path) + 1) * sizeof (WCHAR))))
65037056 570 {
520fcc97 571 paranoid_printf ("malloc (%W) failed", rel_path);
e1e4b104 572 goto out;
65037056 573 }
8895d962 574 wcpcpy (wcpcpy (path, cygheap->installation_root), rel_path);
520fcc97
CV
575 RtlInitUnicodeString (&upath, path);
576
577 InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
578 etc_ix = etc::init (etc_ix, &attr);
579
580 paranoid_printf ("%S", &upath);
581
e9982f2a 582 status = NtOpenFile (&fh, SYNCHRONIZE | FILE_READ_DATA, &attr, &io,
93e88498
CV
583 FILE_SHARE_VALID_FLAGS,
584 FILE_SYNCHRONOUS_IO_NONALERT
585 | FILE_OPEN_FOR_BACKUP_INTENT);
e1e4b104 586 if (!NT_SUCCESS (status))
7905c4f1 587 {
61522196 588 paranoid_printf ("NtOpenFile(%S) failed, status %y", &upath, status);
e1e4b104 589 goto out;
14ea5029 590 }
e1e4b104
CV
591 status = NtQueryInformationFile (fh, &io, &fsi, sizeof fsi,
592 FileStandardInformation);
593 if (!NT_SUCCESS (status))
594 {
61522196 595 paranoid_printf ("NtQueryInformationFile(%S) failed, status %y",
520fcc97 596 &upath, status);
e1e4b104
CV
597 goto out;
598 }
599 /* FIXME: Should we test for HighPart set? If so, the
600 passwd or group file is way beyond what we can handle. */
601 /* FIXME 2: It's still ugly that we keep the file in memory.
602 Big organizations have naturally large passwd files. */
603 buf = (char *) malloc (fsi.EndOfFile.LowPart + 1);
604 if (!buf)
605 {
61522196 606 paranoid_printf ("malloc (%u) failed", fsi.EndOfFile.LowPart);
e1e4b104
CV
607 goto out;
608 }
e9982f2a
CV
609 status = NtReadFile (fh, NULL, NULL, NULL, &io, buf, fsi.EndOfFile.LowPart,
610 NULL, NULL);
e1e4b104
CV
611 if (!NT_SUCCESS (status))
612 {
61522196 613 paranoid_printf ("NtReadFile(%S) failed, status %y", &upath, status);
e1e4b104
CV
614 free (buf);
615 goto out;
616 }
617 buf[fsi.EndOfFile.LowPart] = '\0';
7b9e380f 618 for (char *eptr = buf; (eptr = add_line (eptr)); )
e1e4b104 619 continue;
520fcc97 620 debug_printf ("%W curr_lines %d", rel_path, curr_lines);
e1e4b104
CV
621 res = succeeded;
622
623out:
624 if (fh)
625 NtClose (fh);
520fcc97 626 debug_printf ("%W load %s", rel_path, res);
57394495 627 initialized = true;
14ea5029 628}
This page took 0.564676 seconds and 5 git commands to generate.