utils/net_rpc_rights.c

説明を見る。
00001 /* 
00002    Samba Unix/Linux SMB client library 
00003    Distributed SMB/CIFS Server Management Utility 
00004    Copyright (C) Gerald (Jerry) Carter          2004
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
00019  
00020 #include "includes.h"
00021 #include "utils/net.h"
00022 
00023 /********************************************************************
00024 ********************************************************************/
00025 
00026 static NTSTATUS sid_to_name(struct rpc_pipe_client *pipe_hnd,
00027                                 TALLOC_CTX *mem_ctx,
00028                                 DOM_SID *sid,
00029                                 fstring name)
00030 {
00031         POLICY_HND pol;
00032         enum lsa_SidType *sid_types;
00033         NTSTATUS result;
00034         char **domains, **names;
00035 
00036         result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, 
00037                 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
00038                 
00039         if ( !NT_STATUS_IS_OK(result) )
00040                 return result;
00041 
00042         result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &pol, 1, sid, &domains, &names, &sid_types);
00043         
00044         if ( NT_STATUS_IS_OK(result) ) {
00045                 if ( *domains[0] )
00046                         fstr_sprintf( name, "%s\\%s", domains[0], names[0] );
00047                 else
00048                         fstrcpy( name, names[0] );
00049         }
00050 
00051         rpccli_lsa_close(pipe_hnd, mem_ctx, &pol);
00052         return result;
00053 }
00054 
00055 /********************************************************************
00056 ********************************************************************/
00057 
00058 static NTSTATUS name_to_sid(struct rpc_pipe_client *pipe_hnd,
00059                             TALLOC_CTX *mem_ctx,
00060                             DOM_SID *sid, const char *name)
00061 {
00062         POLICY_HND pol;
00063         enum lsa_SidType *sid_types;
00064         NTSTATUS result;
00065         DOM_SID *sids;
00066 
00067         /* maybe its a raw SID */
00068         if ( strncmp(name, "S-", 2) == 0 && string_to_sid(sid, name) ) {
00069                 return NT_STATUS_OK;
00070         }
00071 
00072         result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, 
00073                 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
00074                 
00075         if ( !NT_STATUS_IS_OK(result) )
00076                 return result;
00077 
00078         result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &pol, 1, &name,
00079                                          NULL, &sids, &sid_types);
00080         
00081         if ( NT_STATUS_IS_OK(result) )
00082                 sid_copy( sid, &sids[0] );
00083 
00084         rpccli_lsa_close(pipe_hnd, mem_ctx, &pol);
00085         return result;
00086 }
00087 
00088 /********************************************************************
00089 ********************************************************************/
00090 
00091 static NTSTATUS enum_privileges(struct rpc_pipe_client *pipe_hnd,
00092                                 TALLOC_CTX *ctx,
00093                                 POLICY_HND *pol )
00094 {
00095         NTSTATUS result;
00096         uint32 enum_context = 0;
00097         uint32 pref_max_length=0x1000;
00098         uint32 count=0;
00099         char   **privs_name;
00100         uint32 *privs_high;
00101         uint32 *privs_low;
00102         int i;
00103         uint16 lang_id=0;
00104         uint16 lang_id_sys=0;
00105         uint16 lang_id_desc;
00106         fstring description;
00107 
00108         result = rpccli_lsa_enum_privilege(pipe_hnd, ctx, pol, &enum_context, 
00109                 pref_max_length, &count, &privs_name, &privs_high, &privs_low);
00110 
00111         if ( !NT_STATUS_IS_OK(result) )
00112                 return result;
00113 
00114         /* Print results */
00115         
00116         for (i = 0; i < count; i++) {
00117                 d_printf("%30s  ", privs_name[i] ? privs_name[i] : "*unknown*" );
00118                 
00119                 /* try to get the description */
00120                 
00121                 if ( !NT_STATUS_IS_OK(rpccli_lsa_get_dispname(pipe_hnd, ctx, pol, 
00122                         privs_name[i], lang_id, lang_id_sys, description, &lang_id_desc)) )
00123                 {
00124                         d_printf("??????\n");
00125                         continue;
00126                 }
00127                 
00128                 d_printf("%s\n", description );         
00129         }
00130 
00131         return NT_STATUS_OK;
00132 }
00133 
00134 /********************************************************************
00135 ********************************************************************/
00136 
00137 static NTSTATUS check_privilege_for_user(struct rpc_pipe_client *pipe_hnd,
00138                                         TALLOC_CTX *ctx,
00139                                         POLICY_HND *pol,
00140                                         DOM_SID *sid,
00141                                         const char *right)
00142 {
00143         NTSTATUS result;
00144         uint32 count;
00145         char **rights;
00146         int i;
00147 
00148         result = rpccli_lsa_enum_account_rights(pipe_hnd, ctx, pol, sid, &count, &rights);
00149 
00150         if (!NT_STATUS_IS_OK(result)) {
00151                 return result;
00152         }
00153 
00154         if (count == 0) {
00155                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
00156         }
00157                 
00158         for (i = 0; i < count; i++) {
00159                 if (StrCaseCmp(rights[i], right) == 0) {
00160                         return NT_STATUS_OK;
00161                 }
00162         }
00163 
00164         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
00165 }
00166 
00167 /********************************************************************
00168 ********************************************************************/
00169 
00170 static NTSTATUS enum_privileges_for_user(struct rpc_pipe_client *pipe_hnd,
00171                                         TALLOC_CTX *ctx,
00172                                         POLICY_HND *pol,
00173                                         DOM_SID *sid )
00174 {
00175         NTSTATUS result;
00176         uint32 count;
00177         char **rights;
00178         int i;
00179 
00180         result = rpccli_lsa_enum_account_rights(pipe_hnd, ctx, pol, sid, &count, &rights);
00181 
00182         if (!NT_STATUS_IS_OK(result))
00183                 return result;
00184 
00185         if ( count == 0 )
00186                 d_printf("No privileges assigned\n");
00187                 
00188         for (i = 0; i < count; i++) {
00189                 printf("%s\n", rights[i]);
00190         }
00191 
00192         return NT_STATUS_OK;
00193 }
00194 
00195 /********************************************************************
00196 ********************************************************************/
00197 
00198 static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd,
00199                                                 TALLOC_CTX *ctx,
00200                                                 POLICY_HND *pol,
00201                                                 const char *privilege)
00202 {
00203         NTSTATUS result;
00204         uint32 enum_context=0;
00205         uint32 pref_max_length=0x1000;
00206         DOM_SID *sids;
00207         uint32 count=0;
00208         int i;
00209         fstring name;
00210 
00211         result = rpccli_lsa_enum_sids(pipe_hnd, ctx, pol, &enum_context, 
00212                 pref_max_length, &count, &sids);
00213 
00214         if (!NT_STATUS_IS_OK(result))
00215                 return result;
00216                 
00217         d_printf("%s:\n", privilege);
00218 
00219         for ( i=0; i<count; i++ ) {
00220         
00221                    
00222                 result = check_privilege_for_user( pipe_hnd, ctx, pol, &sids[i], privilege);
00223                 
00224                 if ( ! NT_STATUS_IS_OK(result)) {
00225                         if ( ! NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
00226                                 return result;
00227                         }
00228                         continue;
00229                 }
00230 
00231                 /* try to convert the SID to a name.  Fall back to 
00232                    printing the raw SID if necessary */
00233                 result = sid_to_name( pipe_hnd, ctx, &sids[i], name );
00234                 if ( !NT_STATUS_IS_OK (result) )
00235                         fstrcpy( name, sid_string_static(&sids[i]) );
00236                         
00237                 d_printf("  %s\n", name);
00238         }
00239 
00240         return NT_STATUS_OK;
00241 }
00242 
00243 /********************************************************************
00244 ********************************************************************/
00245 
00246 static NTSTATUS enum_privileges_for_accounts(struct rpc_pipe_client *pipe_hnd,
00247                                                 TALLOC_CTX *ctx,
00248                                                 POLICY_HND *pol)
00249 {
00250         NTSTATUS result;
00251         uint32 enum_context=0;
00252         uint32 pref_max_length=0x1000;
00253         DOM_SID *sids;
00254         uint32 count=0;
00255         int i;
00256         fstring name;
00257 
00258         result = rpccli_lsa_enum_sids(pipe_hnd, ctx, pol, &enum_context, 
00259                 pref_max_length, &count, &sids);
00260 
00261         if (!NT_STATUS_IS_OK(result))
00262                 return result;
00263                 
00264         for ( i=0; i<count; i++ ) {
00265         
00266                 /* try to convert the SID to a name.  Fall back to 
00267                    printing the raw SID if necessary */
00268                    
00269                 result = sid_to_name(pipe_hnd, ctx, &sids[i], name );
00270                 if ( !NT_STATUS_IS_OK (result) )
00271                         fstrcpy( name, sid_string_static(&sids[i]) );
00272                         
00273                 d_printf("%s\n", name);
00274                 
00275                 result = enum_privileges_for_user(pipe_hnd, ctx, pol, &sids[i] );
00276                 
00277                 if ( !NT_STATUS_IS_OK(result) )
00278                         return result;
00279 
00280                 d_printf("\n");
00281         }
00282 
00283         return NT_STATUS_OK;
00284 }
00285 
00286 /********************************************************************
00287 ********************************************************************/
00288 
00289 static NTSTATUS rpc_rights_list_internal(const DOM_SID *domain_sid,
00290                                         const char *domain_name, 
00291                                         struct cli_state *cli,
00292                                         struct rpc_pipe_client *pipe_hnd,
00293                                         TALLOC_CTX *mem_ctx, 
00294                                         int argc,
00295                                         const char **argv )
00296 {
00297         POLICY_HND pol;
00298         NTSTATUS result;
00299         DOM_SID sid;
00300         fstring privname;
00301         fstring description;
00302         uint16 lang_id = 0;
00303         uint16 lang_id_sys = 0;
00304         uint16 lang_id_desc;
00305         
00306         
00307         result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, 
00308                 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
00309 
00310         if ( !NT_STATUS_IS_OK(result) )
00311                 return result;
00312         
00313         /* backwards compatibility; just list available privileges if no arguement */
00314            
00315         if (argc == 0) {
00316                 result = enum_privileges(pipe_hnd, mem_ctx, &pol );
00317                 goto done;
00318         }
00319 
00320         if (strequal(argv[0], "privileges")) {
00321                 int i = 1;
00322 
00323                 if (argv[1] == NULL) {
00324                         result = enum_privileges(pipe_hnd, mem_ctx, &pol );
00325                         goto done;
00326                 }
00327 
00328                 while ( argv[i] != NULL ) {
00329                         fstrcpy( privname, argv[i] );
00330                         i++;
00331                 
00332                         /* verify that this is a valid privilege for error reporting */
00333                         
00334                         result = rpccli_lsa_get_dispname(pipe_hnd, mem_ctx, &pol, privname, lang_id, 
00335                                 lang_id_sys, description, &lang_id_desc);
00336                         
00337                         if ( !NT_STATUS_IS_OK(result) ) {
00338                                 if ( NT_STATUS_EQUAL( result, NT_STATUS_NO_SUCH_PRIVILEGE ) ) 
00339                                         d_fprintf(stderr, "No such privilege exists: %s.\n", privname);
00340                                 else
00341                                         d_fprintf(stderr, "Error resolving privilege display name [%s].\n", nt_errstr(result));
00342                                 continue;
00343                         }
00344                         
00345                         result = enum_accounts_for_privilege(pipe_hnd, mem_ctx, &pol, privname);
00346                         if (!NT_STATUS_IS_OK(result)) {
00347                                 d_fprintf(stderr, "Error enumerating accounts for privilege %s [%s].\n", 
00348                                         privname, nt_errstr(result));
00349                                 continue;
00350                         }
00351                 }
00352                 goto done;
00353         }
00354 
00355         /* special case to enumerate all privileged SIDs with associated rights */
00356         
00357         if (strequal( argv[0], "accounts")) {
00358                 int i = 1;
00359 
00360                 if (argv[1] == NULL) {
00361                         result = enum_privileges_for_accounts(pipe_hnd, mem_ctx, &pol);
00362                         goto done;
00363                 }
00364 
00365                 while (argv[i] != NULL) {
00366                         result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[i]);
00367                         if (!NT_STATUS_IS_OK(result)) {
00368                                 goto done;
00369                         }
00370                         result = enum_privileges_for_user(pipe_hnd, mem_ctx, &pol, &sid);
00371                         if (!NT_STATUS_IS_OK(result)) {
00372                                 goto done;
00373                         }
00374                         i++;
00375                 }
00376                 goto done;
00377         }
00378 
00379         /* backward comaptibility: if no keyword provided, treat the key
00380            as an account name */
00381         if (argc > 1) {
00382                 d_printf("Usage: net rpc rights list [[accounts|privileges] [name|SID]]\n");
00383                 result = NT_STATUS_OK;
00384                 goto done;
00385         }
00386 
00387         result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[0]);
00388         if (!NT_STATUS_IS_OK(result)) {
00389                 goto done;
00390         }
00391         result = enum_privileges_for_user(pipe_hnd, mem_ctx, &pol, &sid );
00392 
00393 done:
00394         rpccli_lsa_close(pipe_hnd, mem_ctx, &pol);
00395 
00396         return result;
00397 }
00398 
00399 /********************************************************************
00400 ********************************************************************/
00401 
00402 static NTSTATUS rpc_rights_grant_internal(const DOM_SID *domain_sid,
00403                                         const char *domain_name, 
00404                                         struct cli_state *cli,
00405                                         struct rpc_pipe_client *pipe_hnd,
00406                                         TALLOC_CTX *mem_ctx, 
00407                                         int argc,
00408                                         const char **argv )
00409 {
00410         POLICY_HND dom_pol;
00411         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00412 
00413         DOM_SID sid;
00414 
00415         if (argc < 2 ) {
00416                 d_printf("Usage: net rpc rights grant <name|SID> <rights...>\n");
00417                 return NT_STATUS_OK;
00418         }
00419 
00420         result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[0]);
00421         if (!NT_STATUS_IS_OK(result))
00422                 return result;  
00423 
00424         result = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True, 
00425                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
00426                                      &dom_pol);
00427 
00428         if (!NT_STATUS_IS_OK(result))
00429                 return result;  
00430 
00431         result = rpccli_lsa_add_account_rights(pipe_hnd, mem_ctx, &dom_pol, sid, 
00432                                             argc-1, argv+1);
00433 
00434         if (!NT_STATUS_IS_OK(result))
00435                 goto done;
00436                 
00437         d_printf("Successfully granted rights.\n");
00438 
00439  done:
00440         if ( !NT_STATUS_IS_OK(result) ) {
00441                 d_fprintf(stderr, "Failed to grant privileges for %s (%s)\n", 
00442                         argv[0], nt_errstr(result));
00443         }
00444                 
00445         rpccli_lsa_close(pipe_hnd, mem_ctx, &dom_pol);
00446         
00447         return result;
00448 }
00449 
00450 /********************************************************************
00451 ********************************************************************/
00452 
00453 static NTSTATUS rpc_rights_revoke_internal(const DOM_SID *domain_sid,
00454                                         const char *domain_name, 
00455                                         struct cli_state *cli,
00456                                         struct rpc_pipe_client *pipe_hnd,
00457                                         TALLOC_CTX *mem_ctx, 
00458                                         int argc,
00459                                         const char **argv )
00460 {
00461         POLICY_HND dom_pol;
00462         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00463 
00464         DOM_SID sid;
00465 
00466         if (argc < 2 ) {
00467                 d_printf("Usage: net rpc rights revoke <name|SID> <rights...>\n");
00468                 return NT_STATUS_OK;
00469         }
00470 
00471         result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[0]);
00472         if (!NT_STATUS_IS_OK(result))
00473                 return result;  
00474 
00475         result = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True, 
00476                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
00477                                      &dom_pol);
00478 
00479         if (!NT_STATUS_IS_OK(result))
00480                 return result;  
00481 
00482         result = rpccli_lsa_remove_account_rights(pipe_hnd, mem_ctx, &dom_pol, sid, 
00483                                                False, argc-1, argv+1);
00484 
00485         if (!NT_STATUS_IS_OK(result))
00486                 goto done;
00487 
00488         d_printf("Successfully revoked rights.\n");
00489 
00490 done:
00491         if ( !NT_STATUS_IS_OK(result) ) {
00492                 d_fprintf(stderr, "Failed to revoke privileges for %s (%s)\n", 
00493                         argv[0], nt_errstr(result));
00494         }
00495         
00496         rpccli_lsa_close(pipe_hnd, mem_ctx, &dom_pol);
00497 
00498         return result;
00499 }       
00500 
00501 
00502 /********************************************************************
00503 ********************************************************************/
00504 
00505 static int rpc_rights_list( int argc, const char **argv )
00506 {
00507         return run_rpc_command( NULL, PI_LSARPC, 0, 
00508                 rpc_rights_list_internal, argc, argv );
00509 }
00510 
00511 /********************************************************************
00512 ********************************************************************/
00513 
00514 static int rpc_rights_grant( int argc, const char **argv )
00515 {
00516         return run_rpc_command( NULL, PI_LSARPC, 0, 
00517                 rpc_rights_grant_internal, argc, argv );
00518 }
00519 
00520 /********************************************************************
00521 ********************************************************************/
00522 
00523 static int rpc_rights_revoke( int argc, const char **argv )
00524 {
00525         return run_rpc_command( NULL, PI_LSARPC, 0, 
00526                 rpc_rights_revoke_internal, argc, argv );
00527 }
00528 
00529 /********************************************************************
00530 ********************************************************************/
00531 
00532 static int net_help_rights( int argc, const char **argv )
00533 {
00534         d_printf("net rpc rights list [{accounts|privileges} [name|SID]]   View available or assigned privileges\n");
00535         d_printf("net rpc rights grant <name|SID> <right>                  Assign privilege[s]\n");
00536         d_printf("net rpc rights revoke <name|SID> <right>                 Revoke privilege[s]\n");
00537         
00538         d_printf("\nBoth 'grant' and 'revoke' require a SID and a list of privilege names.\n");
00539         d_printf("For example\n");
00540         d_printf("\n  net rpc rights grant 'VALE\\biddle' SePrintOperatorPrivilege SeDiskOperatorPrivilege\n");
00541         d_printf("\nwould grant the printer admin and disk manager rights to the user 'VALE\\biddle'\n\n");
00542         
00543         
00544         return -1;
00545 }
00546 
00547 /********************************************************************
00548 ********************************************************************/
00549 
00550 int net_rpc_rights(int argc, const char **argv) 
00551 {
00552         struct functable func[] = {
00553                 {"list", rpc_rights_list},
00554                 {"grant", rpc_rights_grant},
00555                 {"revoke", rpc_rights_revoke},
00556                 {NULL, NULL}
00557         };
00558         
00559         if ( argc )
00560                 return net_run_function( argc, argv, func, net_help_rights );
00561                 
00562         return net_help_rights( argc, argv );
00563 }
00564 
00565 static NTSTATUS rpc_sh_rights_list(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx,
00566                                    struct rpc_pipe_client *pipe_hnd,
00567                                    int argc, const char **argv)
00568 {
00569         return rpc_rights_list_internal(ctx->domain_sid, ctx->domain_name,
00570                                         ctx->cli, pipe_hnd, mem_ctx,
00571                                         argc, argv);
00572 }
00573 
00574 static NTSTATUS rpc_sh_rights_grant(TALLOC_CTX *mem_ctx,
00575                                     struct rpc_sh_ctx *ctx,
00576                                     struct rpc_pipe_client *pipe_hnd,
00577                                     int argc, const char **argv)
00578 {
00579         return rpc_rights_grant_internal(ctx->domain_sid, ctx->domain_name,
00580                                          ctx->cli, pipe_hnd, mem_ctx,
00581                                          argc, argv);
00582 }
00583 
00584 static NTSTATUS rpc_sh_rights_revoke(TALLOC_CTX *mem_ctx,
00585                                      struct rpc_sh_ctx *ctx,
00586                                      struct rpc_pipe_client *pipe_hnd,
00587                                      int argc, const char **argv)
00588 {
00589         return rpc_rights_revoke_internal(ctx->domain_sid, ctx->domain_name,
00590                                           ctx->cli, pipe_hnd, mem_ctx,
00591                                           argc, argv);
00592 }
00593 
00594 struct rpc_sh_cmd *net_rpc_rights_cmds(TALLOC_CTX *mem_ctx,
00595                                        struct rpc_sh_ctx *ctx)
00596 {
00597         static struct rpc_sh_cmd cmds[] = {
00598 
00599         { "list", NULL, PI_LSARPC, rpc_sh_rights_list,
00600           "View available or assigned privileges" },
00601 
00602         { "grant", NULL, PI_LSARPC, rpc_sh_rights_grant,
00603           "Assign privilege[s]" },
00604 
00605         { "revoke", NULL, PI_LSARPC, rpc_sh_rights_revoke,
00606           "Revoke privilege[s]" },
00607 
00608         { NULL, NULL, 0, NULL, NULL }
00609         };
00610 
00611         return cmds;
00612 }
00613 

Sambaに対してSat Aug 29 21:23:29 2009に生成されました。  doxygen 1.4.7