1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS net command
4 * FILE: base/applications/network/net/cmdLocalGroup.c
5 * PURPOSE:
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10 #include "net.h"
11
12
13 static
14 int
CompareInfo(const void * a,const void * b)15 CompareInfo(const void *a,
16 const void *b)
17 {
18 return _wcsicmp(((PLOCALGROUP_INFO_0)a)->lgrpi0_name,
19 ((PLOCALGROUP_INFO_0)b)->lgrpi0_name);
20 }
21
22
23 static
24 NET_API_STATUS
EnumerateLocalGroups(VOID)25 EnumerateLocalGroups(VOID)
26 {
27 PLOCALGROUP_INFO_0 pBuffer = NULL;
28 PSERVER_INFO_100 pServer = NULL;
29 DWORD dwRead = 0, dwTotal = 0;
30 DWORD i;
31 DWORD_PTR ResumeHandle = 0;
32 NET_API_STATUS Status;
33
34
35 Status = NetServerGetInfo(NULL,
36 100,
37 (LPBYTE*)&pServer);
38 if (Status != NERR_Success)
39 return Status;
40
41 ConPuts(StdOut, L"\n");
42 PrintMessageStringV(4405, pServer->sv100_name);
43 ConPuts(StdOut, L"\n");
44 PrintPadding(L'-', 79);
45 ConPuts(StdOut, L"\n");
46
47 NetApiBufferFree(pServer);
48
49 Status = NetLocalGroupEnum(NULL,
50 0,
51 (LPBYTE*)&pBuffer,
52 MAX_PREFERRED_LENGTH,
53 &dwRead,
54 &dwTotal,
55 &ResumeHandle);
56 if (Status != NERR_Success)
57 return Status;
58
59 qsort(pBuffer,
60 dwRead,
61 sizeof(PLOCALGROUP_INFO_0),
62 CompareInfo);
63
64 for (i = 0; i < dwRead; i++)
65 {
66 if (pBuffer[i].lgrpi0_name)
67 ConPrintf(StdOut, L"*%s\n", pBuffer[i].lgrpi0_name);
68 }
69
70 NetApiBufferFree(pBuffer);
71
72 return NERR_Success;
73 }
74
75
76 static
77 NET_API_STATUS
DisplayLocalGroup(LPWSTR lpGroupName)78 DisplayLocalGroup(LPWSTR lpGroupName)
79 {
80 PLOCALGROUP_INFO_1 pGroupInfo = NULL;
81 PLOCALGROUP_MEMBERS_INFO_3 pMembers = NULL;
82 PSERVER_INFO_100 pServer = NULL;
83 LPWSTR *pNames = NULL;
84 DWORD dwRead = 0;
85 DWORD dwTotal = 0;
86 DWORD_PTR ResumeHandle = 0;
87 DWORD i;
88 DWORD len;
89 INT nPaddedLength = 18;
90 NET_API_STATUS Status;
91
92 Status = NetLocalGroupGetInfo(NULL,
93 lpGroupName,
94 1,
95 (LPBYTE*)&pGroupInfo);
96 if (Status != NERR_Success)
97 return Status;
98
99 Status = NetLocalGroupGetMembers(NULL,
100 lpGroupName,
101 3,
102 (LPBYTE*)&pMembers,
103 MAX_PREFERRED_LENGTH,
104 &dwRead,
105 &dwTotal,
106 &ResumeHandle);
107 if (Status != NERR_Success)
108 goto done;
109
110 Status = NetServerGetInfo(NULL,
111 100,
112 (LPBYTE*)&pServer);
113 if (Status != NERR_Success)
114 goto done;
115
116 pNames = RtlAllocateHeap(RtlGetProcessHeap(),
117 HEAP_ZERO_MEMORY,
118 dwRead * sizeof(LPWSTR));
119 if (pNames == NULL)
120 {
121 Status = ERROR_OUTOFMEMORY;
122 goto done;
123 }
124
125 len = wcslen(pServer->sv100_name);
126 for (i = 0; i < dwRead; i++)
127 {
128 if (!wcsncmp(pMembers[i].lgrmi3_domainandname, pServer->sv100_name, len))
129 pNames[i] = &pMembers[i].lgrmi3_domainandname[len + 1];
130 else
131 pNames[i] = pMembers[i].lgrmi3_domainandname;
132 }
133
134 PrintPaddedMessageString(4406, nPaddedLength);
135 ConPrintf(StdOut, L"%s\n", pGroupInfo->lgrpi1_name);
136
137 PrintPaddedMessageString(4407, nPaddedLength);
138 ConPrintf(StdOut, L"%s\n", pGroupInfo->lgrpi1_comment);
139
140 ConPuts(StdOut, L"\n");
141
142 PrintMessageString(4408);
143 ConPuts(StdOut, L"\n");
144
145 PrintPadding(L'-', 79);
146 ConPuts(StdOut, L"\n");
147
148 for (i = 0; i < dwRead; i++)
149 {
150 if (pNames[i])
151 ConPrintf(StdOut, L"%s\n", pNames[i]);
152 }
153
154 done:
155 if (pNames != NULL)
156 RtlFreeHeap(RtlGetProcessHeap(), 0, pNames);
157
158 if (pServer != NULL)
159 NetApiBufferFree(pServer);
160
161 if (pMembers != NULL)
162 NetApiBufferFree(pMembers);
163
164 if (pGroupInfo != NULL)
165 NetApiBufferFree(pGroupInfo);
166
167 return Status;
168 }
169
170
171 INT
cmdLocalGroup(INT argc,WCHAR ** argv)172 cmdLocalGroup(
173 INT argc,
174 WCHAR **argv)
175 {
176 INT i, j;
177 INT result = 0;
178 ULONG dwMemberCount = 0;
179 BOOL bAdd = FALSE;
180 BOOL bDelete = FALSE;
181 #if 0
182 BOOL bDomain = FALSE;
183 #endif
184 LPWSTR lpGroupName = NULL;
185 LPWSTR lpComment = NULL;
186 LPLOCALGROUP_MEMBERS_INFO_3 lpMembers = NULL;
187 LOCALGROUP_INFO_0 Info0;
188 LOCALGROUP_INFO_1 Info1;
189 LOCALGROUP_INFO_1002 Info1002;
190 NET_API_STATUS Status;
191
192 if (argc == 2)
193 {
194 Status = EnumerateLocalGroups();
195 ConPrintf(StdOut, L"Status: %lu\n", Status);
196 return 0;
197 }
198 else if (argc == 3)
199 {
200 Status = DisplayLocalGroup(argv[2]);
201 ConPrintf(StdOut, L"Status: %lu\n", Status);
202 return 0;
203 }
204
205 i = 2;
206 if (argv[i][0] != L'/')
207 {
208 lpGroupName = argv[i];
209 i++;
210 }
211
212 for (j = i; j < argc; j++)
213 {
214 if (argv[j][0] == L'/')
215 break;
216
217 dwMemberCount++;
218 }
219
220 ConPrintf(StdOut, L"Member count: %lu\n", dwMemberCount);
221
222 if (dwMemberCount > 0)
223 {
224 lpMembers = RtlAllocateHeap(RtlGetProcessHeap(),
225 HEAP_ZERO_MEMORY,
226 dwMemberCount * sizeof(LPLOCALGROUP_MEMBERS_INFO_3));
227 if (lpMembers == NULL)
228 return 0;
229 }
230
231 j = 0;
232 for (; i < argc; i++)
233 {
234 if (argv[i][0] == L'/')
235 break;
236
237 lpMembers[j].lgrmi3_domainandname = argv[i];
238 j++;
239 }
240
241 for (; i < argc; i++)
242 {
243 if (_wcsicmp(argv[i], L"/help") == 0)
244 {
245 PrintMessageString(4381);
246 ConPuts(StdOut, L"\n");
247 PrintNetMessage(MSG_LOCALGROUP_SYNTAX);
248 PrintNetMessage(MSG_LOCALGROUP_HELP);
249 return 0;
250 }
251 else if (_wcsicmp(argv[i], L"/add") == 0)
252 {
253 bAdd = TRUE;
254 }
255 else if (_wcsicmp(argv[i], L"/delete") == 0)
256 {
257 bDelete = TRUE;
258 }
259 else if (_wcsnicmp(argv[i], L"/comment:", 9) == 0)
260 {
261 lpComment = &argv[i][9];
262 }
263 else if (_wcsicmp(argv[i], L"/domain") == 0)
264 {
265 ConPuts(StdErr, L"The /DOMAIN option is not supported yet.\n");
266 #if 0
267 bDomain = TRUE;
268 #endif
269 }
270 else
271 {
272 PrintErrorMessage(3506/*, argv[i]*/);
273 result = 1;
274 goto done;
275 }
276 }
277
278 if (lpGroupName == NULL)
279 {
280 result = 1;
281 goto done;
282 }
283
284 if (bAdd && bDelete)
285 {
286 result = 1;
287 goto done;
288 }
289
290 #if 0
291 ConPrintf(StdOut, L"Group:\n %s\n", lpGroupName);
292
293 if (lpMembers != NULL)
294 {
295 ConPuts(StdOut, L"\nMembers:\n");
296 for (i = 0; i < dwMemberCount; i++)
297 ConPrintf(StdOut, L" %s\n", lpMembers[i].lgrmi3_domainandname);
298 }
299
300 if (lpComment != NULL)
301 {
302 ConPrintf(StdOut, L"\nComment:\n %s\n", lpComment);
303 }
304 #endif
305
306 if (lpMembers == NULL)
307 {
308 if (!bAdd && !bDelete && lpComment != NULL)
309 {
310 /* Set group comment */
311 Info1002.lgrpi1002_comment = lpComment;
312 Status = NetLocalGroupSetInfo(NULL,
313 lpGroupName,
314 1002,
315 (LPBYTE)&Info1002,
316 NULL);
317 ConPrintf(StdOut, L"Status: %lu\n", Status);
318 }
319 else if (bAdd && !bDelete)
320 {
321 /* Add the group */
322 if (lpComment == NULL)
323 {
324 Info0.lgrpi0_name = lpGroupName;
325 }
326 else
327 {
328 Info1.lgrpi1_name = lpGroupName;
329 Info1.lgrpi1_comment = lpComment;
330 }
331
332 Status = NetLocalGroupAdd(NULL,
333 (lpComment == NULL) ? 0 : 1,
334 (lpComment == NULL) ? (LPBYTE)&Info0 : (LPBYTE)&Info1,
335 NULL);
336 ConPrintf(StdOut, L"Status: %lu\n", Status);
337 }
338 else if (!bAdd && bDelete && lpComment == NULL)
339 {
340 /* Delete the group */
341 Status = NetLocalGroupDel(NULL,
342 lpGroupName);
343 ConPrintf(StdOut, L"Status: %lu\n", Status);
344 }
345 else
346 {
347 result = 1;
348 }
349 }
350 else
351 {
352 if (bAdd && !bDelete && lpComment == NULL)
353 {
354 /* Add group members */
355 Status = NetLocalGroupAddMembers(NULL,
356 lpGroupName,
357 3,
358 (LPBYTE)lpMembers,
359 dwMemberCount);
360 ConPrintf(StdOut, L"Status: %lu\n", Status);
361 }
362 else if (!bAdd && bDelete && lpComment == NULL)
363 {
364 /* Delete group members */
365 Status = NetLocalGroupDelMembers(NULL,
366 lpGroupName,
367 3,
368 (LPBYTE)lpMembers,
369 dwMemberCount);
370 ConPrintf(StdOut, L"Status: %lu\n", Status);
371 }
372 else
373 {
374 result = 1;
375 }
376 }
377
378 done:
379 if (lpMembers != NULL)
380 RtlFreeHeap(RtlGetProcessHeap(), 0, lpMembers);
381
382 if (result != 0)
383 {
384 PrintMessageString(4381);
385 ConPuts(StdOut, L"\n");
386 PrintNetMessage(MSG_LOCALGROUP_SYNTAX);
387 }
388
389 return result;
390 }
391
392 /* EOF */
393