Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ntsec.xml « doc « winsup - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ae0a1195ae3d275d612ff51a3cd4911a9b699eb1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
<?xml version="1.0" encoding='UTF-8'?>
<!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
		"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<sect1 id="ntsec"><title>POSIX accounts, permission, and security</title>

<para>This section discusses how the Windows security model is
utilized in Cygwin to implement POSIX account information, POSIX-like
permissions, and how the Windows authentication model is used to allow
cygwin applications to switch users in a POSIX-like fashion.</para>

<para>The setting of POSIX-like file and directory permissions is
controlled by the <link linkend="mount-table">mount</link> option
<literal>(no)acl</literal> which is set to <literal>acl</literal> by
default.</para>

<para>We start with a short overview.  Note that this overview must
be necessarily short.  If you want to learn more about the Windows security
model, see the <ulink url="http://msdn.microsoft.com/en-us/library/aa374860(VS.85).aspx">Access Control</ulink> article in MSDN documentation.</para>

<para>POSIX concepts and in particular the POSIX security model are not
discussed here, but assumed to be understood by the reader.  If you
don't know the POSIX security model, search the web for beginner
documentation.</para>

<sect2 id="ntsec-common"><title>Brief overview of Windows security</title>

<para>In the Windows security model, almost any "object" is securable.
"Objects" are files, processes, threads, semaphores, etc.</para>

<para>Every object has a data structure attached, called a "security
descriptor" (SD).  The SD contains all information necessary to control
who can access an object, and to determine what they are allowed to do
to or with it.  The SD of an object consists of five parts:</para>

<itemizedlist spacing="compact">
<listitem><para>Flags which control several aspects of this SD. This is
not discussed here.</para></listitem>
<listitem><para>The SID of the object owner.</para></listitem>
<listitem><para>The SID of the object owner group.</para></listitem>
<listitem><para>A list of "Access Control Entries" (ACE), called the
"Discretionary Access Control List" (DACL).</para></listitem>
<listitem><para>Another list of ACEs, called the "Security Access Control List"
(SACL), which doesn't matter for our purpose.  We ignore it here.</para></listitem>
</itemizedlist>

<para>Every ACE contains a so-called "Security IDentifier" (SID) and
other stuff which is explained a bit later.  Let's talk about the SID first.
</para>

<para>A SID is a unique identifier for users, groups, computers and
Active Directory (AD) domains.  SIDs are basically comparable to POSIX
user ids (UIDs) and group ids (GIDs), but are more complicated because
they are unique across multiple machines or domains.  A SID is a
structure of multiple numerical values.  There's a convenient convention
to type SIDs, as a string of numerical fields separated by hyphen
characters.  Here's an example:</para>

<para>SID of a machine "foo":</para>

<screen>
  S-1-5-21-165875785-1005667432-441284377
</screen>

<para>SID of a user "johndoe" of the system "foo":</para>

<screen>
  S-1-5-21-165875785-1005667432-441284377-1023
</screen>

<para>The first field is always "S", which is just a notational convention
to show that this is a SID.  The second field is the version number of
the SID structure, So far there exists only one version of SIDs, so this
field is always 1.  The third and fourth fields represent the "authority"
which can be thought of as a type or category of SIDs.  There are a
couple of builtin accounts and accounts with very special meaning which
have certain well known values in these third and fourth fields.
However, computer and domain SIDs always start with "S-1-5-21".  The
next three fields, all 32 bit values, represent the unique 96 bit
identifier of the computer system.  This is a hopefully unique value all
over the world, but in practice it's sufficient if the computer SIDs are
unique within a single Windows network.</para>

<para>As you can see in the above example, SIDs of users (and groups)
are identical to the computer SID, except for an additional part, the
so-called "relative identifier" (RID).  So the SID of a user is always 
uniquely attached to the system on which the account has been generated.</para>

<para>It's a bit different in domains.  The domain has its own SID, and
that SID is identical to the SID of the first domain controller, on
which the domain is created.  Domain user SIDs look exactly like the
computer user SIDs, the leading part is just the domain SID and the RID
is created when the user is created.</para>

<para>Ok, consider you created a new domain "bar" on some new domain
controller and you would like to create a domain account "johndoe":</para>

<para>SID of a domain "bar.local":</para>

<screen>
  S-1-5-21-186985262-1144665072-740312968
</screen>

<para>SID of a user "johndoe" in the domain "bar.local":</para>

<screen>
  S-1-5-21-186985262-1144665072-740312968-1207
</screen>

<para>So you now have two accounts called johndoe, one account
created on the machine "foo", one created in the domain "bar.local".
Both have different SIDs and not even the RID is the same.  How do
the systems know it's the same account?  After all, the name is
the same, right?  The answer is, these accounts are <emphasis
role='bold'>not</emphasis> identical.  All machines on the network will
treat these SIDs as identifying two separate accounts.  One is
"FOO\johndoe", the other one is "BAR\johndoe" or "johndoe@bar.local".
Different SID, different account.  Full stop.  </para>

<para>Starting with Cygwin 1.7.34, Cygwin uses an automatic, internal
translation from Windows SID to POSIX UID/GID.  This mechanism, which is
the preferred method for the SID&lt;=&gt;UID/GID mapping, is described in
detail in <xref linkend="ntsec-mapping"></xref>.</para>

<para>Prior to Cygwin 1.7.34, the last part of the SID, the so called
"Relative IDentifier" (RID), was by default used as UID and/or GID
when you created the <filename>/etc/passwd</filename> and
<filename>/etc/group</filename> files using the
<command><link linkend="mkpasswd">mkpasswd</link></command> and
<command><link linkend="mkgroup">mkgroup</link></command> tools.
These tools as well as reading accounts from <filename>/etc/passwd</filename>
and <filename>/etc/group</filename> files is still present in recent
versions of Cygwin, but you should switch to the aforementioned
automatic translation, unless you have very specific needs. Again,
see <xref linkend="ntsec-mapping"></xref> for the details.</para>

<para>Do you still remember the SIDs with special meaning?  In offical
notation they are called "well-known SIDs".  For example, POSIX has no GID
for the group of "all users" or "world" or "others".  The last three rwx
bits in a unix-style permission value just represent the permissions for
"everyone who is not the owner or is member of the owning group".
Windows has a SID for these poor souls, the "Everyone" SID.  Other
well-known SIDs represent circumstances under which a process is
running, rather than actual users or groups.  Here are a few examples
for well-known SIDs:</para>

<screen>
Everyone                        S-1-1-0    Simply everyone...
Batch                           S-1-5-3    Processes started via the task
					   scheduler are member of this group.
Interactive			S-1-5-4    Only processes of users which are
					   logged in via an interactive
					   session are members here.
Authenticated Users             S-1-5-11   Users which have gone through
                                           the authentication process and
					   survived.  Anonymously accessing
					   users are not incuded here.
SYSTEM                          S-1-5-18   A special account which has all
					   kinds of dangerous rights, sort of
					   an uber-root account.
</screen>

<para>For a full list please refer to the MSDN document <ulink
url="http://msdn.microsoft.com/en-us/library/aa379649.aspx">Well-known
SIDs</ulink>.  The Cygwin package called "csih" provides a tool,
/usr/lib/csih/getAccountName.exe, which can be used to print the
(possibly localized) name for the various well-known SIDS.</para>

<para>Naturally, well-known SIDs are the same on each machine, so they are
not unique to a machine or domain.  They have the same meaning across
the Windows network.</para>

<para>Additionally, there are a couple of well-known builtin groups,
which have the same SID on every machine and which have certain user
rights by default:</para>

<screen>
administrators                  S-1-5-32-544
users                           S-1-5-32-545
guests                          S-1-5-32-546
...
</screen>

<para>For instance, every account is usually member in the "Users"
group.  All administrator accounts are member of the "Administrators"
group.  That's all about it as far as single machines are involved.  In
a domain environment it's a bit more tricky.  Since these SIDs are not
unique to a machine, every domain user and every domain group can be a
member of these well known groups.  Consider the domain group "Domain
Admins".  This group is by default in the "Administrators" group.  Let's
assume the above computer called "foo" is a member machine of the domain
"bar.local".  If you stick the user "BAR\johndoe" into the group "Domain
Admins", this guy will automatically be a member of the administrators
group on "foo" when logging on to "foo".  Neat, isn't it?</para>

<para>Back to ACE and ACL.  POSIX is able to create three different
permissions, the permissions for the owner, for the group and for the
world.  In contrast the Windows ACL has a potentially infinite number of
members... as long as they fit into 64K.  Every member is an ACE.
ACE consist of three parts:</para>

<itemizedlist spacing="compact">
<listitem><para>The type of the ACE (allow ACE or deny ACE).</para></listitem>
<listitem><para>Permission bits, 32 of them.</para></listitem>
<listitem><para>The SID for which the permissions are allowed or denied.</para></listitem>
</itemizedlist>

<para>The two (for us) important types of ACEs are the "access allowed
ACE" and the "access denied ACE".  As the names imply, the allow ACE
tells the system to allow the given permissions to the SID, the deny ACE
results in denying the specific permission bits.</para>

<para>The possible permissions on objects are more detailed than in
POSIX.  For example, the permission to delete an object is different
from the permission to change object data, and even changing object data
can be separated into different permission bits for different kind of
data.  But there's a problem with the definition of a "correct" ACL
which disallows mapping of certain POSIX permissions cleanly.  See
<xref linkend="ntsec-files"></xref>.</para>

<para>POSIX is able to create only three different permissions?  Not quite.
Newer operating systems and file systems on POSIX systems also provide
access control lists.  Two different APIs exist for accessing these
ACLs, the Solaris API and the POSIX API.  Cygwin implements the original
Solaris API to access Windows ACLs in a Unixy way.  Online man pages for the
Solaris ACL API can be found on
<ulink url="http://docs.oracle.com">http://docs.oracle.com</ulink>.
For an overview see <ulink url="http://docs.oracle.com/cd/E23824_01/html/821-1474/acl-5.html#scrolltoc">acl(5)</ulink>.</para>

</sect2>

<sect2 id="ntsec-mapping"><title id="ntsec-mapping.title">Mapping Windows accounts to POSIX accounts</title>

<para>
For as long as Cygwin has existed, it has stored user and group information in
<filename>/etc/passwd</filename> and <filename>/etc/group</filename> files. 
Under the assumption that these files would never be too large, the first
process in a process tree, as well as every execing process within the tree
would parse them into structures in memory.  Thus every Cygwin process would
contain an expanded copy of the full information from
<filename>/etc/passwd</filename> and <filename>/etc/group</filename>.
</para>

<para>
This approach has a few downsides.  One of them is that the idea that these
files will always be small, is flawed.  Another one is that reading the entire
file is most of the time entirely useless, since most processes only
need information on their own user and the primary group.  Last but not
least, the passwd and group files have to be maintained separately from
the already existing Windows user databases, the local SAM and Active
Directory.
</para>

<para>
On the other hand, we have to have this mapping between Windows SIDs and
POSIX uid/gid values, so we need a mechanism to convert SIDs to uid/gid
values and vice versa.
</para>

