[NETAPI32]
authorEric Kohl <eric.kohl@reactos.org>
Sat, 10 Aug 2013 19:24:03 +0000 (19:24 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 10 Aug 2013 19:24:03 +0000 (19:24 +0000)
Reimplement NetUserModalsGet and add NetUserModalsSet stub.

svn path=/trunk/; revision=59689

reactos/dll/win32/netapi32/access.c
reactos/dll/win32/netapi32/netapi32.spec
reactos/dll/win32/netapi32/user.c

index 117392e..968cd30 100644 (file)
@@ -262,130 +262,6 @@ NetGetDCName(LPCWSTR servername, LPCWSTR domainname, LPBYTE *bufptr)
   return NERR_DCNotFound; /* say we can't find a domain controller */  
 }
 
-/******************************************************************************
- * NetUserModalsGet  (NETAPI32.@)
- *
- * Retrieves global information for all users and global groups in the security
- * database.
- *
- * PARAMS
- *  szServer   [I] Specifies the DNS or the NetBIOS name of the remote server
- *                 on which the function is to execute.
- *  level      [I] Information level of the data.
- *     0   Return global passwords parameters. bufptr points to a
- *         USER_MODALS_INFO_0 struct.
- *     1   Return logon server and domain controller information. bufptr
- *         points to a USER_MODALS_INFO_1 struct.
- *     2   Return domain name and identifier. bufptr points to a 
- *         USER_MODALS_INFO_2 struct.
- *     3   Return lockout information. bufptr points to a USER_MODALS_INFO_3
- *         struct.
- *  pbuffer    [I] Buffer that receives the data.
- *
- * RETURNS
- *  Success: NERR_Success.
- *  Failure: 
- *     ERROR_ACCESS_DENIED - the user does not have access to the info.
- *     NERR_InvalidComputer - computer name is invalid.
- */
-NET_API_STATUS WINAPI NetUserModalsGet(
-    LPCWSTR szServer, DWORD level, LPBYTE *pbuffer)
-{
-    TRACE("(%s %d %p)\n", debugstr_w(szServer), level, pbuffer);
-    
-    switch (level)
-    {
-        case 0:
-            /* return global passwords parameters */
-            FIXME("level 0 not implemented!\n");
-            *pbuffer = NULL;
-            return NERR_InternalError;
-        case 1:
-            /* return logon server and domain controller info */
-            FIXME("level 1 not implemented!\n");
-            *pbuffer = NULL;
-            return NERR_InternalError;
-        case 2:
-        {
-            /* return domain name and identifier */
-            PUSER_MODALS_INFO_2 umi;
-            LSA_HANDLE policyHandle;
-            LSA_OBJECT_ATTRIBUTES objectAttributes;
-            PPOLICY_ACCOUNT_DOMAIN_INFO domainInfo;
-            NTSTATUS ntStatus;
-            PSID domainIdentifier = NULL;
-            int domainNameLen, domainIdLen;
-
-            ZeroMemory(&objectAttributes, sizeof(objectAttributes));
-            objectAttributes.Length = sizeof(objectAttributes);
-
-            ntStatus = LsaOpenPolicy(NULL, &objectAttributes,
-                                     POLICY_VIEW_LOCAL_INFORMATION,
-                                     &policyHandle);
-            if (ntStatus != STATUS_SUCCESS)
-            {
-                WARN("LsaOpenPolicy failed with NT status %x\n",
-                     LsaNtStatusToWinError(ntStatus));
-                return ntStatus;
-            }
-
-            ntStatus = LsaQueryInformationPolicy(policyHandle,
-                                                 PolicyAccountDomainInformation,
-                                                 (PVOID *)&domainInfo);
-            if (ntStatus != STATUS_SUCCESS)
-            {
-                WARN("LsaQueryInformationPolicy failed with NT status %x\n",
-                     LsaNtStatusToWinError(ntStatus));
-                LsaClose(policyHandle);
-                return ntStatus;
-            }
-
-            domainIdentifier = domainInfo->DomainSid;
-            domainIdLen = (domainIdentifier) ? GetLengthSid(domainIdentifier) : 0;
-            domainNameLen = lstrlenW(domainInfo->DomainName.Buffer) + 1;
-            LsaClose(policyHandle);
-
-            ntStatus = NetApiBufferAllocate(sizeof(USER_MODALS_INFO_2) +
-                                            domainIdLen +
-                                            domainNameLen * sizeof(WCHAR),
-                                            (LPVOID *)pbuffer);
-
-            if (ntStatus != NERR_Success)
-            {
-                WARN("NetApiBufferAllocate() failed\n");
-                LsaFreeMemory(domainInfo);
-                return ntStatus;
-            }
-
-            umi = (USER_MODALS_INFO_2 *) *pbuffer;
-            umi->usrmod2_domain_id = (domainIdLen > 0) ? (*pbuffer + sizeof(USER_MODALS_INFO_2)) : NULL;
-            umi->usrmod2_domain_name = (LPWSTR)(*pbuffer +
-                sizeof(USER_MODALS_INFO_2) + domainIdLen);
-
-            lstrcpynW(umi->usrmod2_domain_name,
-                      domainInfo->DomainName.Buffer,
-                      domainNameLen);
-            if (domainIdLen > 0)
-                CopySid(GetLengthSid(domainIdentifier), umi->usrmod2_domain_id,
-                        domainIdentifier);
-
-            LsaFreeMemory(domainInfo);
-
-            break;
-        } 
-        case 3:
-            /* return lockout information */
-            FIXME("level 3 not implemented!\n");
-            *pbuffer = NULL;
-            return NERR_InternalError;
-        default:
-            TRACE("Invalid level %d is specified\n", level);
-            *pbuffer = NULL;
-            return ERROR_INVALID_LEVEL;
-    }
-
-    return NERR_Success;
-}
 
 NET_API_STATUS WINAPI NetUseAdd(LMSTR servername, DWORD level, LPBYTE bufptr, LPDWORD parm_err)
 {
index 20ac5fe..2f518b5 100644 (file)
 @ stdcall NetUserGetInfo(wstr wstr long ptr)
 @ stdcall NetUserGetLocalGroups(wstr wstr long long ptr long ptr ptr)
 @ stdcall NetUserModalsGet(wstr long ptr)
-@ stub NetUserModalsSet
+@ stdcall NetUserModalsSet(wstr long ptr ptr)
 @ stdcall NetUserSetGroups(wstr wstr long ptr long)
 @ stdcall NetUserSetInfo(wstr wstr long ptr ptr)
 @ stdcall NetWkstaGetInfo(wstr long ptr)
index 7b5389a..dcd313d 100644 (file)
@@ -47,6 +47,24 @@ typedef struct _ENUM_CONTEXT
 } ENUM_CONTEXT, *PENUM_CONTEXT;
 
 
