Getting Windows domain username in correct case (to match Active Directory) - windows

How can I sensibly get a Windows 7 user's username, but in the case that it's stored in the Active Directory domain (such as BillyBird), not using whatever case the user happened to type it when logging in (probably billybird, but could even be something like bILlYbIRd)?
This is in Perl, but since it's interacting with the operating system, solutions in other languages may be translatable.
I've tried these and they don't work; they all return the username in the case it was typed by the user when logging in*:
getlogin
Win32::LoginName
$ENV{USERNAME}
Win32::OLE->new('WScript.Network')->UserName
Win32API::Net::UserGetInfo
I have come up with a couple of bad ways of getting the right value. I'll post those as answers and hope that somebody else has a better one. Thanks.
* At least they do some of the time. For some users it alternates each time they log in between giving the as-typed and the as-AD values, but in all cases the above methods all agree with each other and %USERNAME%.

This gets the right value, but involves fetching the list of all domain users over the network and iterating over them looking for a case-insensitive match, which seems excessive just for returning something about the current user:
use v5.16;
use Win32::NetAdmin qw<GetDomainController GetUsers FILTER_NORMAL_ACCOUNT>;
my $comparable_username = fc getlogin;
GetDomainController('', '', my $domain_controller);
GetUsers($domain_controller, FILTER_NORMAL_ACCOUNT, \my #all_username);
my $username;
for (#all_username)
{
if (fc eq $comparable_username)
{
$username = $_;
last;
}
}

Here's my thought about using wmic put into practice
use strict;
use warnings 'all';
say username();
sub username {
for ( `wmic useraccount get name` ) {
return $1 if /\A($ENV{USERNAME})\s*\z/i;
}
return;
}
Update
To prevent wmic from fetching the full user name list, you can use the LIKE operator in a WHERE cal
sub username {
my #user = `wmic UserAccount WHERE ( name LIKE '$ENV{username}' ) GET name`;
return unless $user[1] =~ /\S/;
$user[1] =~ s/\s+\z//r;
}

This is a possible solution; it gets the username in the right case:
use IPC::System::Simple qw<capturex>;
my $username;
foreach (capturex qw<NET USER /DOMAIN>, getlogin)
{
if (/^User name\s*(\S+)$/)
{
$username = $1;
last;
}
}
However it involves running an external system command to parse its output (which is relatively slow), and relies on that output always being in English. An alternative solution that used an API for directly looking up whatever the NET USER command is doing would be superior to this one.

Related

how does putty generate the names of it's named pipes?

agent_named_pipe_name.c has this:
char *agent_named_pipe_name(void)
{
char *username = get_username();
char *suffix = capi_obfuscate_string("Pageant");
char *pipename = dupprintf("\\\\.\\pipe\\pageant.%s.%s", username, suffix);
sfree(username);
sfree(suffix);
return pipename;
}
My question is... how does capi_obfuscate_string("Pageant") work? It's defined in cryptoapi.c and appears to just pass the parameter that's passed to it through sha256 and that's it. Except that when I do sha256('Pageant') locally what I get doesn't match the named pipe name that I got on my system. Further, one would think that if that is all that it were doing that running ./pageant --openssh-config pageant.conf on two systems, under different user accounts, would yield the same result on both systems and yet it's not.
Any ideas?

Sitecore item multilistfield XPATH builder

I'm trying to count with XPATH Builder in Sitecore, the number of items which have more than 5 values in a multilist field.
I cannot count the number of "|" from raw values, so I can say I am stuck.
Any info will be helpful.
Thank you.
It's been a long time since I used XPath in Sitecore - so I may have forgotten something important - but:
Sadly, I don't think this is possible. XPath Builder doesn't really run proper XPath. It understands a subset of things that would evaluate correctly in a full XPath parser.
One of the things it can't do (on the v8-initial-release instance I have to hand) is be able to process XPath that returns things that are not Sitecore Items. A query like count(/sitecore/content/*) should return a number - but if you try to run that using either the Sitecore Query syntax, or the XPath syntax options you get an error:
If you could run such a query, then your answer would be based on an expression like this, to perform the count of GUIDs referenced by a specific field:
string-length( translate(/yourNodePath/#yourFieldName, "abcdefg1234567890{}-", "") ) + 1
(Typed from memory, as I can't run a test - so may not be entirely correct)
The translate() function replaces any character in the first string with the relevant character in the second. Hence (if I've typed it correctly) that expression should remove all your GUIDs and just leave the pipe-separator characters. Hence one plus the length of the remaining string is your answer for each Item you need to process.
But, as I say, I don't think you can actually run that from Query Builder...
These days, people tend to use Sitecore PowerShell Extensions to write ad-hoc queries like this. It's much more flexible and powerful - so if you can use that, I'd recommend it.
Edited to add: This question got a bit stuck in my head - so if you are able to use PowerShell, here's how you might do it:
Assuming you have declared where you're searching, what MultiList field you're querying, and what number of selections Items must exceed:
$root = "/sitecore/content/Root"
$field = "MultiListField"
$targetNumber = 3
then the "easy to read" code might look like this:
foreach($item in Get-ChildItem $root)
{
$currentField = Get-ItemField $item -ReturnType Field -Name $field
if($currentField)
{
$count = $currentField.Value.Split('|').Count
if($count -gt $targetNumber)
{
$item.Paths.Path
}
}
}
It iterates the children of the root item you specified, and gets the contents of your field. If that field name had a value, it then splits that into GUIDs and counts them. If the result of that count is greater than your threshold it returns the item's URI.
You can get the same answer out of a (harder to read) one-liner, which would look something like:
Get-ChildItem $root | Select-Object Paths, #{ Name="FieldCount"; Expression={ Get-ItemField $_ -ReturnType Field -Name $field | % { $_.Value.Split('|').Count } } } | Where-Object { $_.FieldCount -gt $targetNumber } | % { $_.Paths.Path }
(Not sure if that's the best way to write that - I'm no expert at PowerShell syntax - but it gives the same results as far as I can see)

Validate file extensions in Apex

End user can upload files in a Visualforce page. In the backend I need to create a list of allowed file extensions, and restrict the user to that list. How do I create the extensions list and validate it? Any help is very much appreciated.
You don't need apex for that?
<apex:inputFile> has accept parameter which you can use. Bear in mind this will check contentType, not extension (which is bit more proper way to do it).
If you still want the validation in apex - probably something like this?
String fileName = 'foobar.xls';
Set<String> acceptedExtensions = new Set<String> {'.doc','.txt', '.jpg'};
Boolean found = false;
for(String s : acceptedExtensions){
if(found = fileName.endsWith(s)){ // yes, there's only one "=", I do want assignment here
break;
}
}
if(!found){ // after the whole loop it's still false?
ApexPages.addMessage(...);
}

How do I prevent Grails for doing any further validations if one validation already fails?

I have a Grails command object that I'm using for updating passwords. It looks like this:
class UpdatePasswordCommand {
String password
static constraints = {
password blank: false,
nullable: false,
size: 8..64,
matches: someLongRegex
validator: { String password, command ->
if (someService.isPasswordSameAsUsername(password)) {
return 'password.invalid.sameasuser'
}
}
I left out everything that doesn't pertain to the question I'm asking.
The problem I'm running into is that, whenever this validation triggers, it will trigger ALL the validations, and the command.errors collection will have an error message for each validation failure. This means that, for example, if the user tried to use test for the password, they will get the following error messages:
* Password length must be between 8 and 64 characters.
* Password must not be the same as the user name.
* Password must contain at least one special character, uppercase letter, and digit.
In this case, if the password length is wrong, I want the validation to stop at that point. Likewise, if it's the same as the username, I don't want it to check against the regex. Is there any way I can get the Grails validation to only return the first validation failure for a particular property? Note that it's important that I only want it to stop per property, because if the user doesn't type in his confirm password, for example, I still want to display two error messages:
* Password length must be between 8 and 64 characters.
* You must enter a confirm password.
Shouldn't that be a practice to provide all the validation messages preemptively to the user so that User can rectify or take care of them in one go, instead of rectifying it one by one?
But anyways you can programmatically force to return back only one message at a time something like below:
static constraints = {
password validator: { String password, command ->
def errorMsgs = []
if (!password){
errorMsgs << 'password.invalid.blank' //'password.invalid.null'
return errorMsgs
} else if (!(password.size() in (8..64))){
if (someService.isPasswordSameAsUsername(password)){
errorMsgs << 'password.invalid.sameasuser'
}
errorMsgs << 'password.invalid.length'
return errorMsgs
} else if (/*password not matching YourRegex*/){
errorMsgs << 'password.invalid.specialCharacters'
return errorMsgs
} else if (someService.isPasswordSameAsUsername(password)){
errorMsgs << 'password.invalid.sameasuser'
return errorMsgs
}
}
}
I think we have to take care of the special cases where more than one message is sent back by adding control logic as done above for password length and its match with user name.
Take a look at grails validate, the interesting thing is that you can pass property names to validate(). The second thing is errors property that implements spring Errors interface. You can use it to clean up messages to show only one for property. Write a custom validator as dmahapatro suggested is a good approach.

Best practice in handling invalid parameter CodeIgniter

Let's say I have a method at Controller named
book($chapter,$page);
where $chapter and $page must be integer. To access the method, the URI will look like
book/chapter/page
For example,
book/1/1
If user try to access the URI without passing all parameter, or wrong parameter, like
book/1/
or
book/abcxyz/1
I can do some if else statements to handle, like
if(!empty($page)){
//process
}else{
//redirect
}
My question is, is there any best practice to handle those invalid parameters passed by user? My ultimate goal is to redirect to the main page whenever there is an invalid parameter? How can I achieve this?
Using the CodeIgniter routing in config/routes.php is pretty useful here, something like this:
$route['book/(:num)/(:num)'] = "book/$1/$2";
$route['book/(:any)'] = "error";
$route['book'] = "error";
Should catch everything. You can have pretty much any regular expressions in the routes, so can validate that the parameters are numeric, start with a lowercase letter, etc..
The best logic here seems to be adding the default values:
book($chapter = 1, $page = 1);
and then checking if they are numeric
So it automatically opens the 1st page of the 1st chapter if there are parameter missing or non-numeric.

Resources