<para>
Microsoft "Services for UNIX" (SFU) (deprecated since Windows 8/Server 2012)
never used passwd/group files.  Rather, SFU used a fixed, computational mapping
between SIDs and POSIX uid/gid which even has Active Directory support.  It
allows us to generate uid/gid values from SIDs and vice versa.  The mechanism is
documented, albeit in a confusing way and spread over multiple MSDN articles.
</para>

<para>
Starting with Cygwin 1.7.34, Cygwin utilizes an approach inspired by the
mapping method as implemented by SFU, with a few differences for backward
compatibility and to handle some border cases differently.
</para>

<sect3 id="ntsec-mapping-how"><title id="ntsec-mapping-how.title">Mapping Windows SIDs to POSIX uid/gid values</title>

<para>
The following description assumes you're comfortable with the concept of
Windows SIDs and RIDs.  For a brief introduction, see
<xref linkend="ntsec-common"></xref>.
</para>

<para>
Cygwin's mapping between SIDs and uid/gid values works in two ways.
</para>

<itemizedlist spacing="compact">
<listitem><para>Read <filename>/etc/passwd<filename> and
</filename>/etc/group</filename> files if they exist, just as in the olden
days, mainly for backward compatibility.</para></listitem>
<listitem><para>If no files are present, or if an entry is missing in the files,
ask Windows.</para></listitem>
</itemizedlist>

<para>
At least, that's the default behaviour now.  It will be configurable
using a file <filename>/etc/nsswitch.conf</filename>, which is discussed in
<xref linkend="ntsec-mapping-nsswitch"></xref>.  Let's explore the default
for now.
</para>

<para>
If the passwd or group files are present, they will be scanned on demand as
soon as a mapping from SIDs to uid/gid or account names is required.  The new
mechanism will never read the entire file into memory, but only scan for
the requested entry and cache this one in memory.
</para>

<para>
If no entry is found, or no passwd or group file was present, Cygwin
will ask the OS.
</para>

<note>
<para>
If the first process in a Cygwin process tree determines that no
<filename>/etc/passwd</filename> or <filename>/etc/group</filename> file is
present, no other process in the entire process tree will try to read the files
later on.  This is done for self-preservation.  It's rather bad if the uid
or gid of a user changes during the lifetime of a process tree.
</para>

<para>
For the same reason, if you delete the <filename>/etc/passwd</filename>
or <filename>/etc/group</filename> file, this will be ignored.  The passwd
and group records read from the files will persist in memory until either a
new <filename>/etc/passwd</filename> or <filename>/etc/group</filename>
is created, or you exit all processes in the current process tree.
</para>

<para>
See the note in <xref linkend="ntsec-mapping-nsswitch"></xref> for some
comprehensive examples.
</para>
</note>

<para>
So if we've drawn a blank reading the files, we're going to ask the OS.
First thing, we ask the local machine for the SID or the username.  The
OS functions
<ulink url="http://msdn.microsoft.com/en-us/library/windows/desktop/aa379166%28v=vs.85%29.aspx">LookupAccountSid</ulink>
and
<ulink url="http://msdn.microsoft.com/en-us/library/windows/desktop/aa379159%28v=vs.85%29.aspx">LookupAccountName</ulink>
are pretty intelligent.  They have all the stuff built in to ask for any
account of the local machine, the Active Directory domain of the machine,
the Global Catalog of the forest of the domain, as well as any trusted
domain of our forest for the information.  One OS call and we're
practically done...
</para>

<para>
Except, the calls only return the mapping between SID, account name and the
account's domain.  We don't have a mapping to POSIX uid/gid and we're missing
information on the user's home dir and login shell.
</para>

<para>
Let's discuss the SID&lt;=&gt;uid/gid mapping first.  Here's how it works.
</para>

<itemizedlist spacing="compact">

<listitem>
<para>
<ulink url="http://msdn.microsoft.com/en-us/library/aa379649.aspx">Well-known
SIDs</ulink>
in the NT_AUTHORITY domain of the S-1-5-RID type, or aliases of the
S-1-5-32-RID type are mapped to the uid/gid value RID.  Examples:
</para>

<screen>
  "SYSTEM" S-1-5-18                    &lt;=&gt; uid/gid: 18
  "Users"  S-1-5-32-545                &lt;=&gt; uid/gid: 545
</screen>
</listitem>

<listitem>
<para>
Other well-known SIDs in the NT_AUTHORITY domain (S-1-5-X-RID):
</para>

<screen>
  S-1-5-X-RID                          &lt;=&gt; uid/gid: 0x1000 * X + RID
</screen>

<para>Example:</para>

<screen>
  "NTLM Authentication" S-1-5-64-10    &lt;=&gt; uid/gid: 0x4000A == 262154
</screen>
</listitem>

<listitem><para>
Other well-known SIDs:
</para>

<screen>
  S-1-X-Y                              &lt;=&gt; uid/gid: 0x10000 + 0x100 * X + Y
</screen>

<para>Example:</para>

<screen>
  "LOCAL" S-1-2-0                      &lt;=&gt; uid/gid: 0x10200 == 66048
  "Creator Group" S-1-3-1              &lt;=&gt; uid/gid: 0x10301 == 66305
</screen>
</listitem>

<listitem>
<para>
Logon SIDs: The LogonSid of the current user's session is converted to the
fixed uid 0xfff == 4095 and named "CurrentSession".  Any other LogonSid is
converted to the fixed uid 0xffe == 4094 and named "OtherSession".
</para>
</listitem>

<listitem>
<para>
Mandatory Labels:
</para>

<screen>
  S-1-16-RID                           &lt;=&gt; uid/gid: 0x60000 + RID
</screen>

<para>Example:</para>

<screen>
  "Medium Mandatory Level" S-1-16-8192 &lt;=&gt; uid/gid: 0x62000 == 401408
</screen>
</listitem>

<listitem>
<para>
Accounts from the local machine's user DB (SAM):
</para>

<screen>
  S-1-5-21-X-Y-Z-RID                   &lt;=&gt; uid/gid: 0x30000 + RID
</screen>

<para>Example:</para>

<screen>
  "Administrator" S-1-5-21-X-Y-Z-500   &lt;=&gt; uid/gid: 0x301f4 == 197108
</screen>
</listitem>

<listitem>
<para>
Accounts from the machine's primary domain:
</para>

<screen>
  S-1-5-21-X-Y-Z-RID                   &lt;=&gt; uid/gid: 0x100000 + RID
</screen>

<para>Example:</para>

<screen>
  "Domain Users" S-1-5-21-X-Y-Z-513    &lt;=&gt; uid/gid: 0x100201 == 1049089
</screen>
</listitem>

<listitem>
<para>
Accounts from a trusted domain of the machine's primary domain:
</para>

<screen>
  S-1-5-21-X-Y-Z-RID                   &lt;=&gt; uid/gid: trustPosixOffset(domain) + RID
</screen>

<para>
<literal>trustPosixOffset</literal>?  This needs a bit of explanation.  This
value exists in Windows domains already since before Active Directory days.
What happens is this.  If you create a domain trust between two domains, a
trustedDomain entry will be added to both databases.  It describes how
<emphasis>this</emphasis> domain trusts the <emphasis>other</emphasis> domain.
One attribute of a trust is a 32 bit value called
<literal>trustPosixOffset</literal>  For each new trust,
<literal>trustPosixOffset</literal> will get some automatic value.  In recent
AD domain implementations, the first trusted domain will get
<literal>trustPosixOffset</literal> set to 0x80000000.  Following domains will
get lower values.  Unfortunately the domain admins are allowed to set the
<literal>trustPosixOffset</literal> value for each trusted domain to some
arbitrary 32 bit value, no matter what the other
<literal>trustPosixOffset</literal> are set to, thus allowing any kind of
collisions between the <literal>trustPosixOffset</literal> values of domains.
That's not exactly helpful, but as the user of this value, we have to
<emphasis>trust</emphasis> the domain admins to set
<literal>trustPosixOffset</literal> to sensible values, or to keep it at the
system chosen defaults.
</para>

<para>
So, for the first (or only) trusted domain of your domain, the automatic offset
is 0x80000000.  An example for a user of that trusted domain is
</para>

<screen>
  S-1-5-21-X-Y-Z-1234                  &lt;=&gt; uid/gid 0x800004d2 == 2147484882
</screen>

<para>
There's one problem with this approach.  Assuming you're running in the context
of a local SAM user on a domain member machine.  Local users don't have the
right to fetch this kind of domain information from the DC, they'll get
permission denied.  In this case Cygwin will fake a sensible
<literal>trustPosixOffset</literal> value.
</para>

<para>
Another problem is if the AD administrators chose an unreasonably small
<literal>trustPosixOffset</literal> value.  Anything below the hexadecimal
value 0x100000 (the POSIX offset of the primary domain) is bound to produce
collisions with system accounts as well as local accounts.  The right thing
to do in this case is to notify your administrator of the problem and to ask
for moving the offset to a more reasonable value.  However, to reduce the
probability for collisions, Cygwin overrides this offset with a sensible
fixed replacement offset.
</para>
</listitem>

<listitem>
<para>
Local accounts from another machine in the network:
</para>

<para>
There's no SID&lt;=&gt;uid/gid mapping implemented for this case.  The problem
is, there's no way to generate a bijective mapping.  There's no central place
which keeps an analogue of the <literal>trustPosixOffset</literal>, and there's
the additional problem that the
<ulink url="http://msdn.microsoft.com/en-us/library/windows/desktop/aa379166%28v=vs.85%29.aspx">LookupAccountSid</ulink>
and
<ulink url="http://msdn.microsoft.com/en-us/library/windows/desktop/aa379159%28v=vs.85%29.aspx">LookupAccountName</ulink>
functions cannnot resolve the SIDs, unless they know the name of the machine
this SID comes from.  And even then it will probably suffer a
<literal>Permission denied</literal> error when trying to ask the machine
for its local account.
</para>
</listitem>

</itemizedlist>

<para>
Now we have a semi-bijective mapping between SIDs and POSIX uid/gid values,
but given that we have potentially users and groups in different domains having
the same name, how do we uniquely distinguish between them by name?  Well, we
can do that by making their names unique in a per-machine way.  Dependent on
the domain membership of the account, and dependent of the machine being a
domain member or not, the user and group names will be generated using a domain
prefix and a separator character between domain and account name.
The <!-- default --> separator character is the plus sign, <literal>+</literal>.
</para>

<itemizedlist spacing="compact">

<listitem>
<para>
Well-known and builtin accounts will be named as in Windows:
</para>

<screen>
  "SYSTEM", "LOCAL", "Medium Mandatory Level", ...
</screen>
</listitem>

<listitem>
<para>
If the machine is not a domain member machine, only local accounts can be resolved
into names, so for ease of use, just the account names are used as Cygwin
user/group names:
</para>

<screen>
  "corinna", "bigfoot", "None", ...
</screen>
</listitem>

<listitem>
<para>
If the machine is a domain member machine, all accounts from the primary domain
of the machine are mapped to Cygwin names without domain prefix:
</para>

<screen>
  "corinna", "bigfoot", "Domain Users", ...
</screen>

<para>
while accounts from other domains are prepended by their domain:
</para>

