powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Сервис от имени user. Проверка/установка политики-права "Вход в качестве службы"
3 сообщений из 3, страница 1 из 1
Сервис от имени user. Проверка/установка политики-права "Вход в качестве службы"
    #39549253
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Установили службу.
Худо-бедно разобрались как запускать ее от имени конкретного пользователя.
Вот этот код я приводил:
Запуск службы "с учетной записью пользователя".

Код: vbnet
1.
2.
3.
    ' Change the service account name
    If ChangeServiceConfig(schService, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, _
     , , , , ServiceStartName, Password, ) = False Then


Но кой-чего существенное я таки упустил.
А именно, если следовать gpedit.exe
Политика "Локальный компьютер" -> Конфигурация компьютера -> Конфигурация Windows -> Параметры безопасности -> Локальные политики -> Назначение прав пользователя -> Вход в качестве службы
Пользователь для которого устанавливается служба должен там присутствовать.
(иначе грош цена моему коду, если права нет).
К слову оснастка mmc "Службы" эту задачу также решает (ну надо думать от имени админа).

Плюс gpedit.exe еще и не на всех системах есть На своем рабочем Home Win 10 я вообще не знаю как это хотяб проверить не методом тыка (тык это мой код по ссылке выше, юзера назначил а не работает).

Т.е. формулируем вопросы:
==================
1) Как мне хотя б ручками проверить имеет ли заданный юзер (напр. текущий D\Dmitry) право "Вход в качестве службы"? (через реестр, cmd, через штатные инструменты). Если нету gpedit.msc и без установки сторонних/левых tools (в том числе неположенной на ЭТОЙ системе gpedit).
2) Как мне проверить наличие указанного права программно?
3) Ну и наконец главное: как программно задать право "Вход в качестве службы" для заданного юзера?
(ну будем считать что по крайней мере пункт 3 выполняется "As Admin", а у админа право сделать это действо надо думать есть)
...
Рейтинг: 0 / 0
Сервис от имени user. Проверка/установка политики-права "Вход в качестве службы"
    #39549288
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, в принципе направление движения примерно понял.
Easiest way to grant “Log on as a service” to a Windows user from the command-line?
Здесь совет такой:

Windows Server 2003 Resource Kit Tools
Утилита ntrights.exe (ее можно тупо вырвать из пакета и перенести на любую Win10 и т.п.)

Добавить права:
Код: vbnet
1.
2.
ntrights.exe -u D\Dmitry +r SeServiceLogonRight
 Granting SeServiceLogonRight to D\Dmitry   ... successful


Отобрать права:
Код: vbnet
1.
2.
ntrights.exe -u D\Dmitry -r SeServiceLogonRight
 Revoking SeServiceLogonRight from D\Dmitry   ... successful



Проверил на десятке x64 - все работает.
Проверил на XP - все работает, делает ровно то что можно сделать ручками в "политиках" через gpedit.msc.

Правда, не дает ответ на вопрос, есть ли эти права, но в принципе и не обязательно, достаточно "успешно добавить".

Как простейший вариант, можно эту утилиту просто стибрить к себе в прогу.

Ну а если делать хорошо (API-простыня), то видимо копать сюда:

How To Manage User Privileges Programmatically in Windows NT

