# Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. # # NAME # asmcmdug - ASM CoMmanD line interface (users and groups) # # DESCRIPTION # This module is a dummy/sample module that provides a working # template for module additions. # # NOTES # usage: asmcmdcore [-p] [command] # # MODIFIED (MM/DD/YY) # sanselva 07/07/09 - fix --privilege flag in GetOptions for orapwusr # sanselva 06/24/09 - fix help text msg for orapwusr,grpmod # sanselva 04/27/09 - add diskgroup filter in 'groups' command,remove # -R from chmod,chgrp,chown & handle incorrect alias # sanselva 04/06/09 - ASMCMD long options and consistency # heyuen 03/23/09 - add rmusr -r # heyuen 10/14/08 - use dynamic modules # heyuen 09/10/08 - use dgname for lsusr # heyuen 07/28/08 - use command properties array # heyuen 05/22/08 - fix lsgrp # heyuen 04/30/08 - bug 6994254: supress aditional error messages # heyuen 04/22/08 - add order to lsusr and lsgrp # heyuen 04/15/08 - reorder help messages # heyuen 03/30/08 - add passwd # heyuen 03/11/08 - rename to mkusr, mkug, rmusr, rmug, chug # heyuen 02/12/08 - change help messages # heyuen 09/20/07 - creation # ############################################################################# # ############################ Functions List ################################# # # asmcmdug_init # asmcmdug_process_cmd # asmcmdug_process_help # asmcmdug_is_cmd # asmcmdug_is_wildcard_cmd # asmcmdug_is_no_instance_cmd # asmcmdug_parse_int_args # asmcmdug_syntax_error # asmcmdug_error_msg # asmcmdug_display_msg # asmcmdug_signal_exception # asmcmdug_get_cmd_desc # asmcmdug_get_cmd_syntax # asmcmdug_get_asmcmd_cmds # asmcmdug_process_lsusr # asmcmdug_process_mkgrp # asmcmdug_process_rmgrp # asmcmdug_process_mkusr # asmcmdug_process_rmusr # asmcmdug_process_lsgrp # asmcmdug_process_chown # asmcmdug_process_chmod # asmcmdug_process_chgrp # asmcmdug_process_grpmod # asmcmdug_process_orapwusr # asmcmdug_process_lspwusr ############################################################################# package asmcmdug; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(asmcmdug_init ); use strict; use Getopt::Long qw(:config no_ignore_case bundling); use asmcmdglobal; use asmcmdshare; use List::Util qw[min max]; ####################### ASMCMDTMPL Global Constants ###################### # ASMCMD Column Header Names: # Below are the names of the column headers for lstmpl. our (%asmcmdug_lsusr_header) = ('dgname' , 'DG_Name', 'user_number' , 'User_Num', 'compound_index' , 'Cmpnd_Idx', 'incarnation' , 'Incarn', 'os_id' , 'OS_ID', 'os_name' , 'OS_Name', ); our (%asmcmdug_lsgrp_header) = ('dgname' , 'DG_Name', 'name' , 'Grp_Name', 'member' , 'Member', 'owner' , 'Owner', 'members' , 'Members' ); our (%asmcmdug_lspwusr_header) = ('username', 'Username', 'sysdba', 'sysdba', 'sysoper', 'sysoper', 'sysasm', 'sysasm' ); ####################### ASMCMDTMPL Global Variables ###################### our (%asmcmdug_cmds) = ( lsusr => {no_instance => 'True', flags => {'G=s'=>'diskGroup', 'H'=>'supressHeaders', 'a'=>'all'} }, mkgrp => {no_instance => 'True' }, rmgrp => {no_instance => 'True' }, mkusr => {no_instance => 'True' }, rmusr => {no_instance => 'True', flags => {'r'=>'recursive'} }, lsgrp => {no_instance => 'True', flags => {'G=s'=>'diskGroup', 'H'=>'supressHeaders', 'a'=>'all'} }, chown => {no_instance => 'True' }, chmod => {no_instance => 'True' }, chgrp => {no_instance => 'True' }, grpmod => {no_instance => 'True', flags => {'add'=>'addUser', 'delete'=>'deleteUser'} }, groups => {no_instance => 'True' }, orapwusr => {no_instance => 'True', flags => {'add'=>'addUser', 'delete'=>'deleteUser', 'modify'=>'modifyUser', 'privilege=s'=> 'systemPrivilege', 'password'=> 'passwordChange'} }, lspwusr => {no_instance => 'True', flags => {'H'=>'supressHeaders'} }, passwd => {no_instance => 'True', } ); sub is_asmcmd { return 1; } ######## # NAME # asmcmdug_init # # DESCRIPTION # This function initializes the asmcmdug module. For now it simply # registers its callbacks with the asmcmdglobal module. # # PARAMETERS # None # # RETURNS # Null # # NOTES # Only asmcmdcore_main() calls this routine. ######## sub init { # All of the arrays defined in the asmcmdglobal module must be # initialized here. Otherwise, an internal error will result. push (@asmcmdglobal_command_callbacks, \&asmcmdug_process_cmd); push (@asmcmdglobal_help_callbacks, \&asmcmdug_process_help); push (@asmcmdglobal_command_list_callbacks, \&asmcmdug_get_asmcmd_cmds); push (@asmcmdglobal_is_command_callbacks, \&asmcmdug_is_cmd); push (@asmcmdglobal_is_wildcard_callbacks, \&asmcmdug_is_wildcard_cmd); push (@asmcmdglobal_syntax_error_callbacks, \&asmcmdug_syntax_error); push (@asmcmdglobal_no_instance_callbacks, \&asmcmdug_is_no_instance_cmd); push (@asmcmdglobal_error_message_callbacks, \&asmcmdug_error_msg); push (@asmcmdglobal_signal_exception_callbacks, \&asmcmdug_signal_exception); %asmcmdglobal_cmds = (%asmcmdglobal_cmds, %asmcmdug_cmds); #Perform ASMCMD consistency check if enabled if($asmcmdglobal_hash{'consistchk'} eq 'y') { if(!asmcmdshare_check_option_consistency(%asmcmdug_cmds)) { exit 1; } } } ######## # NAME # asmcmdug_process_cmd # # DESCRIPTION # This routine calls the appropriate routine to process the command # specified by $asmcmdglobal_hash{'cmd'}. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # 1 if command is found in the asmcmdug module; 0 if not. # # NOTES # Only asmcmdcore_shell() calls this routine. ######## sub asmcmdug_process_cmd { my ($dbh) = @_; my ($succ) = 0; # Get current command from global value, which is set by # asmcmdug_parse_asmcmd_args()and by asmcmdcore_shell(). my ($cmd) = $asmcmdglobal_hash{'cmd'}; # Declare and initialize hash of function pointers, each designating a # routine that processes an ASMCMDUG command. my (%cmdhash) = ( lsusr => \&asmcmdug_process_lsusr, mkgrp => \&asmcmdug_process_mkgrp, rmgrp => \&asmcmdug_process_rmgrp, mkusr => \&asmcmdug_process_mkusr, rmusr => \&asmcmdug_process_rmusr, lsgrp => \&asmcmdug_process_lsgrp, chown => \&asmcmdug_process_chown, chmod => \&asmcmdug_process_chmod, chgrp => \&asmcmdug_process_chgrp, grpmod => \&asmcmdug_process_grpmod, groups => \&asmcmdug_process_groups, orapwusr => \&asmcmdug_process_orapwusr, lspwusr => \&asmcmdug_process_lspwusr, passwd => \&asmcmdug_process_passwd); if (defined ( $cmdhash{ $cmd } )) { # If user specifies a known command, then call routine to process it. # $cmdhash{ $cmd }->($dbh); $succ = 1; } return $succ; } ######## # NAME # asmcmdug_process_help # # DESCRIPTION # This function is the help function for the ASMCMDUG module. # # PARAMETERS # command (IN) - display the help message for this command. # # RETURNS # 1 if command found; 0 otherwise. ######## sub asmcmdug_process_help { my ($command) = shift; # User-specified argument; show help on $cmd. # my ($syntax); # Command syntax for $cmd. # my ($desc); # Command description for $cmd. # my ($succ) = 0; # 1 if command found, 0 otherwise. # if (asmcmdug_is_cmd ($command)) { # User specified a command name to look up. # $syntax = asmcmdug_get_cmd_syntax($command); $desc = asmcmdug_get_cmd_desc($command); print " $syntax\n" . "$desc\n"; $succ = 1; } return $succ; } ######## # NAME # asmcmdug_is_cmd # # DESCRIPTION # This routine checks if a user-entered command is one of the known # ASMCMD internal commands that belong to the ASMCMDUG module. # # PARAMETERS # arg (IN) - user-entered command name string. # # RETURNS # True if $arg is one of the known commands, false otherwise. ######## sub asmcmdug_is_cmd { my ($arg) = shift; return defined ( $asmcmdug_cmds{ $arg } ); } ######## # NAME # asmcmdug_is_wildcard_cmd # # DESCRIPTION # This routine determines if an ASMCMDUG command allows the use # of wild cards. # # PARAMETERS # arg (IN) - user-entered command name string. # # RETURNS # True if $arg is a command that can take wildcards as part of its argument, # false otherwise. ######## sub asmcmdug_is_wildcard_cmd { my ($arg) = shift; # Empty hash; no ASMCMDUG command supports wildcards. # return defined ($asmcmdug_cmds{ $arg }) && defined ($asmcmdug_cmds{ $arg }{ wildcard }); } ######## # NAME # asmcmdug_is_no_instance_cmd # # DESCRIPTION # This routine determines if a command can run without an ASM instance. # # PARAMETERS # arg (IN) - user-entered command name string. # # RETURNS # True if $arg is a command that can run without an ASM instance # or does not exist, false otherwise. # # NOTES # The asmcmdug module currently supports no command that can run # without an ASM instance. ######## sub asmcmdug_is_no_instance_cmd { my ($arg) = shift; return !defined ($asmcmdug_cmds{ $arg }) || !defined ($asmcmdug_cmds{ $arg }{ no_instance }); } ######## # NAME # asmcmdug_parse_int_args # # DESCRIPTION # This routine parses the arguments for flag options for ASMCMDUG # internal commands. # # PARAMETERS # cmd (IN) - user-entered command name string. # args_ref (OUT) - hash of user-specified flag options for a command, # populated by getopts(). # # RETURNS # Zero on success; undefined on error. # # NOTES # $cmd must already be verified as a valid ASMCMDUG internal command. ######## sub asmcmdug_parse_int_args { my ($cmd, $args_ref) = @_; my ($key); my (@string); #build the list of options to parse using GetOptions if($asmcmdug_cmds{ $cmd }{ flags }) { foreach $key(keys %{$asmcmdug_cmds{ $cmd }{ flags }}) { push(@string, $key); } } # Use GetOptions() from the Getopt::Long package to parse arguments for # internal commands. These arguments are stored in @ARGV. if (!GetOptions($args_ref,@string)) { # Print correct command format if syntax error. # asmcmdug_syntax_error($cmd); return undef; } return 0; } ######## # NAME # asmcmdug_syntax_error # # DESCRIPTION # This function prints the correct syntax for a command to STDERR, used # when there is a syntax error. This function is responsible for # only ASMCMDUG commands. # # PARAMETERS # cmd (IN) - user-entered command name string. # # RETURNS # 1 if the command belongs to this module; 0 if command not found. # # NOTES # These errors are user-errors and not internal errors. They are of type # record, not signal. # # N.B. Functions in this module can call this function directly, without # calling the asmcmdshare::asmcmdshare_syntax_error equivalent. The # latter is used only by the asmcmdcore module. ######## sub asmcmdug_syntax_error { my ($cmd) = shift; my ($cmd_syntax); # Correct syntax for $cmd. # my ($succ) = 0; $cmd_syntax = asmcmdug_get_cmd_syntax($cmd); # Get syntax for $cmd. # if (defined ($cmd_syntax)) { print STDERR 'usage: ' . $cmd_syntax . "\n"; print STDERR 'help: help ' . $cmd . "\n"; $succ = 1; } return $succ; } ######## # NAME # asmcmdug_error_msg # # DESCRIPTION # This function is a wrapper around asmcmdug_display_msg(), the # function responsible for displaying error messages for the asmcmdug # module. # # This function is called by the general function asmcmdshare_error_msg, # which calls the respective _error_msg function in each module. # # This function records an error but does not signal one. # # PARAMETERS # err_num (IN) - ASMCMD internal error number. # args_ref (IN) - (Optional) Reference to array of error arguments # # RETURNS # 1 if the error number is supported by the asmcmdug module; 0 # otherwise. # # NOTES # Only asmcmdshare_error_message should call this function. *Do not* # call this function directly; call asmcmdshare_error_message, # instead. ######## sub asmcmdug_error_msg { my ($err_num, $args_ref) = @_; my ($succ) = 0; my (@eargs); # Assert that $err_num is within 8000-9400, inclusive. @eargs = ("asmcmdug_error_msg_05", $err_num); asmcmdshare_assert( (($err_num > 8000) || ($err_num < 9400)) , \@eargs); $succ = asmcmdug_display_msg($err_num, $args_ref); return $succ; } ######## # NAME # asmcmdug_display_msg # # DESCRIPTION # This routine prints error and exception messages to STDERR for the # asmcmdug module. # # PARAMETERS # err_num (IN) - ASMCMD internal error number. # args_ref (IN) - (Optional) Reference to array of error arguments # # RETURNS # 1 if error message is found; 0 otherwise. # # NOTES # This function maintains a hash of error numbers supported by this # module in order to return quickly if the error number is not # supported by asmcmdug. # # If an error is found, this function prints the error message. ######### sub asmcmdug_display_msg { my ($err_num, $args_ref) = @_; my ($errmsg) = ''; # Error message from from $DBI::errstr. # my ($succ) = 0; # 1 if error message found, 0 otherwise. # my ($argument); # Argument iterator of the $args_ref array. # my ($dgname, $usr); my ($alias); # Define a hash of error messages that exist for this module. # 8401-8450 my (%error_messages) = ( 8401 => 'Cannot have add and drop at the same time.', 8402 => 'The operation was not performed on all ' . 'the file $arg', 8403 => 'Need to specify an action', 8404 => 'Invalid permission', 8405 => 'User $arg2 does not exist in diskgroup'. ' $arg1', 8406 => 'Cannot accept null password', 8407 => 'Invalid diskgroup', 8408 => 'Path not valid : $arg', 8409 => 'Operation not allowed for $arg' ); $errmsg = $error_messages{$err_num}; # Process error arguments for errors that support them. if ($err_num == 8402) { # Substitute the string '$arg' with the value of $args_ref->[0] $errmsg =~ s,\$arg,$args_ref->[0],; } if ($err_num == 8405) { $dgname = $args_ref->[0] if (defined($args_ref) && defined($args_ref->[0])); $usr = $args_ref->[1] if (defined($args_ref) && defined($args_ref->[1])); $errmsg =~ s,\$arg1,$dgname,; $errmsg =~ s,\$arg2,$usr,; } if($err_num == 8408 || $err_num == 8409 || $err_num == 8402) { $alias = $args_ref if (defined($args_ref)); $errmsg =~ s,\$arg,$alias,; } # Print error only if this module supports this error number. if (defined ($errmsg)) { $succ = 1; print STDERR $errmsg . "\n"; } return $succ; } ######## # NAME # asmcmdug_signal_exception # # DESCRIPTION # This function is a wrapper around asmcmdug_display_msg(), the # function responsible for displaying error messages for the asmcmdug # module. This function is a callback for asmcmdshare_signal_exception. # # PARAMETERS # exception_num (IN) - ASMCMD internal error/exception number. # args_ref (IN) - (Optional) Reference to array of error arguments # # RETURNS # 1 if the error number is supported by the asmcmdug module; 0 # otherwise. # # NOTES # Only asmcmdshare_signal_exception should call this function. *Do not* # call this function directly; call asmcmdshare_signal_exception, # instead. The caller of this function always exits 1. ######## sub asmcmdug_signal_exception { my ($exception_num, $args_ref) = @_; my ($succ) = 0; # Assert that $exception_num is within 8000-9400, inclusive. if (($exception_num < 8000) || ($exception_num > 9400)) { die "asmcmd: 8202 internal error: [asmcmdug_signal_exception_05] " . "[$exception_num]\n"; } $succ = asmcmdug_display_msg($exception_num, $args_ref); return $succ; } ######## # NAME # asmcmdug_get_cmd_desc # # DESCRIPTION # This routine returns the help description of the command specified by $cmd. # # PARAMETERS # cmd (IN) - the name of the command of which we're looking up the # description. # # RETURNS # The description paragraph(s) for command $cmd; undefined if $cmd does not # exist. # # NOTES # IMPORTANT: the commands descriptions must be preceded by eight (8) spaces # of indention! This formatting is mandatory. ######## sub asmcmdug_get_cmd_desc { my ($cmd) = shift; my (%cmd_desc); # Hash storing the description for each internal command. # $cmd_desc{'lsusr'} = ' List the users of an ASM disk group. [pattern] filter out the usernames with the pattern. [-G dgname] shows the users that belong to a certain disk group. [-a] show the groups that this user belongs to [-H] supress headers. '; $cmd_desc{'mkgrp'} =' Add a user group to an ASM disk group. disk group name. user group name. [user] one or more users that belong to user group. '; $cmd_desc{'rmgrp'} =' Delete a user group from an ASM disk group. disk group name. user group name. '; $cmd_desc{'mkusr'} =' Add a user to an ASM disk group. disk group name. user name. '; $cmd_desc{'rmusr'} =' Delete a user from an ASM disk group. [-r] Delete the suer and all files owned by this user. disk group name. user name. '; $cmd_desc{'lsgrp'} =' List the user groups of an ASM disk group. [-G dgname] disk group name. [-H] suppress headers. [-a] show all columns. [pattern] user group pattern to match. '; $cmd_desc{'chown'} =' Change the owner of a file. username that the file will belong to [group] group that the file will belong to files to change ownership '; $cmd_desc{'chmod'} =' Change access permissions for a file. [augo][[+|-][rw]] affected users: a all u user g group o other + to add permission - to revoke permission allowed permission r read w write OR xyz format where x for owner y for group z for other x,y,z can take values 0 none 4 read only 6 read write files to change permission eg: ASMCMD> chmod ugo+rw FILEA ASMCMD> chmod go-w FILEA ASMCMD> chmod 640 FILEB '; $cmd_desc{'chgrp'} =' Change user group for a file. user group name list of files '; $cmd_desc{'grpmod'} =' Add or delete users from a user group. [--add] add user from [--delete] remove user disk group name user group name user(s) '; $cmd_desc{'groups'} =' List the user groups that a user belongs to. disk group name user name '; $cmd_desc{'orapwusr'} =' Add, drop or change an Oracle pwfile user. --add add user --delete drop user --modify change user username --password change password --privilege System Privilege '; $cmd_desc{'lspwusr'} =' List the users from an orapwd file. [-H] suppress headers '; $cmd_desc{'passwd'} =' Change ASM disk group user password. username to set password. '; return $cmd_desc{$cmd}; } ######## # NAME # asmcmdug_get_cmd_syntax # # DESCRIPTION # This routine returns the help syntax of the command specified by $cmd. # # PARAMETERS # cmd (IN) - the name of the command of which we're looking up the # syntax. # # RETURNS # The syntax for command $cmd; undefined if $cmd does not exist. ######## sub asmcmdug_get_cmd_syntax { my ($cmd) = shift; my (%cmd_syntax); # Hash storing the syntax for each internal command. # $cmd_syntax{'lsusr'} = 'lsusr [-Ha] [-G dgname] [pattern]'; $cmd_syntax{'mkgrp'} = 'mkgrp [user]...'; $cmd_syntax{'rmgrp'} = 'rmgrp '; $cmd_syntax{'mkusr'} = 'mkusr '; $cmd_syntax{'rmusr'} = 'rmusr [-r] '; $cmd_syntax{'lsgrp'} = 'lsgrp [-Ha] [-G dgname] [pattern]'; $cmd_syntax{'chown'} = 'chown [:] ...'; $cmd_syntax{'chmod'} = 'chmod ...'; $cmd_syntax{'chgrp'} = 'chgrp ...'; $cmd_syntax{'grpmod'} = 'grpmod <--add|--delete> ' . '[user] ...'; $cmd_syntax{'groups'} = 'groups '; $cmd_syntax{'orapwusr'} = 'orapwusr <<--add|--modify [--password]> '. '[--privilege ]'. '|--delete> '; $cmd_syntax{'lspwusr'} = 'lspwusr [-H]'; $cmd_syntax{'passwd'} = 'passwd '; return $cmd_syntax{$cmd}; } ######## # NAME # asmcmdug_get_asmcmd_cmds # # DESCRIPTION # This routine constructs a string that contains a list of the names of all # ASMCMD internal commands and returns this string. # # PARAMETERS # None. # # RETURNS # A string contain a list of the names of all ASMCMD internal commands. # # NOTES # Used by the help command and by the error command when the user enters # an invalid internal command. # # IMPORTANT: the commands names must be preceded by eight (8) spaces of # indention! This formatting is mandatory. ######## sub asmcmdug_get_asmcmd_cmds { return asmcmdshare_print_cmds(sort(keys %asmcmdug_cmds)); } ######## # NAME # asmcmdug_process_lsusr # # DESCRIPTION # This function processes the asmcmd command lstmpl. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_lsusr { my ($dbh) = @_; my (%args); my ($ret); my ($dgname, $headers, $gnum, $pattern); my (@what , @from, $sth, $qry, @where, @order, @tmp_cols); my (@usr_list); my ($row, $k, $v, $h); my (%min_col_wid, $print_format, $printf_code, @what_print); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # print headers? $headers = defined($args{'H'}); # get disk group name if (defined($args{'G'})) { $dgname = $args{'G'}; $gnum = asmcmdshare_get_gnum_from_gname($dbh, $dgname); if (!defined($gnum)) { asmcmdug_error_msg(8407, undef); return; } push (@where, 'v$asm_diskgroup.group_number = ' . $gnum); } else { push (@what, 'v$asm_diskgroup.name as dgname'); } # get pattern if (defined($ARGV[0])) { $pattern = $ARGV[0]; $pattern =~ s,$ASMCMDGLOBAL_WCARD_CHARS,\%,g; push (@where, "v\$asm_user.os_name like \'%" . $pattern . "%\'"); } push (@what, 'v$asm_user.user_number as user_number'); push (@what, 'v$asm_user.os_id as os_id'); push (@what, 'v$asm_user.os_name as os_name'); push (@from, 'v$asm_user'); push (@from, 'v$asm_diskgroup'); #join push (@where, 'v$asm_user.group_number = v$asm_diskgroup.group_number'); #order push (@order, 'v$asm_user.group_number'); push (@order, 'v$asm_user.os_name'); $sth = asmcmdshare_do_construct_select($dbh, \@what, \@from, \@where, \@order); warn "$DBI::errstr\n" unless defined ($sth); @tmp_cols = @{$sth->{NAME}}; @what = (); foreach (@tmp_cols) { push (@what, "\L$_"); } #initialize the min_col_wid array foreach(@what) { $min_col_wid{$_} = length($asmcmdug_lsusr_header{$_}); } #get the rows while (defined($row = asmcmdshare_fetch($sth))) { my(%usr_info) = (); while(($k,$v) = each(%{$row})) { $k =~ tr/[A-Z]/[a-z]/; $usr_info{$k} = $v; $min_col_wid{$k} = max($min_col_wid{$k}, length($v)); } push (@usr_list, \%usr_info); } asmcmdshare_finish($sth); #create print format $print_format = ''; foreach (@what) { $print_format .= "%-$min_col_wid{$_}s "; } $print_format .= "\\n"; #print header if (!defined ($args{'H'}) ) { $printf_code = "printf \"$print_format\", "; @what_print = (); foreach (@what) { push (@what_print, "\'" . $asmcmdug_lsusr_header{$_} . "\'"); } $printf_code .= "(" . join (", ", @what_print) . ")"; eval $printf_code; } #print rows foreach $h (@usr_list) { $printf_code = "printf \"$print_format\", "; @what_print = (); foreach (@what) { push (@what_print, "\'" . $h->{$_} . "\'"); } $printf_code .= "(" . join (", ", @what_print) . ")"; eval $printf_code; } } ######## # NAME # asmcmdug_process_mkgrp # # DESCRIPTION # This function processes the asmcmd command mkgrp. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_mkgrp { my ($dbh) = @_; my (%args); my ($ret); my ($sth, $qry); my ($dgname, $grpname); my (@usrs); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # get dgname and group name if (@ARGV < 2) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $dgname = shift(@ARGV); $grpname = shift(@ARGV); # get the users foreach (@ARGV) { push (@usrs, "\'".$_."\'"); } $qry = "alter diskgroup " . $dgname . " add usergroup \'" . $grpname . "\'"; if (@usrs) { $qry .= " with member " . join(',', @usrs); } $ret = asmcmdshare_do_stmt($dbh, $qry); warn "$DBI::errstr\n" unless defined ($ret); } ######## # NAME # asmcmdug_process_rmgrp # # DESCRIPTION # This function processes the asmcmd command rmgrp. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_rmgrp { my ($dbh) = @_; my (%args); my ($ret); my ($sth, $qry, $dgname); my ($grpname); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # get dgname and group name if (@ARGV < 2) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $dgname = $ARGV[0]; $grpname = $ARGV[1]; $qry = "alter diskgroup " . $dgname . " drop usergroup \'" . $grpname . "\'"; $ret = asmcmdshare_do_stmt($dbh, $qry); warn "$DBI::errstr\n" unless defined ($ret); } ######## # NAME # asmcmdug_process_mkusr # # DESCRIPTION # This function processes the asmcmd command mkusr. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_mkusr { my ($dbh) = @_; my (%args); my ($ret); my ($sth, $qry, $dgname); my ($username); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # get disk group name and user name if (@ARGV != 2) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $dgname = $ARGV[0]; $username = $ARGV[1]; $qry = "alter diskgroup " . $dgname . " add user \'" . $username ."\'"; $ret = asmcmdshare_do_stmt($dbh, $qry); warn "$DBI::errstr\n" unless defined ($ret); } ######## # NAME # asmcmdug_process_rmusr # # DESCRIPTION # This function processes the asmcmd command rmusr. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_rmusr { my ($dbh) = @_; my (%args); my ($ret); my ($sth, $qry, $dgname); my ($username); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # get disk group name and user name if (@ARGV != 2) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $dgname = $ARGV[0]; $username = $ARGV[1]; $qry = "alter diskgroup " . $dgname . " drop user \'" . $username . "\'"; if (defined($args{'r'})) { $qry .= ' cascade'; } $ret = asmcmdshare_do_stmt($dbh, $qry); warn "$DBI::errstr\n" unless defined ($ret); } ######## # NAME # asmcmdug_get_users # # DESCRIPTION # This function gets the users given a diskgroup name and a usergroup name. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # ######## sub asmcmdug_get_users { my ($dbh, $gname, $ugname) = @_; my ($gnum, $ugnum); my (@what, @where, @from, @order); my ($sth, $row, $res); $gnum = asmcmdshare_get_gnum_from_gname($dbh, $gname); return if (!defined($gnum)); $ugnum = asmcmdshare_get_ugnum_from_ugname($dbh, $gnum, $ugname); return if (!defined($ugnum)); push (@what, 'v$asm_user.os_name'); push (@from, 'v$asm_user'); push (@from, 'v$asm_usergroup_member'); push (@where, 'v$asm_user.group_number = ' . $gnum); push (@where, 'v$asm_usergroup_member.group_number = ' . $gnum); push (@where, 'v$asm_usergroup_member.usergroup_number = ' . $ugnum); push (@where, 'v$asm_usergroup_member.group_number = v$asm_user.group_number'); push (@where, 'v$asm_usergroup_member.member_number = v$asm_user.user_number'); push (@order, 'v$asm_user.os_name'); $sth = asmcmdshare_do_construct_select($dbh, \@what, \@from, \@where, \@order); warn "$DBI::errstr\n" unless defined ($sth); $res = ''; while (defined($row = asmcmdshare_fetch($sth))) { $res = $res . $row->{'OS_NAME'} . ' '; } asmcmdshare_finish($sth); return $res; } ######## # NAME # asmcmdug_process_lsgrp # # DESCRIPTION # This function processes the asmcmd command lsgrp. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_lsgrp { my ($dbh) = @_; my (%args); my ($ret); my ($dgname, $headers, $gnum, $pattern); my (@what, @from, $sth, $qry, @where, @order); my (@tmp_cols); my ($row, $k, $v, $h); my (%min_col_wid, $print_format, $printf_code, @what_print, @grp_list); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # filter disk group if (defined($args{'G'})) { $dgname = $args{'G'}; $gnum = asmcmdshare_get_gnum_from_gname($dbh, $dgname); if (!defined($gnum)) { asmcmdug_error_msg(8407, undef); return; } push (@where, 'v$asm_usergroup.group_number =' . $gnum); } # filter user group if (defined($ARGV[0])) { $pattern = $ARGV[0]; push (@where, "v\$asm_usergroup.name like \'" . $pattern . "\'"); } push (@what, 'v$asm_diskgroup.name as dgname'); push (@what, 'v$asm_usergroup.name'); push (@from, 'v$asm_usergroup'); push (@from, 'v$asm_diskgroup'); push (@from, 'v$asm_user u1'); #owner push (@what, 'u1.os_name as owner'); #join push (@where, 'u1.user_number = v$asm_usergroup.owner_number' ); push (@where, 'u1.group_number = v$asm_diskgroup.group_number' ); push (@where, 'v$asm_usergroup.group_number = v$asm_diskgroup.group_number' ); #order push (@order, 'v$asm_usergroup.name'); $sth = asmcmdshare_do_construct_select($dbh, \@what, \@from, \@where, \@order); warn "$DBI::errstr\n" unless defined ($sth); @tmp_cols = @{$sth->{NAME}}; @what = (); foreach (@tmp_cols) { push (@what, "\L$_"); } #initialize the min_col_wid array foreach(@what) { $min_col_wid{$_} = length($asmcmdug_lsgrp_header{$_}); } if (defined($args{'a'})) { $min_col_wid{'members'} = length($asmcmdug_lsgrp_header{'members'}); } while (defined($row = asmcmdshare_fetch($sth))) { my(%grp_info) = (); while(($k,$v) = each(%{$row})) { $k =~ tr/[A-Z]/[a-z]/; $grp_info{$k} = $v; $min_col_wid{$k} = max($min_col_wid{$k}, length($v)); } if (defined($args{'a'})) { $v = asmcmdug_get_users($dbh, $grp_info{'dgname'}, $grp_info{'name'}); $grp_info{'members'} = $v; $min_col_wid{'members'} = max($min_col_wid{'members'}, length($v)); } push (@grp_list, \%grp_info); } asmcmdshare_finish($sth); if (defined($args{'a'})) { push (@what, 'members'); } #create print format $print_format = ''; foreach (@what) { $print_format .= "%-$min_col_wid{$_}s "; } $print_format .= "\\n"; #print header if (!defined ($args{'H'}) ) { $printf_code = "printf \"$print_format\", "; @what_print = (); foreach (@what) { push (@what_print, "\'" . $asmcmdug_lsgrp_header{$_} . "\'"); } $printf_code .= "(" . join (", ", @what_print) . ")"; eval $printf_code; } #print rows foreach $h (@grp_list) { $printf_code = "printf \"$print_format\", "; @what_print = (); foreach (@what) { push (@what_print, "\'" . $h->{$_} . "\'"); } $printf_code .= "(" . join (", ", @what_print) . ")"; eval $printf_code; } } ######## # NAME # asmcmdug_process_chown # # DESCRIPTION # This function processes the asmcmd command chown. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_chown { my ($dbh) = @_; my (%args); my ($ret); my ($sth, $qry, $dgname); my ($strperm, $strwho, $alphabet, $oper, $inst, @files); my ($owner, $group); my (@eargs); my (%norm); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); #-R not implemented # get owner/group and list of files if (@ARGV < 2) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $owner = shift(@ARGV); foreach (@ARGV) { push (@files, $_); } if ($owner =~ m/(\w+)[\:]?(\w+)?/) { $owner = $1; $group = $2 if defined($2); } foreach (@files) { if ($_ =~ m/(\w+)[\/]?.*/) { #Normalize path and fetch the grp and file_number %norm = asmcmdshare_normalize_path($dbh, $_, 0, \$ret); if($ret != 0) { asmcmdug_error_msg(8408, $_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); next;#continue with next file } $dgname = (split(/\//, $norm{'path'}->[0]))[0]; $dgname =~s/\+//g; $qry = "alter diskgroup " . $dgname . " set ownership "; $qry .= " owner=\'" . $owner . "\'"; if (defined($group)) { $qry .= ", group=\'" . $group . "\'"; } $qry .= " for file \'" . $norm{'path'}->[0] . "\'"; $ret = asmcmdshare_do_stmt($dbh, $qry); if (!defined($ret)) { @eargs = ($_); asmcmdug_error_msg(8402, \@eargs); warn "$DBI::errstr\n" if(defined($DBI::errstr)); } } else { my $args = ($_); asmcmdug_error_msg(8408,\$args); warn "$DBI::errstr\n" if(defined($DBI::errstr)); } } } ######## # NAME # asmcmdug_process_chmod # # DESCRIPTION # This function processes the asmcmd command chmod. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_chmod { my ($dbh) = @_; my (%args); my ($ret); my ($sth, $qry, $dgname); my ($strperm, $strwho, $alphabet, $oper, $inst, @files); my (@sqlperm); my ($x, $ct); my (@eargs); my (%norm); my (@info); my ($qry_perm, $fnum, $fname, $row, $end_perm, $gnum); my ($req_perm); my ($not_digit) = 0; use warnings qw/FATAL all/; # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); #-R not implemented # get the permissions if (@ARGV < 2) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $inst = shift(@ARGV); # get the files foreach (@ARGV) { push (@files, $_); } #check if it is in 3 digit format if( $inst =~ m/\d{3}/ && length($inst) == 3) { my (@perm); if($inst =~ m/(0|4|6)/) { @perm = split('', $inst); push(@sqlperm, "owner=read write") if ($perm[0] == 6); push(@sqlperm, "owner=read only") if ($perm[0] == 4); push(@sqlperm, "owner=none") if ($perm[0] == 0); push(@sqlperm, "group=read write") if ($perm[1] == 6); push(@sqlperm, "group=read only") if ($perm[1] == 4); push(@sqlperm, "group=none") if ($perm[1] == 0); push(@sqlperm, "other=read write") if ($perm[2] == 6); push(@sqlperm, "other=read only") if ($perm[2] == 4); push(@sqlperm, "other=none") if ($perm[2] == 0); } else { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } } elsif( $inst =~ m/^(.*)(\+|\-)(r|w|rw|wr)$/ ) #permissions in the ug+r/w format { $not_digit =1; if (defined($1)) # we are setting it to someone other than all { $strwho = join('', sort(split('', $1))); #sort the string } else { $strwho = "gou"; } $oper = "add" if ($2 eq '+'); $oper = "del" if ($2 eq '-'); $req_perm = $3; $req_perm = 'rw' if($req_perm eq 'wr'); $x = $strwho; $x =~ s/[^agou]//g; #remove invalid characters if ($x ne $strwho) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } #now look for repetitions of the valid characters if ( ($x =~ tr/a/a/) > 1 ) # excess of a { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } if ( ($x =~ tr/u/u/) > 1 ) # excess of u { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } if ( ($x =~ tr/g/g/) > 1 ) # excess of g { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } if ( ($x =~ tr/o/o/) > 1 ) # excess of o { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } if ( $strwho =~ tr/a/a/ ) { $strwho = "gou"; } } else { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } my %hash = map { $_ => 1 } @files; @files = keys %hash; foreach (@files) { if ($_ =~ m/(\w+)[\/]?.*/) { #$dgname = $1; #If not in numeric format $fname =(split(/\//, $_))[-1]; #Normalize path and fetch the grp and file_number %norm = asmcmdshare_normalize_path($dbh, $_, 0, \$ret); if($ret != 0) { asmcmdug_error_msg(8408, $_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); next;#continue with next file } $dgname = (split(/\//, $norm{'path'}->[0]))[0]; $dgname =~s/\+//g; if($not_digit == 1) { #Retreive the file perms and make sure that after granting requested #we do not end up in write only #retreive the unique file number given the parent_id,reference_id, #group_number and filename asmcmdshare_get_subdirs($dbh, \@info,$norm{'gnum'}->[0], $norm{'ref_id'}->[0],$norm{'par_id'}->[0],$fname, undef, 0, 0); $fnum = $info[0]->{'file_number'}; $gnum = $norm{'gnum'}->[0]; if(!defined($fnum)) { asmcmdug_error_msg(8408, $_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); next; } $qry_perm ="select permissions from v\$asm_file where file_number=$fnum and group_number=$gnum"; $sth = asmcmdshare_do_select($dbh, $qry_perm); if(!defined($sth)) { asmcmdug_error_msg(8408, $_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); next; } $row = asmcmdshare_fetch($sth); asmcmdshare_finish($sth); if(!defined($row)) { asmcmdug_error_msg(8408, $_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); next; } #user,group and other permissions my $user = substr($row->{'PERMISSIONS'},0,2); $user =~s/-//g; my $group = substr($row->{'PERMISSIONS'},3,2); $group =~s/-//g; my $other = substr($row->{'PERMISSIONS'},6,2); $other =~s/-//g; #check if operation can be allowed to user if ( $strwho =~ tr/u/u/ ) { if(asmcmdug_chmod_get_end_perm($user,$req_perm,$oper,\$end_perm)) { push( @sqlperm, "owner=" . $end_perm ); } else { asmcmdug_error_msg(8409,$_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); return; } } #check if operation can be allowed to group if ( $strwho =~ tr/g/g/ ) { if(asmcmdug_chmod_get_end_perm($group,$req_perm,$oper,\$end_perm)) { push( @sqlperm, "group=" . $end_perm ) ; } else { asmcmdug_error_msg(8409, $_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); return; } } #check if operation can be allowed to other if ( $strwho =~ tr/o/o/ ) { if(asmcmdug_chmod_get_end_perm($other,$req_perm,$oper,\$end_perm)) { push( @sqlperm, "other=" . $end_perm ); } else { asmcmdug_error_msg(8409, $_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); return; } } } $qry = "alter diskgroup " . $dgname . " set permission "; $qry .= join (' , ', @sqlperm); $qry .= " for file \'" . $norm{'path'}->[0] . "\'"; $ret = asmcmdshare_do_stmt($dbh, $qry); if (!defined($ret)) { @eargs = ($_); asmcmdug_error_msg(8402, \@eargs); warn "$DBI::errstr\n" if(defined($DBI::errstr)); } #Clear out previous effective permissions if($not_digit == 1) { @sqlperm=(); } } else { asmcmdug_error_msg(8408,$_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); } } } ######## # NAME # asmcmdug_chmod_get_end_perm # DESCRIPTION # This function checks whether the current chmod is allowed. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_chmod() calls this function. ######## sub asmcmdug_chmod_get_end_perm { my ($role,$req_perm,$oper,$end_perm) = @_; my ($retval) = 1; if($oper eq 'add') { $role .= $req_perm; } elsif($oper eq 'del') { $role =~ s/$req_perm/-/g ; } # write only option is not allowed if(($role=~ /w/) and !($role =~ /r/)) { $retval = 0; return $retval; } $$end_perm = "none"; $$end_perm = "read only" if($role =~ /r/); $$end_perm = "read write" if($role =~ /rw/); return $retval; } ######## # NAME # asmcmdug_process_chgrp # # DESCRIPTION # This function processes the asmcmd command chgrp. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_chgrp { my ($dbh) = @_; my (%args); my ($ret); my ($sth, $qry, $dgname, $group); my (@files); my (@eargs); my (%norm); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # get group if (@ARGV < 2) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $group = shift(@ARGV); # get files foreach (@ARGV) { push (@files, $_); } foreach (@files) { if ($_ =~ m/(\w+)[\/]?.*/) { #Normalize path and fetch the grp and file_number %norm = asmcmdshare_normalize_path($dbh, $_, 0, \$ret); if($ret != 0) { asmcmdug_error_msg(8408, $_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); next;#continue with next file } $dgname = (split(/\//, $norm{'path'}->[0]))[0]; $dgname =~s/\+//g; $qry = "alter diskgroup " . $dgname . " set ownership "; $qry .= "group=\'" . $group . "\'"; $qry .= " for file \'" . $norm{'path'}->[0] . "\'"; $ret = asmcmdshare_do_stmt($dbh, $qry); if (!defined($ret)) { @eargs = ($_); asmcmdug_error_msg(8402, \@eargs); warn "$DBI::errstr\n" if(defined($DBI::errstr)); } } else { asmcmdug_error_msg(8408,$_); warn "$DBI::errstr\n" if(defined($DBI::errstr)); } } } ######## # NAME # asmcmdug_process_grpmod # # DESCRIPTION # This function processes the asmcmd command grpmod. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_grpmod { my ($dbh) = @_; my (%args); my ($ret); my ($sth, $qry, $dgname, $grpname, $action); my (@usrs); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # get group if (@ARGV < 2) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $dgname = shift(@ARGV); $grpname = shift(@ARGV); # get the users foreach (@ARGV) { push (@usrs, "\'".$_."\'"); } if ($args{'add'}) #add { $action = "add"; } if ($args{'delete'}) #drop { if (defined($action) && $action eq "add") { asmcmdug_error_msg(8401, undef); return; } $action = "drop"; } if (!defined($action)) { asmcmdug_error_msg(8403, undef); return; } $qry = "alter diskgroup " . $dgname . " modify usergroup \'" .$grpname."\' "; $qry .= $action . " member " . join(',', @usrs); $ret = asmcmdshare_do_stmt($dbh, $qry); warn "$DBI::errstr\n" unless defined ($ret); } ######## # NAME # asmcmdug_process_groups # # DESCRIPTION # Returns the groups that a user belongs to (ASM context). # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_groups { my ($dbh) = @_; my (%args); my ($ret); my ($dgname, $grpname, $usrname); my (@what , @from, $sth, $qry, @where, @order); my (@usrs, $row); my (@groups); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # get parameters if (@ARGV < 2) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $dgname = shift(@ARGV); $dgname =~ tr/a-z/A-Z/; $usrname = shift(@ARGV); push (@what, 'v$asm_usergroup.name as usergroup_name'); push (@from, 'v$asm_usergroup'); push (@from, 'v$asm_user'); push (@from, 'v$asm_usergroup_member'); push (@from, 'v$asm_diskgroup_stat'); push (@where, "v\$asm_user.os_name = '" . $usrname . "'" ); push (@where, "v\$asm_diskgroup_stat.name = '" . $dgname . "'"); push (@where, 'v$asm_usergroup_member.usergroup_number = ' . 'v$asm_usergroup.usergroup_number'); push (@where, 'v$asm_usergroup_member.member_number = ' . 'v$asm_user.user_number'); push (@where, 'v$asm_usergroup_member.group_number = ' . 'v$asm_user.group_number'); push (@where, 'v$asm_user.group_number = ' . 'v$asm_diskgroup_stat.group_number'); push (@where, 'v$asm_usergroup_member.group_number = ' . 'v$asm_diskgroup_stat.group_number'); push (@where, 'v$asm_usergroup.group_number = ' . 'v$asm_diskgroup_stat.group_number'); push (@order, 'v$asm_diskgroup_stat.name'); push (@order, 'usergroup_name'); $sth = asmcmdshare_do_construct_select($dbh, \@what, \@from, \@where, \@order); warn "$DBI::errstr\n" unless defined ($sth); while (defined($row = asmcmdshare_fetch($sth))) { push (@groups, $row->{'USERGROUP_NAME'}); } print join(',', @groups) . "\n"; } ######## # NAME # asmcmdug_process_orapwusr # # DESCRIPTION # Handles Oracle pwfile users. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_orapwusr { my ($dbh) = @_; my (%args); my ($ret); my ($dgname, $grpname, $usrname); my (@what , @from, $sth, $qry, @where); my (@usrs, $row); my (@groups, $user, $passwd, $stmt); # Get option parameters, if any. $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); if (@ARGV != 1) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $user = shift(@ARGV); if (defined($args{'add'})) #add user { $passwd = asmcmdshare_getpswd(); $stmt = "create user " . $user . " identified by " . $passwd; $sth = asmcmdshare_do_stmt($dbh, $stmt); if (!defined($sth)) { warn "$DBI::errstr\n"; return; } if (defined($args{'privilege'})) { #Run GetOpts on the value to support first unique chars for option push(@ARGV,"--".$args{'privilege'}); GetOptions (\%args, 'sysasm','sysdba','sysoper'); pop(@ARGV); if ($args{'sysdba'}) { $stmt = "grant sysdba to " . $user; $sth = asmcmdshare_do_stmt($dbh, $stmt); warn "$DBI::errstr\n" unless defined ($sth); } if ($args{'sysoper'}) { $stmt = "grant sysoper to " . $user; $sth = asmcmdshare_do_stmt($dbh, $stmt); warn "$DBI::errstr\n" unless defined ($sth); } if ($args{'sysasm'}) { $stmt = "grant sysasm to " . $user; $sth = asmcmdshare_do_stmt($dbh, $stmt); warn "$DBI::errstr\n" unless defined ($sth); } } } if (defined($args{'modify'})) # modify user { if (defined($args{'password'})) { $passwd = asmcmdshare_getpswd(); $stmt = "alter user " . $user . " identified by " . $passwd; $sth = asmcmdshare_do_stmt($dbh, $stmt); warn "$DBI::errstr\n" unless defined ($sth); } if (defined($args{'privilege'})) { #Run GetOpts on the value to support first unique chars for option push(@ARGV,"--".$args{'privilege'}); GetOptions (\%args, 'sysasm','sysdba','sysoper'); pop(@ARGV); if ($args{'sysdba'}) { $stmt = "grant sysdba to " . $user; } else { $stmt = "revoke sysdba from " . $user; } $sth = asmcmdshare_do_stmt($dbh, $stmt); warn "$DBI::errstr\n" unless defined ($sth); if ($args{'sysoper'}) { $stmt = "grant sysoper to " . $user; } else { $stmt = "revoke sysoper from " . $user; } $sth = asmcmdshare_do_stmt($dbh, $stmt); warn "$DBI::errstr\n" unless defined ($sth); if ($args{'sysasm'}) { $stmt = "grant sysasm to " . $user; } else { $stmt = "revoke sysasm from " . $user; } $sth = asmcmdshare_do_stmt($dbh, $stmt); warn "$DBI::errstr\n" unless defined ($sth); } } if (defined($args{'delete'})) # drop user { $stmt = "drop user " . $user; $sth = asmcmdshare_do_stmt($dbh, $stmt); warn "$DBI::errstr\n" unless defined ($sth); } } ######## # NAME # asmcmdug_process_lspwusr # # DESCRIPTION # Lists Oracle pwfile users. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_lspwusr { my ($dbh) = @_; my (%args); my ($ret); my ($dgname, $grpname, $usrname); my (@what , @from, $sth, $qry, @where); my (@usrs, $row); my (@groups); my (%min_col_wid, $print_format, $printf_code, @what_print); my ($k, $v, $h); $ret = asmcmdug_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); push (@what, 'username'); push (@what, 'sysdba'); push (@what, 'sysoper'); push (@what, 'sysasm'); push (@from, 'v$pwfile_users'); $sth = asmcmdshare_do_construct_select($dbh, \@what, \@from, \@where); warn "$DBI::errstr\n" unless defined ($sth); foreach(@what) { $min_col_wid{$_} = length($asmcmdug_lspwusr_header{$_}); } #get the rows while (defined($row = asmcmdshare_fetch($sth))) { my (%usr_info) = (); while(($k,$v) = each(%{$row})) { $k =~ tr/[A-Z]/[a-z]/; $usr_info{$k} = $v; $min_col_wid{$k} = max($min_col_wid{$k}, length($v)); } push (@usrs, \%usr_info); } asmcmdshare_finish($sth); foreach (@what) { $print_format .= "%$min_col_wid{$_}s "; } $print_format .= "\\n"; #print header if (!defined ($args{'H'}) ) { $printf_code = "printf \"$print_format\", "; @what_print = (); foreach (@what) { push (@what_print, "\'" . $asmcmdug_lspwusr_header{$_} . "\'"); } $printf_code .= "(" . join (", ", @what_print) . ")"; eval $printf_code; } #print rows foreach $h (@usrs) { $printf_code = "printf \"$print_format\", "; @what_print = (); foreach (@what) { push (@what_print, "\'" . $h->{$_} . "\'"); } $printf_code .= "(" . join (", ", @what_print) . ")"; eval $printf_code; } } ######## # NAME # asmcmdug_process_passwd # # DESCRIPTION # Sets/changes the password of a user. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # Null. # # NOTES # Only asmcmdug_process_cmd() calls this function. ######## sub asmcmdug_process_passwd { my ($dbh) = @_; my (%args); my ($ret); my ($dgname, $usr, $oldpasswd, $newpasswd, $stmt); my (%min_col_wid, $print_format, $printf_code, @what_print); my ($k, $v, $h); if (@ARGV != 1) { asmcmdug_syntax_error($asmcmdglobal_hash{'cmd'}); return; } $usr = $ARGV[0]; $oldpasswd = asmcmdshare_getpswd('Enter old password (optional): '); $newpasswd = asmcmdshare_getpswd('Enter new password: '); if ($newpasswd eq '') { asmcmdug_error_msg(8406, ''); return; } $stmt = ' ALTER USER ' . $usr . ' IDENTIFIED BY ' . $newpasswd; if ($oldpasswd ne '') { $stmt .= ' REPLACE ' . $oldpasswd; } $ret = asmcmdshare_do_stmt($dbh, $stmt); warn "$DBI::errstr\n" unless defined ($ret); } 1;