<screen>
  "DOMAIN1+corinna", "DOMAIN2+bigfoot", "DOMAIN3+Domain Users", ...
</screen>
</listitem>

<listitem>
<para>
Local machine accounts of a domain member machine get a Cygwin user name the
same way as accounts from another domain:  The local machine name gets
prepended:
</para>

<screen>
  "MYMACHINE+corinna", "MYMACHINE+bigfoot", "MYMACHINE+None", ...
</screen>
</listitem>

<listitem>
<para>
If LookupAccountSid fails, Cygwin checks the accounts against the known trusted
domains.  If the account is from one of the trusted domains, an artificial
account name is created.  It consists of the domain name, and a special name
created from the account RID:
</para>

<screen>
  "MY_DOM+User(1234)", "MY_DOM+Group(5678)"
</screen>

<para>
Otherwise we know nothing about this SID, so it will be mapped to the
fake accounts <literal>Unknown+User</literal>/<literal>Unknown+Group</literal>
with uid/gid -1.
</para>
</listitem>

</itemizedlist>

</sect3>

<sect3 id="ntsec-mapping-caching"><title id="ntsec-mapping-caching.title">Caching account information</title>

<para>
The information fetched from the Windows account database or the
<filename>/etc/passwd</filename> and <filename>/etc/group</filename> files is
cached by the process.  The cached information is inherited by Cygwin child
processes.  A Cygwin process invoked from a Windows command, such as CMD.exe,
will start a new Cygwin process tree and the caching starts from scratch
(unless <command><link linkend="using-cygserver">cygserver</link></command> is
running, but read on).
</para>

<para>
While usually working fine, this has some drawbacks.  Consider a shell calling
<command>id</command>.  <command>id</command> fetches all group information
from the current token and caches them.  Unfortunately <command>id</command>
doesn't start any child processes, so the information is lost as soon as
<command>id</command> exits.
</para>

<para>
But there's another caching mechanism available.  If
<command><link linkend="using-cygserver">cygserver</link></command> is running
it will provide passwd and group entry caching for all processes in every Cygwin
process tree started after
<command><link linkend="using-cygserver">cygserver</link></command>.  So, if
you start a Cygwin Terminal and
<command><link linkend="using-cygserver">cygserver</link></command> is running
at the time, <command>mintty</command>, the shell, and all child processes will
use <command><link linkend="using-cygserver">cygserver</link></command> caching.
If you start a Cygwin Terminal and
<command><link linkend="using-cygserver">cygserver</link></command> is not
running at the time, none of the processes started inside this terminal window
will use <command><link linkend="using-cygserver">cygserver</link></command>
caching.
</para>

<para>
The advantage of
<command><link linkend="using-cygserver">cygserver</link></command> caching is
that it's system-wide and, as long as
<command><link linkend="using-cygserver">cygserver</link></command> is running,
unforgetful.  Every Cygwin process on the system will have the
<command><link linkend="using-cygserver">cygserver</link></command> cache at
its service.  Additionally, all information requested from
<command><link linkend="using-cygserver">cygserver</link></command> once, will
be cached inside the process itself and, again, propagated to child processes.
</para>

<para>
If you automatically start Cygwin processes as Windows services at system
startup, you may wish to consider starting
<command><link linkend="using-cygserver">cygserver</link></command> first in
order to take advantage of this system-wide caching.  To assure that
<command><link linkend="using-cygserver">cygserver</link></command> has started
prior to starting <command>sshd</command> or other Cygwin processes, you may
wish to create service startup dependencies.
<command><link linkend="using-cygserver">Cygserver</link></command> should
probably wait for Windows TCPIP and AFD services before it starts, and then
other Cygwin process should start after
<command><link linkend="using-cygserver">cygserver</link></command>.  Example
Windows commands to accomplish this (after the services already exist) are
shown below.  You will need an administrative prompt to run the
<command>sc config</command> commands.
</para>

<screen>
  # Delay Cygserver until TCPIP and AFD have started
  # Note the (odd) required space character after "depend="

  sc config cygserver depend= tcpip/afd

  # Delay sshd until after Cygserver has started
  # Again note the (odd) required space character after "depend="

  sc config sshd depend= cygserver

  # View the Cygserver service details

  sc qc cygserver
</screen>

<para>
Note that this <command>sc config</command> command
<emphasis>replaces</emphasis> any existing dependencies.  The above changes
will not impact the running instance, only future instances.
</para>

<screen>
  # To remove all dependencies from the cygserver service

  sc config cygserver depend= /
</screen>

</sect3>

<sect3 id="ntsec-mapping-passwdinfo"><title id="ntsec-mapping-passwdinfo.title">Cygwin user names, home dirs, login shells</title>

<para>
Obviously, if you don't maintain <filename>passwd</filename> and
<filename>group</filename> files, you need to have a way to maintain the other
fields of a passwd entry as well.  A couple of things come to mind:
</para>

<itemizedlist spacing="compact">

<listitem>
<para>
You want to use a Cygwin username different from your Windows username.
</para>

<note><para>
This is only supported via <filename>/etc/passwd</filename>.  A Cygwin
username maintained in the Windows user databases would require very costly
(read: slow) search operations.
</para></note>
</listitem>

<listitem>
<para>
You want to change the primary group of a user.  For AD accounts this is
not supported.  The primary group of a user is always the Windows
primary group set in Active Directory and can't be changed.  For SAM
accounts, you can add the primary group to the SAM
<literal>description</literal> field of the user.  See <xref
linkend="ntsec-mapping-nsswitch-desc"></xref> for more info.
</para>
</listitem>

<listitem>
<para>
You want a home dir different from the default
<filename>/home/$USERNAME</filename>.
</para>
</listitem>

<listitem>
<para>
You want to specify a different login shell than <filename>/bin/bash</filename>.
</para>
</listitem>

<listitem>
<para>
You want to add specific content to the pw_gecos field.
</para>
</listitem>

</itemizedlist>

<para>
For simple needs you can create <filename>/etc/passwd</filename> and/or
<filename>/etc/group</filename> files with entries for your account
and tweak that.
</para>

<para>
For bigger installations, maintaining per-client files is rather troublesome.
Also, no two environments are the same, so the needs are pretty different.
Therefore Cygwin supports configuring how to fetch home directory,
login shell, and gecos information in /etc/nsswitch.conf.  See the next
section for detailed information how to configure Cygwin's account handling.
</para>

</sect3>

<sect3 id="ntsec-mapping-nsswitch"><title id="ntsec-mapping-nsswitch.title">The <filename>/etc/nsswitch.conf</filename> file</title>

<para>
On Linux and some other UNIXy OSes, we have a file called
<ulink url="http://linux.die.net/man/5/nsswitch.conf">/etc/nsswitch.conf</ulink>.
Among other things, it determines how passwd and group entries are generated.
That's what Cygwin now provides as well.
</para>

<para>
The <filename>/etc/nsswitch.conf</filename> file is optional.  If you don't
have one, Cygwin uses sensible defaults.
</para>

<note>
<para>
The <filename>/etc/nsswitch.conf</filename> file is read exactly once by
the first process of a Cygwin process tree.  If there was no
<filename>/etc/nsswitch.conf</filename> file when this first process started,
then no other process in the running Cygwin process tree will try to read the
file.
</para>

<para>
If you create or change <filename>/etc/nsswitch.conf</filename>, you have to
restart all Cygwin processes that need to see the change.  If the process
you want to see the change is a child of another process, you need to restart
all of that process's parents, too.
</para>

<para>
For example, if you run <command>vim</command> inside the default Cygwin
Terminal, <command>vim</command> is a child of your shell, which is a child
of <command>mintty</command>.  If you edit
<filename>/etc/nsswitch.conf</filename> in that <command>vim</command>
instance, your shell won't immediately see the change, nor will
<command>vim</command> if you restart it from that same shell instance.
This is because both are getting their nsswitch information from their
ancestor, <command>mintty</command>.  You have to start a fresh terminal
window for the change to take effect.
</para>

<para>
By contrast, if you leave that Cygwin Terminal window open after making the
change to <filename>/etc/nsswitch.conf</filename>, then restart a Cygwin
service like <command>cron</command>, <command>cron</command> will see the
change, because it is not a child of <command>mintty</command> or any other
Cygwin process. (Technically, it is a child of <command>cygrunsrv</command>,
but that instance also restarts when you restart the service.)
</para>

<para>
The reason we point all this out is that the requirements for restarting
things are not quite as stringent as when you replace
<filename>cygwin1.dll</filename>. If you have three process trees, you have
three independent copies of the nsswitch information.  If you start a fresh
process tree, it will see the changes.  As long as any process in an existing
process tree remains running, all processes in that tree will continue to use
the old information.
</para>
</note>

<para>
So, what settings can we perform with <filename>/etc/nsswitch.conf</filename>?
Let's start with an example <filename>/etc/nsswitch.conf</filename> file
set up to all default values:
</para>

<screen>
  # /etc/nsswitch.conf
  passwd: files db
  group:  files db
<!--
  db_prefix:    auto
  db_separator: + -->
  db_enum:  cache builtin
  db_home:  /home/%U
  db_shell: /bin/bash
  db_gecos: &lt;empty&gt;
</screen>

<sect4 id="ntsec-mapping-nsswitch-syntax"><title id="ntsec-mapping-nsswitch-syntax.title">The <filename>/etc/nsswitch.conf</filename> syntax</title>

<para>
The first line, starting with a hash <literal>#</literal> is a comment.
The hash character starts a comment, just as in shell scripts.  Everything
up to the end of the line is ignored.  So this:
</para>

<screen>
  foo:  bar # baz
</screen>

<para>
means, set "foo" to value "bar", ignore everything after the hash.
</para>

<para>
The other lines define the available settings.  The first word up to a
colon is a keyword.  Note that the colon <emphasis>must</emphasis> follow
immediately after the keyword.  This is a valid line:
</para>

<screen>
  foo: bar
</screen>

<para>
This is not valid:
</para>

<screen>
  foo  :  bar
</screen>

<para>
Apart from this restriction, the reminder of the line can have as
many spaces and TABs as you like.
</para>

</sect4>

<sect4 id="ntsec-mapping-nsswitch-pwdgrp"><title id="ntsec-mapping-nsswitch-pwdgrp.title">The <literal>passwd:</literal> and <literal>group:</literal> settings</title>

<para>
The two lines starting with the keywords <literal>passwd:</literal> and
<literal>group:</literal> define where Cygwin gets its passwd and group
information from.  <literal>files</literal> means, fetch the information
from the corresponding file in the /etc directory.  <literal>db</literal>
means, fetch the information from the Windows account databases, the SAM
for local accounts, Active Directory for domain account.  Examples:
</para>

<screen>
  passwd: files
</screen>

<para>
Read passwd entries only from /etc/passwd.
</para>

<screen>
  group: db
</screen>

<para>
Read group entries only from SAM/AD.
</para>

<screen>
  group: files # db
</screen>

<para>
Read group entries only from <filename>/etc/group</filename>
(<literal>db</literal> is only a comment).
</para>

<screen>
  passwd: files db
</screen>

<para>
Read passwd entries from <filename>/etc/passwd</filename>.  If a user account
isn't found, try to find it in SAM or AD.  This is the default for both,
passwd and group information.
</para>

