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 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 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 ConResPrintf(StdOut, IDS_LOCALGROUP_ALIASES, pServer->sv100_name); 43 ConPuts(StdOut, L"\n\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 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 PrintPaddedResourceString(IDS_LOCALGROUP_ALIAS_NAME, nPaddedLength); 135 ConPrintf(StdOut, L"%s\n", pGroupInfo->lgrpi1_name); 136 137 PrintPaddedResourceString(IDS_LOCALGROUP_COMMENT, nPaddedLength); 138 ConPrintf(StdOut, L"%s\n", pGroupInfo->lgrpi1_comment); 139 140 ConPuts(StdOut, L"\n"); 141 142 ConResPuts(StdOut, IDS_LOCALGROUP_MEMBERS); 143 ConPuts(StdOut, L"\n\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 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 ConResPuts(StdOut, IDS_GENERIC_SYNTAX); 246 ConResPuts(StdOut, IDS_LOCALGROUP_SYNTAX); 247 ConResPuts(StdOut, IDS_LOCALGROUP_HELP_1); 248 ConResPuts(StdOut, IDS_LOCALGROUP_HELP_2); 249 ConResPuts(StdOut, IDS_LOCALGROUP_HELP_3); 250 ConResPuts(StdOut, IDS_LOCALGROUP_HELP_4); 251 ConResPuts(StdOut, IDS_LOCALGROUP_HELP_5); 252 ConResPuts(StdOut, IDS_LOCALGROUP_HELP_6); 253 ConResPuts(StdOut, IDS_LOCALGROUP_HELP_7); 254 ConResPuts(StdOut, IDS_GENERIC_PAGE); 255 return 0; 256 } 257 else if (_wcsicmp(argv[i], L"/add") == 0) 258 { 259 bAdd = TRUE; 260 } 261 else if (_wcsicmp(argv[i], L"/delete") == 0) 262 { 263 bDelete = TRUE; 264 } 265 else if (_wcsnicmp(argv[i], L"/comment:", 9) == 0) 266 { 267 lpComment = &argv[i][9]; 268 } 269 else if (_wcsicmp(argv[i], L"/domain") == 0) 270 { 271 ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED, L"/DOMAIN"); 272 #if 0 273 bDomain = TRUE; 274 #endif 275 } 276 else 277 { 278 result = 1; 279 goto done; 280 } 281 } 282 283 if (lpGroupName == NULL) 284 { 285 result = 1; 286 goto done; 287 } 288 289 if (bAdd && bDelete) 290 { 291 result = 1; 292 goto done; 293 } 294 295 #if 0 296 ConPrintf(StdOut, L"Group:\n %s\n", lpGroupName); 297 298 if (lpMembers != NULL) 299 { 300 ConPuts(StdOut, L"\nMembers:\n"); 301 for (i = 0; i < dwMemberCount; i++) 302 ConPrintf(StdOut, L" %s\n", lpMembers[i].lgrmi3_domainandname); 303 } 304 305 if (lpComment != NULL) 306 { 307 ConPrintf(StdOut, L"\nComment:\n %s\n", lpComment); 308 } 309 #endif 310 311 if (lpMembers == NULL) 312 { 313 if (!bAdd && !bDelete && lpComment != NULL) 314 { 315 /* Set group comment */ 316 Info1002.lgrpi1002_comment = lpComment; 317 Status = NetLocalGroupSetInfo(NULL, 318 lpGroupName, 319 1002, 320 (LPBYTE)&Info1002, 321 NULL); 322 ConPrintf(StdOut, L"Status: %lu\n", Status); 323 } 324 else if (bAdd && !bDelete) 325 { 326 /* Add the group */ 327 if (lpComment == NULL) 328 { 329 Info0.lgrpi0_name = lpGroupName; 330 } 331 else 332 { 333 Info1.lgrpi1_name = lpGroupName; 334 Info1.lgrpi1_comment = lpComment; 335 } 336 337 Status = NetLocalGroupAdd(NULL, 338 (lpComment == NULL) ? 0 : 1, 339 (lpComment == NULL) ? (LPBYTE)&Info0 : (LPBYTE)&Info1, 340 NULL); 341 ConPrintf(StdOut, L"Status: %lu\n", Status); 342 } 343 else if (!bAdd && bDelete && lpComment == NULL) 344 { 345 /* Delete the group */ 346 Status = NetLocalGroupDel(NULL, 347 lpGroupName); 348 ConPrintf(StdOut, L"Status: %lu\n", Status); 349 } 350 else 351 { 352 result = 1; 353 } 354 } 355 else 356 { 357 if (bAdd && !bDelete && lpComment == NULL) 358 { 359 /* Add group members */ 360 Status = NetLocalGroupAddMembers(NULL, 361 lpGroupName, 362 3, 363 (LPBYTE)lpMembers, 364 dwMemberCount); 365 ConPrintf(StdOut, L"Status: %lu\n", Status); 366 } 367 else if (!bAdd && bDelete && lpComment == NULL) 368 { 369 /* Delete group members */ 370 Status = NetLocalGroupDelMembers(NULL, 371 lpGroupName, 372 3, 373 (LPBYTE)lpMembers, 374 dwMemberCount); 375 ConPrintf(StdOut, L"Status: %lu\n", Status); 376 } 377 else 378 { 379 result = 1; 380 } 381 } 382 383 done: 384 if (lpMembers != NULL) 385 RtlFreeHeap(RtlGetProcessHeap(), 0, lpMembers); 386 387 if (result != 0) 388 { 389 ConResPuts(StdOut, IDS_GENERIC_SYNTAX); 390 ConResPuts(StdOut, IDS_LOCALGROUP_SYNTAX); 391 } 392 393 return result; 394 } 395 396 /* EOF */ 397