+static
+ULONG
+DeltaTimeToSeconds(LARGE_INTEGER DeltaTime)
+{
+    LARGE_INTEGER Seconds;
+
+    if (DeltaTime.QuadPart == 0)
+        return 0;
+
+    Seconds.QuadPart = -DeltaTime.QuadPart / 10000000;
+
+    if (Seconds.HighPart != 0)
+        return TIMEQ_FOREVER;
+
+    return Seconds.LowPart;
+}
+
+
 static
 ULONG
 GetAccountFlags(ULONG AccountControl)
@@ -3058,6 +3076,332 @@ done:
 }
 
 
+/******************************************************************************
+ * NetUserModalsGet  (NETAPI32.@)
+ *
+ * Retrieves global information for all users and global groups in the security
+ * database.
+ *
+ * PARAMS
+ *  servername [I] Specifies the DNS or the NetBIOS name of the remote server
+ *                 on which the function is to execute.
+ *  level      [I] Information level of the data.
+ *     0   Return global passwords parameters. bufptr points to a
+ *         USER_MODALS_INFO_0 struct.
+ *     1   Return logon server and domain controller information. bufptr
+ *         points to a USER_MODALS_INFO_1 struct.
+ *     2   Return domain name and identifier. bufptr points to a 
+ *         USER_MODALS_INFO_2 struct.
+ *     3   Return lockout information. bufptr points to a USER_MODALS_INFO_3
+ *         struct.
+ *  bufptr     [O] Buffer that receives the data.
+ *
+ * RETURNS
+ *  Success: NERR_Success.
+ *  Failure: 
+ *     ERROR_ACCESS_DENIED - the user does not have access to the info.
+ *     NERR_InvalidComputer - computer name is invalid.
+ */
+NET_API_STATUS
+WINAPI
+NetUserModalsGet(LPCWSTR servername,
+                 DWORD level,
+                 LPBYTE *bufptr)
+{
+    UNICODE_STRING ServerName;
+    SAM_HANDLE ServerHandle = NULL;
+    SAM_HANDLE DomainHandle = NULL;
+    PSID DomainSid = NULL;
+    PDOMAIN_PASSWORD_INFORMATION PasswordInfo = NULL;
+    PDOMAIN_LOGOFF_INFORMATION LogoffInfo = NULL;
+    PDOMAIN_SERVER_ROLE_INFORMATION ServerRoleInfo = NULL;
+    PDOMAIN_REPLICATION_INFORMATION ReplicationInfo = NULL;
+    PDOMAIN_NAME_INFORMATION NameInfo = NULL;
+    PDOMAIN_LOCKOUT_INFORMATION LockoutInfo = NULL;
+    ULONG DesiredAccess;
+    ULONG BufferSize;
+    PUSER_MODALS_INFO_0 umi0;
+    PUSER_MODALS_INFO_1 umi1;
+    PUSER_MODALS_INFO_2 umi2;
+    PUSER_MODALS_INFO_3 umi3;
+    NET_API_STATUS ApiStatus = NERR_Success;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    TRACE("(%s %d %p)\n", debugstr_w(servername), level, bufptr);
+
+    *bufptr = NULL;
+
+    if (servername != NULL)
+        RtlInitUnicodeString(&ServerName, servername);
+
+    /* Connect to the SAM Server */
+    Status = SamConnect((servername != NULL) ? &ServerName : NULL,
+                        &ServerHandle,
+                        SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
+                        NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("SamConnect failed (Status %08lx)\n", Status);
+        ApiStatus = NetpNtStatusToApiStatus(Status);
+        goto done;
+    }
+
+    /* Get the Account Domain SID */
+    Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
+                                 &DomainSid);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
+        ApiStatus = NetpNtStatusToApiStatus(Status);
+        goto done;
+    }
+
+    switch (level)
+    {
+        case 0:
+            DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS | DOMAIN_READ_PASSWORD_PARAMETERS;
+            break;
+
+        case 1:
+            DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS;
+            break;
+
+        case 2:
+            DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS;
+            break;
+
+        case 3:
+            DesiredAccess = DOMAIN_READ_PASSWORD_PARAMETERS;
+            break;
+
+        default:
+            ApiStatus = ERROR_INVALID_LEVEL;
+            goto done;
+    }
+
+    /* Open the Account Domain */
+    Status = SamOpenDomain(ServerHandle,
+                           DesiredAccess,
+                           DomainSid,
+                           &DomainHandle);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
+        ApiStatus = NetpNtStatusToApiStatus(Status);
+        goto done;
+    }
+
+    switch (level)
+    {
+        case 0:
+            /* return global passwords parameters */
+            Status = SamQueryInformationDomain(DomainHandle,
+                                               DomainPasswordInformation,
+                                               (PVOID*)&PasswordInfo);
+            if (!NT_SUCCESS(Status))
+            {
+                ApiStatus = NetpNtStatusToApiStatus(Status);
+                goto done;
+            }
+
+            Status = SamQueryInformationDomain(DomainHandle,
+                                               DomainLogoffInformation,
+                                               (PVOID*)&LogoffInfo);
+            if (!NT_SUCCESS(Status))
+            {
+                ApiStatus = NetpNtStatusToApiStatus(Status);
+                goto done;
+            }
+
+            BufferSize = sizeof(USER_MODALS_INFO_0);
+            break;
+
+        case 1:
+            /* return logon server and domain controller info */
+            Status = SamQueryInformationDomain(DomainHandle,
+                                               DomainServerRoleInformation,
+                                               (PVOID*)&ServerRoleInfo);
+            if (!NT_SUCCESS(Status))
+            {
+                ApiStatus = NetpNtStatusToApiStatus(Status);
+                goto done;
+            }
+
+            Status = SamQueryInformationDomain(DomainHandle,
+                                               DomainReplicationInformation,
+                                               (PVOID*)&ReplicationInfo);
+            if (!NT_SUCCESS(Status))
+            {
+                ApiStatus = NetpNtStatusToApiStatus(Status);
+                goto done;
+            }
+
+            BufferSize = sizeof(USER_MODALS_INFO_1) +
+                         ReplicationInfo->ReplicaSourceNodeName.Length + sizeof(WCHAR);
+            break;
+
+        case 2:
+            /* return domain name and identifier */
+            Status = SamQueryInformationDomain(DomainHandle,
+                                               DomainNameInformation,
+                                               (PVOID*)&NameInfo);
+            if (!NT_SUCCESS(Status))
+            {
+                ApiStatus = NetpNtStatusToApiStatus(Status);
+                goto done;
+            }
+
+            BufferSize = sizeof( USER_MODALS_INFO_2 ) +
+                         NameInfo->DomainName.Length + sizeof(WCHAR) +
+                         RtlLengthSid(DomainSid);
+            break;
+
+        case 3:
+            /* return lockout information */
+            Status = SamQueryInformationDomain(DomainHandle,
+                                               DomainLockoutInformation,
+                                               (PVOID*)&LockoutInfo);
+            if (!NT_SUCCESS(Status))
+            {
+                ApiStatus = NetpNtStatusToApiStatus(Status);
+                goto done;
+            }
+
+            BufferSize = sizeof(USER_MODALS_INFO_3);
+            break;
+
+        default:
+            TRACE("Invalid level %d is specified\n", level);
+            ApiStatus = ERROR_INVALID_LEVEL;
+            goto done;
+    }
+
+
+    ApiStatus = NetApiBufferAllocate(BufferSize,
+                                     (LPVOID *)bufptr);
+    if (ApiStatus != NERR_Success)
+    {
+        WARN("NetApiBufferAllocate() failed\n");
+        goto done;
+    }
+
+    switch (level)
+    {
+        case 0:
+            umi0 = (PUSER_MODALS_INFO_0)*bufptr;
+
+            umi0->usrmod0_min_passwd_len = PasswordInfo->MinPasswordLength;
+            umi0->usrmod0_max_passwd_age = (ULONG)(PasswordInfo->MaxPasswordAge.QuadPart / 10000000);
+            umi0->usrmod0_min_passwd_age =
+                DeltaTimeToSeconds(PasswordInfo->MinPasswordAge);
+            umi0->usrmod0_force_logoff =
+                DeltaTimeToSeconds(LogoffInfo->ForceLogoff);
+            umi0->usrmod0_password_hist_len = PasswordInfo->PasswordHistoryLength;
+            break;
+
+        case 1:
+            umi1 = (PUSER_MODALS_INFO_1)*bufptr;
+
+            switch (ServerRoleInfo->DomainServerRole)
+            {
+
+                    umi1->usrmod1_role = UAS_ROLE_STANDALONE;
+                    umi1->usrmod1_role = UAS_ROLE_MEMBER;
+
+                case DomainServerRolePrimary:
+                    umi1->usrmod1_role = UAS_ROLE_PRIMARY;
+                    break;
+
+                case DomainServerRoleBackup:
+                    umi1->usrmod1_role = UAS_ROLE_BACKUP;
+                    break;
+
+                default:
+                    ApiStatus = NERR_InternalError;
+                    goto done;
+            }
+
+            umi1->usrmod1_primary = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_1));
+            RtlCopyMemory(umi1->usrmod1_primary,
+                          ReplicationInfo->ReplicaSourceNodeName.Buffer,
+                          ReplicationInfo->ReplicaSourceNodeName.Length);
+            umi1->usrmod1_primary[ReplicationInfo->ReplicaSourceNodeName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+            break;
+
+        case 2:
+            umi2 = (PUSER_MODALS_INFO_2)*bufptr;
+
+            umi2->usrmod2_domain_name = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_2));
+            RtlCopyMemory(umi2->usrmod2_domain_name,
+                          NameInfo->DomainName.Buffer,
+                          NameInfo->DomainName.Length);
+            umi2->usrmod2_domain_name[NameInfo->DomainName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+            umi2->usrmod2_domain_id = *bufptr +
+                                      sizeof(USER_MODALS_INFO_2) +
+                                      NameInfo->DomainName.Length + sizeof(WCHAR);
+            RtlCopyMemory(umi2->usrmod2_domain_id,
+                          DomainSid,
+                          RtlLengthSid(DomainSid));
+            break;
+
+        case 3:
+            umi3 = (PUSER_MODALS_INFO_3)*bufptr;
+            umi3->usrmod3_lockout_duration =
+                DeltaTimeToSeconds(LockoutInfo->LockoutDuration);
+            umi3->usrmod3_lockout_observation_window =
+                DeltaTimeToSeconds(LockoutInfo->LockoutObservationWindow );
+            umi3->usrmod3_lockout_threshold = LockoutInfo->LockoutThreshold;
+            break;
+    }
+
+done:
+    if (LockoutInfo != NULL)
+        SamFreeMemory(LockoutInfo);
+
+    if (NameInfo != NULL)
+        SamFreeMemory(NameInfo);
+
+    if (ReplicationInfo != NULL)
+        SamFreeMemory(ReplicationInfo);
+
+    if (ServerRoleInfo != NULL)
+        SamFreeMemory(ServerRoleInfo);
+
+    if (LogoffInfo != NULL)
+        SamFreeMemory(LogoffInfo);
+
+    if (PasswordInfo != NULL)
+        SamFreeMemory(PasswordInfo);
+
+    if (DomainSid != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
+
+    if (DomainHandle != NULL)
+        SamCloseHandle(DomainHandle);
+
+    if (ServerHandle != NULL)
+        SamCloseHandle(ServerHandle);
+
+    return ApiStatus;
+}
+
+
+/******************************************************************************
+ * NetUserModalsSet  (NETAPI32.@)
+ */
+NET_API_STATUS
+WINAPI
+NetUserModalsSet(IN LPCWSTR servername,
+                 IN DWORD level,
+                 IN LPBYTE buf,
+                 OUT LPDWORD parm_err)
+{
+    FIXME("(%s %d %p %p)\n", debugstr_w(servername), level, buf, parm_err);
+    return ERROR_ACCESS_DENIED;
+}
+
+
 /******************************************************************************
  * NetUserSetGroups  (NETAPI32.@)
  */