<screen>
  group: db files
</screen>

<para>
This is a valid entry, but the order will be ignored by Cygwin.  If both
settings, <literal>files</literal> and <literal>db</literal> are specified,
Cygwin will always try the files first, then the db.
</para>

<para>
<literal>passwd:</literal> and <literal>group:</literal> are the two basic
settings defining where to get the account information from.  The following
settings starting with <literal>db_</literal> define certain aspects of the
Windows account database search and how to generate <literal>passwd</literal>
and <literal>group</literal> information from the database.
</para>

</sect4>

<!--

  DESCRIPTION OF db_prefix AND db_separator

  Keep in for reference


<itemizedlist spacing="compact">

<listitem>
<para>
<literal>db_prefix:</literal> determines how the Cygwin user or group name
is created.  The recognized values are:
</para>

<variablelist>
  <varlistentry>
    <term><literal>auto</literal></term>
    <listitem>
      <para>
      This is the default.  If your account is from the primary domain of your
      machine, or if your machine is a standalone machine (not a domain member),
      your Cygwin account name is just the Windows account name.
      </para>

      <para>
      If your account is from another domain, or if you're logged in as
      local user on a domain machine, the Cygwin username will be the
      combination of Windows domainname and username, with the separator
      char in between:
      </para>

      <segmentedlist><?dbhtml list-presentation="table"?>
	<seglistitem>
	  <seg><literal>MY_DOM+username</literal></seg>
	  <seg>(foreign domain)</seg>
	</seglistitem>
	<seglistitem>
	  <seg><literal>MACHINE+username</literal></seg>
	  <seg>(local account)</seg>
	</seglistitem>
      </segmentedlist>

      <para>
      Builtin accounts are simply used as is:
      </para>

      <segmentedlist><?dbhtml list-presentation="table"?>
	<seglistitem>
	  <seg><literal>LOCAL</literal></seg>
	</seglistitem>
	<seglistitem>
	  <seg><literal>Users</literal></seg>
	</seglistitem>
      </segmentedlist>

      <para>
      Unknown accounts on NFS or Samba shares (that is, accounts which cannot be
      mapped to Windows user accounts via
      <ulink url="https://tools.ietf.org/html/rfc2307">RFC 2307</ulink>) get a
      Cygwin account name consisting of the artificial domains
      <literal>Unix_User</literal> or <literal>Unix_Group</literal> and the
      uid/gid value, for instance:
      </para>

      <segmentedlist><?dbhtml list-presentation="table"?>
	<seglistitem>
	  <seg><literal>Unix_User+0</literal></seg>
	  <seg>(root)</seg>
	</seglistitem>
	<seglistitem>
	  <seg><literal>Unix_Group+10</literal></seg>
	  <seg>(wheel)</seg>
	</seglistitem>
      </segmentedlist>
    </listitem>
  </varlistentry>

  <varlistentry>
    <term><literal>primary</literal></term>
    <listitem>
      <para>
      Like <literal>auto</literal>, but primary domain accounts will be
      prepended by the domainname as well.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry>
    <term><literal>always</literal></term>
    <listitem>
      <para>
      All accounts, even the builtin accounts, will have the domain name
      prepended:
      </para>

      <segmentedlist><?dbhtml list-presentation="table"?>
	<seglistitem>
	  <seg><literal>BUILTIN+Users</literal></seg>
	</seglistitem>
      </segmentedlist>

      <para>
      A special case are builtin accounts which have an emtpy domain name.
      These will be prependend by just the separator character in
      <literal>always</literal> mode:
      </para>

      <segmentedlist><?dbhtml list-presentation="table"?>
	<seglistitem>
	  <seg><literal>+LOCAL</literal></seg>
	</seglistitem>
      </segmentedlist>
    </listitem>
  </varlistentry>
</variablelist>

</listitem>

<listitem>
<para>
<literal>db_separator:</literal> defines the spearator char used to prepend the
domain name to the user or group name.  The default is the plus character
<literal>+</literal>.
</para>

<screen>
  MY_DOM+username
</screen>

<para>
With <literal>db_separator:</literal>, you can define any ASCII char except
space, tab, carriage return, line feed, and the colon, as separator char.
Example:
</para>

<screen>
  db_separator: \
</screen>

<para>
This results in usernames with the backslash as separator:
</para>

<screen>
  MY_DOM\username
</screen>

</listitem>

</itemizedlist>
-->

<sect4 id="ntsec-mapping-nsswitch-enum"><title id="ntsec-mapping-nsswitch-enum.title">The <literal>db_enum:</literal> setting</title>

<para>
<literal>db_enum:</literal> defines the depth of a database search, if an
application calls one of the enumeration functions
<ulink url="http://linux.die.net/man/3/getpwent">getpwent</ulink>
or <ulink url="http://linux.die.net/man/3/getgrent">getgrent</ulink>.
The problem with these functions is, they neither allow to define how many
entries will be enumerated when calling them in a loop, nor do they
allow to add some filter criteria.  They were designed back in the days,
when only <filename>/etc/passwd</filename> and <filename>/etc/group</filename>
files existed and the number of user accounts on a typical UNIX system was
seldomly a three-digit number.
</para>

<para>
These days, with user and group databases sometimes going in the
six-digit range, they are a potential burden.  For that reason, Cygwin
does not enumerate all user or group accounts by default, but rather
just a very small list, consisting only of the accounts cached in memory
by the current process, as well as a handful of predefined builtin
accounts.
</para>

<para>
<literal>db_enum:</literal> allows to specify the accounts to enumerate in a
fine-grained manner.  It takes a list of sources as argument:
</para>

<screen>
  db_enum:  source1 source2 ...
</screen>

<para>
The recognized sources are the following:
</para>

<variablelist>
  <varlistentry>
    <term><literal>none</literal></term>
    <listitem>No output from
         <function>getpwent</function>/<function>getgrent</function>
	 at all.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>all</literal></term>
    <listitem>The opposite.  Enumerates accounts from all known sources,
	      including all trusted domains.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>cache</literal></term>
    <listitem>Enumerate all accounts currently cached in memory.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>builtin</literal></term>
    <listitem>Enumerate the predefined builtin accounts for backward
	      compatibility.  These are five passwd accounts (SYSTEM,
	      LocalService, NetworkService, Administrators, TrustedInstaller)
	      and two group accounts (SYSTEM and TrustedInstaller).</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>files</literal></term>
    <listitem>Enumerate the accounts from <filename>/etc/passwd</filename> or
	      <filename>/etc/group</filename>.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>local</literal></term>
    <listitem>Enumerate all accounts from the local SAM.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>primary</literal></term>
    <listitem>Enumerate all accounts from the primary domain.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>alltrusted</literal></term>
    <listitem>Enumerate all accounts from all trusted domains.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>some.domain</literal></term>
    <listitem>Enumerate all accounts from the trusted domain some.domain.  The
	      trusted domain can be given as Netbios flat name (MY_DOMAIN) or
	      as dns domain name (my_domain.corp).  In contrast to the
	      aforementioned fixed source keywords, distinct domain names are
	      caseinsensitive.  Only domains which are actually trusted domains
	      are enumerated.  Unknown domains are simply ignored.</listitem>
  </varlistentry>
</variablelist>

<para>
Please note that <function>getpwent</function>/<function>getgrent</function>
do <emphasis>not</emphasis> test if an account was already listed from another
source, so an account can easily show up twice or three times.  Such a test
would be rather tricky, nor does the Linux implementation perform such test.
Here are a few examples for <filename>/etc/nsswitch.conf</filename>:
</para>

<screen>
  db_enum: none
</screen>

<para>
No output from <function>getpwent</function>/<function>getgrent</function>
at all.  The first call to the function immediately returns a NULL pointer.
</para>

<screen>
  db_enum: cache files
</screen>

<para>
Enumerate all accounts cached by the current process, plus all entries
from either the /etc/passwd or /etc/group file.
</para>

<screen>
  db_enum: cache local primary
</screen>

<para>
Enumerate all accounts cached by the current process, all accounts from the SAM
of the local machine, and all accounts from the primary domain of the machine.
</para>

<screen>
  db_enum: local primary alltrusted
</screen>

<para>
Enumerate the accounts from the machine's SAM, from the primary domain of the
machine, and from all trusted domains.
</para>

<screen>
  db_enum: primary domain1.corp sub.domain.corp domain2.net
</screen>

<para>
Enumerate the accounts from the primary domain and from the domains
domain1.corp, sub.domain.corp and domain2.net.
</para>

<screen>
  db_enum: all
</screen>

<para>
Enumerate everything and the kitchen sink.
</para>

</sect4>

<sect4 id="ntsec-mapping-nsswitch-passwd"><title id="ntsec-mapping-nsswitch-passwd.title">Settings defining how to create the <literal>passwd</literal> entry</title>

<para>
<filename>/etc/nsswitch.conf</filename> supports three settings to configure
where to get the pw_dir, pw_shell, and pw_gecos content of a
<literal>passwd</literal> entry from:
</para>

<screen>
  db_home: schema...     # Define how to fetch the pw_dir entry.
  db_shell: schema...    # Define how to fetch the pw_shell entry.
  db_gecos: schema...    # Define how to fetch the pw_gecos entry.
</screen>

"schema..." is a list of up to four space-separated schemata:

<screen>
  db_FOO: schema1 schema2 ...
</screen>

<para>
When generating a passwd entry, Cygwin tries the schemata in order.  If
the first schema returns an empty string, it skips to the second, and so
on.  Schemata only supported on AD are silently skipped for SAM accounts
and on non-AD machines.
</para>

<para>
Four schemata are predefined, two schemata are variable.  The predefined
schemata are the following:
</para>

<variablelist>
  <varlistentry>
    <term><literal>windows</literal></term>
    <listitem>Utilizes typical Windows settings.  Supported for AD and SAM
	      accounts.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>cygwin</literal></term>
    <listitem>Utilizes the cygwinUser AD schema extension.  This schema
	      extension is available via a schema extension file
	      <filename>/usr/share/cygwin/cygwin.ldif</filename>.
	      See <xref linkend="ntsec-mapping-nsswitch-cygwin"></xref> for
	      more information.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>unix</literal></term>
    <listitem>Utilizes the posixAccount schema attributes per
	      <ulink url="https://tools.ietf.org/html/rfc2307">RFC 2307</ulink>.
	      The posixAccount schema is available by default since Windows
	      Server 2003 R2, but typically only utilized when installing the
	      Active Directory "Server for NIS" feature (which is deprecated
	      since Server 2012 R2).
	      See also <xref linkend="ntsec-mapping-nsswitch-posix"></xref>.
	      </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>desc</literal></term>
    <listitem>Utilizes XML-style attributes in the description attribute.
	      Supported for AD and SAM accounts.
	      See <xref linkend="ntsec-mapping-nsswitch-desc"></xref>
	      for a more detailed description.</listitem>
  </varlistentry>
</variablelist>

<para>
The variable schemata are as follows.  Note that the leading characters
(<literal>@</literal> and <literal>/</literal>) are an integral part of the
definition.
</para>

