expect command in Solaris 11 - solaris

New to expect command, In Solaris 11 the expect package is included, and I understand from Linux it's very useful for automation.
Am trying to create around 10 users and set password for the users by a script.
#!/usr/bin/expect
spawn /usr/bin/passwd user1
expect "New password: \n"
send "Userpass123$\r"
expect "Re-enter new Password: \n"
send "Userpass123$\r"
The password is being set correctly, but its taking almost 20 seconds to set the password for a single user,
Find the output below
JUDI-DEV-01# time /tmp/123
spawn /usr/bin/passwd user1
New Password:
Re-enter new Password:
real 0m20.023s
user 0m0.005s
sys 0m0.005s
JUDI-DEV-01#
Please help me in fetching the user id , UID , GID , home dir, from a file and to create the user accounts
example file data is /tmp/userlist
user1:150:20:App User1:/export/home/user1:/bin/ksh
user2:151:20:App User2:/export/home/user2:/bin/ksh
user3:152:20:App User3:/export/home/user3:/bin/ksh
dbuser1:201:30:db user1:/export/home/dbuser1:/usr/bin/ksh
dbuser2:202:30:db user1:/export/home/dbuser2:/usr/bin/ksh
I know to separate the values to different variable in shell script, not sure how it works in expect

After sending the password for the second time, add expect eof. This will ensure the completion of the program.
send "Userpass123$\r"
expect eof
To split the values, you can use split command
% split "dbuser1:201:30:db user1:/export/home/dbuser1:/usr/bin/ksh" :
dbuser1 201 30 {db user1} /export/home/dbuser1 /usr/bin/ksh
%

Related

New users being created in test environment have their IDs continually incrementing using Wallaby/Phoenix

I'm new to Elixir/Phoenix so I'm not sure if this is working as expected or an issue I should address.
I have a Phoenix app that I just started adding integration tests to. Having done this for a few days of setting up and testing the User registration feature, I'm now onto testing the login.
I'm using Wallaby:
test.exs:
config :happy_app, :sql_sandbox, true
config :wallaby,
driver: Wallaby.Experimental.Chrome,
chrome: [headless: true],
screenshot_on_failure: true
test_helper.exs:
ExUnit.start()
Ecto.Adapters.SQL.Sandbox.mode(HappyApp.Repo, :manual)
{:ok, _} = Application.ensure_all_started(:wallaby)
Application.put_env(:wallaby, :base_url, HappyAppWeb.Endpoint.url())
My test looks like this:
defmodule HappyAppWeb.UserLoginTest do
use HappyAppWeb.IntegrationCase, async: true
alias HappyApp.Accounts
import HappyAppWeb.IntegrationSteps
#tag integration: true
test "user can login", %{session: session} do
email = "test-user#example.com"
password = "12345678"
# seed user into db
user = Accounts.create_user(%{email: email, password: password})
IO.inspect user
# logging in with the user's email and password
# asserting the view is correct
end
end
When I inspect the user: IO.inspect user I get:
IO.inspect user
=>
{:ok,
%HappyApp.Accounts.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
email: "test-user#example.com",
id: 449,
inserted_at: ~N[2019-11-24 13:20:33],
password: nil,
password_hash: "shhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh",
updated_at: ~N[2019-11-24 13:20:33]
}}
Notice the id: 449,. Is that correct? Shouldn't that reset between tests back to 1?
Manually looking into postgres I see that happy_app_test db is indeed empty. Is the data elsewhere?
This thing is related to the database engine. I cannot find information that confirms it for sure, however I suspect that rollback is deleting the rows that were previously inserted.
When you delete rows, the id counter is not reset, it continues to increment. Basically you need to delete/update the table to reset the counter, or you can reset it manually if you really need to.
If you restart the tests, you will notice that the first test that inserts the record will start from 1 and others will continue the counter, since before the tests you run migration and create a new table, with a new serial counter.
If you are interested to find more about auto increment of the id you can read here.
Take a look on Phoenix 1.4.17 Testing Document. The reason happy_app_test db is empty:
The default test helper file, test/test_helper.exs, creates and migrates our test database for us. It also starts a transaction for each test to run in. This will "clean" the database by rolling back the transaction as each test completes.
And Why the id doesn't start from 1 is the database keep AUTO_INCREMENT the id unless you reset the database or specify postgres database.
Update: check out mix.exs file
defp aliases do
[
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate", "test"]
]
end
When you run mix test, it actually calls 3 commands: "ecto.create --quiet", "ecto.migrate", "test". This why database is clean after each test.

Using QCMDEXC to call QEZSNDMG via DB2 stored procedure

