http://www.cnblogs.com/bluesky_blog/archive/2009/04/29.html管理用户权限可以实现以编程方式使用下列步骤:
- 打开与 LsaOpenPolicy() 的目标计算机上的策略。 要授予的权限,打开 POLICY_CREATE_ACCOUNT 和 POLICY_LOOKUP_NAMES 访问策略。 若要吊销权限,打开 POLICY_LOOKUP_NAMES 访问策略。
- 获取一个 SID (安全标识符),表示用户 / 组感兴趣。 LookupAccountName() 和 LsaLookupNames() API 可以从一个帐户名获取 SID。
- 调用 LsaAddAccountRights() 向由提供的 SID 的用户授予特权。
- 调用 LsaRemoveAccountRights() 撤消由提供的 SID 的用户权限。
- 关闭该策略与 LsaClose()。
要成功授予和吊销权限,调用方需要是目标系统上的管理员。
LSA API LsaEnumerateAccountRights() 可确定已授予的权限的帐户。
LSA API LsaEnumerateAccountsWithUserRight() 可确定哪些帐户已被授予指定的权限。
MSTOOLS\SECURITY 目录中 Windows 32 SDK 中提供的这些 LSA API 的文档和头文件。
在 Win32 SDK 的最新版本中, 邮件头显示在 mstools\samples\win32\winnt\security\include 目录中且文档处于正在 \security\lsasamp\lsaapi.hlp。
注意: 这些 LSA API 是当前实现以 Unicode 格式仅。
本示例将授予特权 SeServiceLogonRight 为 argv [1] 上指定的帐户。
此示例是依赖于这些导入库
advapi32.lib (对于 LsaXxx)
user32.lib (对于 wsprintf)
本示例将工作正确编译 ANSI 或 Unicode。
示例代码
1
/**//*++
2
You can use domain\account as argv[1]. For instance, mydomain\scott will
3
grant the privilege to the mydomain domain account scott.
4
The optional target machine is specified as argv[2], otherwise, the
5
account database is updated on the local machine.
6
The LSA APIs used by this sample are Unicode only.
7
Use LsaRemoveAccountRights() to remove account rights.
8
Scott Field (sfield) 12-Jul-95
9
--*/
10
#ifndef UNICODE
11
#define UNICODE
12
#endif // UNICODE
13
#include <windows.h>
14
#include <stdio.h>
15
#include "ntsecapi.h"
16
NTSTATUS
17
OpenPolicy(
18
LPWSTR ServerName, // machine to open policy on (Unicode)
19
DWORD DesiredAccess, // desired access to policy
20
PLSA_HANDLE PolicyHandle // resultant policy handle
21
);
22
BOOL
23
GetAccountSid(
24
LPTSTR SystemName, // where to lookup account
25
LPTSTR AccountName, // account of interest
26
PSID *Sid // resultant buffer containing SID
27
);
28
NTSTATUS
29
SetPrivilegeOnAccount(
30
LSA_HANDLE PolicyHandle, // open policy handle
31
PSID AccountSid, // SID to grant privilege to
32
LPWSTR PrivilegeName, // privilege to grant (Unicode)
33
BOOL bEnable // enable or disable
34
);
35
void
36
InitLsaString(
37
PLSA_UNICODE_STRING LsaString, // destination
38
LPWSTR String // source (Unicode)
39
);
40
void
41
DisplayNtStatus(
42
LPSTR szAPI, // pointer to function name (ANSI)
43
NTSTATUS Status // NTSTATUS error value
44
);
45
void
46
DisplayWinError(
47
LPSTR szAPI, // pointer to function name (ANSI)
48
DWORD WinError // DWORD WinError
49
);
50
#define RTN_OK 0
51
#define RTN_USAGE 1
52
#define RTN_ERROR 13
53
//
54
// If you have the ddk, include ntstatus.h.
55
//
56
#ifndef STATUS_SUCCESS
57
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
58
#endif
59
int _cdecl
60
main(int argc, char *argv[])
61