<variablelist>
  <varlistentry>
    <term><literal>@ad_attribute</literal></term>
    <listitem><literal>ad_attribute</literal> is any arbitrary AD attribute
	      name which should (ideally) be available in the User class or
	      in any attached auxiliary class.  It's always treated as a
	      single string argument.  Only the first string of a multi-string
	      attributes will be read.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>/path</literal></term>
    <listitem>An arbitrary string, typically a path.  The leading slash is
	      required.  Given that a single, fixed path for all users
	      only makes marginal sense, the /path schema supports wildcards.
	      A wildcard is a per-cent (<literal>%</literal>) character,
	      followed by another character giving the meaning.  The supported
	      wildcard characters are:
	      
	      <variablelist>
	        <varlistentry>
		  <term><literal>%u</literal></term>
		  <listitem>The Cygwin username (that's lowercase
			    <literal>u</literal>).</listitem>
		</varlistentry>
	        <varlistentry>
		  <term><literal>%U</literal></term>
		  <listitem>The Windows username (that's uppercase
			    <literal>U</literal>).</listitem>
		</varlistentry>
	        <varlistentry>
		  <term><literal>%D</literal></term>
		  <listitem>Windows domain in NetBIOS style.</listitem>
		</varlistentry>
	        <varlistentry>
		  <term><literal>%H</literal></term>
		  <listitem>Windows home directory in POSIX style.  Note that,
			    for the <literal>db_home:</literal> setting, this
			    only makes sense right after the preceeding slash,
			    as in
<screen>
db_home:  /%H/cygwin
</screen>
		  </listitem>
		</varlistentry>
	        <varlistentry>
		  <term><literal>%_</literal></term>
		  <listitem>Since space and TAB characters are used to separate
			    the schemata, a space in the filename has to be
			    given as <literal>%_</literal> (that's an
			    underscore).</listitem>
		</varlistentry>
	        <varlistentry>
		  <term><literal>%%</literal></term>
		  <listitem>A per-cent character.</listitem>
		</varlistentry>
	      </variablelist>
	      <para>Any other <literal>%X</literal> expression is treated as if
	      the character <literal>X</literal> has been given alone.</para>
	      </listitem>
  </varlistentry>
</variablelist>

<para>
The exact meaning of a schema depends on the setting it's used for.  The
following sections explain the settings in detail.
</para>

</sect4>

<sect4 id="ntsec-mapping-nsswitch-home">
  <sectioninfo>
    <title role="texinfo-node">The <literal>db_home</literal> setting</title>
  </sectioninfo>
    <title id="ntsec-mapping-nsswitch-home.title">The <literal>db_home:</literal> setting</title>

<para>
The <literal>db_home:</literal> setting defines how Cygwin fetches the user's
home directory, or, more precise, the content of the <literal>pw_dir</literal>
member of the user's passwd entry.  The following list describes the meaning
of each schema when used with <literal>db_home:</literal>
</para>

<variablelist>
  <varlistentry>
    <term><literal>windows</literal></term>
    <listitem>The user's home directory is set to the same directory which is
	      used as Windows home directory.  This is the
<!--
	      <literal>homeDrive</literal> AD attribute if set, or the
	      <literal>homeDirectory</literal> AD attribute if
	      <literal>homeDrive</literal> is not set.
-->
	      <literal>homeDirectory</literal> AD attribute.
	      For SAM accounts, this is equivalent to the "Home folder" setting
	      in SAM.  If both attributes are unset, Cygwin falls back to the
	      user's local profile directory, typically something along the
	      lines of <filename>C:\Users\$USERNAME</filename>.  Of course, the
	      Windows directory is converted to POSIX-style by Cygwin.
	      </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>cygwin</literal></term>
    <listitem>AD only: The user's home directory is set to the POSIX path given
	      in the <literal>cygwinHome</literal> attribute from the
	      <literal>cygwinUser</literal> auxiliary class.
	      See also <xref linkend="ntsec-mapping-nsswitch-cygwin"></xref>.
	      </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>unix</literal></term>
    <listitem>AD only: The user's home directory is set to the POSIX path given
	      in the <literal>unixHomeDirectory</literal> attribute from the
	      <literal>posixAccount</literal> auxiliary class.
	      See also <xref linkend="ntsec-mapping-nsswitch-posix"></xref>.
	      </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>desc</literal></term>
    <listitem>The user's home directory is set to the POSIX path given in the
	      home="..." XML-alike setting in the user's
	      <literal>description</literal> attribute in SAM or AD.
	      See <xref linkend="ntsec-mapping-nsswitch-desc"></xref>
	      for a detailed description.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>@ad_attribute</literal></term>
    <listitem>AD only: The user's home directory is set to the path given
	      in the <literal>ad_attribute</literal> attribute.  The path
	      can be given as Windows or POSIX path.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>/path</literal></term>
    <listitem>The user's home directory is set to the given POSIX path.
	      Remember the wildcards described in
	      <xref linkend="ntsec-mapping-nsswitch-passwd"></xref>.</listitem>
  </varlistentry>
  <varlistentry>
    <term>Fallback</term>
    <listitem>If none of the schemes given for <literal>db_home:</literal>
	      define a non-empty directory, the user's home directory is set to
	      <filename>/home/$USERNAME</filename>.</listitem>
  </varlistentry>
</variablelist>

<para>
As has been briefly mentioned before, the default setting for
<literal>db_home:</literal> is
</para>

<screen>
  db_home: /home/%U
</screen>

<para>
So by default, Cygwin just sets the home dir to
<filename>/home/$USERNAME</filename>.
</para>

</sect4>

<sect4 id="ntsec-mapping-nsswitch-shell">
  <sectioninfo>
    <title role="texinfo-node">The <literal>db_shell</literal> setting</title>
  </sectioninfo>
  <title id="ntsec-mapping-nsswitch-shell.title">The <literal>db_shell:</literal> setting</title>

<para>
The <literal>db_shell:</literal> setting defines how Cygwin fetches the user's
login shell, the content of the <literal>pw_shell</literal> member of the
user's passwd entry.  The following list describes the meaning of each schema
when used with <literal>db_shell:</literal>
</para>

<variablelist>
  <varlistentry>
    <term><literal>windows</literal></term>
    <listitem>The <literal>windows</literal> schema is ignored for now.
	      The logical choice would be CMD, but that introduces some
	      problems, for instance the fact that CMD has no concept of
	      running as <literal>login shell</literal>.  This may change
	      in future.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>cygwin</literal></term>
    <listitem>AD only: The user's home directory is set to the POSIX path given
	      in the <literal>cygwinShell</literal> attribute from the
	      <literal>cygwinUser</literal> auxiliary class.
	      See also <xref linkend="ntsec-mapping-nsswitch-cygwin"></xref>.
	      </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>unix</literal></term>
    <listitem>AD only: The user's login shell is set to the POSIX path given
	      in the <literal>loginShell</literal> attribute from the
	      <literal>posixAccount</literal> auxiliary class.
	      See also <xref linkend="ntsec-mapping-nsswitch-posix"></xref>.
	      </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>desc</literal></term>
    <listitem>The user's login shell is set to the POSIX path given in the
	      shell="..." XML-alike setting in the user's
	      <literal>description</literal> attribute in SAM or AD.
	      See <xref linkend="ntsec-mapping-nsswitch-desc"></xref>
	      for a detailed description.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>@ad_attribute</literal></term>
    <listitem>AD only: The user's login shell is set to the path given
	      in the <literal>ad_attribute</literal> attribute.  The path
	      can be given as Windows or POSIX path.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>/path</literal></term>
    <listitem>The user's login shell is set to the given POSIX path.
	      Albeit not being as important here, the wildcards described in
	      <xref linkend="ntsec-mapping-nsswitch-passwd"></xref>
	      are also available for specifying a login shell path.</listitem>
  </varlistentry>
  <varlistentry>
    <term>Fallback</term>
    <listitem>If none of the schemes given for <literal>db_shell:</literal>
	      define a non-empty pathname, the user's login shell is set to
	      <filename>/bin/bash</filename>.</listitem>
  </varlistentry>
</variablelist>

<para>
As for <literal>db_home:</literal>, the default setting for
<literal>db_shell:</literal> is pretty much a constant
</para>

<screen>
  db_shell: /bin/bash
</screen>


</sect4>

<sect4 id="ntsec-mapping-nsswitch-gecos">
  <sectioninfo>
    <title role="texinfo-node">The <literal>db_gecos</literal> setting</title>
  </sectioninfo>
  <title id="ntsec-mapping-nsswitch-gecos.title">The <literal>db_gecos:</literal> setting</title>

<para>
The <literal>db_gecos:</literal> setting defines how to fetch additional
content for the <literal>pw_gecos</literal> member of the user's passwd entry.
There's always a fixed, Cygwin-specific part in the <literal>pw_gecos</literal>
field for identifying the account.  However, an administrator might want to
add informative content like, for instance, the user's full name.  That's
what the <literal>db_gecos:</literal> setting is for.
The following list describes the meaning of each schema when used with
<literal>db_gecos:</literal>
</para>

<variablelist>
  <varlistentry>
    <term><literal>windows</literal></term>
    <listitem>Add the AD <literal>displayName</literal> attribute or, for
	      SAM accounts, the "Full name" entry to the
	      <literal>pw_gecos</literal> field.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>cygwin</literal></term>
    <listitem>AD only: The content of the <literal>cygwinGecos</literal>
	      attribute from the <literal>cygwinUser</literal> auxiliary class
	      is added to <literal>pw_gecos</literal>.
	      See also <xref linkend="ntsec-mapping-nsswitch-cygwin"></xref>.
	      </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>unix</literal></term>
    <listitem>AD only: The content of the <literal>gecos</literal> attribute
	      from the <literal>posixAccount</literal> auxiliary class
	      is added to <literal>pw_gecos</literal>.
	      See also <xref linkend="ntsec-mapping-nsswitch-posix"></xref>.
	      </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>desc</literal></term>
    <listitem>The content of the gecos="..." XML-alike setting in the user's
	      <literal>description</literal> attribute in SAM or AD is added
	      to <literal>pw_gecos</literal>.
	      See <xref linkend="ntsec-mapping-nsswitch-desc"></xref>
	      for a detailed description.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>@ad_attribute</literal></term>
    <listitem>AD only: The content of the <literal>ad_attribute</literal>
	      attribute is added to <literal>pw_gecos</literal>.</listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>/path</literal></term>
    <listitem>The string following the slash is added to
	      <literal>pw_gecos</literal>.  Here, the wildcards described in
	      <xref linkend="ntsec-mapping-nsswitch-passwd"></xref>
	      may come in handy.</listitem>
  </varlistentry>
  <varlistentry>
    <term>Fallback</term>
    <listitem>If none of the schemes given for <literal>db_gecos:</literal>
	      define a non-empty pathname, nothing is added to
	      <literal>pw_gecos</literal>.</listitem>
  </varlistentry>
</variablelist>

<para>
The default setting for <literal>db_gecos:</literal> is the empty string.
</para>

</sect4>

<sect4 id="ntsec-mapping-nsswitch-cygwin"><title id="ntsec-mapping-nsswitch-cygwin.title">The <literal>cygwin</literal> schema</title>

