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