1/* 2 Samba Unix/Linux SMB client library 3 Distributed SMB/CIFS Server Management Utility 4 Copyright (C) Gerald (Jerry) Carter 2004 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 19 20#include "includes.h" 21#include "utils/net.h" 22 23/******************************************************************** 24********************************************************************/ 25 26static NTSTATUS sid_to_name(struct cli_state *cli, 27 TALLOC_CTX *mem_ctx, 28 DOM_SID *sid, fstring name) 29{ 30 POLICY_HND pol; 31 uint32 *sid_types; 32 NTSTATUS result; 33 char **domains, **names; 34 35 result = cli_lsa_open_policy(cli, mem_ctx, True, 36 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); 37 38 if ( !NT_STATUS_IS_OK(result) ) 39 return result; 40 41 result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, 1, sid, &domains, &names, &sid_types); 42 43 if ( NT_STATUS_IS_OK(result) ) { 44 if ( *domains[0] ) 45 fstr_sprintf( name, "%s\\%s", domains[0], names[0] ); 46 else 47 fstrcpy( name, names[0] ); 48 } 49 50 cli_lsa_close(cli, mem_ctx, &pol); 51 return result; 52} 53 54/******************************************************************** 55********************************************************************/ 56 57static NTSTATUS name_to_sid(struct cli_state *cli, 58 TALLOC_CTX *mem_ctx, 59 DOM_SID *sid, const char *name) 60{ 61 POLICY_HND pol; 62 uint32 *sid_types; 63 NTSTATUS result; 64 DOM_SID *sids; 65 66 /* maybe its a raw SID */ 67 if ( strncmp(name, "S-", 2) == 0 && string_to_sid(sid, name) ) 68 { 69 return NT_STATUS_OK; 70 } 71 72 result = cli_lsa_open_policy(cli, mem_ctx, True, 73 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); 74 75 if ( !NT_STATUS_IS_OK(result) ) 76 return result; 77 78 result = cli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types); 79 80 if ( NT_STATUS_IS_OK(result) ) 81 sid_copy( sid, &sids[0] ); 82 83 cli_lsa_close(cli, mem_ctx, &pol); 84 return result; 85} 86 87/******************************************************************** 88********************************************************************/ 89 90static NTSTATUS enum_privileges( TALLOC_CTX *ctx, struct cli_state *cli, 91 POLICY_HND *pol ) 92{ 93 NTSTATUS result; 94 uint32 enum_context = 0; 95 uint32 pref_max_length=0x1000; 96 uint32 count=0; 97 char **privs_name; 98 uint32 *privs_high; 99 uint32 *privs_low; 100 int i; 101 uint16 lang_id=0; 102 uint16 lang_id_sys=0; 103 uint16 lang_id_desc; 104 fstring description; 105 106 result = cli_lsa_enum_privilege(cli, ctx, pol, &enum_context, 107 pref_max_length, &count, &privs_name, &privs_high, &privs_low); 108 109 if ( !NT_STATUS_IS_OK(result) ) 110 return result; 111 112 /* Print results */ 113 114 for (i = 0; i < count; i++) { 115 d_printf("%30s ", privs_name[i] ? privs_name[i] : "*unknown*" ); 116 117 /* try to get the description */ 118 119 if ( !NT_STATUS_IS_OK(cli_lsa_get_dispname(cli, ctx, pol, 120 privs_name[i], lang_id, lang_id_sys, description, &lang_id_desc)) ) 121 { 122 d_printf("??????\n"); 123 continue; 124 } 125 126 d_printf("%s\n", description ); 127 } 128 129 return NT_STATUS_OK; 130 131} 132 133/******************************************************************** 134********************************************************************/ 135 136static NTSTATUS enum_privileges_for_user( TALLOC_CTX *ctx, struct cli_state *cli, 137 POLICY_HND *pol, DOM_SID *sid ) 138{ 139 NTSTATUS result; 140 uint32 count; 141 char **rights; 142 int i; 143 144 result = cli_lsa_enum_account_rights(cli, ctx, pol, sid, &count, &rights); 145 146 if (!NT_STATUS_IS_OK(result)) 147 return result; 148 149 if ( count == 0 ) 150 d_printf("No privileges assigned\n"); 151 152 for (i = 0; i < count; i++) { 153 printf("%s\n", rights[i]); 154 } 155 156 return NT_STATUS_OK; 157} 158 159/******************************************************************** 160********************************************************************/ 161 162static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state *cli, 163 POLICY_HND *pol ) 164{ 165 NTSTATUS result; 166 uint32 enum_context=0; 167 uint32 pref_max_length=0x1000; 168 DOM_SID *sids; 169 uint32 count=0; 170 int i; 171 fstring name; 172 173 result = cli_lsa_enum_sids(cli, ctx, pol, &enum_context, 174 pref_max_length, &count, &sids); 175 176 if (!NT_STATUS_IS_OK(result)) 177 return result; 178 179 for ( i=0; i<count; i++ ) { 180 181 /* try to convert the SID to a name. Fall back to 182 printing the raw SID if necessary */ 183 184 result = sid_to_name( cli, ctx, &sids[i], name ); 185 if ( !NT_STATUS_IS_OK (result) ) 186 fstrcpy( name, sid_string_static(&sids[i]) ); 187 188 d_printf("%s\n", name); 189 190 result = enum_privileges_for_user( ctx, cli, pol, &sids[i] ); 191 192 if ( !NT_STATUS_IS_OK(result) ) 193 return result; 194 195 d_printf("\n"); 196 } 197 198 return NT_STATUS_OK; 199} 200 201/******************************************************************** 202********************************************************************/ 203 204static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char *domain_name, 205 struct cli_state *cli, TALLOC_CTX *mem_ctx, 206 int argc, const char **argv ) 207{ 208 POLICY_HND pol; 209 NTSTATUS result; 210 DOM_SID sid; 211 212 result = cli_lsa_open_policy(cli, mem_ctx, True, 213 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); 214 215 if ( !NT_STATUS_IS_OK(result) ) 216 return result; 217 218 switch (argc) { 219 case 0: 220 result = enum_privileges( mem_ctx, cli, &pol ); 221 break; 222 223 case 1: 224 /* special case to enuemrate all privileged SIDs 225 with associated rights */ 226 227 if ( strequal( argv[0], "accounts" ) ) { 228 result = enum_privileges_for_accounts( mem_ctx, cli, &pol ); 229 } 230 else { 231 232 result = name_to_sid(cli, mem_ctx, &sid, argv[0]); 233 if (!NT_STATUS_IS_OK(result)) 234 goto done; 235 result = enum_privileges_for_user( mem_ctx, cli, &pol, &sid ); 236 } 237 break; 238 239 default: 240 if ( argc > 1 ) { 241 d_printf("Usage: net rpc rights list [name|SID]\n"); 242 result = NT_STATUS_OK; 243 } 244 } 245 246 247 248 249done: 250 cli_lsa_close(cli, mem_ctx, &pol); 251 252 return result; 253} 254 255/******************************************************************** 256********************************************************************/ 257 258static NTSTATUS rpc_rights_grant_internal( const DOM_SID *domain_sid, const char *domain_name, 259 struct cli_state *cli, TALLOC_CTX *mem_ctx, 260 int argc, const char **argv ) 261{ 262 POLICY_HND dom_pol; 263 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 264 265 DOM_SID sid; 266 267 if (argc < 2 ) { 268 d_printf("Usage: net rpc rights grant <name|SID> <rights...>\n"); 269 return NT_STATUS_OK; 270 } 271 272 result = name_to_sid(cli, mem_ctx, &sid, argv[0]); 273 if (!NT_STATUS_IS_OK(result)) 274 return result; 275 276 result = cli_lsa_open_policy2(cli, mem_ctx, True, 277 SEC_RIGHTS_MAXIMUM_ALLOWED, 278 &dom_pol); 279 280 if (!NT_STATUS_IS_OK(result)) 281 return result; 282 283 result = cli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid, 284 argc-1, argv+1); 285 286 if (!NT_STATUS_IS_OK(result)) 287 goto done; 288 289 d_printf("Successfully granted rights.\n"); 290 291 done: 292 if ( !NT_STATUS_IS_OK(result) ) { 293 d_printf("Failed to grant privileges for %s (%s)\n", 294 argv[0], nt_errstr(result)); 295 } 296 297 cli_lsa_close(cli, mem_ctx, &dom_pol); 298 299 return result; 300} 301 302/******************************************************************** 303********************************************************************/ 304 305static NTSTATUS rpc_rights_revoke_internal( const DOM_SID *domain_sid, const char *domain_name, 306 struct cli_state *cli, TALLOC_CTX *mem_ctx, 307 int argc, const char **argv ) 308{ 309 POLICY_HND dom_pol; 310 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 311 312 DOM_SID sid; 313 314 if (argc < 2 ) { 315 d_printf("Usage: net rpc rights revoke <name|SID> <rights...>\n"); 316 return NT_STATUS_OK; 317 } 318 319 result = name_to_sid(cli, mem_ctx, &sid, argv[0]); 320 if (!NT_STATUS_IS_OK(result)) 321 return result; 322 323 result = cli_lsa_open_policy2(cli, mem_ctx, True, 324 SEC_RIGHTS_MAXIMUM_ALLOWED, 325 &dom_pol); 326 327 if (!NT_STATUS_IS_OK(result)) 328 return result; 329 330 result = cli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid, 331 False, argc-1, argv+1); 332 333 if (!NT_STATUS_IS_OK(result)) 334 goto done; 335 336 d_printf("Successfully revoked rights.\n"); 337 338done: 339 if ( !NT_STATUS_IS_OK(result) ) { 340 d_printf("Failed to revoke privileges for %s (%s)", 341 argv[0], nt_errstr(result)); 342 } 343 344 cli_lsa_close(cli, mem_ctx, &dom_pol); 345 346 return result; 347} 348 349 350/******************************************************************** 351********************************************************************/ 352 353static int rpc_rights_list( int argc, const char **argv ) 354{ 355 return run_rpc_command( NULL, PI_LSARPC, 0, 356 rpc_rights_list_internal, argc, argv ); 357} 358 359/******************************************************************** 360********************************************************************/ 361 362static int rpc_rights_grant( int argc, const char **argv ) 363{ 364 return run_rpc_command( NULL, PI_LSARPC, 0, 365 rpc_rights_grant_internal, argc, argv ); 366} 367 368/******************************************************************** 369********************************************************************/ 370 371static int rpc_rights_revoke( int argc, const char **argv ) 372{ 373 return run_rpc_command( NULL, PI_LSARPC, 0, 374 rpc_rights_revoke_internal, argc, argv ); 375} 376 377/******************************************************************** 378********************************************************************/ 379 380static int net_help_rights( int argc, const char **argv ) 381{ 382 d_printf("net rpc rights list [accounts|username] View available or assigned privileges\n"); 383 d_printf("net rpc rights grant <name|SID> <right> Assign privilege[s]\n"); 384 d_printf("net rpc rights revoke <name|SID> <right> Revoke privilege[s]\n"); 385 386 d_printf("\nBoth 'grant' and 'revoke' require a SID and a list of privilege names.\n"); 387 d_printf("For example\n"); 388 d_printf("\n net rpc rights grant 'VALE\\biddle' SePrintOperatorPrivilege SeDiskOperatorPrivilege\n"); 389 d_printf("\nwould grant the printer admin and disk manager rights to the user 'VALE\\biddle'\n\n"); 390 391 392 return -1; 393} 394 395/******************************************************************** 396********************************************************************/ 397 398int net_rpc_rights(int argc, const char **argv) 399{ 400 struct functable func[] = { 401 {"list", rpc_rights_list}, 402 {"grant", rpc_rights_grant}, 403 {"revoke", rpc_rights_revoke}, 404 {NULL, NULL} 405 }; 406 407 if ( argc ) 408 return net_run_function( argc, argv, func, net_help_rights ); 409 410 return net_help_rights( argc, argv ); 411} 412 413 414