<para>
The <literal>cygwin</literal> schema is based on a Cygwin-specific Active
Directory schema extension.  Using this schema extension allows to maintain
Cygwin-specific settings entirely within AD, without colliding with any other
schema.
</para>

<para>
The cygwin schema extension is available in a default Cygwin installation
in the file <filename>/usr/share/cygwin/cygwin.ldif</filename>.  To install
the schema extension, you have to be schema admin, and you have to run the
<command>ldifde</command> command on the schema master.  The installation
itself is rather simple.  Assuming you're schema admin and running a shell
with administrative privileges:
</para>

<screen>
  $ cd /usr/share/cygwin
  $ ldifde -i -f cygwin.ldif -k -c "CN=schema,CN=Configuration,DC=X" #schemaNamingContext
</screen>

<para>
Afterwards, the auxiliary class <literal>cygwinUser</literal> is attached to
the class <literal>User</literal>, and the auxiliary class
<literal>cygwinGroup</literal> is attached to the class
<literal>Group</literal>.  The new attributes can be immediately edited
using <command>ADSI Edit</command>.
</para>

<para>
At the time of writing the following attributes are utilized by Cygwin:
</para>

<segmentedlist><?dbhtml list-presentation="table"?>
  <seglistitem>
    <seg><literal>cygwinHome</literal></seg>
    <seg>Used as Cygwin home directory with <literal>db_home: cygwin</literal>.
	 See <xref linkend="ntsec-mapping-nsswitch-home"></xref>.</seg>
  </seglistitem>
  <seglistitem>
    <seg><literal>cygwinShell</literal></seg>
    <seg>Used as Cygwin login shell with <literal>db_shell: cygwin</literal>.
	 See <xref linkend="ntsec-mapping-nsswitch-shell"></xref>.</seg>
  </seglistitem>
  <seglistitem>
    <seg><literal>cygwinGecos</literal></seg>
    <seg>Content will be added to the pw_gecos field with
	 <literal>db_gecos: cygwin</literal>.
	 See <xref linkend="ntsec-mapping-nsswitch-gecos"></xref>.</seg>
  </seglistitem>
<!--
  <seglistitem>
    <seg><literal>cygwinFstab</literal></seg>
    <seg>yada yada yada</seg>
  </seglistitem>
  <seglistitem>
    <seg><literal>cygwinUnixUid</literal></seg>
    <seg>See <xref linkend="ntsec-mapping-nfs"></xref> and
	 <xref linkend="ntsec-mapping-samba"></xref>.</seg>
  </seglistitem>

<para>
The group attributes utilized by Cygwin are:
</para>

</segmentedlist>
  <seglistitem>
    <seg><literal>cygwinUnixGid</literal></seg>
    <seg>See <xref linkend="ntsec-mapping-nfs"></xref> and
	 <xref linkend="ntsec-mapping-samba"></xref>.</seg>
  </seglistitem>
</segmentedlist>
-->
</segmentedlist>

</sect4>

<sect4 id="ntsec-mapping-nsswitch-posix"><title id="ntsec-mapping-nsswitch-posix.title">The <literal>unix</literal> schema</title>

<para>
The <literal>unix</literal> schema utilizes the 
<literal>posixAccount</literal> attribute extension.  This is one of two
schema extensions which are connected to AD accounts, available by default
starting with Windows Server 2003 R2.  They are usually
<emphasis role='bold'>not set</emphasis>, unless used by the Active Directory
<literal>Server for NIS</literal> feature (deprecated since Server 2012 R2).

Two schemata are interesting for Cygwin, <literal>posixAccount</literal>,
connected to user accounts, and <literal>posixGroup</literal>, connected
to group accounts.  Both follow the description of RFC 2307,
<ulink url="https://tools.ietf.org/html/rfc2307">an Approach for Using LDAP as
a Network Information Service</ulink>.
The user attributes utilized by Cygwin are:
</para>

<segmentedlist><?dbhtml list-presentation="table"?>
  <seglistitem>
    <seg><literal>unixHomeDirectory</literal></seg>
    <seg>Used as Cygwin home directory with <literal>db_home: unix</literal>.
	 See <xref linkend="ntsec-mapping-nsswitch-home"></xref>.</seg>
  </seglistitem>
  <seglistitem>
    <seg><literal>loginShell</literal></seg>
    <seg>Used as Cygwin login shell with <literal>db_shell: unix</literal>.
	 See <xref linkend="ntsec-mapping-nsswitch-shell"></xref>.</seg>
  </seglistitem>
  <seglistitem>
    <seg><literal>gecos</literal></seg>
    <seg>Content will be added to the pw_gecos field with
	 <literal>db_gecos: unix</literal>.
	 See <xref linkend="ntsec-mapping-nsswitch-gecos"></xref>.</seg>
  </seglistitem>
  <seglistitem>
    <seg><literal>uidNumber</literal></seg>
    <seg>See <xref linkend="ntsec-mapping-nfs"></xref> and
	 <xref linkend="ntsec-mapping-samba"></xref>.</seg>
  </seglistitem>
</segmentedlist>

<para>
The group attributes utilized by Cygwin are:
</para>

<segmentedlist><?dbhtml list-presentation="table"?>
  <seglistitem>
    <seg><literal>gidNumber</literal></seg>
    <seg>See <xref linkend="ntsec-mapping-nfs"></xref> and
	 <xref linkend="ntsec-mapping-samba"></xref>.</seg>
  </seglistitem>
</segmentedlist>

<para>
Apart from power shell scripting or inventing new CLI tools, these attributes
can be changed using the <literal>Attribute Editor</literal> tab in the user
properties dialog of the <literal>Active Directory Users and Computers</literal>
MMC snap-in.  Alternatively, if the <literal>Server for NIS</literal>
administration feature has been installed, there will be a
<literal>UNIX Attributes</literal> tab which contains the required fields,
except for the gecos field.  Last resort is <command>ADSI Edit</command>.
</para>

</sect4>

<sect4 id="ntsec-mapping-nsswitch-desc"><title id="ntsec-mapping-nsswitch-desc.title">The <literal>desc</literal> schema</title>

<para>
When using user accounts from the local account database, the SAM, there
are only a very limited number of settings available.  In contrast to
Active Directory there's no way to add fields to a user's entry.  You have
to make do with the fields available.  The method to utilize the
<literal>description</literal> field has been mainly introduced for those
accounts, usually the only ones a home user has.  However, for symmetry,
and because there may be a reason to use this in an AD environment, this
schema is also supported for AD users.
</para>

<note>
<para>
The presentation of local user account settings on Windows is confusing,
to say the least.  The <literal>description</literal> field is not visible at
all in the user settings available via the <literal>User Accounts</literal>
control settings.  And while it's called <literal>Description</literal> in the
<literal>Local Users and Groups</literal> MMC snap-in (available, for instance,
via the <literal>Computer Management</literal> GUI), in the command
line tool <command>net user</command> the same field is called
<literal>comment</literal>.  The latter is especially confusing for
AD admins, because the <literal>comment</literal> attribute in AD is called
<literal>usercomment</literal> on the command line.  Confused?  Never mind,
you're not the only one...
</para>
</note>

<para>
Fortunately you can utilize the <literal>description</literal> field even if
you're running a "home edition" of Windows, by using the command line.  The
<command>net user</command> command allows to set all values in the SAM, even
if the GUI is crippled.
</para>

<para>
A Cygwin SAM comment entry looks like this:
</para>

<screen>
&lt;cygwin key="value" key="value" [...] /&gt;
</screen>

<para>
The supported keys are:
</para>

<segmentedlist><?dbhtml list-presentation="table"?>
  <seglistitem>
    <seg><literal>home="value"</literal></seg>
    <seg>Sets the Cygwin home dir to value.</seg>
  </seglistitem>
  <seglistitem>
    <seg><literal>shell="value"</literal></seg>
    <seg>Sets the Cygwin login shell to value.</seg>
  </seglistitem>
  <seglistitem>
    <seg><literal>gecos="value"</literal></seg>
    <seg>Adds the string value to the user's gecos field.</seg>
  </seglistitem>
</segmentedlist>

<para>
The next two settings are only supported for SAM accounts.
</para>

<segmentedlist><?dbhtml list-presentation="table"?>
  <seglistitem>
    <seg><literal>group="value"</literal></seg>
    <seg>Sets the Cygwin primary group of the account to value, provided that
    	 the user <emphasis>is</emphasis> already a member of that group.
	 This allows to override the default <literal>None</literal> primary
	 group for local accounts.  One nice idea here is, for instance,
	 group="Users".</seg>
  </seglistitem>
  <seglistitem>
    <seg><literal>unix="value"</literal></seg>
    <seg>Sets the NFS/Samba uid of the user to the decimal value.
         See <xref linkend="ntsec-mapping-nfs"></xref> and
	 <xref linkend="ntsec-mapping-samba"></xref>.</seg>
  </seglistitem>
</segmentedlist>

<para>
The &lt;cygwin .../&gt; string can start at any point in the comment, but
you have to follow the rules:
</para>

<itemizedlist spacing="compact">
<listitem>
It starts with "&lt;cygwin " and ends with "/&gt;".
</listitem>
<listitem>
The "cygwin" string and the key names have to be lowercase.
</listitem>
<listitem>
No spaces between key and "value", just the equal sign.
</listitem>
<listitem>
The value must be placed within double quotes and it must not contain a double
quote itself.  The double quotes are required for the decimal values as well!
</listitem>
</itemizedlist>

<note>
<para>
There's also a length restriction imposed by Windows.  The
<literal>description</literal> entry has a maximum length of 1023 characters.
</para>
</note>

<para>
CMD example:
</para>

<screen>
net user corinna /comment:"&lt;cygwin home=\"/home/foo\"/&gt;"
</screen>

<para>
Bash example (use single quotes):
</para>

<screen>
net user corinna /comment:'&lt;cygwin home="/home/foo"/&gt;'
</screen>

