1 /*++
2 
3 Copyright (c) 1996  Microsoft Corporation
4 
5 Module Name:
6 
7     acctname.c
8 
9 Abstract:
10 
11     This module illustrates how to obtain user and group names
12     Associated with accounts that have been renamed or localized. This
13     sample works by building a Sid value and then looking up the name
14     associated with that Sid value.
15 
16     For example, in a default English install of Windows NT, the local
17     administrators group is called "Administrators." In a default German
18     install of Windows NT, the local administrators group is called
19     "Administratoren." This can lead to problems when managing users
20     and groups if the proper steps are not taken.
21 
22     The following relative ID values are an index into an account
23     database that represents a specific user or group. In DOMAIN_USER_
24     and DOMAIN_GROUP_ cases, the relative ID is appended to the account
25     domain Sid from the machine of interest. In the DOMAIN_ALIAS_ case,
26     the relative ID is appended to a well-known Sid representing the
27     BUILTIN domain that is consistent across machines.
28 
29     // Well-known users and groups...
30 
31     #define DOMAIN_USER_RID_ADMIN          (0x000001F4L)
32     #define DOMAIN_USER_RID_GUEST          (0x000001F5L)
33 
34     #define DOMAIN_GROUP_RID_ADMINS        (0x00000200L)
35     #define DOMAIN_GROUP_RID_USERS         (0x00000201L)
36     #define DOMAIN_GROUP_RID_GUESTS        (0x00000202L)
37 
38     // well-known aliases ...
39 
40     #define DOMAIN_ALIAS_RID_ADMINS        (0x00000220L)
41     #define DOMAIN_ALIAS_RID_USERS         (0x00000221L)
42     #define DOMAIN_ALIAS_RID_GUESTS        (0x00000222L)
43     #define DOMAIN_ALIAS_RID_POWER_USERS   (0x00000223L)
44     #define DOMAIN_ALIAS_RID_ACCOUNT_OPS   (0x00000224L)
45     #define DOMAIN_ALIAS_RID_SYSTEM_OPS    (0x00000225L)
46     #define DOMAIN_ALIAS_RID_PRINT_OPS     (0x00000226L)
47     #define DOMAIN_ALIAS_RID_BACKUP_OPS    (0x00000227L)
48     #define DOMAIN_ALIAS_RID_REPLICATOR    (0x00000228L)
49 
50     The following section is for informational purposes and is useful
51     for visualizing Sid values:
52 
53     // Universal well-known SIDs:
54     //
55     //     Null SID                     S-1-0-0
56     //     World                        S-1-1-0
57     //     Local                        S-1-2-0
58     //     Creator Owner ID             S-1-3-0
59     //     Creator Group ID             S-1-3-1
60     //     Creator Owner Server ID      S-1-3-2
61     //     Creator Group Server ID      S-1-3-3
62     //
63     //     (Non-unique IDs)             S-1-4
64 
65     #define SECURITY_NULL_SID_AUTHORITY       {0,0,0,0,0,0}
66     #define SECURITY_WORLD_SID_AUTHORITY      {0,0,0,0,0,1}
67     #define SECURITY_LOCAL_SID_AUTHORITY      {0,0,0,0,0,2}
68     #define SECURITY_CREATOR_SID_AUTHORITY    {0,0,0,0,0,3}
69     #define SECURITY_NON_UNIQUE_AUTHORITY     {0,0,0,0,0,4}
70 
71     #define SECURITY_NULL_RID                 (0x00000000L)
72     #define SECURITY_WORLD_RID                (0x00000000L)
73     #define SECURITY_LOCAL_RID                (0X00000000L)
74 
75     #define SECURITY_CREATOR_OWNER_RID        (0x00000000L)
76     #define SECURITY_CREATOR_GROUP_RID        (0x00000001L)
77 
78     #define SECURITY_CREATOR_OWNER_SERVER_RID (0x00000002L)
79     #define SECURITY_CREATOR_GROUP_SERVER_RID (0x00000003L)
80 
81     // NT well-known SIDs:
82     //
83     //     NT Authority          S-1-5
84     //     Dialup                S-1-5-1
85     //
86     //     Network               S-1-5-2
87     //     Batch                 S-1-5-3
88     //     Interactive           S-1-5-4
89     //     Service               S-1-5-6
90     //     AnonymousLogon        S-1-5-7       (aka null logon session)
91     //     Proxy                 S-1-5-8
92     //     ServerLogon           S-1-5-8       (aka domain controller
93     //                                            account)
94     //
95     //     (Logon IDs)           S-1-5-5-X-Y
96     //
97     //     (NT non-unique IDs)   S-1-5-0x15-...
98     //
99     //     (Built-in domain)     S-1-5-0x20
100 
101     #define SECURITY_NT_AUTHORITY           {0,0,0,0,0,5}   // ntifs
102 
103     #define SECURITY_DIALUP_RID             (0x00000001L)
104     #define SECURITY_NETWORK_RID            (0x00000002L)
105     #define SECURITY_BATCH_RID              (0x00000003L)
106     #define SECURITY_INTERACTIVE_RID        (0x00000004L)
107     #define SECURITY_SERVICE_RID            (0x00000006L)
108     #define SECURITY_ANONYMOUS_LOGON_RID    (0x00000007L)
109     #define SECURITY_PROXY_RID              (0x00000008L)
110     #define SECURITY_SERVER_LOGON_RID       (0x00000009L)
111 
112     #define SECURITY_LOGON_IDS_RID          (0x00000005L)
113     #define SECURITY_LOGON_IDS_RID_COUNT    (3L)
114 
115     #define SECURITY_LOCAL_SYSTEM_RID       (0x00000012L)
116 
117     #define SECURITY_NT_NON_UNIQUE          (0x00000015L)
118 
119     #define SECURITY_BUILTIN_DOMAIN_RID     (0x00000020L)
120 
121     If no Command line arguments are specified, names are looked up
122     on the local machine. If argv[1] is present, the lookup occurs
123     on the specified machine.
124 
125     For example, acctname.exe \\winbase will look up names from the
126     machine named \\winbase. If \\winbase is a default German install
127     of Windows NT, names will appear in German locale.
128 
129 Author:
130 
131     Scott Field (sfield)    02-Oct-96
132 
133 --*/
134 
135 #include "stdafx.h"
136 #include "lkuprid.h"
137 
138 
139 BOOL
LookupAliasFromRid(LPWSTR TargetComputer,DWORD Rid,LPWSTR Name,PDWORD cchName)140 LookupAliasFromRid(
141     LPWSTR TargetComputer,
142     DWORD Rid,
143     LPWSTR Name,
144     PDWORD cchName
145     )
146 {
147     SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
148     SID_NAME_USE snu;
149     PSID pSid;
150     WCHAR DomainName[DNLEN+1];
151     DWORD cchDomainName = DNLEN;
152     BOOL bSuccess = FALSE;
153 
154     //
155     // Sid is the same regardless of machine, since the well-known
156     // BUILTIN domain is referenced.
157     //
158 
159     if(AllocateAndInitializeSid(
160             &sia,
161             2,
162             SECURITY_BUILTIN_DOMAIN_RID,
163             Rid,
164             0, 0, 0, 0, 0, 0,
165             &pSid
166             )) {
167 
168         bSuccess = LookupAccountSidW(
169                 TargetComputer,
170                 pSid,
171                 Name,
172                 cchName,
173                 DomainName,
174                 &cchDomainName,
175                 &snu
176                 );
177 
178         FreeSid(pSid);
179     }
180 
181     return bSuccess;
182 }
183 
184 
185 BOOL
LookupUserGroupFromRid(LPWSTR TargetComputer,DWORD Rid,LPWSTR Name,PDWORD cchName)186 LookupUserGroupFromRid(
187     LPWSTR TargetComputer,
188     DWORD Rid,
189     LPWSTR Name,
190     PDWORD cchName
191     )
192 {
193     PUSER_MODALS_INFO_2 umi2;
194     NET_API_STATUS nas;
195 
196     UCHAR SubAuthorityCount;
197     PSID pSid;
198     SID_NAME_USE snu;
199 
200     WCHAR DomainName[DNLEN+1];
201     DWORD cchDomainName = DNLEN;
202     BOOL bSuccess = FALSE; // assume failure
203 
204     //
205     // get the account domain Sid on the target machine
206     // note: if you were looking up multiple sids based on the same
207     // account domain, only need to call this once.
208     //
209 
210     nas = NetUserModalsGet(TargetComputer, 2, (LPBYTE *)&umi2);
211 
212     if(nas != NERR_Success) {
213         SetLastError(nas);
214         return FALSE;
215     }
216 
217     SubAuthorityCount = *GetSidSubAuthorityCount
218                         (umi2->usrmod2_domain_id);
219 
220     //
221     // allocate storage for new Sid. account domain Sid + account Rid
222     //
223 
224     pSid = (PSID)HeapAlloc(GetProcessHeap(), 0,
225             GetSidLengthRequired((UCHAR)(SubAuthorityCount + 1)));
226 
227     if(pSid != NULL) {
228 
229         if(InitializeSid(
230                 pSid,
231                 GetSidIdentifierAuthority(umi2->usrmod2_domain_id),
232                 (BYTE)(SubAuthorityCount+1)
233                 )) {
234 
235             DWORD SubAuthIndex = 0;
236 
237             //
238             // copy existing subauthorities from account domain Sid into
239             // new Sid
240             //
241 
242             for( ; SubAuthIndex < SubAuthorityCount ; SubAuthIndex++) {
243                 *GetSidSubAuthority(pSid, SubAuthIndex) =
244                 *GetSidSubAuthority(umi2->usrmod2_domain_id,
245                                     SubAuthIndex);
246             }
247 
248             //
249             // append Rid to new Sid
250             //
251 
252             *GetSidSubAuthority(pSid, SubAuthorityCount) = Rid;
253 
254             bSuccess = LookupAccountSidW(
255                     TargetComputer,
256                     pSid,
257                     Name,
258                     cchName,
259                     DomainName,
260                     &cchDomainName,
261                     &snu
262                     );
263         }
264 
265         HeapFree(GetProcessHeap(), 0, pSid);
266     }
267 
268     NetApiBufferFree(umi2);
269 
270     return bSuccess;
271 }
272