home *** CD-ROM | disk | FTP | other *** search
- /************************************************************
- * MultiUser - MultiUser Task/File Support System *
- * --------------------------------------------------------- *
- * Server Process *
- * --------------------------------------------------------- *
- * © Copyright 1993-1994 Geert Uytterhoeven *
- * All Rights Reserved. *
- ************************************************************/
-
-
- #include <exec/execbase.h>
- #include <exec/alerts.h>
- #include <exec/ports.h>
- #include <dos/dos.h>
- #include <dos/dostags.h>
- #include <utility/tagitem.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/utility.h>
- #include <proto/reqtools.h>
- #include <libraries/reqtools.h>
- #include <string.h>
-
- #include "Memory.h"
- #include "Server.h"
- #include "Config.h"
- #include "Locale.h"
- #include "LibHeader.h"
- #include "Misc.h"
- #include "Task.h"
- #include "UserInfo.h"
- #include "GroupInfo.h"
- #include "Monitor.h"
-
-
- /*
- * Static Routines
- */
-
- static void __saveds ServerProcess(void);
- static struct muPrivUserInfo *CheckUser(ULONG user, STRPTR userid, STRPTR pwd, BOOL nopasswd,
- BOOL nolog);
- static BOOL Passwd(ULONG user, STRPTR oldpwd, STRPTR newpwd);
- static struct muPrivUserInfo *GetUserInfo(struct muPrivUserInfo *info, ULONG keytype);
- static BOOL Belongs2(struct muUserDef *def, UWORD gid);
- static void FillUserInfo(struct muUserDef *def, struct muPrivUserInfo *info);
- static BOOL CheckPasswd(ULONG user, STRPTR pwd);
- static struct muPrivGroupInfo *GetGroupInfo(struct muPrivGroupInfo *info, ULONG keytype);
- static void FillGroupInfo(struct muGroupDef *def, struct muPrivGroupInfo *info);
-
-
- /*
- * Configuration Stuff
- */
-
- extern BPTR PasswdDirLock;
- extern BPTR ConfigDirLock;
-
-
- /*
- * Start the Server's Process
- */
-
- struct Process *CreateServer(void)
- {
- static struct TagItem tags[] = {
- NP_Entry, (LONG)ServerProcess,
- NP_Name, (LONG)SERVERNAME,
- NP_Priority, SERVERPRI,
- NP_StackSize, SERVERSTACK,
- TAG_DONE
- };
-
- return(muBase->Server = CreateNewProc((struct TagItem *)tags));
-
- }
-
-
- /*
- * Activate the Server by sending the Startup Message
- */
-
- BOOL StartServer(void)
- {
- return((BOOL)DoPkt(&muBase->Server->pr_MsgPort, ACTION_STARTUP, NULL, NULL, NULL, NULL, NULL));
- }
-
-
- /*
- * Kill the Server
- */
-
- BOOL KillServer(void)
- {
- return((BOOL)SendServerPacket(muSAction_Quit, NULL, NULL, NULL, NULL));
- }
-
-
- /*
- * Send a Packet to the Server
- */
-
- LONG SendServerPacket(LONG type, LONG arg1, LONG arg2, LONG arg3, LONG arg4)
- {
- struct muSPacket pkt;
- struct MsgPort *port;
-
- if (port = CreateMsgPort()) {
-
- /*
- * Initialise the Server Packet
- */
-
- pkt.Msg.mn_Node.ln_Succ = NULL;
- pkt.Msg.mn_Node.ln_Pred = NULL;
- pkt.Msg.mn_Node.ln_Type = NULL;
- pkt.Msg.mn_Node.ln_Pri = NULL;
- pkt.Msg.mn_Node.ln_Name = NULL;
- pkt.Msg.mn_ReplyPort = port;
- pkt.Msg.mn_Length = sizeof(struct muSPacket);
- pkt.Type = type;
- pkt.Arg1 = arg1;
- pkt.Arg2 = arg2;
- pkt.Arg3 = arg3;
- pkt.Arg4 = arg4;
- pkt.Res1 = NULL;
-
- /*
- * Transmit the packet and wait for reply
- */
-
- Forbid();
- if (muBase->ServerPort) {
- PutMsg(muBase->ServerPort, (struct Message *)&pkt);
- Permit();
- do
- WaitPort(port);
- while (GetMsg(port) != (struct Message *)&pkt);
- } else
- Permit();
-
- DeleteMsgPort(port);
- return(pkt.Res1);
- } else
- return(NULL);
- }
-
-
- /*
- * The Server's Process
- */
-
- static void __saveds ServerProcess(void)
- {
- struct muSPacket *pkt;
- BOOL quit = FALSE;
- ULONG user;
- ULONG signals;
- struct DosPacket *spkt;
-
- /*
- * Get Startup Message
- */
-
- spkt = WaitPkt();
-
- /*
- * Do all necessary initialisations
- */
-
- ((struct Process *)SysBase->ThisTask)->pr_WindowPtr = (APTR)-1;
-
- if (((muBase->NotifySig = AllocSignal(-1)) == -1) ||
- ((muBase->ConsistencySig = AllocSignal(-1)) == -1) || !(muBase->ServerPort = CreateMsgPort()) ||
- !(muBase->MonitorPort = CreateMsgPort())) {
- ReplyPkt(spkt, DOSFALSE, NULL);
- Die(NULL, AN_Unknown | AG_NoSignal);
- }
-
- /*
- * Reply Startup Message
- */
-
- ReplyPkt(spkt, DOSTRUE, NULL);
-
- InitVolumes();
-
- do {
- signals = Wait(1<<muBase->NotifySig | 1<<muBase->ConsistencySig |
- 1<<muBase->ServerPort->mp_SigBit | 1<<muBase->MonitorPort->mp_SigBit);
-
- if (signals & 1<<muBase->NotifySig)
- FreeDefs();
-
- if (signals & 1<<muBase->ConsistencySig) {
- FreeVolumes();
- InitVolumes();
- }
-
- if (signals & 1<<muBase->ServerPort->mp_SigBit)
- while (!quit && (pkt = (struct muSPacket *)GetMsg(muBase->ServerPort))) {
- switch (pkt->Type) {
- case muSAction_Quit:
-
- /*
- * Quit
- *
- *
- * Arg1: /
- * Arg2: /
- * Arg3: /
- *
- * Res1: BOOL success
- */
-
- quit = TRUE;
- pkt->Res1 = TRUE;
-
- /*
- * Ensure the Server will be RemTask()ed BEFORE any
- * other task will get the processor !!
- */
-
- Forbid();
- break;
-
- case muSAction_CheckUser:
-
- /*
- * CheckUser
- *
- *
- * Arg1: STRPTR uid
- * Arg2: STRPTR pwd
- * Arg3: BOOL nopasswd
- *
- * Res1: struct muPrivUserInfo *info (NULL for failure)
- */
-
- user = GetTaskOwner(pkt->Msg.mn_ReplyPort->mp_SigTask);
- pkt->Res1 = (LONG)CheckUser(user, (STRPTR)pkt->Arg1, (STRPTR)pkt->Arg2,
- (BOOL)pkt->Arg3, (BOOL)pkt->Arg4);
- break;
-
- case muSAction_Passwd:
-
- /*
- * Passwd
- *
- *
- * Arg1: STRPTR oldpwd
- * Arg2: STRPTR newpwd
- * Arg3: /
- *
- * Res1: BOOL success
- */
-
- user = GetTaskOwner(pkt->Msg.mn_ReplyPort->mp_SigTask);
- pkt->Res1 = (LONG)Passwd(user, (STRPTR)pkt->Arg1, (STRPTR)pkt->Arg2);
- break;
-
- case muSAction_GetUserInfo:
-
- /*
- * GetUserInfo
- *
- *
- * Arg1: struct muPrivUserInfo *info
- * Arg2: ULONG keytype
- * Arg3: /
- *
- * Res1: struct muPrivUserInfo *info (NULL for failure)
- */
-
- pkt->Res1 = (LONG)GetUserInfo((struct muPrivUserInfo *)pkt->Arg1, (ULONG)pkt->Arg2);
- break;
-
- case muSAction_CheckPasswd:
-
- /*
- * CheckPasswd
- *
- *
- * Arg1: STRPTR pwd
- * Arg2: /
- * Arg3: /
- *
- * Res1: BOOL success
- */
-
- user = GetTaskOwner(pkt->Msg.mn_ReplyPort->mp_SigTask);
- pkt->Res1 = (LONG)CheckPasswd(user, (STRPTR)pkt->Arg1);
- break;
-
- case muSAction_PasswdDirLock:
-
- /* PasswdDirLock
- *
- *
- * Arg1: /
- * Arg2: /
- * Arg3: /
- *
- * Res1: BPTR lock
- */
-
- if (PasswdDirLock)
- pkt->Res1 = DupLock(PasswdDirLock);
- break;
-
- case muSAction_ConfigDirLock:
-
- /* ConfigDirLock
- *
- *
- * Arg1: /
- * Arg2: /
- * Arg3: /
- *
- * Res1: BPTR lock
- */
-
- if (ConfigDirLock)
- pkt->Res1 = DupLock(ConfigDirLock);
- break;
-
- case muSAction_GetGroupInfo:
-
- /*
- * GetGroupInfo
- *
- *
- * Arg1: struct muPrivGroupInfo *info
- * Arg2: ULONG keytype
- * Arg3: /
- *
- * Res1: struct muPrivGroupInfo *info (NULL for failure)
- */
-
- pkt->Res1 = (LONG)GetGroupInfo((struct muPrivGroupInfo *)pkt->Arg1, (ULONG)pkt->Arg2);
- break;
-
- default:
- break;
- }
- ReplyMsg((struct Message *)pkt);
- }
-
- if (signals & 1<<muBase->MonitorPort->mp_SigBit)
- FreeRepliedMonMsg();
-
- } while (!quit);
-
- FreeVolumes();
-
- DeleteMsgPort(muBase->MonitorPort);
- DeleteMsgPort(muBase->ServerPort);
- FreeSignal(muBase->ConsistencySig);
- FreeSignal(muBase->NotifySig);
- muBase->MonitorPort = NULL;
- muBase->ServerPort = NULL;
- muBase->ConsistencySig = NULL;
- muBase->Server = NULL;
- }
-
-
- /*
- * Check if a user is licensed to login
- */
-
- static struct muPrivUserInfo *CheckUser(ULONG user, STRPTR userid, STRPTR pwd, BOOL nopasswd,
- BOOL nolog)
- {
- BOOL found;
- char buffer[12];
- struct muPrivUserInfo *info = NULL;
- struct muUserDef *def;
- UWORD uid;
-
- uid = user>>16;
-
- if (def = GetUserDefs())
- do
- if ((found = (!strcmp(userid, def->UserID))) && (nopasswd ||
- (Encrypt(buffer, pwd, def->UserID) && !strcmp(buffer, def->Password))) &&
- (info = muAllocUserInfo()))
- FillUserInfo(def, info);
- else
- def = def->Next;
- while (!found && def);
-
- if (info)
- CallMonitors(muTrgB_Login, uid, info->Pub.uid, userid);
- else
- CallMonitors(muTrgB_LoginFail, uid, NULL, userid);
-
- if (!nolog && ((info && (muBase->Config.LogFlags & muLogF_Login)) ||
- (!info && (muBase->Config.LogFlags & muLogF_LoginFail)))) {
- LONG args[2];
- args[0] = uid;
- args[1] = (LONG)userid;
- if (info)
- VLogF(GetLogStr(MSG_LOG_LOGIN), args);
- else
- VLogF(GetLogStr(MSG_LOG_LOGINFAIL), args);
- }
-
- return(info);
- }
-
-
- /*
- * Change the Password of a user
- */
-
- static BOOL Passwd(ULONG user, STRPTR oldpwd, STRPTR newpwd)
- {
- BOOL found;
- BOOL changed = FALSE;
- UWORD uid, gid;
- char buffer[12];
- struct muUserDef *def;
-
- uid = user>>16;
- gid = user&muMASK_GID;
-
- if (((uid >= muBase->Config.PasswduidLevel) || (gid >= muBase->Config.PasswdgidLevel)) &&
- (def = GetUserDefs()))
- do
- if (found = (def->uid == uid))
- changed = Encrypt(buffer, oldpwd, def->UserID) && !strcmp(buffer, def->Password) &&
- Encrypt(def->Password, newpwd, def->UserID) && UpdateUserDefs();
- else
- def = def->Next;
- while (!found && def);
-
- if (changed)
- CallMonitors(muTrgB_Passwd, uid, NULL, NULL);
- else
- CallMonitors(muTrgB_PasswdFail, uid, NULL, NULL);
-
- if ((changed && (muBase->Config.LogFlags & muLogF_Passwd)) ||
- (!changed && (muBase->Config.LogFlags & muLogF_PasswdFail))) {
- LONG args[1];
- args[0] = uid;
- if (changed)
- VLogF(GetLogStr(MSG_LOG_PASSWD), args);
- else
- VLogF(GetLogStr(MSG_LOG_PASSWDFAIL), args);
- }
-
- return(changed);
- }
-
-
- /*
- * Get Information about a User
- */
-
- static struct muPrivUserInfo *GetUserInfo(struct muPrivUserInfo *info, ULONG keytype)
- {
- struct muUserDef *def;
- ULONG len;
- ULONG count = 0;
-
- if (def = GetUserDefs()) {
- switch (keytype) {
- case muKeyType_First:
- break;
-
- case muKeyType_Next:
- while ((count <= info->Count) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_UserID:
- while (strcmp(def->UserID, info->Pub.UserID) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_uid:
- while ((def->uid != info->Pub.uid) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_gid:
- info->Tgid = info->Pub.gid;
- while (!Belongs2(def, info->Tgid) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_gidNext:
- while ((count <= info->Count) && (def = def->Next))
- count++;
- if (def)
- while (!Belongs2(def, info->Tgid) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_UserName:
- while (stricmp(def->UserName, info->Pub.UserName) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_WUserID:
- FreeV(info->Pattern);
- len = 2*strlen(info->Pub.UserID)+2;
- if ((info->Pattern = MAllocV(len)) &&
- (ParsePatternNoCase(info->Pub.UserID, info->Pattern, len) != -1))
- while (!MatchPatternNoCase(info->Pattern, def->UserID) && (def = def->Next))
- count++;
- else {
- FreeV(info->Pattern);
- info->Pattern = NULL;
- def = NULL;
- }
- break;
-
- case muKeyType_WUserIDNext:
- if (info->Pattern) {
- while ((count <= info->Count) && (def = def->Next))
- count++;
- if (def)
- while (!MatchPatternNoCase(info->Pattern, def->UserID) && (def = def->Next))
- count++;
- } else
- def = NULL;
- break;
-
- case muKeyType_WUserName:
- FreeV(info->Pattern);
- len = 2*strlen(info->Pub.UserName)+2;
- if ((info->Pattern = MAllocV(len)) &&
- (ParsePatternNoCase(info->Pub.UserName, info->Pattern, len) != -1))
- while (!MatchPatternNoCase(info->Pattern, def->UserName) && (def = def->Next))
- count++;
- else {
- FreeV(info->Pattern);
- info->Pattern = NULL;
- def = NULL;
- }
- break;
-
- case muKeyType_WUserNameNext:
- if (info->Pattern) {
- while ((count <= info->Count) && (def = def->Next))
- count++;
- if (def)
- while (!MatchPatternNoCase(info->Pattern, def->UserName) && (def = def->Next))
- count++;
- } else
- def = NULL;
- break;
-
- default:
- def = NULL;
- break;
- }
- if (def) {
- FillUserInfo(def, info);
- info->Count = count;
- } else
- info = NULL;
- } else
- info = NULL;
-
- return(info);
- }
-
-
- /*
- * Checker whether a user belongs to a group
- */
-
- static BOOL Belongs2(struct muUserDef *def, UWORD gid)
- {
- int i;
-
- if (def->gid == gid)
- return(TRUE);
- for (i = 0; i < def->NumSecGroups; i++)
- if (def->SecGroups[i] == gid)
- return(TRUE);
- return(FALSE);
- }
-
-
- /*
- * Fill in the User Information
- */
-
- static void FillUserInfo(struct muUserDef *def, struct muPrivUserInfo *info)
- {
- strncpy(info->Pub.UserID, def->UserID, muUSERIDSIZE-1);
- info->Pub.UserID[muUSERIDSIZE-1] = '\0';
- info->Pub.uid = def->uid;
- info->Pub.gid = def->gid;
- strncpy(info->Pub.UserName, def->UserName, muUSERNAMESIZE-1);
- info->Pub.UserName[muUSERNAMESIZE-1] = '\0';
- strncpy(info->Pub.HomeDir, def->HomeDir, muHOMEDIRSIZE-1);
- info->Pub.HomeDir[muHOMEDIRSIZE-1] = '\0';
- if (info->Pub.NumSecGroups)
- Free(info->Pub.SecGroups, info->Pub.NumSecGroups*sizeof(UWORD));
- if (def->NumSecGroups && (info->Pub.SecGroups = MAlloc(def->NumSecGroups*sizeof(UWORD)))) {
- info->Pub.NumSecGroups = def->NumSecGroups;
- CopyMem(def->SecGroups, info->Pub.SecGroups, def->NumSecGroups*sizeof(UWORD));
- } else {
- info->Pub.NumSecGroups = 0;
- info->Pub.SecGroups = NULL;
- }
- strncpy(info->Pub.Shell, def->Shell, muSHELLSIZE-1);
- info->Password = !!strlen(def->Password);
- }
-
-
- /*
- * Check the Password of a User
- */
-
- static BOOL CheckPasswd(ULONG user, STRPTR pwd)
- {
- BOOL found;
- BOOL valid = FALSE;
- UWORD uid;
- char buffer[12];
- struct muUserDef *def;
-
- uid = user>>16;
-
- if (def = GetUserDefs())
- do
- if (found = (def->uid == uid))
- valid = Encrypt(buffer, pwd, def->UserID) && !strcmp(buffer, def->Password);
- else
- def = def->Next;
- while (!found && def);
-
- if (valid)
- CallMonitors(muTrgB_CheckPasswd, uid, NULL, NULL);
- else
- CallMonitors(muTrgB_CheckPasswdFail, uid, NULL, NULL);
-
- if ((valid && (muBase->Config.LogFlags & muLogF_CheckPasswd)) ||
- (!valid && (muBase->Config.LogFlags & muLogF_CheckPasswdFail))) {
- LONG args[1];
- args[0] = uid;
- if (valid)
- VLogF(GetLogStr(MSG_LOG_CHECKPASSWD), args);
- else
- VLogF(GetLogStr(MSG_LOG_CHECKPASSWDFAIL), args);
- }
-
- return(valid);
- }
-
-
- /*
- * Get Information about a Group
- */
-
- static struct muPrivGroupInfo *GetGroupInfo(struct muPrivGroupInfo *info, ULONG keytype)
- {
- struct muGroupDef *def;
- ULONG len;
- ULONG count = 0;
-
- if (def = GetGroupDefs()) {
- switch (keytype) {
- case muKeyType_First:
- break;
-
- case muKeyType_Next:
- while ((count <= info->Count) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_GroupID:
- while (strcmp(def->GroupID, info->Pub.GroupID) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_gid:
- while ((def->gid != info->Pub.gid) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_GroupName:
- while (stricmp(def->GroupName, info->Pub.GroupName) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_WGroupID:
- FreeV(info->Pattern);
- len = 2*strlen(info->Pub.GroupID)+2;
- if ((info->Pattern = MAllocV(len)) &&
- (ParsePatternNoCase(info->Pub.GroupID, info->Pattern, len) != -1))
- while (!MatchPatternNoCase(info->Pattern, def->GroupID) && (def = def->Next))
- count++;
- else {
- FreeV(info->Pattern);
- info->Pattern = NULL;
- def = NULL;
- }
- break;
-
- case muKeyType_WGroupIDNext:
- if (info->Pattern) {
- while ((count <= info->Count) && (def = def->Next))
- count++;
- if (def)
- while (!MatchPatternNoCase(info->Pattern, def->GroupID) && (def = def->Next))
- count++;
- } else
- def = NULL;
- break;
-
- case muKeyType_WGroupName:
- FreeV(info->Pattern);
- len = 2*strlen(info->Pub.GroupName)+2;
- if ((info->Pattern = MAllocV(len)) &&
- (ParsePatternNoCase(info->Pub.GroupName, info->Pattern, len) != -1))
- while (!MatchPatternNoCase(info->Pattern, def->GroupName) && (def = def->Next))
- count++;
- else {
- FreeV(info->Pattern);
- info->Pattern = NULL;
- def = NULL;
- }
- break;
-
- case muKeyType_WGroupNameNext:
- if (info->Pattern) {
- while ((count <= info->Count) && (def = def->Next))
- count++;
- if (def)
- while (!MatchPatternNoCase(info->Pattern, def->GroupName) && (def = def->Next))
- count++;
- } else
- def = NULL;
- break;
-
- case muKeyType_MgrUid:
- while ((def->MgrUid != info->Pub.MgrUid) && (def = def->Next))
- count++;
- break;
-
- case muKeyType_MgrUidNext:
- while ((count <= info->Count) && (def = def->Next))
- count++;
- if (def)
- while ((def->MgrUid != info->Pub.MgrUid) && (def = def->Next))
- count++;
- break;
-
- default:
- def = NULL;
- break;
- }
- if (def) {
- FillGroupInfo(def, info);
- info->Count = count;
- } else
- info = NULL;
- } else
- info = NULL;
-
- return(info);
- }
-
-
- /*
- * Fill in the Group Information
- */
-
- static void FillGroupInfo(struct muGroupDef *def, struct muPrivGroupInfo *info)
- {
- strncpy(info->Pub.GroupID, def->GroupID, muGROUPIDSIZE-1);
- info->Pub.GroupID[muGROUPIDSIZE-1] = '\0';
- info->Pub.gid = def->gid;
- info->Pub.MgrUid = def->MgrUid;
- strncpy(info->Pub.GroupName, def->GroupName, muGROUPNAMESIZE-1);
- info->Pub.GroupName[muGROUPNAMESIZE-1] = '\0';
- }
-