LSA Functions - Privileges and Impersonation
...
Рейтинг: 0 / 0
Сервис от имени user. Проверка/установка политики-права "Вход в качестве службы"
    #39549307
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Ну а если делать хорошо
Как-то так получилось
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    Me.TextBoxUserName.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name
  End Sub

  Private Sub ButtonAddPrivilege_Click(sender As Object, e As EventArgs) Handles ButtonAddPrivilege.Click
    Dim err_text As String = ""
    If SetUserRight(err_text, Me.TextBoxUserName.Text, "SeServiceLogonRight", True) = False Then
      MsgBox(err_text)
    Else
      MsgBox("OK")
    End If
  End Sub

  Private Sub ButtonRemovePrivilege_Click(sender As Object, e As EventArgs) Handles ButtonRemovePrivilege.Click
    Dim err_text As String = ""
    If SetUserRight(err_text, Me.TextBoxUserName.Text, "SeServiceLogonRight", False) = False Then
      MsgBox(err_text)
    Else
      MsgBox("OK")
    End If
  End Sub




Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
 Public Function SetUserRight(ByRef err_text As String, _
   ByVal accountName As String, ByVal privilegeName As String, _
   Optional ByVal bEnable As Boolean = True) As Boolean
    SetUserRight = True

    Dim dwRes As Integer
    Dim p_abytSIDTarget() As Byte 'вместо pSIDTarget
    Dim pSIDTarget As IntPtr
    Dim dwSIDTarget As Integer 'size of the Sid buffer
    Dim DomainName As String = "" 'domain name на выходе
    Dim dwDomainName As Integer 'size of domain name buffer
    Dim eUse As Integer 'SID type
    Dim bRtnBool As Boolean
    Dim pPrivilegeName As IntPtr

    'Create a SID for specified account
    'Preinitialize p_abytSIDAdmin array with one element. It will be redimmed lated
    ReDim p_abytSIDTarget(1)
    'First call to LookupAccountName to get the buffer sizes.
    bRtnBool = LookupAccountName(vbNullString, accountName, p_abytSIDTarget, dwSIDTarget, _
     DomainName, dwDomainName, eUse)
    If (bRtnBool = False) And (Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER) Then
      SetUserRight = False
      err_text = "LookupAccountName Error " & RaiseAPIError()
      GoTo ToExit
    End If
    'Debug.Print("dwSIDTarget=" & dwSIDTarget & vbCrLf & "dwDomainName=" & dwDomainName)

    'Allocate the required space in the p_abytSIDAdmin and DomainName string
    'variables. Allocate 1 byte less to avoid the appended NULL character.
    ReDim p_abytSIDTarget(dwSIDTarget)
    DomainName = Space(dwDomainName - 1)

    'Second call to LookupAccountName to get p_abytSIDAdmin.
    If LookupAccountName(vbNullString, accountName, p_abytSIDTarget, dwSIDTarget, _
     DomainName, dwDomainName, eUse) = False Then
      SetUserRight = False
      err_text = "LookupAccountName Error " & RaiseAPIError()
      GoTo ToExit
    End If
    'Debug.Print(DomainName)

    pSIDTarget = Marshal.AllocHGlobal(dwSIDTarget)
    Marshal.Copy(p_abytSIDTarget, 0, pSIDTarget, dwSIDTarget)

    Dim PolicyHandle As IntPtr
    'initialize an empty unicode-string
    Dim SystemName As New LSA_UNICODE_STRING
    'these attributes are not used, but LsaOpenPolicy wants them to exists
    Dim ObjectAttributes As New LSA_OBJECT_ATTRIBUTES
    With ObjectAttributes
      .Length = 0
      .RootDirectory = IntPtr.Zero
      .Attributes = 0
      .SecurityDescriptor = IntPtr.Zero
      .SecurityQualityOfService = IntPtr.Zero
    End With

    'Attempt to open the policy
    dwRes = LsaOpenPolicy(SystemName, ObjectAttributes, POLICY_CREATE_ACCOUNT Or POLICY_LOOKUP_NAMES, PolicyHandle)
    If dwRes <> STATUS_SUCCESS Then
      SetUserRight = False
      err_text = "LsaOpenPolicy Error " & RaiseAPIErrorByNumber(LsaNtStatusToWinError(dwRes))
      GoTo ToExit
    End If

    'initialize an unicode-string for the privilege name
    Dim userRights As LSA_UNICODE_STRING = New LSA_UNICODE_STRING
    pPrivilegeName = Marshal.StringToHGlobalUni(privilegeName)
    userRights.Buffer = pPrivilegeName
    userRights.Length = CType(Strings.Len(privilegeName) * System.Text.UnicodeEncoding.CharSize, UShort)
    userRights.MaximumLength = CType((Strings.Len(privilegeName) + 1) * System.Text.UnicodeEncoding.CharSize, UShort)
    If bEnable Then
      dwRes = LsaAddAccountRights(PolicyHandle, pSIDTarget, userRights, 1)
      If dwRes <> STATUS_SUCCESS Then
        SetUserRight = False
        err_text = "LsaAddAccountRights Error " & RaiseAPIErrorByNumber(LsaNtStatusToWinError(dwRes))
        GoTo ToExit
      End If
    Else
      dwRes = LsaRemoveAccountRights(PolicyHandle, pSIDTarget, False, userRights, 1)
      If dwRes <> STATUS_SUCCESS Then
        SetUserRight = False
        err_text = "LsaRemoveAccountRights Error " & RaiseAPIErrorByNumber(LsaNtStatusToWinError(dwRes))
        GoTo ToExit
      End If
    End If