<para>
For changing group comments, use the `net localgroup' command.  The supported
key/value pair for SAM groups are:
</para>

<segmentedlist><?dbhtml list-presentation="table"?>
  <seglistitem>
    <seg><literal>unix="value"</literal></seg>
    <seg>Sets the NFS/Samba gid of the group to the decimal value.
         See <xref linkend="ntsec-mapping-nfs"></xref> and
	 <xref linkend="ntsec-mapping-samba"></xref>.</seg>
  </seglistitem>
</segmentedlist>

</sect4>

</sect3>

<sect3 id="ntsec-mapping-nfs"><title id="ntsec-mapping-nfs.title">NFS account mapping</title>

<para>
Microsoft's NFS client does not map the uid/gid values on the NFS shares
to SIDs.  There's no such thing as a (fake) security descriptor returned
to the application.  Rather, via an undocumented API an application can
fetch <ulink url="https://tools.ietf.org/html/rfc1813">RFC 1813</ulink>
compatible NFSv3 stat information from the share.  This is what Cygwin is
using to show stat information for files on NFS shares.
</para>

<para>
The problem is, while all other information in this stat record, like
timestamps, file size etc., can be used by Cygwin, Cygwin had no way to
map the values of the st_uid and st_gid members to a Windows SID for a
long time.  So it just faked the file owner info and claimed that it's
you.
</para>

<para>
However, SFU has, over time, developed multiple methods to map UNIX
uid/gid values on NFS shares to Windows SIDs.  You'll find the full
documentation of the mapping methods in
<ulink url="http://blogs.technet.com/b/filecab/archive/2012/10/09/nfs-identity-mapping-in-windows-server-2012.aspx">NFS Identity Mapping in Windows Server 2012</ulink>
</para>

<para>
Cygwin now utilizes the
<ulink url="https://tools.ietf.org/html/rfc2307">RFC 2307</ulink>
mapping for this purpose.  This is most of the time provided by an AD domain,
but it could also be a standalone LDAP mapping server.  Per
<ulink url="https://tools.ietf.org/html/rfc2307">RFC 2307</ulink>, the uid is
in the attribute <literal>uidNumber</literal>.  For groups, the gid is in the
<literal>gidNumber</literal> attribute.
See <xref linkend="ntsec-mapping-nsswitch-posix"></xref>.
</para>

<para>
When Cygwin stat()s files on an NFS share, it asks the mapping server via
LDAP in two different ways, depending on the role of the mapping server.
</para>

<itemizedlist spacing="compact">

<listitem>
If the server is an AD domain controller, it asks for an account with
<literal>uidNumber</literal> attribute == <literal>st_uid</literal> field of
the stat record returned by NFS.  If an account matches, AD returns the
Windows SID, so we have an immediate mapping from UNIX uid to a Windows SID,
if the user account has a valid <literal>uidNumber</literal> attribute.  For
groups, the method is the same, just that Cygwin asks for a group with
<literal>gidNumber</literal> attribute == <literal>st_gid</literal> field of the
stat record.
</listitem>

<listitem>
If the server is a standalone LDAP mapping server Cygwin asks for the
same <literal>uidNumber</literal>/<literal>gidNumber</literal> attributes, but
it can't expect that the LDAP server knows anything about Windows SIDs.
Rather, the mapping server returns the account name.  Cygwin then asks the
DC for an account with this name, and if that succeeds, we have a mapping
between UNIX uid/gid and Windows SIDs.
</listitem>

</itemizedlist>

<para>
The mapping will be cached for the lifetime of the process, and inherited
by child processes.
</para>

</sect3>

<sect3 id="ntsec-mapping-samba"><title id="ntsec-mapping-samba.title">Samba account mapping</title>

<para>
A fully set up Samba file server with domain integration is running winbindd to
map Windows SIDs to artificially created UNIX uids and gids, and this mapping is
transparent within the domain, so Cygwin doesn't have to do anything special.
</para>

<para>
However, setting up winbindd isn't for everybody, and it fails to map
Windows accounts to already existing UNIX users or groups.  In contrast
to NFS, Samba returns security descriptors, but unmapped UNIX accounts
get special SIDs:
</para>

<itemizedlist spacing="compact">

<listitem>
A UNIX user account with uid X is mapped to the Windows SID S-1-22-1-X.
</listitem>

<listitem>
A UNIX group account with gid X is mapped to SID S-1-22-2-X.
</listitem>

</itemizedlist>

<para>
As you can see, even though we have SIDs, they just reflect the actual
uid/gid values on the UNIX box in the RID value.  It's only marginally
different from the NFS method, so why not just use the same method as
for NFS?
</para>

<para>
That's what Cygwin will do.  If it encounters a S-1-22-x-y SID, it
will perform the same
<ulink url="https://tools.ietf.org/html/rfc2307">RFC 2307</ulink>
mapping as for NFS shares.
</para>

<para>
For home users without any Windows domain or LDAP server per
<ulink url="https://tools.ietf.org/html/rfc2307">RFC 2307</ulink>,
but with a Linux machine running Samba, just add this information to
your SAM account.  Assuming the uid of your Linux user account is 505
and the gid of your primary group is, say, 100, just add the values to
your SAM user and group accounts.  The following example assumes you
didn't already add something else to the comment field.
</para>

<para>
To your user's SAM comment (remember: called <literal>Description</literal>
in the GUI),
add:
</para>

<screen>
  &lt;cygwin group="Users" unix="505"/&gt;
</screen>

<para>
To the <literal>Users</literal> group SAM comment add:
</para>

<screen>
  &lt;cygwin unix="100"/&gt;
</screen>

<para>
This should be sufficient to work on your Samba share and to see
all files owned by your Linux user account as your files.
</para>

</sect3>

</sect2>

<sect2 id="ntsec-files"><title id="ntsec-files.title">File permissions</title>

<para>On NTFS and if the <literal>noacl</literal> mount option is not
specified for a mount point, Cygwin sets file permissions as on POSIX
systems.  Basically this is done by defining a Security Descriptor with the
matching owner and group SIDs, and a DACL which contains ACEs for the owner,
the group and for "Everyone", which represents what POSIX calls "others".</para>

<para>There's just one problem when trying to map the POSIX permission model
onto the Windows permission model.</para>

<para>There's a leak in the definition of a "correct" ACL which disallows a
certain POSIX permission setting.  The official documentation explains in short
the following:</para>

<itemizedlist spacing="compact">
<listitem><para>The requested permissions are checked against all
ACEs of the user as well as all groups the user is member of.  The
permissions given in these user and groups access allowed ACEs are
accumulated and the resulting set is the set of permissions of that
user given for that object.</para></listitem>

<listitem><para>The order of ACEs is important. The system reads them in
sequence until either any single requested permission is denied or all
requested permissions are granted.  Reading stops when this condition is
met.  Later ACEs are not taken into account.</para></listitem>

<listitem><para>All access denied ACEs <emphasis
role='bold'>should</emphasis> precede any access allowed ACE.  ACLs
following this rule are called "canonical".</para></listitem>
</itemizedlist>

<para>Note that the last rule is a preference or a definition of
correctness.  It's not an absolute requirement.  All Windows kernels
will correctly deal with the ACL regardless of the order of allow and
deny ACEs.  The second rule is not modified to get the ACEs in the
preferred order.</para>

<para>Unfortunately the security tab in the file properties dialog of
the Windows Explorer insists to rearrange the order of the ACEs to
canonical order before you can read them. Thank God, the sort order
remains unchanged if one presses the Cancel button.  But don't even
<emphasis role='bold'>think</emphasis> of pressing OK...</para>

<para>Canonical ACLs are unable to reflect each possible combination
of POSIX permissions. Example:</para>

<screen>
rw-r-xrw-
</screen>

<para>Ok, so here's the first try to create a matching ACL, assuming
the Windows permissions only have three bits, as their POSIX counterpart:
</para>

<screen>
UserAllow:   110
GroupAllow:  101
OthersAllow: 110
</screen>

<para>Hmm, because of the accumulation of allow rights the user may
execute because the group may execute.</para>

<para>Second try:</para>

<screen>
UserDeny:    001
GroupAllow:  101
OthersAllow: 110
</screen>

<para>Now the user may read and write but not execute. Better? No!
Unfortunately the group may write now because others may write.</para>

<para>Third try:</para>

<screen>
UserDeny:    001
GroupDeny:   010
GroupAllow:  001
OthersAllow: 110
</screen>

<para>Now the group may not write as intended but unfortunately the user may
not write anymore, either. How should this problem be solved? According to
the canonical order a UserAllow has to follow the GroupDeny but it's
easy to see that this can never be solved that way.</para>

<para>The only chance:</para>

<screen>
UserDeny:    001
UserAllow:   010
GroupDeny:   010
GroupAllow:  001
OthersAllow: 110
</screen>

<para>Again: This works on all existing versions of Windows NT, at the
time of writing from at least Windows XP up to Server 2012 R2.  Only
the GUIs aren't able (or willing) to deal with that order.</para>

</sect2>

<sect2 id="ntsec-setuid-overview"><title id="ntsec-setuid-overview.title">Switching the user context</title>

<para>Since Windows XP, Windows users have been accustomed to the
"Switch User" feature, which switches the entire desktop to another user
while leaving the original user's desktop "suspended".  Another Windows
feature is the "Run as..." context menu entry, which allows you to start
an application using another user account when right-clicking on applications
and shortcuts.</para>

<para>On POSIX systems, this operation can be performed by processes
running under the privileged user accounts (usually the "root" user
account) on a per-process basis.  This is called "switching the user
context" for that process, and is performed using the POSIX
<command>setuid</command> and <command>seteuid</command> system
calls.</para>

<para>While this sort of feature is available on Windows as well,
Windows does not support the concept of these calls in a simple fashion.
Switching the user context in Windows is generally a tricky process with
lots of "behind the scenes" magic involved.</para>

<para>Windows uses so-called `access tokens' to identify a user and its
permissions.  Usually the access token is created at logon time and then
it's attached to the starting process.  Every new process within a session
inherits the access token from its parent process.  Every thread can
get its own access token, which allows, for instance, to define threads
with restricted permissions.</para>

<sect3 id="ntsec-logonuser"><title id="ntsec-logonuser.title">Switching the user context with password authentication</title>

<para>To switch the user context, the process has to request such an access
token for the new user.  This is typically done by calling the Win32 API
function <command>LogonUser</command> with the user name and the user's
cleartext password as arguments.  If the user exists and the password was
specified correctly, the access token is returned and either used in
<command>ImpersonateLoggedOnUser</command> to change the user context of
the current thread, or in <command>CreateProcessAsUser</command> to
change the user context of a spawned child process.</para>

<para>Later versions of Windows define new functions in this context and
there are also functions to manipulate existing access tokens (usually
only to restrict them).  Windows Vista also adds subtokens which are
attached to other access tokens which plays an important role in the UAC
(User Access Control) facility of Vista and later.  However, none of
these extensions to the original concept are important for this
documentation.</para>

<para>Back to this logon with password, how can this be used to
implement <command>set(e)uid</command>?  Well, it requires modification
of the calling application.  Two Cygwin functions have been introduced
to support porting <command>setuid</command> applications which only
require login with passwords.  You only give Cygwin the right access
token and then you can call <command>seteuid</command> or
<command>setuid</command> as usual in POSIX applications.  Porting such
a <command>setuid</command> application is illustrated by a short
example:</para>

<screen>
<![CDATA[
/* First include all needed cygwin stuff. */
#ifdef __CYGWIN__
#include <windows.h>
#include <sys/cygwin.h>
#endif

[...]

  struct passwd *user_pwd_entry = getpwnam (username);
  char *cleartext_password = getpass ("Password:");

[...]

#ifdef __CYGWIN__
  /* Patch the typical password test. */
  {
    HANDLE token;

    /* Try to get the access token from Windows. */
    token = cygwin_logon_user (user_pwd_entry, cleartext_password);
    if (token == INVALID_HANDLE_VALUE)
       error_exit;
    /* Inform Cygwin about the new impersonation token. */
    cygwin_set_impersonation_token (token);
    /* Cygwin is now able, to switch to that user context by setuid or seteuid calls. */
  }
#else
    /* Use standard method on non-Cygwin systems. */
    hashed_password = crypt (cleartext_password, salt);
    if (!user_pwd_entry ||
        strcmp (hashed_password, user_pwd_entry->pw_passwd))
      error_exit;
#endif /* CYGWIN */

[...]

  /* Everything else remains the same! */

  setegid (user_pwd_entry->pw_gid);
  seteuid (user_pwd_entry->pw_uid);
  execl ("/bin/sh", ...);
]]>