{
62
LSA_HANDLE PolicyHandle;
63
WCHAR wComputerName[256]=L""; // static machine name buffer
64
TCHAR AccountName[256]; // static account name buffer
65
PSID pSid;
66
NTSTATUS Status;
67
int iRetVal=RTN_ERROR; // assume error from main
68
if(argc == 1)
69

{
70
fprintf(stderr,"Usage: %s <Account> [TargetMachine]\n",
71
argv[0]);
72
return RTN_USAGE;
73
}
74
//
75
// Pick up account name on argv[1].
76
// Assumes source is ANSI. Resultant string is ANSI or Unicode
77
//
78
wsprintf(AccountName, TEXT("%hS"), argv[1]);
79
//
80
// Pick up machine name on argv[2], if appropriate
81
// assumes source is ANSI. Resultant string is Unicode.
82
//
83
if(argc == 3) wsprintfW(wComputerName, L"%hS", argv[2]);
84
//
85
// Open the policy on the target machine.
86
//
87
if((Status=OpenPolicy(
88
wComputerName, // target machine
89
POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
90
&PolicyHandle // resultant policy handle
91
)) != STATUS_SUCCESS)
{
92
DisplayNtStatus("OpenPolicy", Status);
93
return RTN_ERROR;
94
}
95
//
96
// Obtain the SID of the user/group.
97
// Note that we could target a specific machine, but we don't.
98
// Specifying NULL for target machine searches for the SID in the
99
// following order: well-known, Built-in and local, primary domain,
100
// trusted domains.
101
//
102
if(GetAccountSid(
103
NULL, // default lookup logic
104
AccountName,// account to obtain SID
105
&pSid // buffer to allocate to contain resultant SID
106
))
{
107
//
108
// We only grant the privilege if we succeeded in obtaining the
109
// SID. We can actually add SIDs which cannot be looked up, but
110
// looking up the SID is a good sanity check which is suitable for
111
// most cases.
112
//
113
// Grant the SeServiceLogonRight to users represented by pSid.
114
//
115
if((Status=SetPrivilegeOnAccount(
116
PolicyHandle, // policy handle
117
pSid, // SID to grant privilege
118
L"SeServiceLogonRight", // Unicode privilege
119
TRUE // enable the privilege
120
)) == STATUS_SUCCESS)
121
iRetVal=RTN_OK;
122
else
123
DisplayNtStatus("AddUserRightToAccount", Status);
124
}
125
else
{
126
//
127
// Error obtaining SID.
128
//
129
DisplayWinError("GetAccountSid", GetLastError());
130
}
131
//
132
// Close the policy handle.
133
//
134
LsaClose(PolicyHandle);
135
//
136
// Free memory allocated for SID.
137
//
138
if(pSid != NULL) HeapFree(GetProcessHeap(), 0, pSid);
139
return iRetVal;
140
}
141
void
142
InitLsaString(
143
PLSA_UNICODE_STRING LsaString,
144
LPWSTR String
145
)
146

{
147
DWORD StringLength;
148
if (String == NULL)
{
149
LsaString->Buffer = NULL;
150
LsaString->Length = 0;
151
LsaString->MaximumLength = 0;
152
return;
153
}
154
StringLength = wcslen(String);
155
LsaString->Buffer = String;
156
LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
157
LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
158
}
159
NTSTATUS
160
OpenPolicy(
161
LPWSTR ServerName,
162
DWORD DesiredAccess,
163
PLSA_HANDLE PolicyHandle
164
)
165

{
166
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
167
LSA_UNICODE_STRING ServerString;
168
PLSA_UNICODE_STRING Server = NULL;
169
//
170
// Always initialize the object attributes to all zeroes.
171
//
172
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
173
if (ServerName != NULL)
{
174
//
175
// Make a LSA_UNICODE_STRING out of the LPWSTR passed in
176
//
177
InitLsaString(&ServerString, ServerName);
178
Server = &ServerString;
179
}
180
//
181
// Attempt to open the policy.
182
//
183
return LsaOpenPolicy(
184
Server,
185
&ObjectAttributes,
186
DesiredAccess,
187
PolicyHandle
188
);
189
}
190
/**//*++
191
This function attempts to obtain a SID representing the supplied
192
account on the supplied system.
193
If the function succeeds, the return value is TRUE. A buffer is
194
allocated which contains the SID representing the supplied account.
195
This buffer should be freed when it is no longer needed by calling
196
HeapFree(GetProcessHeap(), 0, buffer)
197
If the function fails, the return value is FALSE. Call GetLastError()
198
to obtain extended error information.
199
Scott Field (sfield) 12-Jul-95
200
--*/
201
BOOL
202
GetAccountSid(
203
LPTSTR SystemName,
204
LPTSTR AccountName,
205
PSID *Sid
206
)
207