ToExit:
    If Not pSIDTarget.Equals(0) Then
      Marshal.FreeHGlobal(pSIDTarget)
    End If

    If Not pPrivilegeName.Equals(0) Then
      Marshal.FreeHGlobal(pPrivilegeName)
    End If

    If PolicyHandle <> IntPtr.Zero Then LsaClose(PolicyHandle)

  End Function



Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
Imports System.Runtime.InteropServices

Module ModuleAPI
  Public Const ERROR_INSUFFICIENT_BUFFER = 122&

  Public Declare Unicode Function LookupAccountName Lib "advapi32.dll" _
   Alias "LookupAccountNameW" (ByVal lpSystemName As String, ByVal lpAccountName As String, _
   <MarshalAs(UnmanagedType.LPArray)> Sid As Byte(), ByRef cbSid As Integer, _
   ByVal ReferencedDomainName As String, _
   ByRef cchReferencedDomainName As Integer, ByRef peUse As Integer) As Boolean

  Public Function RaiseAPIError() As String
    Return Err.LastDllError.ToString & " (" & (New System.ComponentModel.Win32Exception(Err.LastDllError)).Message & ")"
  End Function
  Public Function RaiseAPIErrorByNumber(ByVal ErrNum As Integer) As String
    Return ErrNum.ToString & " (" & (New System.ComponentModel.Win32Exception(ErrNum)).Message & ")"
  End Function

  <StructLayout(LayoutKind.Sequential)>
  Public Structure LSA_UNICODE_STRING
    Dim Length As UShort
    Dim MaximumLength As UShort
    Dim Buffer As IntPtr
  End Structure

  <StructLayout(LayoutKind.Sequential)>
  Public Structure LSA_OBJECT_ATTRIBUTES
    Dim Length As UInteger
    Dim RootDirectory As IntPtr
    Dim ObjectName As LSA_UNICODE_STRING
    Dim Attributes As UInteger
    Dim SecurityDescriptor As IntPtr
    Dim SecurityQualityOfService As IntPtr
  End Structure

  Public Const POLICY_CREATE_ACCOUNT = &H10
  Public Const POLICY_LOOKUP_NAMES = &H800

  Public Const STATUS_SUCCESS = 0

  Public Declare Function LsaAddAccountRights Lib "advapi32.dll" ( _
   ByVal PolicyHandle As IntPtr, _
   ByVal AccountSid As IntPtr, _
   ByRef UserRights As LSA_UNICODE_STRING, _
   ByVal CountOfRights As UInteger _
   ) As Integer
  Public Declare Function LsaClose Lib "advapi32.dll" ( _
   ByVal ObjectHandle As IntPtr) As Integer
  Public Declare Function LsaNtStatusToWinError Lib "advapi32.dll" ( _
   ByVal Status As Integer) As Integer
  Public Declare Function LsaOpenPolicy Lib "advapi32.dll" ( _
   ByRef SystemName As LSA_UNICODE_STRING, _
   ByRef ObjectAttributes As LSA_OBJECT_ATTRIBUTES, _
   ByVal DesiredAccess As Integer, _
   ByRef PolicyHandle As IntPtr) As Integer
  Public Declare Function LsaRemoveAccountRights Lib "advapi32.dll" ( _
   ByVal PolicyHandle As IntPtr, _
   ByVal AccountSid As IntPtr, _
   ByVal AllRights As Boolean, _
   ByRef UserRights As LSA_UNICODE_STRING, _
   ByVal CountOfRights As UInteger _
   ) As Integer
End Module

...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Сервис от имени user. Проверка/установка политики-права "Вход в качестве службы"
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]