Working on a side project where I use a set of views to identify contention of records within an iSeries set of physical files.
What I would like to do once identified is pull the user profile locking the record, and then send a break message to their terminal as an informational break message.
What I have found is the QEZSNDMG API. Simple enough to use interactively, but I'm trying to put together a command that would be used in conjunction with QCMDEXC API to issue the call to QEZSNDMG and alert the user that they are locking a record.
Reviewing the IBM documentation of the QEZSNDMG API, I see that there are two sets of option parameters, but nothing as required (which seems odd to me, but another topic for another day). But I continue to receive the error "Parameters passed on CALL do not match those required."
Here are some examples that I have tried from the command line so far:
CALL PGM(QEZSNDMG) PARM('*INFO' '*BREAK' 'TEST' '4' 'DOUGLAS' '1' '1' '-4')
CALL PGM(QEZSNDMG) PARM('*INFO' '*BREAK' 'TEST' '4' 'DOUGLAS')
CALL PGM(QEZSNDMG) PARM('*INFO' '*BREAK' 'TEST' '4' 'DOUGLAS' '1')
Note: I would like to avoid using a CL or RPG program if possible but understand it may come to that using one of many examples I found before posting. Just want to exhaust this option before going down that road.
Update
While logged in, I used WRKMSGQ to see the message queues assigned to my station. There were two: QSYS/DOUGLAS and QUSRSYS/DOUGLAS. I then issued SNDBRKMSG with no affect on my workstation (IE, the message didn't break my session):
SNDBRKMSG MSG(TESTING) TOMSGQ(QSYS/DOUGLAS)
SNDBRKMSG MSG(TESTING) TOMSGQ(QUSRSYS/DOUGLAS)
I realized if I provide the workstation session name in the TOMSG parameter it worked:
SNDBRKMSG MSG(TESTING) TOMSGQ(*LIBL/QPADEV0003)
Using SNDBRKMSG was what I was looking for.
Some nudging in the right direction lead me to realize that the workstation session ID is located within QSYS2.RCD_LOCK in field JOB_NAME (job number/username/workstation).
Extracting the workstation ID allowed me to create a correctly formatted SNDBRKMSG command to QCMDEXC and alert the user that they are locking a record needed by another process.

Gather results from rundeck

I am new to rundeck and I wrote a basic script that will check if a file exists on a bunch of nodes ie it returns true or false. What I want to do next is then to parse whether the file exists or not and then send a single email with the results saying something like node x doesn't have the file, node y does have the file etc. My question is how can I aggregate the results from the other nodes so that I can loop through it and email it?
You can use a simple echo in your script to mention the existence of the file and then turn on Send Notification for the job, so that you can receive an email with the Log. This log will have the output of your script.

how can one user create userlevel variable for other users

A windows server has 20 users as usr01 - usr20. For particular application, each users should have user level environment variable such as LDTP_PORT but different values as 4001 for usr 1 and 4020 for usr20.
As manual process , I could log on as each user and update but not possible for 30 servers. I tried through codes but it needs explicit log in as specific user.
I look for powershell or some other way as one user (who is admin user) could set the user level variable for all other users. I do not want to work with -SID- at registry HKU as I am not sure how to map the user with SID)
I think, that there is one simple way, but not really elegant.
Since port number is not sensitive data (because in your case, you can easily predict other user's ports), I would just make 20 global variables, so everyone will have his own. For example:
User with username $env:userName, will have his port in $env:userNameLPTPort.
So code will be as simple as this:
$firstLPTPort = 4000
ForEach ($userName in $usersList) {
$newEnvVariableName = "env:" + $userName + "LPTPort"
#machine means that the scope is for whole machine and it wont disappear after closing the session
[System.Environment]::SetEnvironmentVariable($newEnvVariableName, $firstLPTPort, "Machine")
$firstLPTPort++
}
To confirm, that it works, use this:
echo ([System.Environment]::GetEnvironmentVariable($envName,"Machine"))
Remember that SetEnvironemtVariable function, will not throw exception, if there is already one variable with this name, but just simply overwrite the old one.
Edit:
You can also specify scope for specific user, just change this:
[System.Environment]::SetEnvironmentVariable($newEnvVariableName, $firstLPTPort, "Machine")
into this:
[System.Environment]::SetEnvironmentVariable($newEnvVariableName, $firstLPTPort, $userName)
But make sure, that $usersList contains correct user names.

Password hashing (crackstation.net)

I have a question regarding password hashing. I found a great tutorial on http://crackstation.net/hashing-security.htm. This is how I create a hash from the password using this code:
$hashed_password = create_hash(form_password);
The problem with this code is that it creates a different hash for the same password every time. I guess it's because of adding a random salt to the password:
function create_hash($password)
{
// format: algorithm:iterations:salt:hash
$salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));
return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" . $salt . ":" .
base64_encode(pbkdf2(
PBKDF2_HASH_ALGORITHM,
$password,
$salt,
PBKDF2_ITERATIONS,
PBKDF2_HASH_BYTES,
true
));
}
So due to this, I cannot compare the hash created from the password typed by the user at the login with the hash retrieved from the database, because that hash will never be the same with the one stored in the database. The only way I see that it can be done is to store the salt in another column, or am I wrong?
A thing also annoys me. The format of the hast is e.g. sha256:1000:u9p+OqAZgVkIBtlTBkr9ZxhFvtt+zjcA:PvhJY+oesrdBeD5pjeXMQ/3wficCU0EG. A hacker obviously knows this form of hash so the algorythm that created this hash is clear for him. Let's suppose the database has been compromised and thousands of these hash codes were revealed. Doesn't having this form of hash code raise security issues? I guess a simple OqAZgVkIBtlTBkr9ZxhFvtt+zjcA:PvhJY+oesrdBeD5pjeXMQ/3wfic would be better because it reveals nothing about the encryption mechanism.
Read this link to Wikipedia here
It explains more about the use of a random salt. The key information there is that the random salt is stored in the same database as the hashed password. It is only created randomly a few time, when the user creates or changes their password. It is used whenever authentication is required.
Leaving the info about which algorithm it used to create the password hash leaves you the option of changing the algorithm at some time in the future without interrupting your users. If you decide up upgrade the hash algorithm you wait until a user logs in. At that point you have their password in plain text. Once you authenticate against the old algorithm, you rehash and store the new hash in their database row. It may take months or years for all users to log in but once they have they will accrue the benefits of better hashing. So you would then send out an email asking them to login and read your special news about better security (and as a side effect, improve their hashed password).
Here is an interesting discussion of password hashing StackOverflow:Passwords Storage Hash ...
The reason two hashes of the same password don't match for you is because the result of create_hash() includes the salt, which is randomly generated.
To get the same hash, you have to provide the salt as you validate. The code CrackStation.net provides makes this super simple - just store the result of create_hash() in your database, exactly as-is. To confirm a user entered the correct password, use
validate_password('provided-password','hash-from-database');
This will return a boolean of whether the password was correct. Using this method is better than writing your own, because it is specifically designed to prevent certain hints at what the correct password might be based on the time it takes to return an answer. This is a minor weakness, but better to avoid it anyway, especially since the provided function takes care of it for you.
The provided functions give you a solid implementation, so don't mess with it too much. The hash includes those extra details - sha256:1000 - in order to allow future changes to your hashing without affecting the ability of existing users to login; it will simply use the method provided in the hash, no matter what the current method is.
As far as showing a potential attacker how the hash was created: the format does show everything about how, but this doesn't matter very much at all. An attacker can easily figure out the method used from one or two known password:hash pairs. Far more important than this is using a good algorithm. The goal is to make it difficult to impossible to crack the password even with all the details, as security by obscurity is poor security.
Finally, just to reiterate, you do not need to store the salt in a separate column, just leave the big 70-80 character chunk it returns alone as your hash and let the functions take care of everything for you - anything else is a waste of time and resources
To add a bit more to the excellent accepted answer:
The point about salting the hash is to make it impossible for someone to come along with a huge pile of pre-encrypted hashes and try them one by one. Even with the salt in your database, they'd have to hash every possible dictionary entry against that salt to successfully match a hash. And the salt needs to be different every time to prevent duplicate entries (they hack one password, they have that same password that other users have entered).
As for not being able to compare the login hash to the stored hash, that is on purpose: you use a validation function to check the login password against the stored password, not a string comparison function.
Store the salt then add the salt to the password then turn it into a hash then store it.
Then to compare the passwords you retrieve the salt and add it to he password, convert it into a hash and then compare the two hashes.
(python example, the indentation is messed up when I copied the code from my code)
def Createpassword():
import random
import hashlib
username = input("type your username")
newpassword = input("type your new password? ")
#adds some salt
b = random.randint(1, 2000000000000)
randomsalt = str(b)
saltedpassword = (newpassword + randomsalt)
#hashes the newpassword
saltedpassword = saltedpassword.encode('utf-8')
h = hashlib.sha256(saltedpassword)
finsh = h.hexdigest()
#creates file names
saltname = username + "salt.txt"
username = username + ".txt"
#saves the hashedpassword and the salt
text_file = open(username, "w")
text_file.write(finsh)
text_file.close()
text_file = open(saltname, "w")
text_file.write(randomsalt)
text_file.close()
print("your new password has been saved")
def EnterPassword():
trys = 0
while (trys < 3):
username = input("type your username: ")
#takes password input
password = input("type your password: ")
#gets file names
saltname = username + "salt.txt"
username = username + ".txt"
#opens salt file
text_file = open(saltname, "r")
salt1 = text_file.read(50)
text_file.close()
#opens the hashed passwords file
text_file = open(username, "r")
correctpassword = text_file.read(500)
text_file.close()
#adds the salt to the password input
saltedpassword = password + salt1
#hashes the saltedpassword
saltedpassword = saltedpassword.encode('utf-8')
m = hashlib.sha256(saltedpassword)
hashedpassword = m.hexdigest()
#compears hashed passwords
if hashedpassword != correctpassword:
trys += 1
print("your password or username is incorrect")
if trys == 3:
print("you have been locked out for using to many failed trys")
if hashedpassword == correctpassword:
print ("Password Correct ")
#done give access
trys = 0
break
(I'm new to programming so feel free to correct me)