{
208
LPTSTR ReferencedDomain=NULL;
209
DWORD cbSid=128; // initial allocation attempt
210
DWORD cchReferencedDomain=16; // initial allocation size
211
SID_NAME_USE peUse;
212
BOOL bSuccess=FALSE; // assume this function will fail
213
__try
{
214
//
215
// initial memory allocations
216
//
217
if((*Sid=HeapAlloc(
218
GetProcessHeap(),
219
0,
220
cbSid
221
)) == NULL) __leave;
222
if((ReferencedDomain=(LPTSTR)HeapAlloc(
223
GetProcessHeap(),
224
0,
225
cchReferencedDomain * sizeof(TCHAR)
226
)) == NULL) __leave;
227
//
228
// Obtain the SID of the specified account on the specified system.
229
//
230
while(!LookupAccountName(
231
SystemName, // machine to lookup account on
232
AccountName, // account to lookup
233
*Sid, // SID of interest
234
&cbSid, // size of SID
235
ReferencedDomain, // domain account was found on
236
&cchReferencedDomain,
237
&peUse
238
))
{
239
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
240
//
241
// reallocate memory
242
//
243
if((*Sid=HeapReAlloc(
244
GetProcessHeap(),
245
0,
246
*Sid,
247
cbSid
248
)) == NULL) __leave;
249
if((ReferencedDomain=(LPTSTR)HeapReAlloc(
250
GetProcessHeap(),
251
0,
252
ReferencedDomain,
253
cchReferencedDomain * sizeof(TCHAR)
254
)) == NULL) __leave;
255
}
256
else __leave;
257
}
258
//
259
// Indicate success.
260
//
261
bSuccess=TRUE;
262
} // finally
263
__finally
{
264
//
265
// Cleanup and indicate failure, if appropriate.
266
//
267
HeapFree(GetProcessHeap(), 0, ReferencedDomain);
268
if(!bSuccess)
{
269
if(*Sid != NULL)
{
270
HeapFree(GetProcessHeap(), 0, *Sid);
271
*Sid = NULL;
272
}
273
}
274
} // finally
275
return bSuccess;
276
}
277
NTSTATUS
278
SetPrivilegeOnAccount(
279
LSA_HANDLE PolicyHandle, // open policy handle
280
PSID AccountSid, // SID to grant privilege to
281
LPWSTR PrivilegeName, // privilege to grant (Unicode)
282
BOOL bEnable // enable or disable
283
)
284

{
285
LSA_UNICODE_STRING PrivilegeString;
286
//
287
// Create a LSA_UNICODE_STRING for the privilege name.
288
//
289
InitLsaString(&PrivilegeString, PrivilegeName);
290
//
291
// grant or revoke the privilege, accordingly
292
//
293
if(bEnable)
{
294
return LsaAddAccountRights(
295
PolicyHandle, // open policy handle
296
AccountSid, // target SID
297
&PrivilegeString, // privileges
298
1 // privilege count
299
);
300
}
301
else
{
302
return LsaRemoveAccountRights(
303
PolicyHandle, // open policy handle
304
AccountSid, // target SID
305
FALSE, // do not disable all rights
306
&PrivilegeString, // privileges
307
1 // privilege count
308
);
309
}
310
}
311
void
312
DisplayNtStatus(
313
LPSTR szAPI,
314
NTSTATUS Status
315
)
316

{
317
//
318
// Convert the NTSTATUS to Winerror. Then call DisplayWinError().
319
//
320
DisplayWinError(szAPI, LsaNtStatusToWinError(Status));
321
}
322
void
323
DisplayWinError(
324
LPSTR szAPI,
325
DWORD WinError
326
)
327

{
328
LPSTR MessageBuffer;
329
DWORD dwBufferLength;
330
//
331
// TODO: Get this fprintf out of here!
332
//
333
fprintf(stderr,"%s error!\n", szAPI);
334
if(dwBufferLength=FormatMessageA(
335
FORMAT_MESSAGE_ALLOCATE_BUFFER |
336
FORMAT_MESSAGE_FROM_SYSTEM,
337
NULL,
338
WinError,
339
GetUserDefaultLangID(),
340
(LPSTR) &MessageBuffer,
341
0,
342
NULL
343
))
344

{
345
DWORD dwBytesWritten; // unused
346
//
347
// Output message string on stderr.
348
//
349
WriteFile(
350
GetStdHandle(STD_ERROR_HANDLE),
351
MessageBuffer,
352
dwBufferLength,
353
&dwBytesWritten,
354
NULL
355
);
356
//
357
// Free the buffer allocated by the system.
358
//
359
LocalFree(MessageBuffer);
360
}
361
}
362
363
/**//*++
364
This function enables system access on the account represented by the
365
supplied SID. An example of such access is the SeLogonServiceRight.
366
Note: to disable a given system access, simply remove the supplied
367
access flag from the existing flag, and apply the result to the
368
account.
369
If the function succeeds, the return value is STATUS_SUCCESS.
370
If the function fails, the return value is an NTSTATUS value.
371
Scott Field (sfield) 14-Jul-95
372
--*/
373
NTSTATUS
374
AddSystemAccessToAccount(
375
LSA_HANDLE PolicyHandle,
376
PSID AccountSid,
377
ULONG NewAccess
378
)
379

