Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

uipriv.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 priv.c 00008 00009 Abstract: 00010 00011 This module provides a command capability to enable and disable 00012 privileges. This command is expected to be an internal cmd.exe 00013 command, but is expected to be passed parameters as if it were 00014 an external command. 00015 00016 00017 THIS IS A TEMPORARY COMMAND. IF IT IS DESIRED TO MAKE THIS A 00018 PERMANENT COMMAND, THEN THIS FILE NEEDS TO BE GONE THROUGH WITH 00019 A FINE-TOOTH COMB TO ROBUSTLY HANDLE ALL ERROR SITUATIONS AND TO 00020 PROVIDE APPROPRIATE ERROR MESSAGES. 00021 00022 Author: 00023 00024 Jim Kelly 1-Apr-1991. 00025 00026 Revision History: 00027 00028 --*/ 00029 00030 #include <nt.h> 00031 #include <ntrtl.h> 00032 00033 //#include <sys\types.h> 00034 //#include <sys\stat.h> 00035 //#include <malloc.h> 00036 //#include <stdlib.h> 00037 //#include <ctype.h> 00038 #include <stdio.h> 00039 #include <string.h> 00040 00041 //#include <tools.h> 00042 00043 // 00044 // command qualifier flag values 00045 // 00046 00047 BOOLEAN SwitchEnable = FALSE; 00048 BOOLEAN SwitchDisable = FALSE; 00049 BOOLEAN SwitchReset = FALSE; 00050 BOOLEAN SwitchAll = FALSE; 00051 00052 #ifndef SHIFT 00053 #define SHIFT(c,v) {c--; v++;} 00054 #endif //SHIFT 00055 00056 00057 00058 00059 // 00060 // Function definitions... 00061 // 00062 00063 00064 VOID 00065 Usage ( VOID ); 00066 00067 BOOLEAN 00068 OpenAppropriateToken( 00069 OUT PHANDLE Token 00070 ); 00071 00072 VOID 00073 EnableAllPrivileges( VOID ); 00074 00075 VOID 00076 ResetAllPrivileges( VOID ); 00077 00078 VOID 00079 DisableAllPrivileges( VOID ); 00080 00081 int 00082 PrivMain ( 00083 IN int c, 00084 IN PCHAR v[] 00085 ); 00086 00087 00088 00089 00090 VOID 00091 Usage ( 00092 VOID 00093 ) 00094 /*++ 00095 00096 00097 Routine Description: 00098 00099 This routine prints the "Usage:" message. 00100 00101 Arguments: 00102 00103 None. 00104 00105 Return Value: 00106 00107 None. 00108 00109 --*/ 00110 { 00111 00112 printf( "\n"); 00113 printf( "\n"); 00114 00115 printf( "Usage: priv [/EDRA] {PrivilegeName}\n"); 00116 printf( " /E - Enable Privilege(s)\n"); 00117 printf( " /D - Disable Privilege(s)\n"); 00118 printf( " /R - Reset to default setting(s)\n"); 00119 printf( " /A - Apply To All Privileges\n"); 00120 printf( "\n"); 00121 00122 printf( " The qualifiers /E and /D are mutually exclusive and can not\n"); 00123 printf( " be used in the same command.\n"); 00124 printf( " If /A is specified, then the PrivilegeName is ignored.\n"); 00125 printf( "\n"); 00126 printf( "\n"); 00127 printf( "Examples:\n"); 00128 printf( "\n"); 00129 printf( " priv /ae\n"); 00130 printf( " (enables all held privileges.\n"); 00131 printf( "\n"); 00132 printf( " priv /ad\n"); 00133 printf( " disables all held privileges.\n"); 00134 printf( "\n"); 00135 printf( " priv /ar\n"); 00136 printf( " (returns all privileges to their default setting.\n"); 00137 printf( "\n"); 00138 printf( " priv /e SeSetTimePrivilege\n"); 00139 printf( " (enables the privileges called: SeSetTimePrivilege\n"); 00140 printf( "\n"); 00141 printf( "\n"); 00142 00143 return; 00144 } 00145 00146 00147 BOOLEAN 00148 OpenAppropriateToken( 00149 OUT PHANDLE Token 00150 ) 00151 /*++ 00152 00153 00154 Routine Description: 00155 00156 This routine opens the appropriate TOKEN object. For an internal 00157 command, this is the current process's token. If this command is 00158 ever made external, then it will be the parent process's token. 00159 00160 If the token can't be openned, then a messages is printed indicating 00161 a problem has been encountered. 00162 00163 The caller is expected to close this token when no longer needed. 00164 00165 00166 Arguments: 00167 00168 Token - Receives the handle value of the openned token. 00169 00170 00171 Return Value: 00172 00173 TRUE - Indicates the token was successfully openned. 00174 00175 FALSE - Indicates the token was NOT successfully openned. 00176 00177 --*/ 00178 00179 { 00180 NTSTATUS Status, IgnoreStatus; 00181 OBJECT_ATTRIBUTES ProcessAttributes; 00182 HANDLE Process; 00183 PTEB CurrentTeb; 00184 00185 CurrentTeb = NtCurrentTeb(); 00186 InitializeObjectAttributes(&ProcessAttributes, NULL, 0, NULL, NULL); 00187 Status = NtOpenProcess( 00188 &Process, // TargetHandle 00189 PROCESS_QUERY_INFORMATION, // DesiredAccess 00190 &ProcessAttributes, // ObjectAttributes 00191 &CurrentTeb->ClientId // ClientId 00192 ); 00193 00194 if (NT_SUCCESS(Status)) { 00195 00196 Status = NtOpenProcessToken( 00197 Process, 00198 TOKEN_ADJUST_PRIVILEGES | 00199 TOKEN_QUERY, 00200 Token 00201 ); 00202 00203 IgnoreStatus = NtClose( Process ); 00204 00205 if ( NT_SUCCESS(Status) ) { 00206 00207 return TRUE; 00208 00209 } 00210 00211 } 00212 00213 printf( "\n"); 00214 printf( "\n"); 00215 printf( "You are not allowed to change your own privilege settings.\n"); 00216 printf( "Operation failed.\n"); 00217 00218 return FALSE; 00219 00220 } 00221 00222 00223 00224 VOID 00225 EnableAllPrivileges( 00226 VOID 00227 ) 00228 /*++ 00229 00230 00231 Routine Description: 00232 00233 This routine enables all privileges in the token. 00234 00235 Arguments: 00236 00237 None. 00238 00239 Return Value: 00240 00241 None. 00242 00243 --*/ 00244 { 00245 NTSTATUS Status; 00246 HANDLE Token; 00247 ULONG ReturnLength, Index; 00248 PTOKEN_PRIVILEGES NewState; 00249 00250 00251 if ( !OpenAppropriateToken(&Token) ) { 00252 return; 00253 } 00254 00255 // 00256 // Get the size needed to query current privilege settings... 00257 // 00258 00259 Status = NtQueryInformationToken( 00260 Token, // TokenHandle 00261 TokenPrivileges, // TokenInformationClass 00262 NewState, // TokenInformation 00263 0, // TokenInformationLength 00264 &ReturnLength // ReturnLength 00265 ); 00266 ASSERT( Status == STATUS_BUFFER_TOO_SMALL ); 00267 00268 NewState = RtlAllocateHeap( RtlProcessHeap(), 0, ReturnLength ); 00269 ASSERT( NewState != NULL ); 00270 00271 00272 Status = NtQueryInformationToken( 00273 Token, // TokenHandle 00274 TokenPrivileges, // TokenInformationClass 00275 NewState, // TokenInformation 00276 ReturnLength, // TokenInformationLength 00277 &ReturnLength // ReturnLength 00278 ); 00279 ASSERT( NT_SUCCESS(Status) || NT_INFORMATION(Status) ); 00280 00281 00282 // 00283 // Set the state settings so that all privileges are enabled... 00284 // 00285 00286 if (NewState->PrivilegeCount > 0) { 00287 Index = NewState->PrivilegeCount; 00288 00289 while (Index < NewState->PrivilegeCount) { 00290 NewState->Privileges[Index].Attributes = SE_PRIVILEGE_ENABLED; 00291 Index += 1; 00292 } 00293 } 00294 00295 00296 // 00297 // Change the settings in the token... 00298 // 00299 00300 Status = NtAdjustPrivilegesToken( 00301 Token, // TokenHandle 00302 FALSE, // DisableAllPrivileges 00303 NewState, // NewState (OPTIONAL) 00304 ReturnLength, // BufferLength 00305 NULL, // PreviousState (OPTIONAL) 00306 &ReturnLength // ReturnLength 00307 ); 00308 ASSERT( NT_SUCCESS(Status) || NT_INFORMATION(Status) ); 00309 00310 00311 00312 RtlFreeHeap( RtlProcessHeap(), 0, NewState ); 00313 Status = NtClose( Token ); 00314 00315 return; 00316 00317 } 00318 00319 00320 00321 VOID 00322 ResetAllPrivileges( 00323 VOID 00324 ) 00325 /*++ 00326 00327 00328 Routine Description: 00329 00330 This routine resets all privileges in the token to their default state. 00331 00332 Arguments: 00333 00334 None. 00335 00336 Return Value: 00337 00338 None. 00339 00340 --*/ 00341 { 00342 NTSTATUS Status; 00343 HANDLE Token; 00344 ULONG ReturnLength, Index; 00345 PTOKEN_PRIVILEGES NewState; 00346 00347 00348 if ( !OpenAppropriateToken(&Token) ) { 00349 printf( "\n"); 00350 printf( "\n"); 00351 printf( "You are not allowed to change your own privilege settings.\n"); 00352 printf( "Operation failed.\n"); 00353 return; 00354 } 00355 00356 // 00357 // Get the size needed to query current privilege settings... 00358 // 00359 00360 Status = NtQueryInformationToken( 00361 Token, // TokenHandle 00362 TokenPrivileges, // TokenInformationClass 00363 NewState, // TokenInformation 00364 0, // TokenInformationLength 00365 &ReturnLength // ReturnLength 00366 ); 00367 ASSERT( STATUS_BUFFER_TOO_SMALL ); 00368 00369 NewState = RtlAllocateHeap( RtlProcessHeap(), 0, ReturnLength ); 00370 ASSERT( NewState != NULL ); 00371 00372 00373 Status = NtQueryInformationToken( 00374 Token, // TokenHandle 00375 TokenPrivileges, // TokenInformationClass 00376 NewState, // TokenInformation 00377 ReturnLength, // TokenInformationLength 00378 &ReturnLength // ReturnLength 00379 ); 00380 ASSERT( NT_SUCCESS(Status) || NT_INFORMATION(Status) ); 00381 00382 00383 // 00384 // Set the state settings so that all privileges are reset to 00385 // their default settings... 00386 // 00387 00388 if (NewState->PrivilegeCount > 0) { 00389 Index = NewState->PrivilegeCount; 00390 00391 while (Index < NewState->PrivilegeCount) { 00392 if (NewState->Privileges[Index].Attributes == 00393 SE_PRIVILEGE_ENABLED_BY_DEFAULT) { 00394 NewState->Privileges[Index].Attributes = SE_PRIVILEGE_ENABLED; 00395 } 00396 else { 00397 NewState->Privileges[Index].Attributes = 0; 00398 } 00399 00400 Index += 1; 00401 } 00402 } 00403 00404 00405 // 00406 // Change the settings in the token... 00407 // 00408 00409 Status = NtAdjustPrivilegesToken( 00410 Token, // TokenHandle 00411 FALSE, // DisableAllPrivileges 00412 NewState, // NewState (OPTIONAL) 00413 ReturnLength, // BufferLength 00414 NULL, // PreviousState (OPTIONAL) 00415 &ReturnLength // ReturnLength 00416 ); 00417 ASSERT( NT_SUCCESS(Status) || NT_INFORMATION(Status) ); 00418 00419 00420 00421 RtlFreeHeap( RtlProcessHeap(), 0, NewState ); 00422 Status = NtClose( Token ); 00423 00424 return; 00425 00426 } 00427 00428 00429 00430 00431 VOID 00432 DisableAllPrivileges( 00433 VOID 00434 ) 00435 /*++ 00436 00437 00438 Routine Description: 00439 00440 This routine disables all privileges in the token. 00441 00442 Arguments: 00443 00444 None. 00445 00446 Return Value: 00447 00448 None. 00449 00450 --*/ 00451 { 00452 ULONG IgnoredReturnLength; 00453 HANDLE Token; 00454 NTSTATUS Status; 00455 00456 if ( !OpenAppropriateToken(&Token) ) { 00457 printf( "\n"); 00458 printf( "\n"); 00459 printf( "You are not allowed to change your own privilege settings.\n"); 00460 printf( "Operation failed.\n"); 00461 return; 00462 } 00463 00464 // 00465 // Disable all the privileges. 00466 // 00467 00468 00469 Status = NtAdjustPrivilegesToken( 00470 Token, // TokenHandle 00471 TRUE, // DisableAllPrivileges 00472 NULL, // NewState (OPTIONAL) 00473 0, // BufferLength 00474 NULL, // PreviousState (OPTIONAL) 00475 &IgnoredReturnLength // ReturnLength 00476 ); 00477 ASSERT( NT_SUCCESS(Status) || NT_INFORMATION(Status) ); 00478 00479 Status = NtClose( Token ); 00480 return; 00481 00482 } 00483 00484 00485 int 00486 PrivMain ( 00487 IN int c, 00488 IN PCHAR v[] 00489 ) 00490 /*++ 00491 00492 00493 Routine Description: 00494 00495 This routine is the main entry routine for the "priv" command. 00496 00497 Arguments: 00498 00499 TBS 00500 00501 Return Value: 00502 00503 TBS 00504 00505 --*/ 00506 { 00507 PCHAR p; 00508 CHAR ch; 00509 ULONG DispositionDirectives; 00510 00511 00512 try { 00513 DispositionDirectives = 0; 00514 SHIFT (c,v); 00515 while ((c > 0) && ((ch = *v[0]))) { 00516 p = *v; 00517 if (ch == '/') { 00518 while (*++p != '\0') { 00519 if (*p == 'E') { 00520 SwitchEnable = TRUE; 00521 DispositionDirectives += 1; 00522 } 00523 if (*p == 'D') { 00524 SwitchDisable = TRUE; 00525 DispositionDirectives += 1; 00526 } 00527 if (*p == 'R') { 00528 SwitchReset = TRUE; 00529 DispositionDirectives += 1; 00530 } 00531 else if (*p == 'A') { 00532 SwitchAll = TRUE; 00533 } 00534 else { 00535 Usage(); 00536 } 00537 } 00538 SHIFT(c,v); 00539 } 00540 } 00541 00542 // 00543 // Make sure we don't have conflicting parameters 00544 // 00545 // Rules: 00546 // 00547 // If /A isn't specified, then a privilege name must be. 00548 // Exactly one of /E, /D, and /R must be specified. 00549 // 00550 // 00551 00552 00553 if (!SwitchAll && (c == 0)) { 00554 printf( "\n"); 00555 printf( "\n"); 00556 printf( "You must provide privilege name or use the /A switch.\n"); 00557 Usage(); 00558 return ( 0 ); 00559 } 00560 00561 if (DispositionDirectives != 1) { 00562 printf( "\n"); 00563 printf( "\n"); 00564 printf( "You must provide one and only one of the following"); 00565 printf( "switches: /E, /D, /R\n"); 00566 Usage(); 00567 return ( 0 ); 00568 00569 } 00570 00571 00572 // 00573 // Everything appears legitimate 00574 // 00575 00576 if (SwitchAll) { 00577 00578 // 00579 // /A switch specified 00580 // 00581 00582 if (SwitchEnable) { 00583 EnableAllPrivileges(); 00584 } 00585 else if (SwitchDisable) { 00586 DisableAllPrivileges(); 00587 } 00588 else { 00589 ResetAllPrivileges(); 00590 } 00591 } 00592 00593 // 00594 // privilege name specified... 00595 // 00596 00597 else { 00598 printf( "\n"); 00599 printf( "I'm sorry, but due to the lack of time and interest,\n"); 00600 printf( "individual privilege selection is not yet supported.\n"); 00601 printf( "Please use the /A qualifier for the time being.\n"); 00602 printf( "\n"); 00603 } 00604 00605 } finally { 00606 return ( 0 ); 00607 } 00608 00609 return( 0 ); 00610 00611 }

Generated on Sat May 15 19:42:11 2004 for test by doxygen 1.3.7