In local security policy (PC-Control panel-Administration-local security policy) there is a parameter "Minimum length of the password" and a parameter "Password must meet complexity requirements" (true/false). How can I read them in Delphi (for WinXpSp3-Win2003-Vista-Win7-Win2008(+r2))?
I'm looking for something like:
Function DetectSystemMinPassLength:integer;
begin
//?
end;
Function DetectSystemPassComplexity:boolean;
begin
//?
end;
Additional question:
Does there exist in Delphi (or WinApi) function which can check if a given password conforms to system policies (or set)?
For example:
Function MyCheckPassComplexity (Password:string):boolean;
begin
// ???
end;
use
MyCheckPassComplexity (' 12345 '); //result False
MyCheckPassComplexity (' MyCoolPassword9999 '); //result True
Usually to read a local or group policy setting you must use the Group Policy Settings Reference for Windows and Windows Server which basically is a set of excel files which contains the windows registry keys where is stored such info. unfortunately in this case if you check such reference for these Account policies (Enforce password history,
Maximum password age, Minimum password age, Minimum password length) you will find this message:
Password Policy security settings are not registry keys.
Exist a set of WMI classes in the root\RSOP\Computer namespace like RSOP_SecuritySettingBoolean, RSOP_SecuritySettingNumeric , RSOP_SecuritySettings to access the an account policy but these classes only works (I mean retrieve information) on systems which is are in a domain, but it does not work in a workgroup.
For the moment I think which you best option is export the local policies to a ini file using this command (and then parse the result using a TIniFile class)
secedit.exe /export /cfg C:\Output\Policy.Ini
This command will create a file like this
[Unicode]
Unicode=yes
[System Access]
MinimumPasswordAge = 0
MaximumPasswordAge = 42
MinimumPasswordLength = 0
PasswordComplexity = 0
PasswordHistorySize = 0
About your second question to validate a password you can use the NetValidatePasswordPolicy WinAPI function.
Related
I have implemented Radius MAC authentication with Unifi AP and freeradius. I am using Radius primarily to set the vlan that the device should sent to allowing a consolidated SSID to handle multiple vlans. (This is a home network, not an enterprise so I am not concerned with the mac spoofing situation). Any MAC connecting will get a vlan (but non-radius users will go to a guest vlan by default)
The freeradius question is how I can go about assigning a group value to each MAC user definition and then post-auth use that group name to define the specific attributes such as Tunnel-Type, Tunnel-Medium-Type, and Tunnel-Private-Group-Id. I simply want to do this to avoid having to repeat all these tunnel values for each device.
Example (not sure if syntax is right)
authorize file
AABBCCDDEEFFGG Group := "iot", Cleartext-Password := "AABBCCDDEEFFGG"
site-enabled/default (I think it might go here)
if (group == "iot) { #update reply, set Tunnel-* values }
Any guidance someone could provide would be great. All the examples I have found seem to be using the mysql backend and I don't have a need for the additional complexity.
I was able to figure this out using control variables. Here is the solution.
Create a custom attribute in the dictionary file.
ATTRIBUTE VLAN-Group-Name 3000 string
Add users to the authorize file like so
AA-BB-CC-DD-EE-FF Cleartext-Password := "AA-BB-CC-DD-EE-FF", VLAN-Group-Name := "iot"
In your virtual server, in my case it was sites-enabled/default, look for the post-auth section and add code similar to this. You will replace the group-id XXX with your vlan # you want sent back to the AP to be assigned. I placed the code right above the -sql portion.
switch "&control:VLAN-Group-Name" {
case "iot" {
update reply {
Tunnel-Type = 13,
Tunnel-Medium-Type = 6,
Tunnel-Private-Group-Id = XXX
}
}
case "general" {
update reply {
Tunnel-Type = 13,
Tunnel-Medium-Type = 6,
Tunnel-Private-Group-Id = XXX
}
}
}
This allows you to keep the authorize file clean with just users and assign them a group and keep the group values simplified in the post-auth. If you ever needed to change the vlan # of any group just one update and restart.
Cheers!
I am using this function to map a network drive:
CONST
MapNetDrvDefFlags = CONNECT_TEMPORARY OR CONNECT_INTERACTIVE {$IFDEF CONSOLE } OR CONNECT_COMMANDLINE {$ENDIF };
FUNCTION MapNetworkDrive(D : CHAR ; CONST UNC,UserName,Password,Provider : STRING ; Flags : DWORD = MapNetDrvDefFlags) : DWORD;
VAR
NetResource : _NETRESOURCEW;
LocalRes : STRING;
BEGIN
FillChar(NetResource,SizeOf(_NETRESOURCEW),0);
NetResource.dwType:=RESOURCETYPE_DISK;
LocalRes:=D+':'; NetResource.lpLocalName:=POINTER(LocalRes);
NetResource.lpRemoteName:=POINTER(UNC);
NetResource.lpProvider:=POINTER(Provider);
Result:=WNetAddConnection2W(NetResource,POINTER(Password),POINTER(UserName),Flags)
END;
and it works fine on a standard SAMBA WORKGROUP network. But at a customer's place it doesn't. It does map the drive, but when I try to access it, I get an "invalid user or password" error.
One difference I notice is that if I execute a manual
NET USE <Drive>: <UNC>
on my own network (WORKGROUP), I get a simple prompt for a user name. But on the customer's network, I get a different prompt:
Skriv brugernavnet for 'xxxx.yyyy':
(translation: Enter user name for 'xxxx.yyyy')
I assume that this is a domain name, but how do I give that to the WNetAddConnection2W call? I have tried sending username as "xxxx.yyyy#user" but that doesn't work. Is there another place I need to supply a domain name (if this is, indeed, what it is)?
I have also tried specifying the xxxx.yyyy part as the "Provider" in the _NETRESOURCEW structure, but if I do that, I get an "Invalid provider" error.
Here's an answer to a very similar question: https://stackoverflow.com/a/29420529/759049
In essence, I think that you should just use domain name in lpRemoteName and you'll be good to go.
I am writing code for a custom SAP program regarding some Vendor information. In my program flow, there is a possibility of me trying to use a Vendor VAT Number that belongs to an unknown Vendor. There is a Web site (EU Based - https://ec.europa.eu/taxation_customs/vies/) for such purposes that requires a country key and the specified VAT Number in order for it to provide an answer with the available Company information (only works for company VAT numbers of course). My problem is that I cannot seem to find any way to pass those parameters dynamically to the Web site without needing the user to interfere during this process. Manually, the process would be to select a country key, type in a VAT number and press 'Verify'.
Is there any way for me to call this specific Web site URL and "bypass" this process to only display the result page? For now, I'm using the following Function Module to just call the specified URL, in lack of any better choices.
call function 'CALL_INTERNET_ADRESS'
exporting
pi_adress = 'https://ec.europa.eu/taxation_customs/vies/'
exceptions
no_input_data = 1
others = 2.
You can use CL_HTTP_CLIENT class or HTTP_POST/HTPP_GET FM.
You need to install given web page SSL root certificate to your system with STRUST t-code.
Example usage of CL_HTTP_CLIENT below.
DATA: lv_url TYPE string VALUE 'http://mkysoft.com/ip.php'.
DATA: o_client TYPE REF TO if_http_client.
DATA: lv_http_rc TYPE i.
DATA: lv_reason TYPE string.
DATA: lt_fields TYPE tihttpnvp.
TRY.
cl_http_client=>create_by_url( EXPORTING
url = lv_url
IMPORTING
client = o_client
EXCEPTIONS
OTHERS = 0 ).
o_client->request->get_header_fields( CHANGING fields = lt_fields ).
o_client->request->set_header_field( name = '~request_uri' value = '/ip.php' ).
o_client->request->set_header_field( name = '~host' value = 'mkysoft.com' ).
o_client->request->set_method( if_http_request=>co_request_method_get ).
o_client->send( ).
o_client->receive( ).
o_client->response->get_status( IMPORTING
code = lv_http_rc
reason = lv_reason ).
* Error check
IF lv_http_rc = 200.
DATA(lv_xml) = o_client->response->get_cdata( ).
* Handle error
ELSE.
WRITE: / 'Fehler: ', lv_http_rc.
ENDIF.
o_client->close( ).
CATCH cx_root INTO DATA(e_txt).
WRITE: / e_txt->get_text( ).
ENDTRY.
EU Commission has a SOAP service for vat numbers.
See the info page
https://ec.europa.eu/taxation_customs/vies/technicalInformation.html
and that it even supports http
http://ec.europa.eu/taxation_customs/vies/checkVatTestService.wsdl
You have a non screen scrape method, proper interface you should look at.
On the other point of Avoiding SSL.
Make a basic guide for customers to add the European commission cert to their SAP system. If someone is complaining about that, then they are a serious user of the internet. Every sap on premise user, that needs to call the internet adds certs.
Http is dead....
Trying to insert simple xml file with one row in IIB with simple message flow into Oracle XE DB. Message flow works fine and inserts data into database, but data written in db is different from starting data. For example, as I'm trying to insert my name "Dino" I'd get Korean/Japanese/Chinese signs in return.
I've tried changing XML formats thinking there might be problem, but I suppose it has to do with encoding.
Input:
Output in DB:
This is how my compute node looks like:
CREATE COMPUTE MODULE SimpleDB_mf_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL CopyMessageHeaders();
-- CALL CopyEntireMessage();
INSERT INTO Database.dkralj.emp VALUES(InputRoot.XMLNSC.emp.name);
SET OutputRoot.XMLNSC.DBINSERT.STATUS='SUCCESS';
RETURN TRUE;
END;
CREATE PROCEDURE CopyMessageHeaders() BEGIN
DECLARE I INTEGER 1;
DECLARE J INTEGER;
SET J = CARDINALITY(InputRoot.*[]);
WHILE I < J DO
SET OutputRoot.*[I] = InputRoot.*[I];
SET I = I + 1;
END WHILE;
END;
CREATE PROCEDURE CopyEntireMessage() BEGIN
SET OutputRoot = InputRoot;
END;
END MODULE;
Looking at the IBM documentation for the INSERT statement in ESQL it might be worth trying.
INSERT INTO Database.dkralj(NAME) VALUES(InputRoot.XMLNSC.emp.name);
If weird things are still happening then I'd try a string constant to avoid any issues with character coding in the input message.
INSERT INTO Database.dkralj(NAME) VALUES('TheEmpValue');
Before this statement in your code
SET OutputRoot.XMLNSC.DBINSERT.STATUS='SUCCESS';
You should check for success or otherwise by using the inbuilt SQLSTATE, SQLCODE, SQLERRORTEXT to check the result of your call.
IF NOT ((SQLCODE = 0) OR (SQLSTATE = '01000' AND SQLNATIVEERROR = 8153)) THEN
-- Do something about the error.
-- The check of SQLSTATE and SQLNATIVEERROR covers warnings
-- The 8153 is for Microsoft SQL Server other databases may use a different value
END IF;
Also check the codepages aka CodedCharSetId of the source system data, the message in IIB and the default codepage of the database.
Use mqsicvp MYBROKER -n ODBC_DB_NAME to get other details about the connection you need to use -n to get the details.
Use something like DBeaver to add some data. Have a look at the datatype specified for the field.
As per your comment below and my response here is an example of a PASSTHRU statement. Note the use of the ? to avoid SQL Injection.
PASSTHRU('SELECT RTRIM(A.EMPLID) AS EMPLID,
RTRIM(A.ADDRESS_TYPE) AS ADDRESS_TYPE,
RTRIM(A.ADDR_TYPE_DESCR) AS ADDR_TYPE_DESCR,
CAST(RTRIM(A.EFFDT) AS DATE) AS EFFDT,
RTRIM(A.EFF_STATUS) AS EFF_STATUS,
RTRIM(A.ADDRESS1) AS ADDRESS1,
RTRIM(A.ADDRESS2) AS ADDRESS2,
RTRIM(A.ADDRESS3) AS ADDRESS3,
RTRIM(A.ADDRESS4) AS ADDRESS4,
RTRIM(A.CITY) AS CITY,
RTRIM(A.STATE) AS STATE,
RTRIM(A.POSTAL) AS POSTAL
FROM ADDRESS_VW AS A
WHERE UPPER(A.EMPLID) = ?') VALUES(AggrRef.EmployeeID)
I'm sending E Mails with INDY 10 components with the following code :
try
MyNewIndyMessage.From.Address := edFrom.Text;
MyNewIndyMessage.Recipients.EMailAddresses := edTo.Text;
MyNewIndyMessage.CCList.EMailAddresses := edCC.Text;
MyNewIndyMessage.BCCList.EMailAddresses := edBCC.Text;
MyNewIndyMessage.Subject := edSubject.Text;
MyNewIndyMessage.Body := edContent.Lines;
MyIndySMTP.Send(MyNewIndyMessage);
finally
MyIndySMTP.Disconnect;
end;
Indy smtp requests me to enter a valid organisation in the Message.from.address like "myname#companyX.com" , I wouöld like to enter here and arbitray string like "This mail is urgent to read".
Can I bypass such check done in my INDY SMTP components ?
According to the Internet Message Format specification (RFC 2822), the From field must contain a valid mailbox, which normally is (section 3.4):
Normally, a mailbox is comprised of two parts: (1)
an optional display name that indicates the name of the recipient
(which could be a person or a system) that could be displayed to the
user of a mail application, and (2) an addr-spec address enclosed in
angle brackets ("<" and ">"). There is also an alternate simple form
of a mailbox where the addr-spec address appears alone, without the
recipient's name or the angle brackets.
An example of this may be like this:
John Doe <john.doe#example.com>
As implied, mail clients usually display the (optional) name attribute if present, and the address itself if a name is not present.
In INDY terms, the TIdEMailAddressItem have three properties, which are always in sync:
Address is the address-spec part of the mailbox, for example: john.doe#example.com
Name is the name part of the mailbox, for example: John Doe
Text have both parts, for example: John Doe <john.doe#example.com>
You can change one of that and the others will reflect the same changes.
So, you can do what you want by setting the Text property directly, like this:
MyNewIndyMessage.From.Text := 'This mail is urgent to read <myname#companyX.com>';
Or you may want to set each one separately:
MyNewIndyMessage.From.Address := 'myname#companyX.com';
MyNewIndyMessage.From.Name := 'This mail is urgent to read';
All this said, you may want to use that name as the subject (along with some more info), and not really as the name, but that's up to you.