home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / library / user.c < prev    next >
C/C++ Source or Header  |  1996-10-01  |  7KB  |  337 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. static char *
  31. getUserPasswd(char *name)
  32. {
  33. #if 1 /* This gets muFS's password */
  34.       /* Only uncomment this when I figure out how ACrypt works */
  35.     char *retval = NULL;
  36.     char passdir[MAXPATHLEN];
  37.     BPTR passwddir = muGetPasswdDirLock();
  38.  
  39.     if (passwddir) {
  40.     if (NameFromLock(passwddir, passdir, MAXPATHLEN)) {
  41.         if (AddPart(passdir, muPasswd_FileName, MAXPATHLEN)) {
  42.         FILE *fi = (FILE *)syscall(SYS_fopen,passdir,"r");
  43.         char passwdline[1024];
  44.         char username[muUSERNAMESIZE] = {0,};
  45.         char passwd[muPASSWORDSIZE] = {0,};
  46.         int found_it = 0;
  47.  
  48.         if (fi) {
  49.             while (fgets(passwdline,1024,fi)) {
  50.  
  51.             char *sep = strchr(passwdline,'|');
  52.             char *old;
  53.             strncpy(username,passwdline,sep-passwdline);
  54.  
  55.             old = ++sep;
  56.             sep = strchr(old,'|');
  57.             strncpy(passwd,old,sep - old);
  58.  
  59.             if (!strcmp(username,name)) {
  60.                 found_it = 1;
  61.                 break;
  62.             }
  63.             }
  64.             if (found_it) {
  65.             retval = strdup(passwd);
  66.             }
  67.             fclose(fi);
  68.         }
  69.         }
  70.     }
  71.     UnLock(passwddir);
  72.     }
  73.     if (!retval)
  74.     retval = strdup("*");
  75.     return retval;
  76. #else
  77. /* Use the network's password */
  78.     struct passwd *pwd = netcall(NET_getpwnam,name);
  79.     char *retval;
  80.     if (pwd)
  81.     retval = strdup(pwd->pw_passwd);
  82.     else
  83.     retval = strdup("*");
  84.     return retval;
  85. #endif
  86. }
  87.  
  88. /* multiuser doesn't allow a password entry for nobody (uid = 0)
  89.  * I will create one though
  90.  */
  91. static struct muUserInfo nobody_userinfo = {
  92.     "nobody",
  93.     0,
  94.     0,
  95.     "nobody",
  96.     "t:",
  97.     0,
  98.     (UWORD *)NULL,
  99.     "cli",
  100. };
  101.  
  102.  
  103. static struct passwd *
  104. UserInfo2pw (struct muUserInfo *UI)
  105. {
  106.   struct passwd *pw = &u.u_passwd;
  107.  
  108.   if (UI == NULL)
  109.     return NULL;
  110.  
  111.   pw->pw_name = UI->UserID;
  112.   pw->pw_dir = UI->HomeDir;
  113. #if 1
  114.   if (pw->pw_passwd)
  115.     free(pw->pw_passwd);
  116.   pw->pw_passwd = getUserPasswd(pw->pw_name);
  117. #else
  118.   pw->pw_passwd = "*";
  119. #endif
  120.   pw->pw_uid = UI->uid;
  121.   pw->pw_gid = UI->gid;
  122.   pw->pw_change = 0;
  123.   pw->pw_class = 0;
  124.   pw->pw_gecos = UI->UserName;
  125.   pw->pw_shell = UI->Shell;
  126.   pw->pw_expire = 0;
  127.  
  128.   return pw;
  129. }
  130.  
  131. uid_t
  132. getuid(void)
  133. {
  134.   if (muBase)
  135.     return (muGetTaskOwner(NULL) >> 16);
  136.   if (u.u_ixnetbase)
  137.     return netcall(NET_getuid);
  138.   return 0;
  139. }
  140.  
  141. uid_t
  142. geteuid(void)
  143. {
  144.   if (muBase)
  145.     return getuid();
  146.   if (u.u_ixnetbase)
  147.     return netcall(NET_geteuid);
  148.   return 0;
  149. }
  150.  
  151. int
  152. setuid (uid_t uid)
  153. {
  154.   int retval = 0;
  155.  
  156.   if (muBase)
  157.   {
  158.     if (getuid() == muROOT_UID)
  159.     {
  160.       struct muUserInfo *UI = muAllocUserInfo();
  161.  
  162.       if (UI) {
  163.     UI->uid = uid;
  164.     UI = muGetUserInfo (UI, muKeyType_uid);
  165.  
  166.     if (muLogin(muT_Task, (ULONG)FindTask(NULL),
  167.         muT_UserID, (ULONG)UI->UserID,
  168.         muT_NoLog, TRUE,
  169.         TAG_DONE)) {
  170.         u.u_setuid++;
  171.     }
  172.     muFreeUserInfo(UI);
  173.       }
  174.     }
  175.     else {
  176.       errno = EPERM;
  177.       retval = -1;
  178.     }
  179.  
  180.     return retval;
  181.     /* I don't think usergroup + muFS need to setuid */
  182.     /* uid = MU2UG(uid); */
  183.   }
  184.  
  185.   if (u.u_ixnetbase)
  186.     return netcall(NET_setuid, uid);
  187.   else
  188.   /* just always succeed... */
  189.     return retval;
  190. }
  191.  
  192. int
  193. seteuid (uid_t uid)
  194. {
  195.   if (u.u_ixnetbase)
  196.     return netcall(NET_seteuid, uid);
  197.   else
  198.     return setuid(uid);
  199. }
  200.  
  201. int
  202. setreuid (int ruid, int euid)
  203. {
  204.   if (u.u_ixnetbase)
  205.     return netcall(NET_setreuid, ruid, euid);
  206.   else
  207.     return setuid(euid);
  208. }
  209.  
  210. struct passwd *getpwuid (uid_t uid)
  211. {
  212.   char *name;
  213.   struct passwd *retval;
  214.  
  215.   if (muBase)
  216.     {
  217.       /* active multiuser */
  218.       struct muUserInfo *UI = u.u_UserInfo;
  219.  
  220.       UI->uid = uid;
  221.  
  222.       /*
  223.        * "nobody" can't have a password entry
  224.        * so I will create one
  225.        */
  226.       UI = (uid == muOWNER_NOBODY ? &nobody_userinfo : muGetUserInfo (UI, muKeyType_uid));
  227.  
  228.       return UserInfo2pw (UI);      /* handles errors */
  229.     }
  230.  
  231.   if (u.u_ixnetbase)
  232.     return (struct passwd *)netcall(NET_getpwuid, uid);
  233.  
  234.   if ((name = (char *)syscall(SYS_getenv, "USER")))
  235.     retval = (struct passwd *)syscall(SYS_getpwnam, name);
  236.   else
  237.     retval = (struct passwd *)syscall(SYS_getpwnam, "root");
  238.   retval->pw_uid = uid;
  239.   return retval;
  240. }
  241.  
  242. struct passwd *getpwnam (const char *name)
  243. {
  244.   /* this is not quite safe, since this library function could be called
  245.    * in parallel with different names... well, I don't consider this worth
  246.    * doing `right', it's here to be able to link some programs ;-)
  247.    */
  248.   static struct passwd pw = {
  249.     0,        /* pw_name */
  250.         "*",        /* pw_passwd */
  251.         0,        /* pw_uid */
  252.         0,        /* pw_gid */
  253.         0,         /* pw_change */
  254.         0,        /* pw_class */
  255.     0,        /* pw_dir */
  256.     0,        /* pw_gecos */
  257.     "/bin/sh",      /* pw_shell */
  258.     0        /* pw_expire */
  259.   };
  260.  
  261.   if (muBase)
  262.     {
  263.       struct muUserInfo *UI = u.u_UserInfo;
  264.  
  265.       /*
  266.        * some validation checks
  267.        */
  268.     
  269.       if (name == NULL)
  270.         return NULL;
  271.     
  272.       if ((muUSERIDSIZE - 1) < strlen (name))
  273.         return NULL;
  274.  
  275.       strcpy (UI->UserID, name);
  276.       UI = muGetUserInfo (UI, muKeyType_UserID);
  277.       /* special case for nobody (uid 0) */
  278.       /* Not sure if this should come before muGetUserInfo()
  279.        * since nobody could have another uid
  280.        */
  281.        if (!UI && !strcmp(name,"nobody"))
  282.       UI = &nobody_userinfo;
  283.  
  284.       return UserInfo2pw (UI);      /* handles errors */
  285.     }
  286.  
  287.   if (u.u_ixnetbase)
  288.     return (struct passwd *)netcall(NET_getpwnam, name);
  289.  
  290.   pw.pw_name = (char *)name;
  291.  
  292.   if (!(pw.pw_dir = (char *)syscall(SYS_getenv, "HOME"))) {
  293.     pw.pw_dir = "SYS:";
  294.   }
  295.  
  296.   if (!(pw.pw_gecos = (char *)syscall(SYS_getenv, "REALNAME"))) {
  297.     pw.pw_gecos = "amiga user";
  298.   }
  299.   return &pw;
  300. }
  301.  
  302. struct passwd *
  303. getpwent(void)
  304. {
  305.   char *name;
  306.  
  307.   if (!muBase && u.u_ixnetbase)
  308.     return (struct passwd *)netcall(NET_getpwent);
  309.   name = getenv("USER");
  310.   if (name)
  311.     return (struct passwd *)syscall(SYS_getpwnam, name);
  312.   return (struct passwd *)syscall(SYS_getpwnam, "root");
  313. }
  314.  
  315. int
  316. setpassent(int stayopen)
  317. {
  318.   if (u.u_ixnetbase)
  319.     return netcall(NET_setpassent, stayopen);
  320.   return 1;
  321. }
  322.  
  323. int
  324. setpwent(void)
  325. {
  326.   if (u.u_ixnetbase)
  327.     return netcall(NET_setpwent);
  328.   return 1 ;
  329. }
  330.  
  331. void
  332. endpwent(void)
  333. {
  334.   if (u.u_ixnetbase)
  335.     netcall(NET_endpwent);
  336. }
  337.