home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / dev / gcc / ixemulsrc.lha / ixemul / library / user.c < prev    next >
C/C++ Source or Header  |  1996-12-11  |  11KB  |  531 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Portions Copyright (C) 1994 Rafael W. Luebbert
  5.  *  Portions Copyright (C) 1996 Jeff Shepherd
  6.  *
  7.  *  This library is free software; you can redistribute it and/or
  8.  *  modify it under the terms of the GNU Library General Public
  9.  *  License as published by the Free Software Foundation; either
  10.  *  version 2 of the License, or (at your option) any later version.
  11.  *
  12.  *  This library is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  *  Library General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU Library General Public
  18.  *  License along with this library; if not, write to the Free
  19.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. #define _KERNEL
  23. #include "ixemul.h"
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <pwd.h>
  27. #include "multiuser.h"
  28. #include <amitcp/usergroup.h>
  29.  
  30. /* builtin passwd info */
  31.  
  32. static const struct passwd builtin_root =
  33.  
  34. { "root", "", 0, 0, 0, "", "The Master of All Things", "SYS:", "sh", 0 };
  35.  
  36. static const struct passwd builtin_nobody =
  37.  
  38. { "nobody", "", -2, -2, 0, "", "The Anonymous One", "T:", "sh", 0 };
  39.  
  40. /* multiuser specific stuff */
  41.  
  42. static char *
  43. getUserPasswd(char *name)
  44. {
  45.   char *retval = NULL;
  46.   char passdir[MAXPATHLEN];
  47.   BPTR passwddir;
  48.  
  49.   if(!muBase || !strcmp(name,"nobody")) return("");
  50.  
  51.   if ((passwddir = muGetPasswdDirLock())) {
  52.     if (NameFromLock(passwddir, passdir, MAXPATHLEN)) {
  53.       if (AddPart(passdir, muPasswd_FileName, MAXPATHLEN)) {
  54.         FILE *fi = (FILE *)syscall(SYS_fopen,passdir,"r");
  55.         char passwdline[1024];
  56.         char username[muUSERNAMESIZE] = {0,};
  57.         char passwd[muPASSWORDSIZE] = {0,};
  58.         int found_it = 0;
  59.  
  60.         if (fi) {
  61.           while (fgets(passwdline,1024,fi)) {
  62.             char *sep = strchr(passwdline,'|');
  63.             char *old;
  64.             strncpy(username,passwdline,sep-passwdline);
  65.  
  66.             old = ++sep;
  67.             sep = strchr(old,'|');
  68.             strncpy(passwd,old,sep - old);
  69.  
  70.             if (!strcmp(username,name)) {
  71.               found_it = 1;
  72.               break;
  73.             }
  74.           }
  75.           if (found_it) {
  76.             retval = strdup(passwd);
  77.           }
  78.           fclose(fi);
  79.         }
  80.       }
  81.     }
  82.     UnLock(passwddir);
  83.   }
  84.   if (!retval)
  85.     retval = strdup("*");
  86.  
  87.   return retval;
  88. }
  89.  
  90. static struct passwd *
  91. UserInfo2pw (struct muUserInfo *UI)
  92. {
  93.   struct passwd *pw = &u.u_passwd;
  94.  
  95.   if (UI == NULL)
  96.     return NULL;
  97.  
  98.   pw->pw_name = UI->UserID;
  99.   pw->pw_dir = UI->HomeDir;
  100.   if (pw->pw_passwd)
  101.     free(pw->pw_passwd);
  102.   pw->pw_passwd = getUserPasswd(pw->pw_name);
  103.   pw->pw_uid = __amiga2unixid(UI->uid);
  104.   pw->pw_gid = __amiga2unixid(UI->gid);
  105.   pw->pw_change = 0;
  106.   pw->pw_class = "";
  107.   pw->pw_gecos = UI->UserName;
  108.   pw->pw_shell = UI->Shell;
  109.   pw->pw_expire = 0;
  110.  
  111.   return pw;
  112. }
  113.  
  114. /* builtin passwd file parsing */
  115.  
  116. #define MAXLINELENGTH    1024
  117. #define UNIX_STRSEP     ":\n"
  118. #define AMIGAOS_STRSEP  "|\n"
  119.  
  120. static int
  121. start_pw(void)
  122. {
  123.   if (u.u_pwd_fp) {
  124.     syscall(SYS_rewind, u.u_pwd_fp);
  125.     return 1;
  126.   }
  127.   return ((u.u_pwd_fp = (FILE *)syscall(SYS_fopen, _PATH_PASSWD, "r")) ? 1 : 0);
  128. }
  129.  
  130. static int
  131. pwscan(int search, uid_t uid, char *name)
  132. {
  133.   register char *cp;
  134.   char *bp;
  135.   char *fgets(), *strsep(), *index();
  136.   char *sep;
  137.  
  138.   if (u.u_pwd_line == NULL)
  139.     u.u_pwd_line = malloc(MAXLINELENGTH);
  140.   if (u.u_pwd_line == NULL)
  141.     {
  142.       errno = ENOMEM;
  143.       return 0;
  144.     }
  145.   for (;;) {
  146.     if (!syscall(SYS_fgets, u.u_pwd_line, MAXLINELENGTH, u.u_pwd_fp))
  147.       return 0;
  148.  
  149.     bp = u.u_pwd_line;
  150.     /* skip lines that are too big */
  151.     if (!index(u.u_pwd_line, '\n')) {
  152.       int ch;
  153.  
  154.       while ((ch = getc(u.u_pwd_fp)) != '\n' && ch != EOF) ;
  155.       continue;
  156.     }
  157.  
  158.     sep = index(u.u_pwd_line,'|') ? AMIGAOS_STRSEP : UNIX_STRSEP;
  159.  
  160.     u.u_passwd.pw_name = strsep(&bp, sep);
  161.     if (search && name && strcmp(u.u_passwd.pw_name, name))
  162.       continue;
  163.  
  164.     u.u_passwd.pw_passwd = strsep(&bp, sep);
  165.     if (!(cp = strsep(&bp, sep)))
  166.       continue;
  167.  
  168.     u.u_passwd.pw_uid = (uid_t)atoi(cp);
  169.     if (search && name == NULL && u.u_passwd.pw_uid != uid)
  170.       continue;
  171.  
  172.     if (!(cp = strsep(&bp, sep))) continue;
  173.  
  174.     u.u_passwd.pw_gid = (gid_t)atoi(cp);
  175.  
  176.     u.u_passwd.pw_gecos = cp = strsep(&bp, sep);
  177.     if (!cp) continue;
  178.     
  179.     u.u_passwd.pw_dir = cp = strsep(&bp, sep);
  180.     if (!cp) continue;
  181.     
  182.     u.u_passwd.pw_shell = cp = strsep(&bp, "\n");
  183.     if (!cp) continue;
  184.  
  185.     return 1;
  186.   }
  187.   /* NOTREACHED */
  188. }
  189.  
  190. /* the real stuff */
  191.  
  192. uid_t
  193. getuid(void)
  194. {
  195.   if (muBase)
  196.     return (__amiga2unixid(muGetTaskOwner(NULL) >> 16));
  197.  
  198.   return u.u_ruid;
  199. }
  200.  
  201. uid_t
  202. geteuid(void)
  203. {
  204.   if (muBase)
  205.     return (__amiga2unixid(muGetTaskOwner(NULL) >> 16));
  206.  
  207.   return u.u_euid;
  208. }
  209.  
  210. int
  211. setreuid (int ruid, int euid)
  212. {
  213.   if (muBase)
  214.   {
  215.     int retval = 0;
  216.  
  217.     if (syscall(SYS_geteuid) == 0)
  218.     {
  219.       if (euid != -1)
  220.         {
  221.           struct muUserInfo *UI = u.u_UserInfo;
  222.  
  223.           UI->uid = __unix2amigaid(euid);
  224.           if ((UI = muGetUserInfo (UI, muKeyType_uid)))
  225.             {
  226.  
  227.               if (muLogin(muT_Task, (ULONG)FindTask(NULL),
  228.                           muT_UserID, (ULONG)UI->UserID,
  229.                           muT_NoLog, TRUE,
  230.                           TAG_DONE)) {
  231.                 u.u_setuid++;
  232.         }
  233.           }
  234.        }
  235.     }
  236.     else
  237.       {
  238.         errno = EPERM;
  239.         retval = -1;
  240.       }
  241.  
  242.     return retval;
  243.   }
  244.   else
  245.     {
  246.       if (ruid != -1)
  247.         u.u_ruid = (uid_t)ruid;
  248.  
  249.       if (euid != -1)
  250.         u.u_euid = (uid_t)euid;
  251.  
  252.       /* just always succeed... */
  253.       return 0;
  254.     }
  255. }
  256.  
  257. int
  258. setuid (uid_t uid)
  259. {
  260.   return syscall(SYS_setreuid, (int)uid, (int)uid);
  261. }
  262.  
  263. int
  264. seteuid (uid_t uid)
  265. {
  266.   return syscall(SYS_setreuid, -1, (int)uid);
  267. }
  268.  
  269. struct passwd *getpwuid (uid_t uid)
  270. {
  271.   struct passwd *pw;
  272.  
  273.   if (uid == (uid_t)(-2))
  274.     return (struct passwd *)&builtin_nobody; /* always handle nobody */
  275.  
  276.   if (muBase)
  277.     {
  278.       /* active multiuser */
  279.       struct muUserInfo *UI = u.u_UserInfo;
  280.  
  281.       UI->uid = __unix2amigaid(uid);
  282.  
  283.       UI = muGetUserInfo (UI, muKeyType_uid);
  284.  
  285.       return UserInfo2pw (UI);      /* handles errors */
  286.     }
  287.  
  288.   if (u.u_ixnetbase && (pw = (struct passwd *)netcall(NET_getpwuid, (int)uid)))
  289.     return pw;
  290.  
  291.   if (start_pw())
  292.     {
  293.       int rval;
  294.  
  295.       rval = pwscan(1, uid, NULL);
  296.       if (!u.u_pwd_stayopen)
  297.         syscall(SYS_endpwent);
  298.  
  299.       return (rval ? &u.u_passwd : NULL);
  300.     }
  301.  
  302.   if (uid == 0)
  303.     return (struct passwd *)&builtin_root;
  304.  
  305.   if (uid == syscall(SYS_getuid) &&
  306.       ((u.u_passwd.pw_name = (char *)syscall(SYS_getlogin))))
  307.     {
  308.       if (!(u.u_passwd.pw_dir = (char *)syscall(SYS_getenv, "HOME"))) {
  309.         u.u_passwd.pw_dir = "SYS:";
  310.       }
  311.  
  312.       if (!(u.u_passwd.pw_gecos = (char *)syscall(SYS_getenv, "REALNAME"))) {
  313.         u.u_passwd.pw_gecos = "Amiga User";
  314.       }
  315.  
  316.       u.u_passwd.pw_uid = uid;
  317.       u.u_passwd.pw_gid = syscall(SYS_getgid);
  318.  
  319.       u.u_passwd.pw_change = u.u_passwd.pw_expire = 0;
  320.       u.u_passwd.pw_class  = "";
  321.       u.u_passwd.pw_passwd = "*";
  322.       u.u_passwd.pw_shell  = "sh";
  323.  
  324.       return(&u.u_passwd);
  325.   
  326.     }
  327.  
  328.   return 0;
  329. }
  330.  
  331. struct passwd *getpwnam (const char *name)
  332. {
  333.   struct passwd *pw;
  334.  
  335.   if (!strcmp(name,"nobody"))
  336.     return (struct passwd *)&builtin_nobody;
  337.  
  338.   if (muBase)
  339.     {
  340.       struct muUserInfo *UI = u.u_UserInfo;
  341.  
  342.       /*
  343.        * some validation checks
  344.        */
  345.     
  346.       if (name == NULL)
  347.         return NULL;
  348.     
  349.       if ((muUSERIDSIZE - 1) < strlen (name))
  350.         return NULL;
  351.  
  352.       strcpy (UI->UserID, name);
  353.       UI = muGetUserInfo (UI, muKeyType_UserID);
  354.  
  355.       return UserInfo2pw (UI);      /* handles errors */
  356.     }
  357.  
  358.   if (u.u_ixnetbase && (pw = (struct passwd *)netcall(NET_getpwnam, name)))
  359.     return pw;
  360.  
  361.   if (start_pw())
  362.     {
  363.       int rval;
  364.  
  365.       rval = pwscan(1, 0, (char *)name);
  366.       if (!u.u_pwd_stayopen)
  367.         syscall(SYS_endpwent);
  368.  
  369.       return (rval ? &u.u_passwd : NULL);
  370.     }
  371.  
  372.   if (!strcmp(name,"root"))
  373.     return (struct passwd *)&builtin_root;
  374.  
  375.   if (((u.u_passwd.pw_name = (char *)syscall(SYS_getlogin))) &&
  376.       !strcmp(name,u.u_passwd.pw_name))
  377.     {
  378.       if (!(u.u_passwd.pw_dir = (char *)syscall(SYS_getenv, "HOME"))) {
  379.         u.u_passwd.pw_dir = "SYS:";
  380.       }
  381.  
  382.       if (!(u.u_passwd.pw_gecos = (char *)syscall(SYS_getenv, "REALNAME"))) {
  383.         u.u_passwd.pw_gecos = "Amiga User";
  384.       }
  385.  
  386.       u.u_passwd.pw_uid = syscall(SYS_getuid);
  387.       u.u_passwd.pw_gid = syscall(SYS_getgid);
  388.  
  389.       u.u_passwd.pw_change = u.u_passwd.pw_expire = 0;
  390.       u.u_passwd.pw_class  = "";
  391.       u.u_passwd.pw_passwd = "*";
  392.       u.u_passwd.pw_shell  = "sh";
  393.  
  394.       return(&u.u_passwd);
  395.   
  396.     }
  397.  
  398.   return 0;
  399. }
  400.  
  401. struct passwd *
  402. getpwent(void)
  403. {
  404.   char *name;
  405.  
  406.   if (muBase)
  407.     {
  408.       struct muUserInfo *UI  = u.u_fileUserInfo;
  409.  
  410.       UI = muGetUserInfo (UI, u.u_passwdfileopen ? muKeyType_Next : muKeyType_First);
  411.       u.u_passwdfileopen = TRUE;
  412.  
  413.       return UserInfo2pw (UI);       /* handles errors */
  414.     }
  415.  
  416.   if (u.u_ixnetbase)
  417.     return (struct passwd *)netcall(NET_getpwent);
  418.  
  419.   if ((u.u_pwd_fp || start_pw()) && pwscan(0, 0, NULL))
  420.     return &u.u_passwd;
  421.  
  422.   switch (u.u_nextuid) {
  423.     case 0:
  424.       u.u_nextuid = 1;
  425.       return (struct passwd *)&builtin_root;
  426.     default:
  427.       u.u_nextuid = -2;
  428.      
  429.       if ((name = (char *)syscall(SYS_getlogin)))
  430.         return (struct passwd *)syscall(SYS_getpwnam, name);
  431.     case (uid_t)(-2):
  432.       u.u_nextuid = -1;
  433.       return (struct passwd *)&builtin_nobody;
  434.     case (uid_t)(-1):
  435.       return 0;        
  436.   }
  437. }
  438.  
  439. int
  440. setpassent(int stayopen)
  441. {
  442.   if (muBase)
  443.     {
  444.       u.u_passwdfileopen = FALSE;
  445.       return 1;
  446.     }
  447.  
  448.   if (u.u_ixnetbase)
  449.     return netcall(NET_setpassent, stayopen);
  450.  
  451.   if (start_pw())
  452.     u.u_pwd_stayopen = stayopen;
  453.  
  454.   u.u_nextuid = 0;
  455.   return 1;
  456. }
  457.  
  458. int
  459. setpwent(void)
  460. {
  461.   if (muBase)
  462.     {
  463.       u.u_passwdfileopen = FALSE;
  464.       return 1;
  465.     }
  466.  
  467.   if (u.u_ixnetbase)
  468.     return netcall(NET_setpwent);
  469.  
  470.   if (start_pw())
  471.     u.u_pwd_stayopen = 0;
  472.  
  473.   u.u_nextuid = 0;
  474.   return 1 ;
  475. }
  476.  
  477. void
  478. endpwent(void)
  479. {
  480.   if (muBase)
  481.     {
  482.       u.u_passwdfileopen = FALSE;
  483.       return;
  484.     }
  485.  
  486.   if (u.u_ixnetbase)
  487.     netcall(NET_endpwent);
  488.  
  489.   if (u.u_pwd_fp) {
  490.     syscall(SYS_fclose, u.u_pwd_fp);
  491.     u.u_pwd_fp = NULL;
  492.   }
  493.  
  494.   u.u_nextuid = 0;
  495. }
  496.  
  497. int
  498. _getlogin (char *s, int size)
  499. {
  500.   char *cp = (char *)syscall(SYS_getlogin);
  501.  
  502.   if (cp)
  503.     strncpy (s, cp, size);
  504.   else
  505.     *s = '\0';
  506.  
  507.   return 0;
  508. }
  509.  
  510. char *
  511. getlogin(void) 
  512. {
  513.   if (u.u_logname_valid)
  514.     {
  515.       strcpy(u.u_logname_buf,u.u_logname);
  516.       return (*u.u_logname_buf ? u.u_logname_buf : 0);
  517.     }
  518.   else
  519.     return 0;
  520. }
  521.  
  522. int
  523. setlogin (const char *s)
  524. {
  525.   strncpy (u.u_logname, s, MAXLOGNAME);
  526.   u.u_logname[MAXLOGNAME] = '\0';
  527.   u.u_logname_valid = 1;
  528.  
  529.   return 0;
  530. }
  531.