{
380
LSA_HANDLE AccountHandle;
381
ULONG PreviousAccess;
382
NTSTATUS Status;
383
//
384
// open the account object. If it doesn't exist, create a new one
385
//
386
if((Status=LsaOpenAccount(
387
PolicyHandle,
388
AccountSid,
389
ACCOUNT_ADJUST_SYSTEM_ACCESS | ACCOUNT_VIEW,
390
&AccountHandle
391
)) == STATUS_OBJECT_NAME_NOT_FOUND)
392

{
393
Status=LsaCreateAccount(
394
PolicyHandle,
395
AccountSid,
396
ACCOUNT_ADJUST_SYSTEM_ACCESS | ACCOUNT_VIEW,
397
&AccountHandle
398
);
399
}
400
//
401
// if an error occurred opening or creating, return
402
//
403
if(Status != STATUS_SUCCESS) return Status;
404
//
405
// obtain current system access flags
406
//
407
if((Status=LsaGetSystemAccessAccount(
408
AccountHandle,
409
&PreviousAccess
410
)) == STATUS_SUCCESS)
411

{
412
//
413
// Add the specified access to the account
414
//
415
Status=LsaSetSystemAccessAccount(
416
AccountHandle,
417
PreviousAccess | NewAccess
418
);
419
}
420
LsaClose(AccountHandle);
421
return Status;
422
}
423
/**//*++
424
This function grants a privilege to the account represented by the
425
supplied SID. An example of such a privilege is the
426
SeBackupPrivilege.
427
Note: To revoke a privilege, use LsaRemovePrivilegesFromAccount.
428
If the function succeeds, the return value is STATUS_SUCCESS.
429
If the function fails, the return value is an NTSTATUS value.
430
Scott Field (sfield) 13-Jul-95
431
--*/
432
NTSTATUS
433
AddPrivilegeToAccount(
434
LSA_HANDLE PolicyHandle,
435
PSID AccountSid,
436
LPWSTR PrivilegeName
437
)
438

{
439
PRIVILEGE_SET ps;
440
LUID_AND_ATTRIBUTES luidattr;
441
LSA_HANDLE AccountHandle;
442
LSA_UNICODE_STRING PrivilegeString;
443
NTSTATUS Status;
444
//
445
// Create a LSA_UNICODE_STRING for the privilege name
446
//
447
InitLsaString(&PrivilegeString, PrivilegeName);
448
//
449
// obtain the LUID of the supplied privilege
450
//
451
if((Status=LsaLookupPrivilegeValue(
452
PolicyHandle,
453
&PrivilegeString,
454
&luidattr.Luid
455
)) != STATUS_SUCCESS) return Status;
456
//
457
// setup PRIVILEGE_SET
458
//
459
luidattr.Attributes=0;
460
ps.PrivilegeCount=1;
461
ps.Control=0;
462
ps.Privilege[0]=luidattr;
463
//
464
// open the account object if it doesn't exist, create a new one
465
//
466
if((Status=LsaOpenAccount(
467
PolicyHandle,
468
AccountSid,
469
ACCOUNT_ADJUST_PRIVILEGES,
470
&AccountHandle
471
)) == STATUS_OBJECT_NAME_NOT_FOUND)
472

{
473
Status=LsaCreateAccount(
474
PolicyHandle,
475
AccountSid,
476
ACCOUNT_ADJUST_PRIVILEGES,
477
&AccountHandle
478
);
479
}
480
//
481
// if an error occurred opening or creating, return
482
//
483
if(Status != STATUS_SUCCESS) return Status;
484
//
485
// add the privileges to the account
486
//
487
Status=LsaAddPrivilegesToAccount(
488
AccountHandle,
489
&ps
490
);
491
LsaClose(AccountHandle);
492
return Status;
493
}
494
495