USHORT MNetGroupAddUser ( const CHAR FAR * pszServer, CHAR FAR * pszGroupName, CHAR FAR * pszUserName ) { return(NetGroupAddUser(pszServer, pszGroupName, pszUserName)); }
APIERR MNetGroupAddUser( const TCHAR FAR * pszServer, TCHAR FAR * pszGroupName, TCHAR FAR * pszUserName ) { return NetGroupAddUser( pszServer, pszGroupName, pszUserName ); } // MNetGroupAddUser
DWORD request_incognito_add_group_user(Remote *remote, Packet *packet) { DWORD dwLevel = 1, dwError = 0, num_tokens = 0, i; NET_API_STATUS nStatus; SavedToken *token_list = NULL; HANDLE saved_token; wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], groupname_u[BUF_SIZE]; char *dc_netbios_name, *groupname, *username, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = ""; // Read arguments Packet *response = packet_create_response(packet); dc_netbios_name = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME); groupname = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_GROUPNAME); username = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME); mbstowcs(dc_netbios_name_u, dc_netbios_name, strlen(dc_netbios_name)+1); mbstowcs(username_u, username, strlen(username)+1); mbstowcs(groupname_u, groupname, strlen(groupname)+1); // Save current thread token if one is currently being impersonated if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token)) saved_token = INVALID_HANDLE_VALUE; token_list = get_token_list(&num_tokens); if (!token_list) { sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError()); goto cleanup; } sprintf(return_value, "[*] Attempting to add user %s to group %s on domain controller %s\n", username, groupname, dc_netbios_name); // Attempt to add user to group with every token for (i=0;i<num_tokens;i++) if (token_list[i].token) { // causes major problems (always error 127) once you have impersonated this token once. No idea why!!! if (!_stricmp("NT AUTHORITY\\ANONYMOUS LOGON", token_list[i].username)) continue; ImpersonateLoggedOnUser(token_list[i].token); nStatus = NetGroupAddUser(dc_netbios_name_u, groupname_u, username_u); RevertToSelf(); switch (nStatus) { case ERROR_ACCESS_DENIED: case ERROR_LOGON_FAILURE: // unknown username or bad password case ERROR_INVALID_PASSWORD: break; case NERR_Success: strncat(return_value, "[+] Successfully added user to group\n", sizeof(return_value)-strlen(return_value)-1);; goto cleanup; case NERR_InvalidComputer: strncat(return_value, "[-] Computer name invalid\n", sizeof(return_value)-strlen(return_value)-1); goto cleanup; case NERR_NotPrimary: strncat(return_value, "[-] Operation only allowed on primary domain controller\n", sizeof(return_value)-strlen(return_value)-1); goto cleanup; case NERR_SpeGroupOp: strncat(return_value, "[-] Special group\n", sizeof(return_value)-strlen(return_value)-1); goto cleanup; case NERR_UserNotFound: strncat(return_value, "[-] User not found\n", sizeof(return_value)-strlen(return_value)-1); goto cleanup; case NERR_GroupNotFound: strncat(return_value, "[-] Group not found\n", sizeof(return_value)-strlen(return_value)-1); goto cleanup; case 2236: // Can't find error code in documentation...found by testing strncat(return_value, "[-] User already in group\n", sizeof(return_value)-strlen(return_value)-1); goto cleanup; default: sprintf(temp, "Unknown error: %d\n", nStatus); strncat(return_value, temp, sizeof(return_value)-strlen(return_value)-1); goto cleanup; } } strncat(return_value, "[-] Access denied with all tokens\n", sizeof(return_value)-strlen(return_value)-1); cleanup: for (i=0;i<num_tokens;i++) CloseHandle(token_list[i].token); free(token_list); packet_add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value); packet_transmit_response(ERROR_SUCCESS, remote, response); // Restore token impersonation if (saved_token != INVALID_HANDLE_VALUE) ImpersonateLoggedOnUser(saved_token); return ERROR_SUCCESS; }
NET_API_STATUS netapitest_group(struct libnetapi_ctx *ctx, const char *hostname) { NET_API_STATUS status = 0; const char *username, *groupname, *groupname2; uint8_t *buffer = NULL; struct GROUP_INFO_0 g0; uint32_t parm_err = 0; uint32_t levels[] = { 0, 1, 2, 3}; uint32_t enum_levels[] = { 0, 1, 2, 3}; uint32_t getmem_levels[] = { 0, 1}; int i; printf("NetGroup tests\n"); username = "******"; groupname = "torture_test_group"; groupname2 = "torture_test_group2"; /* cleanup */ NetGroupDel(hostname, groupname); NetGroupDel(hostname, groupname2); NetUserDel(hostname, username); /* add a group */ g0.grpi0_name = groupname; printf("testing NetGroupAdd\n"); status = NetGroupAdd(hostname, 0, (uint8_t *)&g0, &parm_err); if (status) { NETAPI_STATUS(ctx, status, "NetGroupAdd"); goto out; } /* 2nd add must fail */ status = NetGroupAdd(hostname, 0, (uint8_t *)&g0, &parm_err); if (status == 0) { NETAPI_STATUS(ctx, status, "NetGroupAdd"); goto out; } /* test enum */ for (i=0; i<ARRAY_SIZE(enum_levels); i++) { status = test_netgroupenum(hostname, enum_levels[i], groupname); if (status) { NETAPI_STATUS(ctx, status, "NetGroupEnum"); goto out; } } /* basic queries */ for (i=0; i<ARRAY_SIZE(levels); i++) { printf("testing NetGroupGetInfo level %d\n", levels[i]); status = NetGroupGetInfo(hostname, groupname, levels[i], &buffer); if (status && status != 124) { NETAPI_STATUS(ctx, status, "NetGroupGetInfo"); goto out; } } /* group rename */ g0.grpi0_name = groupname2; printf("testing NetGroupSetInfo level 0\n"); status = NetGroupSetInfo(hostname, groupname, 0, (uint8_t *)&g0, &parm_err); switch (status) { case 0: break; case 50: /* not supported */ case 124: /* not implemented */ groupname2 = groupname; goto skip_rename; default: NETAPI_STATUS(ctx, status, "NetGroupSetInfo"); goto out; } /* should not exist anymore */ status = NetGroupDel(hostname, groupname); if (status == 0) { NETAPI_STATUS(ctx, status, "NetGroupDel"); goto out; } skip_rename: /* query info */ for (i=0; i<ARRAY_SIZE(levels); i++) { status = NetGroupGetInfo(hostname, groupname2, levels[i], &buffer); if (status && status != 124) { NETAPI_STATUS(ctx, status, "NetGroupGetInfo"); goto out; } } /* add user to group */ status = test_netuseradd(hostname, username); if (status) { NETAPI_STATUS(ctx, status, "NetUserAdd"); goto out; } /* should not be member */ for (i=0; i<ARRAY_SIZE(getmem_levels); i++) { status = test_netgroupgetusers(hostname, getmem_levels[i], groupname2, NULL); if (status) { NETAPI_STATUS(ctx, status, "NetGroupGetUsers"); goto out; } } printf("testing NetGroupAddUser\n"); status = NetGroupAddUser(hostname, groupname2, username); if (status) { NETAPI_STATUS(ctx, status, "NetGroupAddUser"); goto out; } /* should be member */ for (i=0; i<ARRAY_SIZE(getmem_levels); i++) { status = test_netgroupgetusers(hostname, getmem_levels[i], groupname2, username); if (status) { NETAPI_STATUS(ctx, status, "NetGroupGetUsers"); goto out; } } printf("testing NetGroupDelUser\n"); status = NetGroupDelUser(hostname, groupname2, username); if (status) { NETAPI_STATUS(ctx, status, "NetGroupDelUser"); goto out; } /* should not be member */ status = test_netgroupgetusers(hostname, 0, groupname2, NULL); if (status) { NETAPI_STATUS(ctx, status, "NetGroupGetUsers"); goto out; } /* set it again via exlicit member set */ status = test_netgroupsetusers(hostname, groupname2, 0, 1, &username); if (status) { NETAPI_STATUS(ctx, status, "NetGroupSetUsers"); goto out; } /* should be member */ status = test_netgroupgetusers(hostname, 0, groupname2, username); if (status) { NETAPI_STATUS(ctx, status, "NetGroupGetUsers"); goto out; } #if 0 /* wipe out member list */ status = test_netgroupsetusers(hostname, groupname2, 0, 0, NULL); if (status) { NETAPI_STATUS(ctx, status, "NetGroupSetUsers"); goto out; } /* should not be member */ status = test_netgroupgetusers(hostname, 0, groupname2, NULL); if (status) { NETAPI_STATUS(ctx, status, "NetGroupGetUsers"); goto out; } #endif status = NetUserDel(hostname, username); if (status) { NETAPI_STATUS(ctx, status, "NetUserDel"); goto out; } /* delete */ printf("testing NetGroupDel\n"); status = NetGroupDel(hostname, groupname2); if (status) { NETAPI_STATUS(ctx, status, "NetGroupDel"); goto out; }; /* should not exist anymore */ status = NetGroupGetInfo(hostname, groupname2, 0, &buffer); if (status == 0) { NETAPI_STATUS_MSG(ctx, status, "NetGroupGetInfo", "expected failure and error code"); goto out; }; status = 0; printf("NetGroup tests succeeded\n"); out: if (status != 0) { printf("NetGroup testsuite failed with: %s\n", libnetapi_get_error_string(ctx, status)); } return status; }