2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS net command
4 * FILE: base/applications/network/net/cmdUser.c
7 * PROGRAMMERS: Eric Kohl
13 static WCHAR szPasswordChars
[] = L
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@#$%_-+:";
17 CompareInfo(const void *a
, const void *b
)
19 return _wcsicmp(((PUSER_INFO_0
)a
)->usri0_name
,
20 ((PUSER_INFO_0
)b
)->usri0_name
);
28 PUSER_INFO_0 pBuffer
= NULL
;
29 PSERVER_INFO_100 pServer
= NULL
;
30 DWORD dwRead
= 0, dwTotal
= 0;
32 DWORD ResumeHandle
= 0;
33 NET_API_STATUS Status
;
35 Status
= NetServerGetInfo(NULL
,
38 if (Status
!= NERR_Success
)
41 ConPuts(StdOut
, L
"\n");
42 ConResPrintf(StdOut
, IDS_USER_ACCOUNTS
, pServer
->sv100_name
);
43 ConPuts(StdOut
, L
"\n\n");
44 PrintPadding(L
'-', 79);
45 ConPuts(StdOut
, L
"\n");
47 NetApiBufferFree(pServer
);
51 Status
= NetUserEnum(NULL
,
59 if ((Status
!= NERR_Success
) && (Status
!= ERROR_MORE_DATA
))
67 for (i
= 0; i
< dwRead
; i
++)
69 if (pBuffer
[i
].usri0_name
)
70 ConPrintf(StdOut
, L
"%s\n", pBuffer
[i
].usri0_name
);
73 NetApiBufferFree(pBuffer
);
76 while (Status
== ERROR_MORE_DATA
);
84 PrintDateTime(DWORD dwSeconds
)
88 SYSTEMTIME SystemTime
;
92 RtlSecondsSince1970ToTime(dwSeconds
, &Time
);
93 FileTime
.dwLowDateTime
= Time
.u
.LowPart
;
94 FileTime
.dwHighDateTime
= Time
.u
.HighPart
;
95 FileTimeToLocalFileTime(&FileTime
, &FileTime
);
96 FileTimeToSystemTime(&FileTime
, &SystemTime
);
98 GetDateFormatW(LOCALE_USER_DEFAULT
,
105 GetTimeFormatW(LOCALE_USER_DEFAULT
,
112 ConPrintf(StdOut
, L
"%s %s", DateBuffer
, TimeBuffer
);
118 GetTimeInSeconds(VOID
)
124 GetSystemTimeAsFileTime(&FileTime
);
125 Time
.u
.LowPart
= FileTime
.dwLowDateTime
;
126 Time
.u
.HighPart
= FileTime
.dwHighDateTime
;
127 RtlTimeToSecondsSince1970(&Time
, &dwSeconds
);
135 DisplayUser(LPWSTR lpUserName
)
137 PUSER_MODALS_INFO_0 pUserModals
= NULL
;
138 PUSER_INFO_4 pUserInfo
= NULL
;
139 PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo
= NULL
;
140 PGROUP_USERS_INFO_0 pGroupInfo
= NULL
;
141 DWORD dwLocalGroupRead
, dwLocalGroupTotal
;
142 DWORD dwGroupRead
, dwGroupTotal
;
145 INT nPaddedLength
= 29;
146 NET_API_STATUS Status
;
148 /* Modify the user */
149 Status
= NetUserGetInfo(NULL
,
152 (LPBYTE
*)&pUserInfo
);
153 if (Status
!= NERR_Success
)
156 Status
= NetUserModalsGet(NULL
,
158 (LPBYTE
*)&pUserModals
);
159 if (Status
!= NERR_Success
)
162 Status
= NetUserGetLocalGroups(NULL
,
166 (LPBYTE
*)&pLocalGroupInfo
,
167 MAX_PREFERRED_LENGTH
,
170 if (Status
!= NERR_Success
)
173 Status
= NetUserGetGroups(NULL
,
176 (LPBYTE
*)&pGroupInfo
,
177 MAX_PREFERRED_LENGTH
,
180 if (Status
!= NERR_Success
)
183 PrintPaddedResourceString(IDS_USER_NAME
, nPaddedLength
);
184 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_name
);
186 PrintPaddedResourceString(IDS_USER_FULL_NAME
, nPaddedLength
);
187 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_full_name
);
189 PrintPaddedResourceString(IDS_USER_COMMENT
, nPaddedLength
);
190 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_comment
);
192 PrintPaddedResourceString(IDS_USER_USER_COMMENT
, nPaddedLength
);
193 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_usr_comment
);
195 PrintPaddedResourceString(IDS_USER_COUNTRY_CODE
, nPaddedLength
);
196 ConPrintf(StdOut
, L
"%03ld ()\n", pUserInfo
->usri4_country_code
);
198 PrintPaddedResourceString(IDS_USER_ACCOUNT_ACTIVE
, nPaddedLength
);
199 if (pUserInfo
->usri4_flags
& UF_ACCOUNTDISABLE
)
200 ConResPuts(StdOut
, IDS_GENERIC_NO
);
201 else if (pUserInfo
->usri4_flags
& UF_LOCKOUT
)
202 ConResPuts(StdOut
, IDS_GENERIC_LOCKED
);
204 ConResPuts(StdOut
, IDS_GENERIC_YES
);
205 ConPuts(StdOut
, L
"\n");
207 PrintPaddedResourceString(IDS_USER_ACCOUNT_EXPIRES
, nPaddedLength
);
208 if (pUserInfo
->usri4_acct_expires
== TIMEQ_FOREVER
)
209 ConResPuts(StdOut
, IDS_GENERIC_NEVER
);
211 PrintDateTime(pUserInfo
->usri4_acct_expires
);
212 ConPuts(StdOut
, L
"\n\n");
214 PrintPaddedResourceString(IDS_USER_PW_LAST_SET
, nPaddedLength
);
215 dwLastSet
= GetTimeInSeconds() - pUserInfo
->usri4_password_age
;
216 PrintDateTime(dwLastSet
);
217 ConPuts(StdOut
, L
"\n");
219 PrintPaddedResourceString(IDS_USER_PW_EXPIRES
, nPaddedLength
);
220 if ((pUserInfo
->usri4_flags
& UF_DONT_EXPIRE_PASSWD
) || pUserModals
->usrmod0_max_passwd_age
== TIMEQ_FOREVER
)
221 ConResPuts(StdOut
, IDS_GENERIC_NEVER
);
223 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_max_passwd_age
);
224 ConPuts(StdOut
, L
"\n");
226 PrintPaddedResourceString(IDS_USER_PW_CHANGEABLE
, nPaddedLength
);
227 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_min_passwd_age
);
228 ConPuts(StdOut
, L
"\n");
230 PrintPaddedResourceString(IDS_USER_PW_REQUIRED
, nPaddedLength
);
231 ConResPuts(StdOut
, (pUserInfo
->usri4_flags
& UF_PASSWD_NOTREQD
) ? IDS_GENERIC_NO
: IDS_GENERIC_YES
);
232 ConPuts(StdOut
, L
"\n");
234 PrintPaddedResourceString(IDS_USER_CHANGE_PW
, nPaddedLength
);
235 ConResPuts(StdOut
, (pUserInfo
->usri4_flags
& UF_PASSWD_CANT_CHANGE
) ? IDS_GENERIC_NO
: IDS_GENERIC_YES
);
236 ConPuts(StdOut
, L
"\n\n");
238 PrintPaddedResourceString(IDS_USER_WORKSTATIONS
, nPaddedLength
);
239 if (pUserInfo
->usri4_workstations
== NULL
|| wcslen(pUserInfo
->usri4_workstations
) == 0)
240 ConResPuts(StdOut
, IDS_GENERIC_ALL
);
242 ConPrintf(StdOut
, L
"%s", pUserInfo
->usri4_workstations
);
243 ConPuts(StdOut
, L
"\n");
245 PrintPaddedResourceString(IDS_USER_LOGON_SCRIPT
, nPaddedLength
);
246 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_script_path
);
248 PrintPaddedResourceString(IDS_USER_PROFILE
, nPaddedLength
);
249 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_profile
);
251 PrintPaddedResourceString(IDS_USER_HOME_DIR
, nPaddedLength
);
252 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_home_dir
);
254 PrintPaddedResourceString(IDS_USER_LAST_LOGON
, nPaddedLength
);
255 if (pUserInfo
->usri4_last_logon
== 0)
256 ConResPuts(StdOut
, IDS_GENERIC_NEVER
);
258 PrintDateTime(pUserInfo
->usri4_last_logon
);
259 ConPuts(StdOut
, L
"\n\n");
261 PrintPaddedResourceString(IDS_USER_LOGON_HOURS
, nPaddedLength
);
262 if (pUserInfo
->usri4_logon_hours
== NULL
)
263 ConResPuts(StdOut
, IDS_GENERIC_ALL
);
264 ConPuts(StdOut
, L
"\n\n");
266 ConPuts(StdOut
, L
"\n");
267 PrintPaddedResourceString(IDS_USER_LOCAL_GROUPS
, nPaddedLength
);
268 if (dwLocalGroupTotal
!= 0 && pLocalGroupInfo
!= NULL
)
270 for (i
= 0; i
< dwLocalGroupTotal
; i
++)
273 PrintPadding(L
' ', nPaddedLength
);
274 ConPrintf(StdOut
, L
"*%s\n", pLocalGroupInfo
[i
].lgrui0_name
);
279 ConPuts(StdOut
, L
"\n");
282 PrintPaddedResourceString(IDS_USER_GLOBAL_GROUPS
, nPaddedLength
);
283 if (dwGroupTotal
!= 0 && pGroupInfo
!= NULL
)
285 for (i
= 0; i
< dwGroupTotal
; i
++)
288 PrintPadding(L
' ', nPaddedLength
);
289 ConPrintf(StdOut
, L
"*%s\n", pGroupInfo
[i
].grui0_name
);
294 ConPuts(StdOut
, L
"\n");
298 if (pGroupInfo
!= NULL
)
299 NetApiBufferFree(pGroupInfo
);
301 if (pLocalGroupInfo
!= NULL
)
302 NetApiBufferFree(pLocalGroupInfo
);
304 if (pUserModals
!= NULL
)
305 NetApiBufferFree(pUserModals
);
307 if (pUserInfo
!= NULL
)
308 NetApiBufferFree(pUserInfo
);
320 WCHAR szPassword1
[PWLEN
+ 1];
321 WCHAR szPassword2
[PWLEN
+ 1];
324 *lpAllocated
= FALSE
;
328 ConResPuts(StdOut
, IDS_USER_ENTER_PASSWORD1
);
329 ReadFromConsole(szPassword1
, PWLEN
+ 1, FALSE
);
330 ConPuts(StdOut
, L
"\n");
332 ConResPuts(StdOut
, IDS_USER_ENTER_PASSWORD2
);
333 ReadFromConsole(szPassword2
, PWLEN
+ 1, FALSE
);
334 ConPuts(StdOut
, L
"\n");
336 if (wcslen(szPassword1
) == wcslen(szPassword2
) &&
337 wcscmp(szPassword1
, szPassword2
) == 0)
339 ptr
= HeapAlloc(GetProcessHeap(),
341 (wcslen(szPassword1
) + 1) * sizeof(WCHAR
));
344 wcscpy(ptr
, szPassword1
);
352 ConPuts(StdOut
, L
"\n");
353 ConResPuts(StdOut
, IDS_USER_NO_PASSWORD_MATCH
);
354 ConPuts(StdOut
, L
"\n");
363 GenerateRandomPassword(
367 LPWSTR pPassword
= NULL
;
368 INT nCharsLen
, i
, nLength
= 8;
370 srand(GetTickCount());
372 pPassword
= HeapAlloc(GetProcessHeap(),
374 (nLength
+ 1) * sizeof(WCHAR
));
375 if (pPassword
== NULL
)
378 nCharsLen
= wcslen(szPasswordChars
);
380 for (i
= 0; i
< nLength
; i
++)
382 pPassword
[i
] = szPasswordChars
[rand() % nCharsLen
];
385 *lpPassword
= pPassword
;
392 BuildWorkstationsList(
393 _Out_ PWSTR
*pWorkstationsList
,
396 BOOL isLastSep
, isSep
;
404 /* Check for invalid characters in the raw string */
405 if (wcspbrk(pRaw
, L
"/[]=?\\+:.") != NULL
)
408 /* Count the number of workstations in the list and
409 * the required buffer size */
412 nRawLength
= wcslen(pRaw
);
413 for (i
= 0; i
< nRawLength
; i
++)
416 if (c
== L
',' || c
== L
';')
421 if ((isLastSep
== FALSE
) && (i
!= 0) && (i
!= nRawLength
- 1))
428 if (isLastSep
== TRUE
|| (isLastSep
== FALSE
&& i
== 0))
438 /* Leave, if there are no workstations in the list */
441 pWorkstationsList
= NULL
;
445 /* Fail if there are more than eight workstations in the list */
449 /* Allocate the buffer for the clean workstation list */
450 pList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, nLength
* sizeof(WCHAR
));
452 return ERROR_NOT_ENOUGH_MEMORY
;
454 /* Build the clean workstation list */
457 nRawLength
= wcslen(pRaw
);
458 for (i
= 0, j
= 0; i
< nRawLength
; i
++)
461 if (c
== L
',' || c
== L
';')
466 if ((isLastSep
== FALSE
) && (i
!= 0) && (i
!= nRawLength
- 1))
477 if (isLastSep
== TRUE
|| (isLastSep
== FALSE
&& i
== 0))
485 *pWorkstationsList
= pList
;
500 while (iswdigit(**s
))
502 *pwValue
= *pwValue
* 10 + **s
- L
'0';
515 if (**s
== L
'/' || **s
== L
'.')
531 SYSTEMTIME SystemTime
= {0};
532 FILETIME LocalFileTime
, FileTime
;
540 GetLocaleInfoW(LOCALE_USER_DEFAULT
,
549 if (!ReadNumber(&p
, &SystemTime
.wMonth
))
551 if (!ReadSeparator(&p
))
553 if (!ReadNumber(&p
, &SystemTime
.wDay
))
555 if (!ReadSeparator(&p
))
557 if (!ReadNumber(&p
, &SystemTime
.wYear
))
562 if (!ReadNumber(&p
, &SystemTime
.wDay
))
564 if (!ReadSeparator(&p
))
566 if (!ReadNumber(&p
, &SystemTime
.wMonth
))
568 if (!ReadSeparator(&p
))
570 if (!ReadNumber(&p
, &SystemTime
.wYear
))
575 if (!ReadNumber(&p
, &SystemTime
.wYear
))
577 if (!ReadSeparator(&p
))
579 if (!ReadNumber(&p
, &SystemTime
.wMonth
))
581 if (!ReadSeparator(&p
))
583 if (!ReadNumber(&p
, &SystemTime
.wDay
))
588 /* if only entered two digits: */
589 /* assume 2000's if value less than 80 */
590 /* assume 1900's if value greater or equal 80 */
591 if (SystemTime
.wYear
<= 99)
593 if (SystemTime
.wYear
>= 80)
594 SystemTime
.wYear
+= 1900;
596 SystemTime
.wYear
+= 2000;
599 if (!SystemTimeToFileTime(&SystemTime
, &LocalFileTime
))
602 if (!LocalFileTimeToFileTime(&LocalFileTime
, &FileTime
))
605 Time
.u
.LowPart
= FileTime
.dwLowDateTime
;
606 Time
.u
.HighPart
= FileTime
.dwHighDateTime
;
608 if (!RtlTimeToSecondsSince1970(&Time
, pSeconds
))
623 BOOL bDelete
= FALSE
;
625 BOOL bDomain
= FALSE
;
627 BOOL bRandomPassword
= FALSE
;
628 LPWSTR lpUserName
= NULL
;
629 LPWSTR lpPassword
= NULL
;
630 PUSER_INFO_4 pUserInfo
= NULL
;
631 USER_INFO_4 UserInfo
;
632 LPWSTR pWorkstations
= NULL
;
636 BOOL bPasswordAllocated
= FALSE
;
637 NET_API_STATUS Status
;
641 Status
= EnumerateUsers();
642 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
647 Status
= DisplayUser(argv
[2]);
648 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
653 if (argv
[i
][0] != L
'/')
655 lpUserName
= argv
[i
];
656 // ConPrintf(StdOut, L"User: %s\n", lpUserName);
660 if (argv
[i
][0] != L
'/')
662 lpPassword
= argv
[i
];
663 // ConPrintf(StdOut, L"Password: %s\n", lpPassword);
667 for (j
= i
; j
< argc
; j
++)
669 if (_wcsicmp(argv
[j
], L
"/help") == 0)
671 ConResPuts(StdOut
, IDS_USER_HELP
);
674 else if (_wcsicmp(argv
[j
], L
"/add") == 0)
678 else if (_wcsicmp(argv
[j
], L
"/delete") == 0)
682 else if (_wcsicmp(argv
[j
], L
"/domain") == 0)
684 ConResPrintf(StdErr
, IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/DOMAIN");
689 else if (_wcsicmp(argv
[j
], L
"/random") == 0)
691 bRandomPassword
= TRUE
;
692 GenerateRandomPassword(&lpPassword
,
693 &bPasswordAllocated
);
703 /* Interactive password input */
704 if (lpPassword
!= NULL
&& wcscmp(lpPassword
, L
"*") == 0)
706 ReadPassword(&lpPassword
,
707 &bPasswordAllocated
);
710 if (!bAdd
&& !bDelete
)
712 /* Modify the user */
713 Status
= NetUserGetInfo(NULL
,
716 (LPBYTE
*)&pUserInfo
);
717 if (Status
!= NERR_Success
)
719 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
724 else if (bAdd
&& !bDelete
)
727 ZeroMemory(&UserInfo
, sizeof(USER_INFO_4
));
729 UserInfo
.usri4_name
= lpUserName
;
730 UserInfo
.usri4_password
= lpPassword
;
731 UserInfo
.usri4_flags
= UF_SCRIPT
| UF_NORMAL_ACCOUNT
;
732 UserInfo
.usri4_acct_expires
= TIMEQ_FOREVER
;
734 pUserInfo
= &UserInfo
;
737 for (j
= i
; j
< argc
; j
++)
739 if (_wcsnicmp(argv
[j
], L
"/active:", 8) == 0)
742 if (_wcsicmp(p
, L
"yes") == 0)
744 pUserInfo
->usri4_flags
&= ~UF_ACCOUNTDISABLE
;
746 else if (_wcsicmp(p
, L
"no") == 0)
748 pUserInfo
->usri4_flags
|= UF_ACCOUNTDISABLE
;
752 ConResPrintf(StdErr
, IDS_ERROR_INVALID_OPTION_VALUE
, L
"/ACTIVE");
757 else if (_wcsnicmp(argv
[j
], L
"/comment:", 9) == 0)
759 pUserInfo
->usri4_comment
= &argv
[j
][9];
761 else if (_wcsnicmp(argv
[j
], L
"/countrycode:", 13) == 0)
764 value
= wcstoul(p
, &endptr
, 10);
767 ConResPrintf(StdErr
, IDS_ERROR_INVALID_OPTION_VALUE
, L
"/COUNTRYCODE");
772 /* FIXME: verify the country code */
774 pUserInfo
->usri4_country_code
= value
;
776 else if (_wcsnicmp(argv
[j
], L
"/expires:", 9) == 0)
779 if (_wcsicmp(p
, L
"never") == 0)
781 pUserInfo
->usri4_acct_expires
= TIMEQ_FOREVER
;
783 else if (!ParseDate(p
, &pUserInfo
->usri4_acct_expires
))
785 ConResPrintf(StdErr
, IDS_ERROR_INVALID_OPTION_VALUE
, L
"/EXPIRES");
789 /* FIXME: Parse the date */
790 // ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED, L"/EXPIRES");
793 else if (_wcsnicmp(argv
[j
], L
"/fullname:", 10) == 0)
795 pUserInfo
->usri4_full_name
= &argv
[j
][10];
797 else if (_wcsnicmp(argv
[j
], L
"/homedir:", 9) == 0)
799 pUserInfo
->usri4_home_dir
= &argv
[j
][9];
801 else if (_wcsnicmp(argv
[j
], L
"/passwordchg:", 13) == 0)
804 if (_wcsicmp(p
, L
"yes") == 0)
806 pUserInfo
->usri4_flags
&= ~UF_PASSWD_CANT_CHANGE
;
808 else if (_wcsicmp(p
, L
"no") == 0)
810 pUserInfo
->usri4_flags
|= UF_PASSWD_CANT_CHANGE
;
814 ConResPrintf(StdErr
, IDS_ERROR_INVALID_OPTION_VALUE
, L
"/PASSWORDCHG");
819 else if (_wcsnicmp(argv
[j
], L
"/passwordreq:", 13) == 0)
822 if (_wcsicmp(p
, L
"yes") == 0)
824 pUserInfo
->usri4_flags
&= ~UF_PASSWD_NOTREQD
;
826 else if (_wcsicmp(p
, L
"no") == 0)
828 pUserInfo
->usri4_flags
|= UF_PASSWD_NOTREQD
;
832 ConResPrintf(StdErr
, IDS_ERROR_INVALID_OPTION_VALUE
, L
"/PASSWORDREQ");
837 else if (_wcsnicmp(argv
[j
], L
"/profilepath:", 13) == 0)
839 pUserInfo
->usri4_profile
= &argv
[j
][13];
841 else if (_wcsnicmp(argv
[j
], L
"/scriptpath:", 12) == 0)
843 pUserInfo
->usri4_script_path
= &argv
[j
][12];
845 else if (_wcsnicmp(argv
[j
], L
"/times:", 7) == 0)
848 ConResPrintf(StdErr
, IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/TIMES");
850 else if (_wcsnicmp(argv
[j
], L
"/usercomment:", 13) == 0)
852 pUserInfo
->usri4_usr_comment
= &argv
[j
][13];
854 else if (_wcsnicmp(argv
[j
], L
"/workstations:", 14) == 0)
857 if (wcscmp(p
, L
"*") == 0 || wcscmp(p
, L
"") == 0)
859 pUserInfo
->usri4_workstations
= NULL
;
863 Status
= BuildWorkstationsList(&pWorkstations
, p
);
864 if (Status
== NERR_Success
)
866 pUserInfo
->usri4_workstations
= pWorkstations
;
870 ConPrintf(StdOut
, L
"Status %lu\n\n", Status
);
878 if (!bAdd
&& !bDelete
)
880 /* Modify the user */
881 Status
= NetUserSetInfo(NULL
,
886 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
888 else if (bAdd
&& !bDelete
)
891 Status
= NetUserAdd(NULL
,
895 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
897 else if (!bAdd
&& bDelete
)
899 /* Delete the user */
900 Status
= NetUserDel(NULL
,
902 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
905 if (Status
== NERR_Success
&&
906 lpPassword
!= NULL
&&
907 bRandomPassword
== TRUE
)
909 ConPrintf(StdOut
, L
"The password for %s is: %s\n", lpUserName
, lpPassword
);
913 if (pWorkstations
!= NULL
)
914 HeapFree(GetProcessHeap(), 0, pWorkstations
);
916 if ((bPasswordAllocated
== TRUE
) && (lpPassword
!= NULL
))
917 HeapFree(GetProcessHeap(), 0, lpPassword
);
919 if (!bAdd
&& !bDelete
&& pUserInfo
!= NULL
)
920 NetApiBufferFree(pUserInfo
);
924 ConResPuts(StdOut
, IDS_GENERIC_SYNTAX
);
925 ConResPuts(StdOut
, IDS_USER_SYNTAX
);