</screen>

</sect3>

<sect3 id="ntsec-nopasswd1"><title id="ntsec-nopasswd1.title">Switching the user context without password, Method 1: Create a token from scratch</title>

<para>An unfortunate aspect of the implementation of
<command>set(e)uid</command> is the fact that the calling process
requires the password of the user to which to switch.  Applications such as
<command>sshd</command> wishing to switch the user context after a
successful public key authentication, or the <command>cron</command>
application which, again, wants to switch the user without any authentication
are stuck here.  But there are other ways to get new user tokens.</para>

<para>One way is just to create a user token from scratch.  This is
accomplished by using an (officially undocumented) function on the NT
function level.  The NT function level is used to implement the Win32
level, and, as such is closer to the kernel than the Win32 level.  The
function of interest, <command>NtCreateToken</command>, allows you to
specify user, groups, permissions and almost everything you need to
create a user token, without the need to specify the user password.  The
only restriction for using this function is that the calling process
needs the "Create a token object" user right, which only the SYSTEM user
account has by default, and which is considered the most dangerous right
a user can have on Windows systems.</para>

<para>That sounds good.  We just start the servers which have to switch
the user context (<command>sshd</command>, <command>inetd</command>,
<command>cron</command>, ...) as Windows services under the SYSTEM
(or LocalSystem in the GUI) account and everything just works.
Unfortunately that's too simple.  Using <command>NtCreateToken</command>
has a few drawbacks.</para>

<para>First of all, beginning with Windows Server 2003,
the permission "Create a token object" gets explicitly removed from
the SYSTEM user's access token, when starting services under that
account.  That requires us to create a new account with this specific
permission just to run this kind of services.  But that's a minor
problem.</para>

<para>A more important problem is that using <command>NtCreateToken</command>
is not sufficient to create a new logon session for the new user.  What
does that mean?  Every logon usually creates a new logon session.
A logon session has a couple of attributes which are unique to the
session.  One of these attributes is the fact, that Windows functions
identify the user domain and user name not by the SID of the access
token owner, but only by the logon session the process is running under.</para>

<para>This has the following unfortunate consequence.  Consider a
service started under the SYSTEM account (up to Windows XP) switches the
user context to DOMAIN\my_user using a token created directly by calling
the <command>NtCreateToken</command> function.  A process running under
this new access token might want to know under which user account it's
running.  The corresponding SID is returned correctly, for instance
S-1-5-21-1234-5678-9012-77777.  However, if the same process asks the OS
for the user name of this SID something wierd happens.  For instance,
the <command>LookupAccountSid</command> function will not return
"DOMAIN\my_user", but "NT AUTHORITY\SYSTEM" as the user name.</para>

<para>You might ask "So what?"  After all, this only <emphasis
role='bold'>looks</emphasis> bad, but functionality and permission-wise
everything should be ok.  And Cygwin knows about this shortcoming so it
will return the correct Cygwin username when asked.  Unfortunately this
is more complicated.  Some native, non-Cygwin Windows applications will
misbehave badly in this situation.  A well-known example are certain versions
of Visual-C++.</para>

<para>Last but not least, you don't have the usual comfortable access
to network shares.  The reason is that the token has been created
without knowing the password.  The password are your credentials
necessary for network access.  Thus, if you logon with a password, the
password is stored hidden as "token credentials" within the access token
and used as default logon to access network resources.  Since these
credentials are missing from the token created with
<command>NtCreateToken</command>, you only can access network shares
from the new user's process tree by using explicit authentication, on
the command line for instance:</para>

<screen>
bash$ net use '\\server\share' /user:DOMAIN\my_user my_users_password
</screen>

<para>Note that, on some systems, you can't even define a drive letter
to access the share, and under some circumstances the drive letter you
choose collides with a drive letter already used in another session.
Therefore it's better to get used to accessing these shares using the UNC
path as in</para>

<screen>
bash$ grep foo //server/share/foofile
</screen>

</sect3>

<sect3 id="ntsec-nopasswd2"><title id="ntsec-nopasswd2.title">Switching the user context without password, Method 2: LSA authentication package</title>

<para>We're looking for another way to switch the user context without
having to provide the password.  Another technique is to create an
LSA authentication package.  LSA is an acronym for "Local Security Authority"
which is a protected part of the operating system which only allows changes
to become active when rebooting the system after the change.  Also, as soon as
the LSA encounters serious problems (for instance, one of the protected
LSA processes died), it triggers a system reboot.  LSA is the part of
the OS which cares for the user logons and which also creates logon
sessions.</para>

<para>An LSA authentication package is a DLL which has to be installed
as part of the LSA.  This is done by tweaking a special registry key.
Cygwin provides such an authentication package.  It has to be installed
and the machine has to be rebooted to activate it.  This is the job of the
shell script <filename>/usr/bin/cyglsa-config</filename> which is part of
the Cygwin package.</para>

<para>After running <filename>/usr/bin/cyglsa-config</filename> and
rebooting the system, the LSA authentication package is used by Cygwin
when <command>set(e)uid</command> is called by an application.  The
created access token using this method has its own logon session.</para>

<para>This method has two advantages over the <command>NtCreateToken</command>
method.</para>

<para>The very special and very dangerous "Create a token object" user
right is not required by a user using this method.  Other privileged
user rights are still necessary, especially the "Act as part of the
operating system" right, but that's just business as usual.</para>

<para>The user is correctly identified, even by delicate native applications
which choke on that using the <command>NtCreateToken</command> method.</para>

<para>Disadvantages?  Yes, sure, this is Windows.  The access token
created using LSA authentication still lacks the credentials for network
access.  After all, there still hasn't been any password authentication
involved.  The requirement to reboot after every installation or
deinstallation of the cygwin LSA authentication DLL is just a minor
inconvenience compared to that...</para>

<para>Nevertheless, this is already a lot better than what we get by
using <command>NtCreateToken</command>, isn't it?</para>

</sect3>

<sect3 id="ntsec-nopasswd3"><title id="ntsec-nopasswd3.title">Switching the user context without password, Method 3: With password</title>

<para>Ok, so we have solved almost any problem, except for the network
access problem.  Not being able to access network shares without
having to specify a cleartext password on the command line or in a 
script is a harsh problem for automated logons for testing purposes
and similar stuff.</para>

<para>Fortunately there is a solution, but it has its own drawbacks.
But, first things first, how does it work?  The title of this section
says it all.  Instead of trying to logon without password, we just logon
with password.  The password gets stored two-way encrypted in a hidden,
obfuscated area of the registry, the LSA private registry area.  This
part of the registry contains, for instance, the passwords of the Windows
services which run under some non-default user account.</para>

<para>So what we do is to utilize this registry area for the purpose of
<command>set(e)uid</command>.  The Cygwin command <command><link
linkend="passwd">passwd</link> -R</command> allows a user to specify
his/her password for storage in this registry area.  When this user
tries to login using ssh with public key authentication, Cygwin's
<command>set(e)uid</command> examines the LSA private registry area and
searches for a Cygwin specific key which contains the password.  If it
finds it, it calls <command>LogonUser</command> under the hood, using
this password.  If that works, <command>LogonUser</command> returns an
access token with all credentials necessary for network access.</para>

<para>For good measure, and since this way to implement
<command>set(e)uid</command> is not only used by Cygwin but also by
Microsoft's SFU (Services for Unix), we also look for a key stored by
SFU (using the SFU command <command>regpwd</command>) and use that if it's
available.</para>

<para>We got it.  A full access token with its own logon session, with
all network credentials.  Hmm, that's heaven...</para>

<para>Back on earth, what about the drawbacks?</para>

<para>First, adding a password to the LSA private registry area
requires administrative access.  So calling <command>passwd -R</command>
as a normal user will fail!  Cygwin provides a workaround for
this.  If <command>cygserver</command> is started as a service running
under the SYSTEM account (which is the default way to run
<command>cygserver</command>) you can use <command>passwd -R</command>
as normal, non-privileged user as well.</para>

<para>Second, as aforementioned, the password is two-way encrypted in a
hidden, obfuscated registry area.  Only SYSTEM has access to this area
for listing purposes, so, even as an administrator, you can't examine
this area with regedit.  Right?  No.  Every administrator can start
regedit as SYSTEM user:</para>

<screen>
bash$ date
Tue Dec  2 16:28:03 CET 2008
bash$ at 16:29 /interactive regedit.exe
</screen>

<para>Additionally, if an administrator knows under which name
the private key is stored (which is well-known since the algorithms
used to create the Cygwin and SFU keys are no secret), every administrator
can access the password of all keys stored this way in the registry.</para>

<para>Conclusion: If your system is used exclusively by you, and if
you're also the only administrator of your system, and if your system is
adequately locked down to prevent malicious access, you can safely use
this method.  If your machine is part of a network which has
dedicated administrators, and you're not one of these administrators,
but you (think you) can trust your administrators, you can probably
safely use this method.</para>

<para>In all other cases, don't use this method.  You have been warned.</para>

</sect3>

<sect3 id="ntsec-setuid-impl"><title id="ntsec-setuid-impl.title">Switching the user context, how does it all fit together?</title>

<para>Now we learned about four different ways to switch the user
context using the <command>set(e)uid</command> system call, but
how does <command>set(e)uid</command> really work?  Which method does it
use now?</para>

<para>The answer is, all four of them.  So here's a brief overview
what <command>set(e)uid</command> does under the hood:</para>

<itemizedlist>
<listitem>
<para>When <command>set(e)uid</command> is called, it tests if the
user context had been switched by an earlier call already, and if the
new user account is the privileged user account under which the process
had been started originally.  If so, it just switches to the original
access token of the process it had been started with.</para>
</listitem>

<listitem>
<para>
Next, it tests if an access token has been stored by an earlier call
to <command>cygwin_set_impersonation_token</command>.  If so, it tests
if that token matches the requested user account.  If so, the stored
token is used for the user context switch.</para>

<para>
If not, there's no predefined token which can just be used for
the user context switch, so we have to create a new token.  The order
is as follows.</para>
</listitem>

<listitem>
<para>Check if the user has stored the logon password in the LSA
private registry area, either under a Cygwin key, or under a SFU key.
If so, use this to call <command>LogonUser</command>.  If this
succeeds, we use the resulting token for the user context switch.</para>
</listitem>

<listitem>
<para>Otherwise, check if the Cygwin-specifc LSA authentication package
has been installed and is functional.  If so, use the appropriate LSA
calls to communicate with the Cygwin LSA authentication package and
use the returned token.</para>
</listitem>

<listitem>
<para>Last chance, try to use the <command>NtCreateToken</command> call
to create a token.  If that works, use this token.</para>
</listitem>

<listitem>
<para>If all of the above fails, our process has insufficient privileges
to switch the user context at all, so <command>set(e)uid</command>
fails and returns -1, setting errno to EPERM.</para>
</listitem>
</itemizedlist>

</sect3>

</sect2>

</sect1>