home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / util / misc / multiuser / src / library / log.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-29  |  12.3 KB  |  511 lines

  1. /************************************************************
  2. * MultiUser - MultiUser Task/File Support System                *
  3. * ---------------------------------------------------------    *
  4. * Login Access Management                                                *
  5. * ---------------------------------------------------------    *
  6. * © Copyright 1993-1994 Geert Uytterhoeven                        *
  7. * All Rights Reserved.                                                    *
  8. ************************************************************/
  9.  
  10.  
  11. #include <proto/exec.h>
  12. #include <proto/dos.h>
  13. #include <proto/utility.h>
  14. #include <proto/reqtools.h>
  15. #include <exec/execbase.h>
  16. #include <exec/alerts.h>
  17. #include <dos/dos.h>
  18. #include <dos/var.h>
  19. #include <dos/datetime.h>
  20. #include <utility/tagitem.h>
  21. #include <libraries/reqtools.h>
  22. #include <string.h>
  23.  
  24. #include "Log.h"
  25. #include "Misc.h"
  26. #include "Config.h"
  27. #include "Locale.h"
  28. #include "LibHeader.h"
  29. #include "UserInfo.h"
  30. #include "Task.h"
  31. #include "Server.h"
  32. #include "Monitor.h"
  33.  
  34.  
  35.     /*
  36.      *        Static Routines
  37.      */
  38.  
  39. static void myfputs(BPTR file, STRPTR str);
  40. static BOOL myfgets(BPTR file, STRPTR str, ULONG len);
  41. static struct muPrivUserInfo *LoginRequest(struct muTags *tags, BOOL failallowed, BOOL nopasswd, struct LocaleInfo *li);
  42. static BOOL GetUserIDGUI(STRPTR userid, STRPTR version, STRPTR hostname, STRPTR scrname, struct LocaleInfo *li);
  43. static BOOL GetPasswordGUI(STRPTR password, STRPTR scrname, struct LocaleInfo *li);
  44. static BOOL GetUserIDCon(STRPTR userid, STRPTR version, STRPTR hostname, BPTR input, BPTR output,
  45.                                  int *retry, struct LocaleInfo *li);
  46. static BOOL GetPasswordCon(STRPTR password, BPTR input, BPTR output, struct LocaleInfo *li);
  47. static BOOL CheckPassword(STRPTR uid);
  48.  
  49.  
  50.     /*
  51.      *        Support Functions
  52.      */
  53.  
  54. static void __inline myfputs(BPTR file, STRPTR str)
  55. {
  56.     Write(file, str, strlen(str));
  57. }
  58.  
  59.  
  60. static BOOL __inline myfgets(BPTR file, STRPTR str, ULONG len)
  61. {
  62.     LONG readlen;
  63.  
  64.     readlen = Read(file, str, len);
  65.     if (readlen > 1) {
  66.         str[readlen-1] = '\0';
  67.         return(TRUE);
  68.     } else {
  69.         str[0] = '\0';
  70.         return(FALSE);
  71.     }
  72. }
  73.  
  74.  
  75.     /*
  76.      *        Logout and Restore the Previous User
  77.      *
  78.      *        Public Library Function
  79.      *
  80.      *        If there are no users left for the task, a login requester will
  81.      *        appear.
  82.      */
  83.  
  84.  
  85. ULONG __asm __saveds muLogoutA(register __a0 struct TagItem *taglist)
  86. {
  87.     struct muExtOwner *xuser;
  88.     ULONG user;
  89.     struct muPrivUserInfo *info;
  90.     char day[LEN_DATSTRING];
  91.     char date[LEN_DATSTRING];
  92.     char time[LEN_DATSTRING];
  93. #define LASTLOGINSIZE (3*LEN_DATSTRING+2)
  94.     char lastlogin[LASTLOGINSIZE+1];
  95.         /* V39+: use lastlogin[LASTLOGINSIZE] */
  96.     char buffer[256];
  97.     BPTR file, dir, seglist;
  98.     struct DateTime dt;
  99.     struct FileInfoBlock *fib;
  100.     STRPTR args[6];
  101.     struct muTags tags;
  102.     struct Segment *seg;
  103.     BOOL neverloggedin = TRUE;
  104.     int i;
  105.     char *fmt;
  106.     BOOL nobody;
  107.     struct LocaleInfo li;
  108.  
  109.     if (!InterpreteTagList(taglist, &tags))
  110.         return(muOWNER_NOBODY);
  111.  
  112.     tags.UserID = tags.Password = NULL;
  113.     tags.NoLog = FALSE;
  114.  
  115.     OpenLoc(&li);
  116.  
  117.     do {
  118.         if (tags.Global)
  119.             nobody = !PopTaskLevelDetach(tags.Task);
  120.         else
  121.             nobody = !PopTaskDetach(tags.Task);
  122.     } while (tags.All && !nobody);
  123.     user = GetTaskOwner(tags.Task);
  124.     if (nobody && !tags.Quiet)
  125.         if (info = LoginRequest(&tags, FALSE, FALSE, &li)) {
  126.             PushTask(SysBase->ThisTask, &RootExtOwner);
  127.  
  128.             xuser = muUserInfo2ExtOwner(info);
  129.             SetVar("Home", info->Pub.HomeDir, -1, GVF_LOCAL_ONLY);
  130.             if (fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL)) {
  131.                 if (dir = Lock(info->Pub.HomeDir, ACCESS_READ)) {
  132.                     if (Examine(dir, fib) && (fib->fib_DirEntryType > 0)) {
  133.                         if (NameFromLock(dir, buffer, 256))
  134.                             SetCurrentDirName(buffer);
  135.                         dir = CurrentDir(dir);
  136.                     }
  137.                     UnLock(dir);
  138.                 }
  139.                 FreeDosObject(DOS_FIB, fib);
  140.             }
  141.             muFreeUserInfo(info);
  142.  
  143.             if (file = Open(muLastLogin_FileName, MODE_OLDFILE)) {
  144.                 if (FGets(file, lastlogin, LASTLOGINSIZE))
  145.                     neverloggedin = FALSE;
  146.                 Close(file);
  147.             }
  148.             dt.dat_Format = FORMAT_DOS;
  149.             dt.dat_Flags = NULL;
  150.             DateStamp(&dt.dat_Stamp);
  151.             dt.dat_StrDay = day;
  152.             dt.dat_StrDate = date;
  153.             dt.dat_StrTime = time;
  154.             DateToStr(&dt);
  155.             args[0] = day;
  156.             args[1] = date;
  157.             args[2] = time;
  158.             if (file = Open(muLastLogin_FileName, MODE_NEWFILE)) {
  159.                 VFPrintf(file, "%s %s %s\n", (LONG *)args);
  160.                 Close(file);
  161.             }
  162.             if (!neverloggedin) {
  163.                 args[3] = lastlogin;
  164.                 args[4] = "";
  165.                 args[5] = "";
  166.                 for (i = 0; lastlogin[i] && (lastlogin[i] != ' '); i++);
  167.                 if (lastlogin[i]) {
  168.                     lastlogin[i++] = '\0';
  169.                     while (lastlogin[i] == ' ')
  170.                         i++;
  171.                     args[4] = &lastlogin[i];
  172.                     while (lastlogin[i] && (lastlogin[i] != ' '))
  173.                         i++;
  174.                     if (lastlogin[i]) {
  175.                         lastlogin[i++] = '\0';
  176.                         while (lastlogin[i] == ' ')
  177.                             i++;
  178.                         args[5] = &lastlogin[i];
  179.                         while (lastlogin[i] && (lastlogin[i] != ' ') &&
  180.                                  (lastlogin[i] != '\n'))
  181.                             i++;
  182.                         lastlogin[i] = '\0';
  183.                     }
  184.                 }
  185.             }
  186.  
  187.             PopTask(SysBase->ThisTask);
  188.  
  189.             if (neverloggedin)
  190.                 fmt = GetLocS(&li,MSG_FIRSTLOGIN);
  191.             else
  192.                 fmt = GetLocS(&li,MSG_LASTLOGIN);
  193.  
  194.             if (tags.Graphical) {
  195.                 if (muBase->Config.Flags & muCFGF_LastLoginReq)
  196.                     rtEZRequestTags(fmt, GetLocS(&li,MSG_OK), NULL, args,
  197.                                          RTEZ_Flags, EZREQF_CENTERTEXT,
  198.                                          RT_PubScrName, tags.PubScrName,
  199.                                          RT_ReqPos, REQPOS_CENTERSCR,
  200.                                          RT_LockWindow, TRUE,
  201.                                          TAG_DONE);
  202.             } else {
  203.                 FPuts(tags.Output, "\n");
  204.                 VFPrintf(tags.Output, fmt, (LONG *)args);
  205.                 FPuts(tags.Output, "\n");
  206.                 Flush(tags.Output);
  207.             }
  208.  
  209.             if (tags.Global)
  210.                 PushTaskLevel(tags.Task, xuser);
  211.             else
  212.                 PushTask(tags.Task, xuser);
  213.  
  214.             if ((muBase->Config.Flags & muCFGF_Profile) &&
  215.                  (dir = (BPTR)SendServerPacket(muSAction_ConfigDirLock, NULL,
  216.                                                          NULL, NULL, NULL))) {
  217.                 dir = CurrentDir(dir);
  218.                 if (file = Lock(muProfile_FileName, ACCESS_READ)) {
  219.                     Forbid();
  220.                     if (seg = FindSegment("Execute", NULL, NULL))
  221.                         seg->seg_UC++;
  222.                     Permit();
  223.                     if (seg)
  224.                         seglist = seg->seg_Seg;
  225.                     else
  226.                         seglist = NewLoadSeg("C:Execute", NULL);
  227.                     if (seglist) {
  228.                         RunCommand(seglist, 4000, muProfile_FileName "\n",
  229.                                       strlen(muProfile_FileName "\n"));
  230.                         if (!seg)
  231.                             UnLoadSeg(seglist);
  232.                     }
  233.                     if (seg) {
  234.                         Forbid();
  235.                         seg->seg_UC--;
  236.                         Permit();
  237.                     }
  238.                     UnLock(file);
  239.                 }
  240.                 UnLock(CurrentDir(dir));
  241.             }
  242.             user = muExtOwner2ULONG(xuser);
  243.             muFreeExtOwner(xuser);
  244.         } else
  245.             Die(NULL, AN_Unknown | AG_BadParm);
  246.  
  247.     CloseLoc(&li);
  248.  
  249.     return(user);
  250. }
  251.  
  252.  
  253.     /*
  254.      *        Login to the System and Add the User to the Task
  255.      *
  256.      *        Public Library Function
  257.      */
  258.  
  259.  
  260. ULONG __asm __saveds muLoginA(register __a0 struct TagItem *taglist)
  261. {
  262.     struct muExtOwner *xuser;
  263.     struct muPrivUserInfo *info;
  264.     struct muTags tags;
  265.     BOOL res;
  266.     struct LocaleInfo li;
  267.  
  268.     if (!InterpreteTagList(taglist, &tags) || (tags.Password && !tags.UserID))
  269.         return(muOWNER_NOBODY);
  270.  
  271.     xuser = GetTaskExtOwner(SysBase->ThisTask);
  272.     if (!tags.Own)
  273.         OpenLoc(&li);
  274.         if (info = LoginRequest(&tags, TRUE, muGetRelationshipA(xuser, NULL, NULL) & muRelF_ROOT_UID, &li)) {
  275.             muFreeExtOwner(xuser);
  276.             xuser = muUserInfo2ExtOwner(info);
  277.             muFreeUserInfo(info);
  278.         } else {
  279.             muFreeExtOwner(xuser);
  280.             return(muOWNER_NOBODY);
  281.         }
  282.         CloseLoc(&li);
  283.  
  284.     if (tags.Global)
  285.         res = PushTaskLevel(tags.Task, xuser);
  286.     else
  287.         res = PushTask(tags.Task, xuser);
  288.     muFreeExtOwner(xuser);
  289.  
  290.     return(GetTaskOwner(tags.Task));
  291. }
  292.  
  293.  
  294.     /*
  295.      *        Request the User for a Login
  296.      */
  297.  
  298. static struct muPrivUserInfo *LoginRequest(struct muTags *tags, BOOL failallowed, BOOL nopasswd, struct LocaleInfo *li)
  299. {
  300.     BOOL ret;
  301.     char version[8];
  302.     char hostname[32];
  303.     char uidbuf[muUSERIDSIZE];
  304.     char pwdbuf[muPASSWORDSIZE];
  305.     STRPTR userid, password;
  306.     struct muPrivUserInfo *info = NULL;
  307.     int retry = 0, i;
  308.  
  309.     if (GetVar("Kickstart", version, 8, GVF_GLOBAL_ONLY) == -1)
  310.         strcpy(version, "?");
  311.     if (GetVar("HostName", hostname, 32, GVF_GLOBAL_ONLY) == -1)
  312.         strcpy(hostname, "?");
  313.     else {
  314.         for (i = 0; hostname[i] && (hostname[i] != '.'); i++);
  315.         if (hostname[i] == '.')
  316.             hostname[i] = '\0';
  317.     }
  318.  
  319.     do {
  320.         if (tags->UserID)
  321.             userid = tags->UserID;
  322.         else {
  323.             userid = uidbuf;
  324.             do {
  325.                 memset(uidbuf, '\0', sizeof(uidbuf));
  326.                 if (tags->Graphical)
  327.                     ret = GetUserIDGUI(uidbuf, version, hostname,
  328.                                              tags->PubScrName, li);
  329.                 else
  330.                     ret = GetUserIDCon(uidbuf, version, hostname, tags->Input,
  331.                                              tags->Output, &retry, li);
  332.                 if (!ret && failallowed)
  333.                     return(NULL);
  334.             } while (!ret);
  335.         }
  336.         if (tags->Password)
  337.             password = tags->Password;
  338.         else {
  339.             password = pwdbuf;
  340.             memset(pwdbuf, '\0', sizeof(pwdbuf));
  341.             if (!nopasswd && CheckPassword(userid)) {
  342.                 if (tags->Graphical)
  343.                     ret = GetPasswordGUI(pwdbuf, tags->PubScrName, li);
  344.                 else
  345.                     ret = GetPasswordCon(pwdbuf, tags->Input, tags->Output, li);
  346.                 if (!ret)
  347.                     if (failallowed)
  348.                         return(NULL);
  349.                     else
  350.                         password = NULL;
  351.             }
  352.         }
  353.         if (userid && password) {
  354.             info = (struct muPrivUserInfo *)SendServerPacket(muSAction_CheckUser, (LONG)userid,
  355.                                                                              (LONG)password, (LONG)nopasswd,
  356.                                                                              (LONG)tags->NoLog);
  357.             memset(pwdbuf, '\0', sizeof(pwdbuf));
  358.             if (!info)
  359.                 if (failallowed)
  360.                     return(NULL);
  361.                 else if (tags->Graphical)
  362.                     rtEZRequestTags(GetLocS(li,MSG_LOGINFAIL_GUI), 
  363.                                          GetLocS(li,MSG_OK), NULL, NULL,
  364.                                          RTEZ_Flags, EZREQF_CENTERTEXT,
  365.                                          RT_PubScrName, tags->PubScrName,
  366.                                          RT_ReqPos, REQPOS_CENTERSCR,
  367.                                          RT_LockWindow, TRUE,
  368.                                          TAG_DONE);
  369.                 else
  370.                     myfputs(tags->Output, GetLocS(li,MSG_LOGINFAIL_CON));
  371.         }
  372.     } while (!info);
  373.     return(info);
  374. }
  375.  
  376.  
  377.     /*
  378.      *        Ask the User for his UserID (Graphical User Interface version)
  379.      */
  380.  
  381. static BOOL GetUserIDGUI(STRPTR userid, STRPTR version, STRPTR hostname, STRPTR scrname, struct LocaleInfo *li)
  382. {
  383.     STRPTR args[2];
  384.  
  385.     args[0] = version;
  386.     args[1] = hostname;
  387.     return((BOOL)rtGetString(userid, muUSERIDSIZE-1, GetLocS(li,MSG_LOGINREQ_GUI),
  388.                                      NULL, RTGS_TextFmt, GetLocS(li,MSG_LOGINPROMPT_GUI),
  389.                                              RTGS_TextFmtArgs, args,
  390.                                              RTGS_Flags, GSREQF_CENTERTEXT,
  391.                                              RT_PubScrName, scrname,
  392.                                              RT_ReqPos, REQPOS_CENTERSCR,
  393.                                              RT_LockWindow, TRUE,
  394.                                              TAG_DONE));
  395. }
  396.  
  397.  
  398.     /*
  399.      *        Ask the User for his Password (Graphical User Interface version)
  400.      */
  401.  
  402. static BOOL GetPasswordGUI(STRPTR password, STRPTR scrname, struct LocaleInfo *li)
  403. {
  404.     return((BOOL)rtGetString(password, muPASSWORDSIZE-1,
  405.                                      GetLocS(li,MSG_LOGINREQ_GUI), NULL,
  406.                                      RTGS_TextFmt, GetLocS(li,MSG_PASSWDPROMPT_GUI),
  407.                                      RTGS_Invisible, TRUE,
  408.                                      RTGS_AllowEmpty, TRUE,
  409.                                      RTGS_Flags, GSREQF_CENTERTEXT,
  410.                                      RT_PubScrName, scrname,
  411.                                      RT_ReqPos, REQPOS_CENTERSCR,
  412.                                      RT_LockWindow, TRUE,
  413.                                      TAG_DONE));
  414. }
  415.  
  416.  
  417.     /*
  418.      *        Ask the User for his UserID (Standard Console I/O version)
  419.      */
  420.  
  421. static BOOL GetUserIDCon(STRPTR userid, STRPTR version, STRPTR hostname, BPTR input, BPTR output,
  422.                                  int *retry, struct LocaleInfo *li)
  423. {
  424.     STRPTR args[2];
  425.     BOOL ret;
  426.  
  427.     args[0] = version;
  428.     args[1] = hostname;
  429.     if (!*retry) {
  430.         VFPrintf(output, GetLocS(li,MSG_LOGINREQ_CON), (LONG *)args);
  431.         Flush(output);
  432.     }
  433.     myfputs(output, GetLocS(li,MSG_LOGINPROMPT_CON));
  434.     myfputs(output," ");
  435.     ret = myfgets(input, userid, muUSERIDSIZE);
  436.     if (ret)
  437.         *retry = (*retry+1) % 4;
  438.     else
  439.         *retry = 0;
  440.     return(ret);
  441. }
  442.  
  443.  
  444.     /*
  445.      *        Ask the User for his Password (Standard Console I/O version)
  446.      */
  447.  
  448. static BOOL GetPasswordCon(STRPTR password, BPTR input, BPTR output, struct LocaleInfo *li)
  449. {
  450.     BOOL done;
  451.     ULONG len;
  452.     char buffer;
  453.  
  454.     myfputs(output, GetLocS(li,MSG_PASSWDPROMPT_CON));
  455.     myfputs(output, " ");
  456.     done = FALSE;
  457.     len = 0;
  458.     SetMode(input, 1);
  459.     do {
  460.         Read(input, &buffer, 1);
  461.         switch(buffer) {
  462.             case    '\b':
  463.                 if (len) {
  464.                     FPutC(output, '\b');
  465.                     Flush(output);
  466.                     len--;
  467.                 }
  468.                 break;
  469.  
  470.             case    '\n':
  471.             case    '\r':
  472.                 done = TRUE;
  473.                 break;
  474.  
  475.             default:
  476.                 if ((len < muPASSWORDSIZE-1) && ((buffer & 0x7f) > 31)
  477.                      && (buffer != 127)) {
  478.                     FPutC(output, ' ');
  479.                     password[len++] = buffer;
  480.                 } else
  481.                     FPutC(output, 7);
  482.                 Flush(output);
  483.                 break;
  484.         }
  485.     } while (!done);
  486.     password[len] = '\0';
  487.     SetMode(input, 0);
  488.     myfputs(output, "\n");
  489.     return(TRUE);
  490. }
  491.  
  492.  
  493.     /*
  494.      *        Check whether a User has a Password or not
  495.      */
  496.  
  497. static BOOL CheckPassword(STRPTR userid)
  498. {
  499.     struct muPrivUserInfo *info;
  500.     BOOL pwd = TRUE;
  501.  
  502.     if (info = muAllocUserInfo()) {
  503.         strncpy(info->Pub.UserID, userid, muUSERIDSIZE-1);
  504.         info->Pub.UserID[muUSERIDSIZE-1] = '\0';
  505.         if (SendServerPacket(muSAction_GetUserInfo, (LONG)info, muKeyType_UserID, NULL, NULL))
  506.             pwd = info->Password;
  507.         muFreeUserInfo(info);
  508.     }
  509.     return(pwd);
  510. }
  511.