home *** CD-ROM | disk | FTP | other *** search
- RCS_ID_C="$Id: passwdunit.c,v 3.2 1994/05/19 04:29:29 ppessi Exp $";
- /*
- * passwdunit.c --- unit for passwd entries
- *
- * Author: ppessi <Pekka.Pessi@hut.fi>
- *
- * This file is part of the AmiTCP/IP User Library.
- *
- * Copyright © 1993 AmiTCP/IP Group, <AmiTCP-Group@hut.fi>
- * Helsinki University of Technology, Finland.
- *
- * Created : Wed Sep 15 01:25:26 1993 ppessi
- * Last modified: Thu May 19 04:01:50 1994 ppessi
- */
-
- #include "entries.h"
- #include <string.h>
- #include <assert.h>
-
- static void *CopyEntToPasswd(struct NetInfoReq *req, struct Ent *e);
- static struct Ent *CopyPasswdToEnt(BASE, struct NetInfoReq *req);
- static struct Ent *ParsePasswd(BASE, register UBYTE *p);
- static void GetMembers(BASE, struct NetInfoReq *req, struct NetInfoMap *nim);
- static int PrintPasswd(BASE, BPTR file, struct Ent *e);
-
- const static struct MapMethods passwd_methods[1] =
- {
- {
- ParsePasswd,
- PrintPasswd,
- CopyEntToPasswd,
- CopyPasswdToEnt,
- EntCleanup,
- NULL,
- EntHandleNotify,
- },
- };
-
- /*
- * Allocate and initialize passwd map
- */
- struct NetInfoMap *InitPasswdMap(BASE)
- {
- struct NetInfoMap *nim = AllocVec(sizeof(*nim), MEMF_CLEAR|MEMF_PUBLIC);
-
- if (nim) {
- nim->nim_Methods = passwd_methods;
- nim->nim_Name = "passwd";
- nim->nim_Filename = _PATH_PASSWD;
- }
-
- return nim;
- }
-
- /*
- * Copy an PasswdEnt structure to passwd structure
- */
- static void *CopyEntToPasswd(struct NetInfoReq *req, struct Ent *e)
- {
- struct PasswdEnt *pe = (struct PasswdEnt *)e;
- struct NetInfoPasswd *pw = req->io_Data;
- UBYTE *to = (UBYTE *)(pw + 1);
-
- ULONG size = req->io_Length;
- ULONG actual = sizeof(*pw) + pe->pe_tlen;
-
- req->io_Actual = actual;
-
- if (size < actual) {
- return NULL;
- }
-
- /* copy strings */
- to = stpcopy(pw->pw_name = to, pe->pe_passwd->pw_name);
- to = stpcopy(pw->pw_passwd = to, pe->pe_passwd->pw_passwd);
- to = stpcopy(pw->pw_gecos = to, pe->pe_passwd->pw_gecos);
- to = stpcopy(pw->pw_dir = to, pe->pe_passwd->pw_dir);
- to = stpcopy(pw->pw_shell = to, pe->pe_passwd->pw_shell);
-
- assert(to == (UBYTE *)req->io_Data + actual);
-
- /* .. and ids */
- pw->pw_uid = pe->pe_passwd->pw_uid;
- pw->pw_gid = pe->pe_passwd->pw_gid;
-
- return pw;
- }
-
- /*
- * Copy an passwd structure into a internal entry
- */
- static struct Ent *CopyPasswdToEnt(BASE, struct NetInfoReq *req)
- {
- struct NetInfoPasswd *pw = (struct NetInfoPasswd*)req->io_Data;
- struct PasswdEnt *pe;
- UBYTE *to;
- ULONG txtlen;
-
- /*
- * These cause EFAULT
- */
- if (pw == NULL || (1 & (LONG)pw) != 0 ||
- pw->pw_name == NULL ||
- pw->pw_passwd == NULL ||
- pw->pw_gecos == NULL ||
- pw->pw_dir == NULL ||
- pw->pw_shell == NULL) {
- req->io_Error = IOERR_BADADDRESS;
- return NULL;
- }
-
- txtlen = strlen(pw->pw_name) + strlen(pw->pw_passwd) + strlen(pw->pw_gecos) +
- strlen(pw->pw_dir) + strlen(pw->pw_shell) + 5;
-
- pe = AllocVec(sizeof(*pe) + txtlen, MEMF_CLEAR);
- if (pe == NULL) {
- req->io_Error = NIERR_NOMEM;
- return NULL;
- }
-
- pe->pe_node.ln_Type = ENT_PASSWD;
- pe->pe_node.ln_Pri = ENT_CHANGED;
- pe->pe_tlen = txtlen;
- pe->pe_passwd->pw_uid = pw->pw_uid;
- pe->pe_passwd->pw_gid = pw->pw_gid;
-
- to = (UBYTE *)(pe + 1);
- to = stpcopy(pe->pe_passwd->pw_name = to, pw->pw_name);
- to = stpcopy(pe->pe_passwd->pw_passwd = to, pw->pw_passwd);
- to = stpcopy(pe->pe_passwd->pw_gecos = to, pw->pw_gecos);
- to = stpcopy(pe->pe_passwd->pw_dir = to, pw->pw_dir);
- to = stpcopy(pe->pe_passwd->pw_shell = to, pw->pw_shell);
-
- assert(to == pe->pe_passwd->pw_name + txtlen);
-
- return (struct Ent *)pe;
- }
-
- /****** netinfo.device/passwd **********************************************
-
- NAME
- passwd - format of the password file
-
- DESCRIPTION
-
- The passwd files are files consisting of newline separated records,
- one per user, containing seven bar (`|') separated fields. These
- fields are as follows:
-
- name User's login name.
-
- password User's encrypted password.
-
- uid User's id.
-
- gid User's login group id.
-
- gecos General information about the user.
-
- home_dir User's home directory.
-
- shell User's login shell.
-
- The name field is the login used to access the computer account, and
- the uid field is the number associated with it. They should both be
- unique across the system (and often across a group of systems) since
- they control file access.
-
- While it is possible to have multiple entries with identical login
- names and/or identical user id's, it is usually a mistake to do so.
- Routines that manipulate these files will often return only one of
- the multiple entries, and that one by random selection.
-
- The login name must never begin with a hyphen (`-'); also, it is
- strongly suggested that neither upper-case characters or dots (`.')
- be part of the name, as this tends to confuse mailers. No field may
- contain a bar (`|') as this has been used to separate the fields in
- the user database.
-
- The password field is the encrypted form of the password. The actual
- format is not restricted by netinfo.device, but usergroup.library
- uses same format as Version 7 UNIX (POSIX) or 4.4BSD. The format
- used by MultiUser 1.5 or AS225r2ß is also possible, but its use is
- strongly discouraged.
-
- If the password field is empty, no password will be required to gain
- access to the machine. This is almost invariably a mistake. Because
- these files contain the encrypted user passwords, they should not be
- readable by anyone without appropriate privileges.
-
- The group field is the group that the user will be placed in upon
- login.
-
- The gecos field normally contains comma (`,') separated subfields as
- follows:
-
- name user's full name
- office user's office number
- wphone user's work phone number
- hphone user's home phone number
-
- This information is used by the finger program.
-
- The user's home directory is the full DOS path name where the user
- will be placed on login.
-
- The shell field is the command interpreter the user prefers. If
- there is nothing in the shell field, the CLI is assumed.
-
- FILES
- AmiTCP:db/passwd
-
- SEE ALSO
- group
-
- COPYRIGHT
- Copyright 1980, 1991 The Regents of the University of California.
- Copyright 1993, 1994 AmiTCP/IP-Group, <AmiTCP-Group@hut.fi>,
- Helsinki University of Technology, Helsinki
-
- HISTORY
- A passwd file format appeared in Version 6 AT&T UNIX.
-
- The used format is basically the same as in the Multiuser Library
- 1.3 and AS225r2 use, except the password field.
-
- ****************************************************************************
- */
-
- /*
- * Parse a passwd database entry
- */
- static struct Ent *ParsePasswd(BASE, register UBYTE *p)
- {
- int i;
- UBYTE *to, *np = p, *field[PASSWDFIELDS];
- ULONG txtlen;
- LONG uid, gid;
- struct PasswdEnt *pe;
-
- for (i = 0;
- i < PASSWDFIELDS && (field[i++] = strsep(&np, "|\n")) && np && *np;)
- ;
-
- assert(np != NULL);
- if (i < PASSWDFIELDS || !np) {
- return NULL;
- }
-
- if ((i = StrToLong(field[2], &uid)) <= 0 || field[2][i] != '\0')
- return NULL;
- if ((i = StrToLong(field[3], &gid)) <= 0 || field[3][i] != '\0')
- return NULL;
-
- txtlen = np - field[0] - (field[4] - field[2]);
- pe = AllocVec(sizeof(*pe) + txtlen, MEMF_CLEAR);
- if (!pe)
- return NULL;
-
- pe->pe_node.ln_Type = ENT_PASSWD;
- pe->pe_tlen = txtlen;
- pe->pe_passwd->pw_uid = uid;
- pe->pe_passwd->pw_gid = gid;
-
- to = (UBYTE *)(pe + 1);
- to = stpcopy(pe->pe_passwd->pw_name = to, field[0]);
- to = stpcopy(pe->pe_passwd->pw_passwd = to, field[1]);
- to = stpcopy(pe->pe_passwd->pw_gecos = to, field[4]);
- to = stpcopy(pe->pe_passwd->pw_dir = to, field[5]);
- to = stpcopy(pe->pe_passwd->pw_shell = to, field[6]);
-
- assert(to == pe->pe_passwd->pw_name + txtlen);
-
- return (struct Ent *)pe;
- }
-
- /*
- * Print out an passwd entry
- */
- static int PrintPasswd(BASE, BPTR file, struct Ent *e)
- {
- struct PasswdEnt *pe = (struct PasswdEnt *)e;
-
- if (VFPrintf(file, "%s|%s|%ld|%ld|%s|%s|%s\n", (LONG*)pe->pe_passwd) == -1)
- return NIERR_ACCESS;
- else
- return 0;
- }
-
- /*
- * Find all UIDs in the named group
- */
- static void GetMembers(BASE, struct NetInfoReq *req, struct NetInfoMap *nim)
- {
- req->io_Error = NIERR_NOTFOUND;
- TermIO(req);
- }
-