1443 lines
50 KiB
ObjectPascal
1443 lines
50 KiB
ObjectPascal
{$X+,B-,V-,S-} {essential compiler directives}
|
|
|
|
UNIT nwBindry;
|
|
|
|
{ nwBindry unit as of 950301 / NwTP 0.6 API. (c) 1993,1995, R.Spronk }
|
|
|
|
INTERFACE
|
|
|
|
USES nwIntr,nwMisc;
|
|
|
|
{ Primary Functions: Interrupt: comments:
|
|
|
|
* AddBinderyObjectToSet (F217/41)
|
|
* ChangeBinderyObjectPassword (F217/40) Unencrypted Passwords.
|
|
* ChangeEncrBinderyObjectPassword (F217/4B) Encrypted Passwords.
|
|
* ChangeBinderyObjectSecurity (F217/38)
|
|
* ChangePropertySecurity (F217/3B)
|
|
* CloseBindery (F217/44)
|
|
* CreateBinderyObject (F217/32)
|
|
* CreateProperty (F217/39)
|
|
* DeleteBinderyObject (F217/33)
|
|
* DeleteBinderyObjectFromSet (F217/42)
|
|
* DeleteProperty (F217/3A)
|
|
* GetBinderyAccessLevel (F217/46)
|
|
* GetBinderyObjectID (F217/35)
|
|
* GetBinderyObjectName (F217/36)
|
|
* GetEncryptionKey (F217/17) (1)
|
|
* GetRelationOfBinderyObject (F217/4C)
|
|
* IsBinderyObjectInSet (F217/43)
|
|
* IsStationAManager (F217/49)
|
|
* OpenBindery (F217/45)
|
|
* ReadPropertyValue (F217/3D)
|
|
* RenameBinderyObject (F217/34)
|
|
* ScanBinderyObject (F217/37)
|
|
* ScanProperty (F217/3C)
|
|
* VerifyBinderyObjectPassword (F217/3F) Unencrypted Passwords.
|
|
* VerifyEncrBinderyObjectPassword (F217/4A) Encrypted passwords
|
|
* WritePropertyValue (F217/3E)
|
|
|
|
Secondary Functions:
|
|
|
|
* IsShellLoaded
|
|
* IsUserLoggedOn
|
|
* ExistsUser
|
|
* ExistsFileServer
|
|
* GetRealUserName
|
|
* IsGroupMember
|
|
* AddUserToGroup
|
|
* DeleteUserFromGroup
|
|
|
|
Not implemented:
|
|
|
|
- ChangePassword (F217/01) (2)
|
|
- GetMemberSetMofGroupG (F217/09) (3)
|
|
- GetStationsRootMask (E3../06) (4)
|
|
- MapNumberToGroupName (F217/08) (5)
|
|
- MapNumberToObject (F217/04) (6)
|
|
- MapObjectToNumber (F217/03) (7)
|
|
|
|
Notes: -Names of Objects & Properties (and Passwords) are converted to
|
|
uppercase by the above functions.
|
|
-Functions marked with a '*' are tested (with 3.1x) and found correct.
|
|
(See example programs in XBIND.ZIP, e.g. SCANBIND,TSTBIND,BACKBIN).
|
|
-(1): Called by other functions, e.g. ChangeEncrBinderObjectPassword,
|
|
VerifyEncrBinderyObjectPassword, LoginEncrToFileserver.
|
|
(2): This call has been replaced by F217/40 ChangeBinderyObjectPassword.
|
|
(3): replaced by F217/37 ScanBinderyObject and F217/3D ReadPropertyValue.
|
|
(4): -obsolete call-
|
|
(5,6): Replaced by F217/36 GetBinderyObjectName.
|
|
(7): Replaced by F217/35 GetBinderyObjectID.
|
|
}
|
|
|
|
CONST
|
|
{ known object types: (see the file OT_XXX for a full list)}
|
|
OT_WILD = Word(-1);
|
|
OT_UNKNOWN = 0;
|
|
OT_USER = 1;
|
|
OT_USER_GROUP = 2;
|
|
OT_PRINT_QUEUE = 3;
|
|
OT_FILE_SERVER = 4;
|
|
OT_JOB_SERVER = 5;
|
|
OT_GATEWAY = 6;
|
|
OT_PRINT_SERVER = 7;
|
|
OT_ARCHIVE_QUEUE = 8;
|
|
OT_ARCHIVE_SERVER = 9;
|
|
OT_JOB_QUEUE = $0A;
|
|
OT_ADMINISTRATION = $0B;
|
|
OT_ADVERTISING_PRINTSERVER = $47;
|
|
OT_NETWARE_ACCESS_SERVER = $98;
|
|
OT_NAMED_PIPES_SERVER = $9A;
|
|
OT_RSPCX_SERVER = $0107; { # Rconsole/FileServer, Sckt. 0451h, 8140h }
|
|
|
|
{ bindery security: }
|
|
BS_ANY_READ = $00;
|
|
BS_LOGGED_READ = $01;
|
|
BS_OBJECT_READ = $02;
|
|
BS_SUPER_READ = $03;
|
|
BS_BINDERY_READ = $04;
|
|
|
|
BS_ANY_WRITE = $00;
|
|
BS_LOGGED_WRITE = $10;
|
|
BS_OBJECT_WRITE = $20;
|
|
BS_SUPER_WRITE = $30;
|
|
BS_BINDERY_WRITE = $40;
|
|
|
|
{property & object objFlag/propFlags Constants:}
|
|
BF_ITEM = $00;
|
|
BF_SET = $02;
|
|
BF_DYN_PROP = $10; {1}
|
|
BF_STAT_PROP = $00; {1}
|
|
{ or BF_ITEM/SET with BF_xx_PROP to obtain propFlags }
|
|
BF_STAT_OBJ = $00; {1}
|
|
BF_DYN_OBJ = $01; {1}
|
|
|
|
{ Note 1: not available in the NW interface for C }
|
|
|
|
|
|
Type Tproperty=Array[1..128] of Byte;
|
|
|
|
TobjIdArray=array[1..$20] of Longint;
|
|
|
|
Var result:word;
|
|
|
|
{F217/32 [2.15c+] }
|
|
Function CreateBinderyObject(objName:string; objType:Word;
|
|
objFlaG, objSecurity :Byte ):boolean;
|
|
{ Creates an object in the bindery. }
|
|
|
|
{F217/33 [2.15c+] }
|
|
Function DeleteBinderyObject( objName:String; objType:Word ):boolean;
|
|
{ deletes a bindery object and all asociated properties. }
|
|
|
|
{F217/34 [2.15c+]}
|
|
Function RenameBinderyObject( objName,NewObjName :string; objType :word ):boolean;
|
|
{ This function allows the (supervisor-equivalent) user to rename an object,
|
|
given its' type and old name. }
|
|
|
|
{F217/35 [2.15c+] }
|
|
Function GetBinderyObjectID( objName:String; objType:word;
|
|
Var objID:Longint ):boolean;
|
|
{ returns the object ID of an object, given its type and name. }
|
|
|
|
{F217/36 [2.15c+] }
|
|
Function GetBinderyObjectName( object_Id:LongInt;
|
|
Var objName:String; Var objType:word ):boolean;
|
|
{ returns the type and name of an object, given its four BYTE-id. }
|
|
|
|
{F217/37 [2.15c+]}
|
|
Function ScanBinderyObject( SearchObjName: String;
|
|
SearchObjType: Word;
|
|
{i/o:} Var lastObjSeen : Longint;
|
|
{out:} Var RepName : String;
|
|
Var RepType : Word;
|
|
Var RepId : LongInt;
|
|
Var RepFlag : Byte;
|
|
Var RepSecurity : Byte;
|
|
Var RepHasProperties: Boolean
|
|
) :boolean;
|
|
{ This function scans the bindery and returns complete information about
|
|
one or more bindery object(s). It can be called iteratively. }
|
|
|
|
{F217/38 [2.15c+]}
|
|
Function ChangeBinderyObjectSecurity(objName :String; objType :Word;
|
|
NewObjSecurity :Byte ):boolean;
|
|
{ Changes the security of a Bindery object. }
|
|
|
|
{F217/39 [2.15c+]}
|
|
Function CreateProperty( objName:String; objType:Word;
|
|
propertyName:String; propFlags,propSecurity:Byte ):boolean;
|
|
{ Creates a property to be associated with a bindery object. }
|
|
|
|
{F217/3A [2.15c+]}
|
|
Function DeleteProperty( objName:String; objType:Word;
|
|
propertyName:String ):boolean;
|
|
{ Deletes a property from a bindery object. }
|
|
|
|
{F217/3B [2.15c+] }
|
|
Function ChangePropertySecurity( objName:String; objType:Word;
|
|
propName:String; newPropSecurity:Byte ):boolean;
|
|
{ The call can't assign a greater access security level for the property
|
|
than the security level of the caller. }
|
|
|
|
{F217/3C [2.15c+]}
|
|
Function ScanProperty( objName:String; objType:Word; searchPropName:String;
|
|
{i/o var:} Var SequenceNumber:LongInt;
|
|
{ output:} Var propName:String;
|
|
Var propFlags:Byte;
|
|
Var propSecurity:Byte;
|
|
Var propHasValue:Boolean;
|
|
Var moreProperties:Boolean ):boolean;
|
|
{ return information about one or more properties. }
|
|
|
|
{F217/3D [2.15c+]}
|
|
Function ReadPropertyValue( objName:String; objType:Word;
|
|
propName:String; segmentNumber:Word;
|
|
Var propValue : Tproperty;
|
|
Var moreSegments: Boolean;
|
|
Var propFlags : Byte ):boolean;
|
|
{ Returns the value of a property associated with a Bindery object. }
|
|
|
|
{F217/3E [2.15c+]}
|
|
Function WritePropertyValue( objName:String; objType:Word;
|
|
propName:String; segmentNbr: Byte; propValue:Tproperty;
|
|
moreSegments:Boolean ):boolean;
|
|
{ Changes the value of a (NON-SET) property associated with a Bindery object. }
|
|
|
|
{F217/3F [2.15c+]}
|
|
FUNCTION VerifyBinderyObjectPassword
|
|
( objName:string; objType:Word; password:string):boolean;
|
|
{ Verifies the accuracy of a password for a bindery object. (UNencrypted version) }
|
|
|
|
{F217/4A [2.15c+]}
|
|
FUNCTION VerifyEncrBinderyObjectPassword
|
|
( objName:string; objType:Word; password:string):boolean;
|
|
{ Verifies the accuracy of a password for a bindery object. (ENcrypted version) }
|
|
|
|
{F217/ [2.15c+] }
|
|
Function ChangeEncrBinderyObjectPassword(objName:String; objType:Word;
|
|
oldPassWord,newPassWord:String ):boolean;
|
|
{ Changes the password of a bindery object. (UNencrypted version) }
|
|
|
|
{F217/40 [2.0/2.1/3.x] }
|
|
Function ChangeBinderyObjectPassword(objName:String; objType:Word;
|
|
oldPassWord,newPassWord:String ):boolean;
|
|
{ Changes the password of a bindery object. (UNencrypted version) }
|
|
|
|
{F217/41 [2.15c+]}
|
|
Function AddBinderyObjectToSet(objName:String; objType:Word;propName,
|
|
memberName:String; memberType:Word ):boolean;
|
|
{ Adds a bindery object (member) to a property set. }
|
|
|
|
{F217/42 [2.15c+]}
|
|
Function DeleteBinderyObjectFromSet(objName:String; objType:Word;propName,
|
|
memberName:String; memberType:Word ):boolean;
|
|
{ Deletes a (member) bindery object from a property set. }
|
|
|
|
{F217/43 [2.15c+]}
|
|
Function IsBinderyObjectInSet(objName:String; objType:Word;propName,
|
|
memberName:String; memberType:Word ):boolean;
|
|
{ Allows the programmer to check whether a bindery object is a member of a
|
|
set-property. }
|
|
|
|
{F217/44 [2.15c+]}
|
|
Function CloseBindery:boolean;
|
|
{ Closes the bindery files so they can be backed up. (Supervisor only) }
|
|
|
|
{F217/45 [2.15c+]}
|
|
Function OpenBindery:boolean;
|
|
{ This call must be used after the CloseBindery call. No other bindery
|
|
call will work while the bindery is closed. }
|
|
|
|
{F217/46 [2.15c+] }
|
|
Function getBinderyAccessLevel( {out:} Var SecurityAccesslevel:byte;
|
|
Var ObjId:Longint ): Boolean;
|
|
{ It returns the user's access level to the bindery. }
|
|
|
|
{F217/17 [3.x]}
|
|
FUNCTION GetEncryptionKey(VAR key : TencryptionKey): Boolean;
|
|
{ Used by calls using encrypted passwords to query the target fileserver
|
|
for an encryption key. }
|
|
|
|
|
|
{F217/49 [2.15c+]}
|
|
Function IsStationAManager:boolean;
|
|
{ Is station a workgroup manager ? }
|
|
|
|
|
|
{F217/4C [2.15c+]}
|
|
Function GetRelationOfBinderyObject(ObjName:string;ObjType:word;
|
|
relationPropertyName:string;
|
|
{i/o} Var sequenceNbr:longint;
|
|
{out} Var NbrOfObjects:word;
|
|
Var Info:TobjIdArray ):boolean;
|
|
|
|
{************************** secondary functions: ****************************}
|
|
|
|
Function IsShellLoaded:boolean;
|
|
Function IsUserLoggedOn:boolean;
|
|
Function ExistsUser(userObjName:string):boolean;
|
|
Function GetRealUserName(userObjname:string; Var realname:string):boolean;
|
|
Function IsGroupMember(GroupName,UserObjName:String): Boolean;
|
|
Function AddUserToGroup(userName,GroupName:String):boolean;
|
|
Function DeleteUserFromGroup(userName,GroupName:String):boolean;
|
|
Function ExistsFileServer(ServerName:string):Boolean;
|
|
|
|
IMPLEMENTATION{=============================================================}
|
|
|
|
|
|
{F217/17 [3.x]}
|
|
FUNCTION GetEncryptionKey(VAR key : TencryptionKey): Boolean;
|
|
Type Treq=RECORD
|
|
len : WORD;
|
|
func: BYTE;
|
|
END;
|
|
TPreq=^Treq;
|
|
BEGIN
|
|
With TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len := 1;
|
|
func := $17;
|
|
end;
|
|
F2SystemCall($17,sizeof(Treq),SizeOf(TencryptionKey),result);
|
|
Move(GlobalReplyBuf^,key,SizeOf(key));
|
|
GetEncryptionKey:=(Result=0);
|
|
END;
|
|
|
|
|
|
{F217/3F [2.15c+]}
|
|
FUNCTION VerifyBinderyObjectPassword
|
|
( objName:string;objType:Word; password : string):boolean;
|
|
{ Verifies the accuracy of a password for a bindery object. }
|
|
{ Passwords need to be converted to upper case, NULL if there is no password. }
|
|
Type TReq=record
|
|
buffer_length : Word;
|
|
subfunction : byte;
|
|
obj_type : word; { hi-lo }
|
|
_ObjectName : string[48];
|
|
_PassWord : string[127];
|
|
end;
|
|
TPreq=^Treq;
|
|
begin
|
|
With TPreq(GlobalReqBuf)^
|
|
do begin
|
|
buffer_length := SizeOf(Treq)-2;
|
|
subfunction :=$3F;
|
|
obj_type:=swap(objType); { force hi-lo }
|
|
UpString(objName);
|
|
UpString(password);
|
|
PStrCopy(_ObjectName,objName,48); _ObjectName[48]:=#0; UpString(_ObjectName);
|
|
PStrCopy(_PassWord,password,127); Upstring(_PassWord);
|
|
end;
|
|
F2SystemCall($17,sizeof(Treq),0,result);
|
|
VerifyBinderyObjectPassword:=(result=0);
|
|
{ possible resultcodes:
|
|
$00 0 verification of object_name/password combination
|
|
$96 150 Sever out of memory
|
|
$C5 197 account disabled due to intrusion lockout
|
|
$D6 214 unencrypted password calls not allowed on this v3+ server
|
|
$F0 240 Wildcard not allowed
|
|
$FB 251 no such property
|
|
$FC 252 no such object_name on this server
|
|
$FE 254 Server Bindery Locked
|
|
$FF 255 Bindery failure (No such object or bad password) }
|
|
end;
|
|
|
|
|
|
{F217/4A [3.x]}
|
|
FUNCTION VerifyEncrBinderyObjectPassword(ObjName: String; ObjType: Word; PassWord: String): Boolean;
|
|
|
|
FUNCTION VerifyEncrypted(ObjName : String; ObjType : Word; VAR key : TencryptionKey): Boolean;
|
|
Type TReq=RECORD
|
|
BufLen : Word;
|
|
_func : Byte;
|
|
_key : TencryptionKey;
|
|
_ObjType: Word;
|
|
_ObjName: String[48];
|
|
End;
|
|
TPreq=^Treq;
|
|
Begin
|
|
With TPreq(GlobalReqBuf)^
|
|
do Begin
|
|
_func := $4A;
|
|
_key := key;
|
|
_ObjType := Swap(objType);
|
|
PstrCopy(_ObjName,ObjName,48); UpString(_ObjName);
|
|
if ObjName[0]<#48
|
|
then _objName[0]:=objName[0]
|
|
else _objname[0]:=#48;
|
|
BufLen:=ord(_ObjName[0])+12;
|
|
End;
|
|
F2SystemCall($17,sizeof(Treq),0,result);
|
|
VerifyEncrypted:=(result=0);
|
|
End;
|
|
|
|
VAR
|
|
key : TencryptionKey;
|
|
ObjId:LongInt;
|
|
_pw:string;
|
|
|
|
Begin
|
|
UpString(password);
|
|
_pw:=password;
|
|
if _pw[0]>#127 Then _pw[0]:=#127;
|
|
|
|
IF GetEncryptionKey(key)
|
|
Then Begin
|
|
|
|
IF GetBinderyObjectId(objName,objType,ObjId)
|
|
Then Begin
|
|
EncryptPassword(objId,_pw,key);
|
|
VerifyEncrypted(ObjName, ObjType, key);
|
|
End;
|
|
End
|
|
Else VerifyBinderyObjectPassword(ObjName, ObjType, Password);
|
|
|
|
VerifyEncrBinderyObjectPassword := (result=0);
|
|
End;
|
|
|
|
|
|
{F217/37 [2.15c+]}
|
|
Function ScanBinderyObject( SearchObjName: String;
|
|
SearchObjType: Word;
|
|
{i/o:} Var lastObjSeen : Longint;
|
|
{out:} Var RepName : String;
|
|
Var RepType : Word;
|
|
Var RepId : LongInt;
|
|
Var RepFlag : Byte;
|
|
Var RepSecurity : Byte;
|
|
Var RepHasProperties: Boolean
|
|
) :boolean;
|
|
{ This function scans the bindery and returns complete information about
|
|
a bindery object. }
|
|
Type TReq = record
|
|
length : word;
|
|
subfunction : byte;
|
|
last_obj_id : longint; {hi-lo}
|
|
search_obj_type : word; {hi-lo}
|
|
search_obj_name : string[48];
|
|
end;
|
|
TRep= record
|
|
object_id : longint; {hi-lo}
|
|
object_type : word; {hi-lo}
|
|
object_name : array [1..48] of byte;
|
|
object_flag : byte;
|
|
security : byte;
|
|
properties : byte;
|
|
end;
|
|
TPreq=^Treq;
|
|
TPrep=^Trep;
|
|
|
|
Var TempStr:string;
|
|
count : integer;
|
|
begin
|
|
with TPreq(GlobalReqBuf)^
|
|
do begin
|
|
length := SizeOf(Treq)-2;
|
|
subfunction := $37;
|
|
last_obj_id := Lswap(lastObjseen); { force hi-lo }
|
|
search_obj_type:= swap(Word(SearchObjType)); { force hi-lo }
|
|
PstrCopy(Search_obj_name,SearchObjName,48); Search_obj_Name[48]:=#0; UpString(Search_obj_name);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),sizeOf(Trep),result);
|
|
With TPrep(GlobalReplyBuf)^
|
|
do begin
|
|
repFlag := object_flag;
|
|
repHasProperties := (properties>0);
|
|
repSecurity := security;
|
|
repType := swap(object_type); { force lo-hi }
|
|
repId := Lswap(object_id); { force lo-hi }
|
|
lastObjSeen := repId;
|
|
ZStrCopy(repName,Object_Name,48);
|
|
end;
|
|
scanBinderyObject:=(result=0);
|
|
{ Possible Resultcodes:
|
|
96h server out of memory; EFh Invalid Name; FCh No Such Object;
|
|
FEh Server Bindery Locked; FFh Bindery failure }
|
|
end;
|
|
|
|
|
|
{F217/3D [2.15c+]}
|
|
Function ReadPropertyValue( objName:String; objType:Word;
|
|
propName:String; segmentNumber:Word;
|
|
Var propValue : Tproperty;
|
|
Var moreSegments: Boolean;
|
|
Var propFlags : Byte ):boolean;
|
|
{ Returns the value of a property associated with a Bindery object. }
|
|
Type Treq=record
|
|
len : word;
|
|
subfunction : byte;
|
|
_objType : word; { hi-lo }
|
|
_ObjName : string[48];
|
|
_segNbr : byte;
|
|
_propName : string[15];
|
|
end;
|
|
Trep = record
|
|
_propValue : Tproperty; {array [1..128] of byte}
|
|
_moreSegments : byte;
|
|
_propFlags : byte;
|
|
end;
|
|
TPreq=^Treq;
|
|
TPrep=^Trep;
|
|
BEGIN
|
|
With TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subfunction := $3d;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
_segNbr:=segmentNumber;
|
|
PStrCopy(_ObjName,objName,48); _ObjName[48]:=#0; UpString(_ObjName);
|
|
PStrCopy(_PropName,propName,15); UpString(_propName);
|
|
end;
|
|
F2SystemCall($17,sizeof(Treq),sizeof(Trep),result);
|
|
if result=0
|
|
then with TPrep(GlobalreplyBuf)^
|
|
do begin
|
|
propValue:=_propValue;
|
|
moreSegments:=(_moreSegments>0);
|
|
propFlags:=_propFlags;
|
|
end;
|
|
ReadPropertyValue:=(result=0);
|
|
{ 96 server out of memory; EC no such segment; F0 wilcard not allowed;
|
|
f1 invalid bindery security; f9 no property read privileges;
|
|
fb no such property; fc no such object; FE Server Bindery Locked;
|
|
FF Bindery Failure. }
|
|
end;
|
|
|
|
|
|
{F217/36 [2.15c+] }
|
|
Function GetBinderyObjectName( object_Id:LongInt;
|
|
Var objName:String; Var objType:word ):boolean;
|
|
{ returns the type and name of an object, given its four BYTE-id. }
|
|
Type TReq =record
|
|
len:word;
|
|
subF:byte;
|
|
_objId:LongInt; { hi-lo }
|
|
end;
|
|
Trep=record
|
|
_objId:LongInt; { hi-lo }
|
|
_objType:word; { hi-lo }
|
|
_objName:array[1..48] of Byte;
|
|
end;
|
|
TPreq=^Treq;
|
|
TPrep=^Trep;
|
|
BEGIN
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len :=SizeOf(TReq)-2;
|
|
SubF:=$36;
|
|
_objId:=Lswap(object_Id); { force hi-lo }
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),sizeOf(Trep),result);
|
|
IF result=0
|
|
then with TPrep(GlobalReplyBuf)^
|
|
do begin
|
|
ZstrCopy(objName,_objName,48);
|
|
objType:=swap(_objType); { force lo-hi }
|
|
end;
|
|
GetBinderyObjectName:=(result=0);
|
|
end;
|
|
|
|
|
|
{F217/35 [2.15c+] }
|
|
Function GetBinderyObjectID( objName:String; objType:word;
|
|
Var objID:Longint ):boolean;
|
|
{ returns the object ID of an object, given its type and name. }
|
|
Type Treq=record
|
|
len:word;
|
|
subF:Byte;
|
|
_objType:word; { hi-lo }
|
|
_objName:string[48];
|
|
end;
|
|
TRep=record
|
|
_objId:LongInt; { hi-lo }
|
|
_objType:word; { hi-lo }
|
|
_objName:array[1..48] of char;
|
|
end;
|
|
TPreq=^Treq;
|
|
TPrep=^Trep;
|
|
BEGIN
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len :=SizeOf(TReq)-2;
|
|
SubF:=$35;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PStrCopy(_objName,objName,48); _objName[48]:=#0;
|
|
UpString(_objName);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),sizeOf(Trep),result);
|
|
IF result=0
|
|
then with TPrep(GlobalReplyBuf)^
|
|
do objID:=Lswap(_objId); { force lo-hi }
|
|
GetBinderyObjectID:=(result=0);
|
|
end;
|
|
|
|
|
|
{F217/46 [2.15c+]}
|
|
Function getBinderyAccessLevel(Var SecurityAccessLevel:byte;
|
|
Var objId:Longint ):boolean;
|
|
{ It returns the user's access level to the bindery. }
|
|
{ Often used as a quick way of determining the current users' object id }
|
|
{ use the BS_xxxx constants to determine the exact rights of the user }
|
|
Type Treq=record
|
|
len :word;
|
|
subF :byte;
|
|
end;
|
|
Trep=record
|
|
accLeveL:byte;
|
|
_objId:longInt;
|
|
fill:array[1..20] of byte;
|
|
end;
|
|
TPreq=^Treq;
|
|
TPrep=^Trep;
|
|
BEGIN
|
|
With TPreq(GlobalReqBuf)^
|
|
do begin
|
|
subF:=$46;
|
|
len:=sizeOf(Treq)-2;
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),sizeOf(Trep),result);
|
|
If result=0
|
|
then with TPrep(GlobalReplyBuf)^
|
|
do begin
|
|
SecurityAccessLevel:=accLevel;
|
|
objId:=Lswap(_objId);
|
|
end;
|
|
GetBinderyAccessLevel:=(result=0);
|
|
end;
|
|
|
|
|
|
|
|
{F217/45 [2.15c+]}
|
|
Function OpenBindery:boolean;
|
|
{ This call must be used after the CloseBindery call. No other bindery
|
|
call will work while the bindery is closed. }
|
|
Type Treq=record
|
|
len:word;
|
|
subFunc:byte;
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=1;
|
|
subFunc:=$45;
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
OpenBindery:=(result=0)
|
|
end;
|
|
|
|
|
|
{F217/44 [2.15c+]}
|
|
Function CloseBindery:boolean;
|
|
{ Closes the bindery files so they can be backed up. (Supervisor only) }
|
|
Type Treq=record
|
|
len:word;
|
|
subFunc:byte;
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$44;
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
CloseBindery:=(result=0)
|
|
end;
|
|
|
|
|
|
{F217/32 [2.15c+] }
|
|
Function CreateBinderyObject(objName:string; objType:Word;
|
|
objFlaG, objSecurity :Byte ):boolean;
|
|
{ Creates an object in the bindery.
|
|
objName: name of the new object (47 chars)
|
|
objType: object type number (own type number or OT_xxx constant)
|
|
objFlag: identifies an object as static (0) or dynamic (1)
|
|
(dynamic objects are removed from the bindery when the server goes down)
|
|
objSecurity: high nibble: write privileges needed to modify this object
|
|
low nibble: read privileges needed to access this object
|
|
(default: $31 Supervisor write/Logged read) }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objFlag :Byte;
|
|
_objSecurity :Byte;
|
|
_objType :word; { hi-lo }
|
|
_objName :string[48]
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$32;
|
|
_objFlag:=objFlag;
|
|
_objSecurity:=objSecurity;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PStrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
|
|
end;
|
|
F2SystemCall($17,sizeof(Treq),0,result);
|
|
CreateBinderyObject:=(result=0)
|
|
{ 96h server out of memory; EEh Object Already Exists; EFh Invalid Name
|
|
F1h invalid Bindery security; F5h no object create privileges
|
|
FEh Server Bindery Locked; FFh Bindery Failure }
|
|
end;
|
|
|
|
|
|
|
|
{F217/33 [2.15c+] }
|
|
Function DeleteBinderyObject( objName:String; objType:Word ):boolean;
|
|
{ deletes a bindery object and all asociated properties. }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objType :Word; { hi-lo }
|
|
_objName :string[48];
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalreqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$33;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PStrCopy(_objName,objName,48); _objName[48]:=#48; UpString(_objName);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
DeleteBinderyObject:=(result=0)
|
|
{ 96h Server out of memory; EFh Invalid name; F0h wildcard not allowed;
|
|
F4h No object delete privileges; FCh no such object
|
|
FEh Server Bindery Locked; FFh bindery failure }
|
|
end;
|
|
|
|
|
|
{F217/34 [2.15c+]}
|
|
Function RenameBinderyObject( objName,NewObjName :string; objType :word ):boolean;
|
|
{ This function allows the (supervisor-equivalent) user to rename an object,
|
|
given its' type and old name. }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objType :word; { hi-lo }
|
|
_objName :string[48];
|
|
_NewObjName :string[48];
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$34;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PstrCopy(_objName,objName,48); _objName[48]:=#0; Upstring(_objName);
|
|
PstrCopy(_NewObjName,NewObjName,48); _NewObjName[48]:=#0; UpString(_NewObjName);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
RenameBinderyObject:=(result=0)
|
|
{ 96h Server out of memory; EFh Invalid name; F0h wildcard not allowed;
|
|
F3h No object rename privileges; FCh no such object
|
|
FEh Server Bindery Locked; FFh bindery failure }
|
|
end;
|
|
|
|
|
|
|
|
{F217/43 [2.15c+]}
|
|
Function IsBinderyObjectInSet(objName:String; objType:Word;
|
|
propName, memberName:String; memberType:Word ):boolean;
|
|
{ Allows the programmer to check whether a bindery object is a member of a
|
|
set-property. Objectname( of Objecttype) is the object to be searched for,
|
|
PropName (attached to the object with name memberName (of memberType))
|
|
is the property containing the set to be searched.
|
|
User must have read rights to the object and the property.
|
|
Ex: ('SUPERVISOR',OT_USER,'GROUP_MEMBERS','EVERYONE',OT_USER_GROUP) }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objType :Word; { hi-lo }
|
|
_objName :String[48]; { [48]=#0 }
|
|
_propName :String[15];
|
|
_memObjType :Word; { hi-lo }
|
|
_memName :String[48]; { [48]=#0 }
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$43;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PstrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
|
|
PstrCopy(_propName,propName,15); UpString(_propName);
|
|
_memObjType:=swap(memberType); { force hi-lo }
|
|
PStrCopy(_memName,memberName,48); _memName[48]:=#0; UpString(_memName);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
IsBinderyObjectInSet:=(result=0)
|
|
{ 96h Server out of memory; EA No Such member; EB Not Group Property
|
|
F0h wildcard not allowed; F9 No Property read privileges;
|
|
FCh no such object; FEh Server Bindery Locked; FFh bindery failure }
|
|
end;
|
|
|
|
|
|
|
|
{F217/41 [2.15c+]}
|
|
Function AddBinderyObjectToSet(objName:String; objType:Word;
|
|
propName, memberName:String; memberType:Word ):boolean;
|
|
{ Adds a bindery object to a property set.
|
|
user must have write access to the set property. }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objType :Word; { hi-lo }
|
|
_objName :String[48]; { [48]=#0 }
|
|
_propName :String[15];
|
|
_memObjType :Word; { hi-lo }
|
|
_memName :String[48]; { [48]=#0 }
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$41;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PstrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
|
|
PstrCopy(_propName,propName,15); UpString(_propName);
|
|
_memObjType:=swap(memberType); { force hi-lo }
|
|
PStrCopy(_memName,memberName,48); _memName[48]:=#0; UpString(_memName);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
AddBinderyObjectToSet:=(result=0)
|
|
{ 96h Server out of memory; E9 Member already Exists; EB Not Group Property
|
|
F0h wildcard not allowed; F8 No Property write privileges;
|
|
FCh no such object; FEh Server Bindery Locked; FFh bindery failure }
|
|
end;
|
|
|
|
|
|
{F217/42 [2.0/2.1/3.x]}
|
|
Function DeleteBinderyObjectFromSet(objName:String; objType:Word;
|
|
propName, memberName:String; memberType:Word ):boolean;
|
|
{ Deltes a bindery object from a property set.
|
|
user must have write access to the set property. }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objType :Word; { hi-lo }
|
|
_objName :String[48]; { [48]=#0 }
|
|
_propName :String[15];
|
|
_memObjType :Word; { hi-lo }
|
|
_memName :String[48]; { [48]=#0 }
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$42;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PstrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
|
|
PstrCopy(_propName,propName,15); UpString(_propName);
|
|
_memObjType:=swap(memberType); { force hi-lo }
|
|
PStrCopy(_memName,memberName,48); _memName[48]:=#0; UpString(_memName);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
DeleteBinderyObjectFromSet:=(result=0)
|
|
{ 96h Server out of memory; EA No Such Member; EB Not Group Property
|
|
F0h wildcard not allowed; F8 No Property write privileges; FB No Such property;
|
|
FCh no such object; FEh Server Bindery Locked; FFh bindery failure }
|
|
end;
|
|
|
|
|
|
{F217/38 [2.15c+]}
|
|
Function ChangeBinderyObjectSecurity(objName :String; objType :Word;
|
|
NewObjSecurity :Byte ):boolean;
|
|
{ Changes the security of a Bindery object. This call is made successfully,
|
|
if the user is supervisor equivalent and the current security is unequal to
|
|
NetWare Read/ NetWare Write. }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_NobjSec :Byte;
|
|
_objType :Word; { hi-lo }
|
|
_objName :String[48]; { [48]=#0 }
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$38;
|
|
_NobjSec:=NewObjSecurity;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PstrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
ChangeBinderyObjectSecurity:=(result=0)
|
|
{ Completion Codes:
|
|
96 Server out of memory; F0 Wildcard Not Allowed; F1 Invalid Bindery Security;
|
|
FC No Such Object; FE Server Bindery Locked; FF Bindery Failure. }
|
|
end;
|
|
|
|
|
|
|
|
|
|
{F217/4B [3.x]}
|
|
FUNCTION ChangeEncrBinderyObjectPassword(ObjName: String; ObjType: Word;
|
|
{#d} oldPassWord,newPassword: String): Boolean;
|
|
{ Changes the password of a bindery object.
|
|
Old Password can be NULL. To log into a file server, an object must have a
|
|
PASSWORD property. User must have read and write access to the bindery object. }
|
|
FUNCTION ChangeEncrypted(ObjName : String; ObjType : Word;
|
|
oldEncrPW:TencryptionKey;
|
|
Var newPWdif:TencrPWdifference;
|
|
PWdifCheckSum:byte
|
|
):boolean;
|
|
Type Treq=RECORD
|
|
BufLen : Word;
|
|
_func : Byte;
|
|
_oldPW : TencryptionKey;
|
|
_ObjType: Word;
|
|
_ObjNameLen : byte;
|
|
_Various: array [1..48+1+16] of byte; { ObjName, difCheksum, PWdif }
|
|
End;
|
|
TPreq=^Treq;
|
|
Begin
|
|
With TPreq(GlobalreqBuf)^
|
|
do Begin
|
|
_func := $4B;
|
|
_oldPW:=oldEncrPW;
|
|
_ObjType := Swap(objType);
|
|
if objName[0]>#48
|
|
then objName[0]:=#48;
|
|
move (objName[0],_objNameLen,ord(objName[0])+1);
|
|
_Various[_objNamelen+1]:=PWdifCheckSum;
|
|
move(newPWdif,_Various[_objNamelen+2],16);
|
|
BufLen:=29+_objNameLen;
|
|
F2SystemCall($17,buflen+2,0,result);
|
|
end;
|
|
ChangeEncrypted:=(result=0);
|
|
End;
|
|
|
|
VAR
|
|
key : TencryptionKey;
|
|
ObjId:LongInt;
|
|
PWdif:TencrPWdifference;
|
|
PWdifChecksum:byte;
|
|
|
|
Begin
|
|
UpString(oldPassword);
|
|
if oldPassword[0]>#127
|
|
Then oldPassword[0]:=#127;
|
|
UpString(newPassword);
|
|
if newPassword[0]>#127
|
|
Then newPassword[0]:=#127;
|
|
UpString(ObjName);
|
|
|
|
IF GetEncryptionKey(key)
|
|
Then Begin
|
|
IF GetBinderyObjectId(objName,objType,ObjId)
|
|
Then Begin
|
|
EncryptPasswordDifference(objId,
|
|
OldPassword,NewPassword,
|
|
key, { i/o, out: EncrOldPW }
|
|
PWdif, { out, 16 bytes }
|
|
PWdifChecksum { out, 1 byte }
|
|
);
|
|
ChangeEncrypted(ObjName, ObjType, key, PWdif, PWdifChecksum);
|
|
End;
|
|
End
|
|
Else ChangeBinderyObjectPassword(ObjName, ObjType, OldPassword, NewPassword);
|
|
|
|
ChangeEncrBinderyObjectPassword:= (result=0);
|
|
{ Completion Codes:
|
|
96 Server Out Of Memory; F0 Wildcard Not Allowed; FB No Such Property;
|
|
FC No Such Object; FE Server Bindery Locked; FF No Such Object *OR*
|
|
No Password Associated With Object *OR* Old Password Invalid. }
|
|
End;
|
|
|
|
|
|
{F217/40 [2.0/2.1/3.x] }
|
|
Function ChangeBinderyObjectPassword(objName:String; objType:Word;
|
|
oldPassWord,newPassWord:String ):boolean;
|
|
{ Changes the password of a bindery object.
|
|
Allow unencrypted passwords must be ON!
|
|
Old Password can be NULL. To log into a file server, an object must have a
|
|
PASSWORD property. User must have read and write access to the bindery object. }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objType :Word; { hi-lo }
|
|
_objName :String[48]; { [48]=#0 }
|
|
_oldPW :String[128]; { wow! a password of 128 chars! }
|
|
_newPW :String[128];
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$40;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PStrCopy(_objName,objName,48); _ObjName[48]:=#0; UpString(_objName);
|
|
PStrCopy(_oldPW,oldPassWord,128); UpString(_oldPW);
|
|
PStrCopy(_newPW,newPassWord,128); UpString(_newPW);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
ChangeBinderyObjectPassword:=(result=0)
|
|
{ Completion Codes:
|
|
96 Server Out Of Memory; F0 Wildcard Not Allowed; FB No Such Property;
|
|
FC No Such Object; FE Server Bindery Locked; FF No Such Object *OR*
|
|
No Password Associated With Object *OR* Old Password Invalid. }
|
|
end;
|
|
|
|
|
|
|
|
|
|
{F217/39 [2.15c+]}
|
|
Function CreateProperty( objName:String; objType:Word;
|
|
propertyName:String; propFlags,propSecurity:Byte ):boolean;
|
|
{ Creates a property to be associated with a bindery object.
|
|
property flags tell whether a property is dynamic or static and whether
|
|
the property is defined as static or dynamic. }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objType :Word; { hi-lo }
|
|
_objName :String[48]; { [48]=#0 }
|
|
_propFlags:Byte;
|
|
_propSec :Byte;
|
|
_propName :String[15];
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$39;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PStrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
|
|
_propFlags:=propFlags;
|
|
_propSec:=propSecurity;
|
|
PStrCopy(_propName,propertyName,15); UpString(_propName);
|
|
end;
|
|
F2SystemCall($17,sizeof(Treq),0,result);
|
|
CreateProperty:=(result=0)
|
|
{ Completion Codes:
|
|
96 Server Out Of Memory; ED Property already exists; EF Invalid Name;
|
|
F0 Wildcard Not Allowed; F1 Invalid Bindery Security; F7 No Property Create Privileges;
|
|
FC No Such Object; FE Server Bindery Locked; FF Bindery Failure }
|
|
end;
|
|
|
|
|
|
{F217/3A [2.15c+]}
|
|
Function DeleteProperty( objName:String; objType:Word;
|
|
propertyName:String ):boolean;
|
|
{ Deletes a property from a bindery object.
|
|
The property field may contain wildcards. }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objType :Word; { hi-lo }
|
|
_objName :String[48]; { [48]=#0 }
|
|
_propName :String[15];
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$3A;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PStrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
|
|
PStrCopy(_propName,propertyName,15); UpString(_propName);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
DeleteProperty:=(result=0)
|
|
{ Completion Codes:
|
|
96 Server Out Of Memory; F0 Wildcard Not Allowed; F1 Invalid Bindery Security;
|
|
F6 No property delete privileges; FB No Such property;
|
|
FC No Such Object; FE Server Bindery Locked; FF Bindery Failure }
|
|
end;
|
|
|
|
|
|
{F217/3C [2.15c+]}
|
|
Function ScanProperty( objName:String; objType:Word; searchPropName:String;
|
|
{i/o var:} Var SequenceNumber:LongInt;
|
|
{ output:} Var propName:String;
|
|
Var propFlags:Byte;
|
|
Var propSecurity:Byte;
|
|
Var propHasValue:Boolean;
|
|
Var moreProperties:Boolean ):boolean;
|
|
{ Sequence number should be -1 the first time this call is made.
|
|
The call can be reiterated (by supplying the returned Seq.#) until
|
|
moreProperties=FALSE or nwBindry.Result=NO_SUCH_PROPERTY.
|
|
searchPropName may contain wildcards;
|
|
If propHasValue=TRUE, the value can be read by calling ReadPropertyValue;
|
|
moreProperties=TRUE if more properties exist for this object. }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objType :Word; {hi-lo}
|
|
_objName :String[48];
|
|
_SeqNbr :LongInt; {hi-lo}
|
|
_propName :String[15];
|
|
end;
|
|
Trep=record
|
|
_propName :array[1..16] of Byte;
|
|
_propFlags:Byte;
|
|
_propSec :Byte;
|
|
_SeqNbr :Longint; {hi-lo}
|
|
_propHasValue:Byte;
|
|
_moreProp :Byte;
|
|
end;
|
|
TPreq=^Treq;
|
|
TPrep=^Trep;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$3C;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PStrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
|
|
_SeqNbr:=Lswap(SequenceNumber); { force hi-lo }
|
|
PstrCopy(_propName,searchPropName,15); UpString(_propName);
|
|
end;
|
|
F2SystemCall($17,sizeof(Treq),sizeof(Trep),result);
|
|
With TPrep(GlobalReplyBuf)^
|
|
do begin
|
|
SequenceNumber:=Lswap(_SeqNbr); { force lo-hi }
|
|
ZStrCopy(propName,_propName,15);
|
|
propFlags:=_propFlags;
|
|
propSecurity:=_propSec;
|
|
propHasValue:=(_propHasValue>0);
|
|
moreProperties:=(_moreProp>0);
|
|
end;
|
|
ScanProperty:=(result=0)
|
|
{ Completion Codes:
|
|
96 Server Out Of Memory; F1 Invalid Bindery Security; FB No Such property;
|
|
FC No Such Object; FE Server Bindery Locked; FF Bindery Failure }
|
|
end;
|
|
|
|
|
|
{F217/3E [2.15c+]}
|
|
Function WritePropertyValue( objName:String; objType:Word;
|
|
propName:String; segmentNbr: Byte; propValue:Tproperty;
|
|
moreSegments:Boolean ):boolean;
|
|
{ Changes the value of a (NON-SET) property associated with a Bindery object.}
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_objType :Word; { hi-lo }
|
|
_objName :String[48];
|
|
_segNbr :Byte;
|
|
_EraseRemainingSeg:Byte; { FF=true 00=false }
|
|
_propName :String[15];
|
|
_propValSeg :Tproperty;
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$3E;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PStrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
|
|
_segNbr:=segmentNbr;
|
|
if moreSegments
|
|
then _EraseRemainingSeg:=$00
|
|
else _EraseRemainingSeg:=$FF;
|
|
PstrCopy(_propName,propName,15); UpString(_propName);
|
|
_propValSeg:=propValue;
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
WritePropertyValue:=(result=0)
|
|
{ Completion Codes:
|
|
96 Server Out Of Memory; E8 Not Item Property; EC no such segment;
|
|
F0 Wildcard Not Allowed; F1 Invalid Bindery Security;
|
|
F8 No property write privileges; FB No Such property;
|
|
FC No Such Object; FE Server Bindery Locked; FF Bindery Failure }
|
|
end;
|
|
|
|
{F217/3B [2.15c+] }
|
|
Function ChangePropertySecurity( objName:String; objType:Word;
|
|
propName:String; newPropSecurity:Byte ):boolean;
|
|
{ The user must have read and write access to the property to make this call.
|
|
The call can't assign a greater security level than the security level of
|
|
the caller. }
|
|
Type Treq=record
|
|
len:word;
|
|
subFunc:byte;
|
|
_objType:Word; { hi-lo }
|
|
_objName:String[48];
|
|
_NewPropSec:Byte;
|
|
_PropName:String[15];
|
|
end;
|
|
TPreq=^Treq;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$3B;
|
|
_objType:=swap(objType); { force hi-lo }
|
|
PstrCopy(_objName,objName,48); _objName[48]:=#0; Upstring(_objName);
|
|
_NewPropSec:=NewPropSecurity;
|
|
PstrCopy(_propName,propName,15); Upstring(_propName);
|
|
end;
|
|
F2SystemCall($17,sizeOf(Treq),0,result);
|
|
ChangePropertySecurity:=(result=0)
|
|
{ Completion Codes:
|
|
96 Server Out Of Memory; F0 Wildcard Not Allowed; F1 Invalid Bindery Security;
|
|
FB No Such property; FC No Such Object; FE Server Bindery Locked;
|
|
FF Bindery Failure }
|
|
end;
|
|
|
|
{F217/49 [3.0+]}
|
|
Function IsStationAManager:boolean;
|
|
{ Fast way to detremine if: object ID of caller included in the MANAGERS
|
|
set property attached to the SUPERVISOR object. }
|
|
Type Treq=record
|
|
len:word;
|
|
subFunc:byte;
|
|
end;
|
|
Trep=record
|
|
unknown:byte;
|
|
end;
|
|
TPreq=^Treq;
|
|
TPrep=^Trep;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
len:=SizeOf(Treq)-2;
|
|
subFunc:=$49;
|
|
end;
|
|
F2SystemCall($17,SizeOf(Treq),Sizeof(Trep),result);
|
|
{With TPrep(GlobalReplyBuf)^
|
|
do begin
|
|
|
|
end; }
|
|
IsStationAManager:=(result=0)
|
|
{ Completion codes:
|
|
00 Successful (WS is a manager);
|
|
FF Not a manager }
|
|
end;
|
|
|
|
{F217/4C [3.0+]}
|
|
Function GetRelationOfBinderyObject(ObjName:string;ObjType:word;
|
|
relationPropertyName:string;
|
|
{i/o} Var sequenceNbr:longint;
|
|
{out} Var NbrOfObjects:word;
|
|
Var Info:TobjIdArray ):boolean;
|
|
{ OBJ_SUPERVISORS GROUPS_I'M_IN SECURITY_EQUALS }
|
|
Type Treq=record
|
|
len :word;
|
|
subFunc :byte;
|
|
_SeqObjId :Longint; {hi-lo}
|
|
_ObjType :word; {hi-lo}
|
|
_ObjAndPropName:string;
|
|
end;
|
|
Trep=record
|
|
_NbrOfObj:Word;
|
|
_Info :TobjIdArray;
|
|
end;
|
|
TPreq=^Treq;
|
|
TPrep=^Trep;
|
|
Var t:byte;
|
|
Begin
|
|
WITH TPreq(GlobalReqBuf)^
|
|
do begin
|
|
subFunc:=$4C;
|
|
_SeqObjId:=Lswap(SequenceNbr);
|
|
_ObjType:=swap(ObjType);
|
|
Upstring(ObjName);UpString(RelationPropertyName);
|
|
_ObjAndPropName:=ObjName;
|
|
move(RelationPropertyName[0],
|
|
_ObjAndPropName[ord(ObjName[0])+1],
|
|
ord(RelationPropertyName[0])+1);
|
|
len:=9+ord(ObjName[0])+ord(RelationPropertyName[0]);
|
|
F2SystemCall($17,len+2,Sizeof(Trep),result);
|
|
end;
|
|
With TPrep(GlobalReplyBuf)^
|
|
do begin
|
|
NbrOfObjects:=swap(_NbrOfObj);
|
|
for t:= 1 to NbrOfObjects
|
|
do Info[t]:=Lswap(_Info[t]);
|
|
if NbrOfObjects=$20
|
|
then SequenceNbr:=Info[$20]
|
|
else SequenceNbr:=-1;
|
|
end;
|
|
if result<>0 then SequenceNbr:=-1;
|
|
GetRelationOfBinderyObject:=(result=0)
|
|
end;
|
|
|
|
|
|
|
|
{=======SECONDARY FUNCTIONS===================================================}
|
|
|
|
|
|
|
|
Function IsShellLoaded:boolean;
|
|
Var mask:byte;
|
|
id:LongInt;
|
|
begin
|
|
{$IFNDEF MSDOS}
|
|
FillChar(nwintr.GlobalReplyBuf^,Sizeof(nwintr.TintrBuffer),#$0);
|
|
{ Only needed in protected mode, otherwise an invalid value is reported.
|
|
Doesn't harm a bit if you use it in other modes, though. }
|
|
{$ENDIF}
|
|
IsShellLoaded:=(nwBindry.getBinderyAccessLevel(mask,id) and (id<>0));
|
|
end;
|
|
|
|
|
|
Function IsUserLoggedOn:boolean;
|
|
Var mask:byte;
|
|
id:LongInt;
|
|
objName:String;
|
|
objType:word;
|
|
begin
|
|
IsUserLoggedOn:=( nwBindry.getBinderyAccessLevel(mask,id)
|
|
and (id<>0)
|
|
and nwBindry.GetBinderyObjectName(id,objName,objType)
|
|
)
|
|
end;
|
|
|
|
|
|
Function GetRealUserName(userObjName:string; Var realname:string):boolean;
|
|
Var propValue:Tproperty;
|
|
moreSeg:Boolean;
|
|
w,propFlag:Byte;
|
|
begin
|
|
If ReadPropertyValue(userObjName,OT_USER,'IDENTIFICATION',1,propValue,moreSeg,propFlag)
|
|
then ZstrCopy(RealName,PropValue,128)
|
|
else realname:='';
|
|
GetRealUserName:=(result=0);
|
|
end;
|
|
|
|
Function GetUserObjectID:LongInt;
|
|
Var mask:byte;
|
|
id:LongInt;
|
|
begin
|
|
if getBinderyAccessLevel(mask,id)
|
|
then GetUserObjectID:=id
|
|
else getUserObjectID:=-1;
|
|
{ -1 : look at nwBindry.result for error number }
|
|
end;
|
|
|
|
|
|
Function ExistsUser(userObjName:string):boolean;
|
|
Var ObjId:Longint;
|
|
begin
|
|
ExistsUser:=GetBinderyObjectId(userObjName,OT_USER,ObjId);
|
|
end;
|
|
|
|
Function IsGroupMember( GroupName,UserObjName:String): Boolean;
|
|
begin
|
|
IsGroupMember:=IsBinderyObjectInSet(GroupName,OT_USER_GROUP,'GROUP_MEMBERS',
|
|
UserObjName,OT_USER);
|
|
end;
|
|
|
|
|
|
|
|
|
|
Function AddUserToGroup(userName,GroupName:String):boolean;
|
|
begin
|
|
{ first create the necessary properties. They may already exist. }
|
|
|
|
CreateProperty(userName,OT_USER,'GROUPS_I''M_IN',
|
|
BF_SET,BS_SUPER_WRITE OR BS_LOGGED_READ);
|
|
IF (result<>$00) and (result<>$ED) { property already exists }
|
|
then begin AddUserToGroup:=false;exit end; { bindery failure / bad username}
|
|
|
|
CreateProperty(userName,OT_USER,'SECURITY_EQUALS',
|
|
BF_SET,BS_SUPER_WRITE OR BS_LOGGED_READ);
|
|
IF (result<>$00) and (result<>$ED) { property already exists }
|
|
then begin AddUserToGroup:=false;exit end;
|
|
|
|
{ The following construction seems a bit overdone, but it is needed to keep
|
|
the bindery consistent. A user is either fully added to a group OR
|
|
nothing happens, this way we ensure that a user is not 'patially added'
|
|
to a group.
|
|
If the user already is a member of the group, no error is returned. }
|
|
IF AddBinderyObjectToSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
|
|
userName,OT_USER)
|
|
then begin
|
|
IF AddBinderyObjectToSet(userName,OT_USER,'GROUPS_I''M_IN',
|
|
GroupName,OT_USER_GROUP)
|
|
then begin
|
|
IF AddBinderyObjectToSet(userName,OT_USER,'SECURITY_EQUALS',
|
|
GroupName,OT_USER_GROUP)
|
|
then begin
|
|
AddUserToGroup:=true;
|
|
exit;
|
|
end
|
|
else begin { attempt to delete partially setup member }
|
|
DeleteBinderyObjectFromSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
|
|
userName,OT_USER);
|
|
DeleteBinderyObjectFromSet(userName,OT_USER,'GROUPS_I''M_IN',
|
|
GroupName,OT_USER_GROUP)
|
|
end
|
|
end
|
|
else begin
|
|
DeleteBinderyObjectFromSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
|
|
userName,OT_USER);
|
|
end;
|
|
end;
|
|
if result=$E9 then result:=$00; { $E9: user already a member of group }
|
|
AddUserToGroup:=(result=0);
|
|
{ As all these called functions are in this unit, you can check nwBindry.result
|
|
for the errorcode. }
|
|
{ resultcodes: $FC user OR group object doesn't exist. }
|
|
end;
|
|
|
|
|
|
|
|
|
|
Function DeleteUserFromGroup(userName,GroupName:String):boolean;
|
|
begin
|
|
{ The following construction seems a bit overdone, but it is needed to keep
|
|
the bindery consistent. A user is either totally deleted from a group OR
|
|
nothing happens, this way we ensure that a user is not 'patially deleted'
|
|
from a group.
|
|
If the user was not a member of the group, no error is returned. }
|
|
IF DeleteBinderyObjectFromSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
|
|
userName,OT_USER)
|
|
then begin
|
|
IF DeleteBinderyObjectFromSet(userName,OT_USER,'GROUPS_I''M_IN',
|
|
GroupName,OT_USER_GROUP)
|
|
then begin
|
|
IF DeleteBinderyObjectFromSet(userName,OT_USER,'SECURITY_EQUALS',
|
|
GroupName,OT_USER_GROUP)
|
|
then begin
|
|
DeleteUserFromGroup:=True;
|
|
exit;
|
|
end
|
|
else begin { attempt to repair partially deleted member }
|
|
AddBinderyObjectToSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
|
|
userName,OT_USER);
|
|
AddBinderyObjectToSet(userName,OT_USER,'GROUPS_I''M_IN',
|
|
GroupName,OT_USER_GROUP)
|
|
end
|
|
end
|
|
else AddBinderyObjectToSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
|
|
userName,OT_USER);
|
|
end;
|
|
if result=$EA then result:=0; { $EA: user obj NOT a member of group }
|
|
DeleteUserFromGroup:=false;
|
|
{ As all these called functions are in this unit, you can check nwBindry.result
|
|
for the errorcode. }
|
|
{ Resultcodes: $FC user OR group object doesn't exist. }
|
|
end;
|
|
|
|
Function ExistsFileServer(ServerName:string):Boolean;
|
|
{ You must be attached to at least one server before using this function. }
|
|
Var ObjId:Longint;
|
|
begin
|
|
UpString(ServerName);
|
|
ExistsFileServer:=GetBinderyObjectId(ServerName,OT_FILE_SERVER,ObjId);
|
|
end;
|
|
|
|
|
|
|
|
end. { end of unit nwBindry }
|
|
|