summaryrefslogtreecommitdiff
path: root/packages/users
diff options
context:
space:
mode:
authormarco <marco@3ad0048d-3df7-0310-abae-a5850022a9f2>2008-01-26 23:39:08 +0000
committermarco <marco@3ad0048d-3df7-0310-abae-a5850022a9f2>2008-01-26 23:39:08 +0000
commita94785d9ccf7f6aeb25eb9eabd24aacf6f61f389 (patch)
tree6986d34a9d2752e00a791d3ab61c21046e72a1dc /packages/users
parent1db34a35686c4b80ade20c124e64591d3c7b8d74 (diff)
downloadfpc-a94785d9ccf7f6aeb25eb9eabd24aacf6f61f389.tar.gz
* users first pass
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@10007 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/users')
-rw-r--r--packages/users/examples/testpass.pp101
-rw-r--r--packages/users/examples/testuser.pp25
-rw-r--r--packages/users/grp.pp65
-rw-r--r--packages/users/pwd.pp64
-rw-r--r--packages/users/shadow.pp65
-rw-r--r--packages/users/src/users.pp331
6 files changed, 651 insertions, 0 deletions
diff --git a/packages/users/examples/testpass.pp b/packages/users/examples/testpass.pp
new file mode 100644
index 0000000000..c7437ef845
--- /dev/null
+++ b/packages/users/examples/testpass.pp
@@ -0,0 +1,101 @@
+Program TestPass;
+
+{Test the user's password}
+{$DEFINE DEBUG}
+
+uses shadow, pwd, strings, crypt_h, cmem;
+
+Var
+ strUserName, Password : String;
+ sEntry : PPasswordFileEntry;
+ pEntry : PPasswd;
+
+Const
+ Err_NoErr = 0;
+ Err_NoUser = 1;
+ Err_WrongPass = 2;
+ NoUser = '*NO USER*';
+
+Function UserEncPass(User: String): String;
+Var
+ A : Array[0..255] of char;
+Begin
+ A := strUserName;
+ {$IFDEF DEBUG}
+ Writeln('User name is ',A);
+ {$ENDIF}
+ sEntry := getspnam(A);
+ If sEntry = nil then
+ Begin
+ {$IFDEF DEBUG}
+ Writeln('No shadow entry');
+ {$ENDIF}
+ pEntry := getpwnam(A);
+ If pEntry = nil then
+ Begin
+ {$IFDEF DEBUG}
+ Writeln('No passwd entry');
+ {$ENDIF}
+ UserEncPass := NoUser
+ End
+ End;
+ if sEntry <> nil then UserEncPass := sEntry^.sp_pwdp;
+ if pEntry <> nil then UserEncPass := pEntry^.pw_passwd
+End;
+
+Function CheckPass(User, Pass: String): Integer;
+Var
+ EncPass, ResultPass, SSalt : String;
+ PCPass, PCSalt, PCResult : Array[0..255] of Char;
+ I : Integer;
+Begin
+ EncPass := UserEncPass(User);
+ {$IFDEF DEBUG}
+ Writeln('Encrypted PW is : ',EncPass);
+ {$ENDIF}
+ If EncPass = NoUser then
+ Begin
+ CheckPass := Err_NoUser;
+ {$IFDEF DEBUG}
+ Writeln('No user named ',User,'.');
+ {$ENDIF}
+ Exit
+ End;
+ PCPass := Pass;
+ If Copy(EncPass,1,3) = '$1$' then
+ Begin
+ I := 4;
+ SSalt := '$1$';
+ Repeat
+ SSalt := SSalt + EncPass[I];
+ Inc(I)
+ Until EncPass[I] = '$';
+ PCSalt := SSalt
+ End
+ else
+ PCSalt := Copy(EncPass,1,2);
+ {$IFDEF DEBUG}
+ Writeln('Salt is : ',PCSalt);
+ {$ENDIF}
+ PCResult := crypt(PCPass, PCSalt);
+ ResultPass := StrPas(PCResult);
+ {$IFDEF DEBUG}
+ Writeln('From passwd/shadow : ',EncPass);
+ Writeln('From crypt : ',ResultPass);
+ {$ENDIF}
+ If ResultPass = EncPass then
+ CheckPass := Err_NoErr
+ else
+ CheckPass := Err_WrongPass
+End;
+
+Begin
+ Write('User name : ');
+ Readln(strUserName);
+ Write('Password : ');
+ Readln(Password);
+ If CheckPass(strUserName, Password) = Err_NoErr then
+ Writeln('User authentication succeeded')
+ else
+ Writeln('User autentication failed.');
+End.
diff --git a/packages/users/examples/testuser.pp b/packages/users/examples/testuser.pp
new file mode 100644
index 0000000000..ab1637f239
--- /dev/null
+++ b/packages/users/examples/testuser.pp
@@ -0,0 +1,25 @@
+program testuser;
+
+uses users,classes;
+
+var
+ Ulist,GList : TStringlist;
+ i : longint;
+
+begin
+ Ulist:=TStringList.Create;
+ Glist:=TStringList.Create;
+ Try
+ GetUserList(Ulist,True);
+ GetGroupList(Glist,True);
+ Writeln('Users: ');
+ For I:=0 to Ulist.Count-1 do
+ Writeln('User ',Ulist[i]);
+ Writeln('Groups: ');
+ For I:=0 to Glist.Count-1 do
+ Writeln('Group ',Glist[i]);
+ finally
+ Ulist.Free;
+ Glist.Free;
+ end;
+end.
diff --git a/packages/users/grp.pp b/packages/users/grp.pp
new file mode 100644
index 0000000000..16f92e92ef
--- /dev/null
+++ b/packages/users/grp.pp
@@ -0,0 +1,65 @@
+unit grp;
+interface
+
+{
+ Automatically converted by H2Pas 0.99.15 from grp.h
+ The following command line parameters were used:
+ -D
+ -l
+ c
+ -p
+ -s
+ -u
+ grp
+ -v
+ grp.h
+}
+
+ const
+ External_library='c'; {Setup as you need}
+
+ { Pointers to basic pascal types, inserted by h2pas conversion program.}
+ Type
+ PLongint = ^Longint;
+ PSmallInt = ^SmallInt;
+ PByte = ^Byte;
+ PWord = ^Word;
+ PDWord = ^DWord;
+ PDouble = ^Double;
+
+{$PACKRECORDS C}
+
+
+type
+ PFILE = Pointer;
+ __gid_t = Longint;
+ P__gid_t = ^__gid_t;
+ size_t = longint;
+
+ PGroup = ^group;
+ group = record
+ gr_name : Pchar;
+ gr_passwd : Pchar;
+ gr_gid : __gid_t;
+ gr_mem : ^Pchar;
+ end;
+ TGroup = Group;
+ PPGROUP = ^PGroup;
+
+procedure setgrent;cdecl;external External_library name 'setgrent';
+procedure endgrent;cdecl;external External_library name 'endgrent';
+function getgrent:Pgroup;cdecl;external External_library name 'getgrent';
+function fgetgrent(__stream:PFILE):Pgroup;cdecl;external External_library name 'fgetgrent';
+function getgrgid(__gid:__gid_t):Pgroup;cdecl;external External_library name 'getgrgid';
+function getgrnam(__name:Pchar):Pgroup;cdecl;external External_library name 'getgrnam';
+function getgrgid_r(__gid:__gid_t; __resultbuf:Pgroup; __buffer:Pchar; __buflen:size_t; __result:PPgroup):longint;cdecl;external External_library name 'getgrgid_r';
+function getgrnam_r(__name:Pchar; __resultbuf:Pgroup; __buffer:Pchar; __buflen:size_t; __result:PPgroup):longint;cdecl;external External_library name 'getgrnam_r';
+function fgetgrent_r(__stream:PFILE; __resultbuf:Pgroup; __buffer:Pchar; __buflen:size_t; __result:PPgroup):longint;cdecl;external External_library name 'fgetgrent_r';
+function setgroups(__n:size_t; __groups:P__gid_t):longint;cdecl;external External_library name 'setgroups';
+function getgrouplist(__user:Pchar; __group:__gid_t; __groups:P__gid_t; __ngroups:Plongint):longint;cdecl;external External_library name 'getgrouplist';
+function initgroups(__user:Pchar; __group:__gid_t):longint;cdecl;external External_library name 'initgroups';
+
+
+implementation
+
+end.
diff --git a/packages/users/pwd.pp b/packages/users/pwd.pp
new file mode 100644
index 0000000000..739bae99c6
--- /dev/null
+++ b/packages/users/pwd.pp
@@ -0,0 +1,64 @@
+unit pwd;
+interface
+
+{
+ Automatically converted by H2Pas 0.99.15 from pwd.H
+ The following command line parameters were used:
+ -D
+ -l
+ c
+ -p
+ -s
+ -u
+ pwd
+ -v
+ pwd.H
+}
+
+const
+ External_library='c'; {Setup as you need}
+
+{ Pointers to basic pascal types, inserted by h2pas conversion program.}
+Type
+ PLongint = ^Longint;
+ PSmallInt = ^SmallInt;
+ PByte = ^Byte;
+ PWord = ^Word;
+ PDWord = ^DWord;
+ PDouble = ^Double;
+
+{$PACKRECORDS C}
+
+
+type
+ PFile = Pointer;
+ __uid_t = longint;
+ __gid_t = longint;
+
+ Ppasswd = ^passwd;
+ passwd = record
+ pw_name : Pchar;
+ pw_passwd : Pchar;
+ pw_uid : __uid_t;
+ pw_gid : __gid_t;
+ pw_gecos : Pchar;
+ pw_dir : Pchar;
+ pw_shell : Pchar;
+ end;
+ TPasswordRecord = passwd;
+ PPasswordRecord = ^TPasswordRecord;
+
+procedure setpwent;cdecl; external External_library name 'setpwent';
+procedure endpwent;cdecl; external External_library name 'endpwent';
+function getpwent:Ppasswd;cdecl;external External_library name 'getpwent';
+function fgetpwent(__stream:PFILE):Ppasswd;cdecl;external External_library name 'fgetpwent';
+function putpwent(__p:Ppasswd; __f:PFILE):longint;cdecl;external External_library name 'putpwent';
+function getpwuid(__uid:__uid_t):Ppasswd;cdecl;external External_library name 'getpwuid';
+function getpwnam(__name:Pchar):Ppasswd;cdecl;external External_library name 'getpwnam';
+function getpw(__uid:__uid_t; __buffer:Pchar):longint;cdecl;external External_library name 'getpw';
+
+
+implementation
+
+
+end.
diff --git a/packages/users/shadow.pp b/packages/users/shadow.pp
new file mode 100644
index 0000000000..c50d94cc1e
--- /dev/null
+++ b/packages/users/shadow.pp
@@ -0,0 +1,65 @@
+unit shadow;
+interface
+
+{
+ Automatically converted by H2Pas 0.99.15 from shadow.h
+ The following command line parameters were used:
+ -D
+ -l
+ c
+ -p
+ -s
+ -u
+ shadow
+ -v
+ shadow.h
+}
+
+ const
+ External_library='c'; {Setup as you need}
+
+ { Pointers to basic pascal types, inserted by h2pas conversion program.}
+ Type
+ PLongint = ^Longint;
+ PSmallInt = ^SmallInt;
+ PByte = ^Byte;
+ PWord = ^Word;
+ PDWord = ^DWord;
+ PDouble = ^Double;
+
+{$PACKRECORDS C}
+
+
+type
+ PFile = Pointer;
+
+ Pspwd = ^spwd;
+ spwd = record
+ sp_namp : pchar;
+ sp_pwdp : pchar;
+ sp_lstchg : longint;
+ sp_min : longint;
+ sp_max : longint;
+ sp_warn : longint;
+ sp_inact : longint;
+ sp_expire : longint;
+ sp_flag : longint;
+ end;
+ TPasswordFileEntry = spwd;
+ PPasswordFileEntry = ^TPasswordFileEntry;
+
+procedure setspent;cdecl;external External_library name 'setspent';
+procedure endspent;cdecl;external External_library name 'endspent';
+function getspent:Pspwd;cdecl;external External_library name 'getspent';
+function getspnam(__name:Pchar):Pspwd;cdecl;external External_library name 'getspnam';
+function sgetspent(__string:Pchar):Pspwd;cdecl;external External_library name 'sgetspent';
+function fgetspent(__stream:PFILE):Pspwd;cdecl;external External_library name 'fgetspent';
+function putspent(__p:Pspwd; __stream:PFILE):longint;cdecl;external External_library name 'putspent';
+function lckpwdf:longint;cdecl;external External_library name 'lckpwdf';
+function ulckpwdf:longint;cdecl;external External_library name 'ulckpwdf';
+
+
+implementation
+
+
+end.
diff --git a/packages/users/src/users.pp b/packages/users/src/users.pp
new file mode 100644
index 0000000000..d5f221488b
--- /dev/null
+++ b/packages/users/src/users.pp
@@ -0,0 +1,331 @@
+unit users;
+
+Interface
+
+uses pwd,shadow,grp,Linux,SysUtils,Classes;
+
+Type
+ EUserLookupError = Class(Exception);
+ EGroupLookupError = Class(Exception);
+ EShadowLookupError = Class(Exception);
+
+{ User functions }
+
+Function getpwnam(Const UserName: String) : PPasswordRecord;
+Procedure GetUserData(Const UserName : String; Var Data : TPasswordRecord); overload;
+Procedure GetUserData(Uid : Integer; Var Data : TPasswordRecord); overload;
+function GetUserName(UID : Integer) : String;
+function GetUserId(Const UserName : String) : Integer;
+function GetUserGid(Const UserName : String) : Integer;
+function GetUserDir(Const UserName : String): String;
+function GetUserDescription(Const UserName : String): String;
+Procedure GetUserList(List : Tstrings);overload;
+Procedure GetUserList(List : TStrings; WithIDs : Boolean);overload;
+
+{ Group functions }
+
+Function getgrnam(Const GroupName: String) : PGroup;
+Procedure GetGroupData(Const GroupName : String; Var Data : TGroup); overload;
+Procedure GetGroupData(Gid : Integer; Var Data : TGroup); overload;
+function GetGroupName(GID : Integer) : String;
+function GetGroupId(Const GroupName : String) : Integer;
+Procedure GetGroupList(List : Tstrings);overload;
+Procedure GetGroupList(List : TStrings; WithIDs : Boolean);overload;
+Procedure GetGroupMembers(GID : Integer;List : TStrings);overload;
+Procedure GetGroupMembers(Const GroupName : String;List : TStrings);overload;
+
+{ Shadow password functions }
+
+function getspnam(UserName : String): PPasswordFileEntry;
+function sgetspent(Line : String): PPasswordFileEntry;
+Procedure GetUserShadowData(Const UserName : String; Var Data : TPasswordFileEntry);overload;
+Procedure GetUserShadowData(UID : Integer; Var Data : TPasswordFileEntry);overload;
+
+{ Extra functions }
+
+Function GetUserGroup(Const UserName : String) : String;
+
+Implementation
+
+ResourceString
+
+EnoSuchUserName = 'Unknown username: "%s"';
+EnoSuchUserID = 'Unknown user ID: %d';
+EnoSuchGroupName = 'Unknown groupname: "%s"';
+EnoSuchGroupID = 'Unknown group ID: %d';
+ENoShadowEntry = 'No shadow file entry for "%s"';
+EShadowNotPermitted = 'Not enough permissions to access shadow password file';
+
+Function getpwnam(Const UserName: String) : PPasswordRecord;
+
+begin
+ Result:=pwd.getpwnam(Pchar(UserName));
+end;
+
+Procedure GetUserData(Const UserName : String; Var Data : TPasswordRecord);
+
+Var P : PPasswordRecord;
+
+begin
+ P:=Getpwnam(UserName);
+ If P<>Nil then
+ Data:=P^
+ else
+ Raise EUserLookupError.CreateFmt(ENoSuchUserName,[UserName]);
+end;
+
+Procedure GetUserData(Uid : Integer; Var Data : TPasswordRecord);
+
+Var P : PPasswordRecord;
+
+begin
+ P:=Getpwuid(Uid);
+ If P<>Nil then
+ Data:=P^
+ else
+ Raise EUserLookupError.CreateFmt(ENoSuchUserID,[Uid]);
+end;
+
+function GetUserName(UID : Integer) : String;
+
+Var
+ UserData : TPasswordRecord;
+
+begin
+ GetuserData(UID,UserData);
+ Result:=strpas(UserData.pw_Name);
+end;
+
+function GetUserId(Const UserName : String) : Integer;
+
+Var
+ UserData : TPasswordRecord;
+
+begin
+ GetUserData(UserName,UserData);
+ Result:=UserData.pw_uid;
+end;
+
+function GetUserGId(Const UserName : String) : Integer;
+
+Var
+ UserData : TPasswordRecord;
+
+begin
+ GetUserData(UserName,UserData);
+ Result:=UserData.pw_gid;
+end;
+
+function GetUserDir(Const UserName : String): String;
+
+Var
+ UserData : TPasswordRecord;
+
+begin
+ GetUserData(UserName,UserData);
+ Result:=strpas(UserData.pw_dir);
+end;
+
+function GetUserDescription(Const UserName : String): String;
+
+Var
+ UserData : TPasswordRecord;
+
+begin
+ GetUserData(UserName,UserData);
+ Result:=strpas(UserData.pw_gecos);
+end;
+
+Procedure GetUserList(List : Tstrings);
+
+begin
+ GetUserList(List,False);
+end;
+
+Procedure GetUserList(List : TStrings; WithIDs : Boolean);
+
+Var
+ P : PPasswordRecord;
+
+begin
+ List.Clear;
+ setpwent;
+ try
+ Repeat
+ P:=getpwent;
+ If P<>Nil then
+ begin
+ If WithIDs then
+ List.Add(Format('%d=%s',[P^.pw_uid,strpas(p^.pw_name)]))
+ else
+ List.Add(strpas(p^.pw_name));
+ end;
+ until (P=Nil);
+ finally
+ endpwent;
+ end;
+end;
+
+{ ---------------------------------------------------------------------
+ Group Functions
+ ---------------------------------------------------------------------}
+
+
+Function getgrnam(Const GroupName: String) : PGroup;
+
+begin
+ Result:=grp.getgrnam(Pchar(GroupName));
+end;
+
+Procedure GetGroupData(Const GroupName : String; Var Data : TGroup); overload;
+
+Var P : PGroup;
+
+begin
+ P:=Getgrnam(GroupName);
+ If P<>Nil then
+ Data:=P^
+ else
+ Raise EGroupLookupError.CreateFmt(ENoSuchGroupName,[GroupName]);
+end;
+
+Procedure GetGroupData(Gid : Integer; Var Data : TGroup); overload;
+
+Var P : PGroup;
+
+begin
+ P:=Getgrgid(gid);
+ If P<>Nil then
+ Data:=P^
+ else
+ Raise EGroupLookupError.CreateFmt(ENoSuchGroupID,[Gid]);
+end;
+
+function GetGroupName(GID : Integer) : String;
+
+Var
+ G : TGroup;
+
+begin
+ GetGroupData(Gid,G);
+ Result:=StrPas(G.gr_name);
+end;
+
+function GetGroupId(Const GroupName : String) : Integer;
+
+Var
+ G : TGroup;
+
+begin
+ GetGroupData(GroupName,G);
+ Result:=G.gr_gid;
+end;
+
+Procedure GetGroupList(List : Tstrings);overload;
+
+begin
+ GetGroupList(List,False);
+end;
+
+Procedure GetGroupList(List : TStrings; WithIDs : Boolean);overload;
+
+Var
+ G : PGroup;
+
+begin
+ List.Clear;
+ setgrent;
+ try
+ Repeat
+ G:=getgrent;
+ If G<>Nil then
+ begin
+ If WithIDs then
+ List.Add(Format('%d=%s',[G^.gr_gid,strpas(G^.gr_name)]))
+ else
+ List.Add(strpas(G^.gr_name));
+ end;
+ until (G=Nil);
+ finally
+ endgrent;
+ end;
+end;
+
+Function PCharListToStrings(P : PPChar; List : TStrings) : Integer;
+
+begin
+ List.Clear;
+ While P^<>Nil do
+ begin
+ List.Add(StrPas(P^));
+ P:=PPChar(PChar(P)+SizeOf(PChar));
+ end;
+ Result:=List.Count;
+end;
+
+
+Procedure GetGroupMembers(GID : Integer;List : TStrings);
+
+Var
+ G : TGroup;
+
+begin
+ GetGroupData(GID,G);
+ PCharListToStrings(G.gr_mem,List);
+end;
+
+Procedure GetGroupMembers(Const GroupName : String;List : TStrings);
+
+Var
+ G : TGroup;
+
+begin
+ GetGroupData(GroupName,G);
+ PCharListToStrings(g.gr_mem,List);
+end;
+
+{ Shadow password functions }
+
+function getspnam(UserName : String): PPasswordFileEntry;
+
+begin
+ result:=shadow.getspnam(Pchar(UserName));
+end;
+
+function sgetspent(Line : String): PPasswordFileEntry;
+
+begin
+ Result:=shadow.sgetspent(Pchar(Line));
+end;
+
+Procedure GetUserShadowData(Const UserName : String; Var Data : TPasswordFileEntry);
+
+Var
+ P : PPasswordFileEntry;
+
+begin
+ P:=getspnam(UserName);
+ If P=Nil then
+ If (GetUID<>0) and (GetEUID<>0) then
+ Raise EShadowLookupError.Create(EShadowNotPermitted)
+ else
+ Raise EShadowLookupError.CreateFmt(ENoShadowEntry,[UserName])
+ else
+ Data:=P^;
+end;
+
+Procedure GetUserShadowData(UID : Integer; Var Data : TPasswordFileEntry);
+
+begin
+ GetUserShadowData(GetUserName(UID),Data);
+end;
+
+{ Extra functions }
+
+Function GetUserGroup(Const UserName : String) : String;
+
+begin
+ GetGroupName(GetUserGid(UserName));
+end;
+
+end.