source: trunk/athena/lib/al/access.c @ 11605

Revision 11605, 4.9 KB checked in by ghudson, 26 years ago (diff)
Make sure to initialize *text in the cases where we don't set it.
Line 
1/* Copyright 1998 by the Massachusetts Institute of Technology.
2 *
3 * Permission to use, copy, modify, and distribute this
4 * software and its documentation for any purpose and without
5 * fee is hereby granted, provided that the above copyright
6 * notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting
8 * documentation, and that the name of M.I.T. not be used in
9 * advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission.
11 * M.I.T. makes no representations about the suitability of
12 * this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 */
15
16/* This file is part of the Athena login library.  It implements the
17 * function to get the access string and text strings from the access
18 * file for a user.
19 */
20
21static const char rcsid[] = "$Id: access.c,v 1.4 1998-06-04 18:26:03 ghudson Exp $";
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <ctype.h>
27#include <unistd.h>
28#include <errno.h>
29#include <pwd.h>
30#include "al.h"
31#include "al_private.h"
32
33static int first_field_match(const char *line, const char *s);
34
35/* The al_get_access() function reads the access bits and explanatory
36 * text from the access file.  The calling program may specify NULL
37 * for either the access or text parameter if it is not interested
38 * in that piece of information.  On successful return, *access is
39 * set to the access bits for the user and *text is set to the
40 * explanatory text given for that user, or NULL if there is no text.
41 *
42 * The al_get_access() function may return the following values:
43 *
44 *      AL_SUCCESS      Access information successfully read
45 *      AL_ENOENT       Access file does not exist
46 *      AL_EPERM        Permissions error reading access file
47 *      AL_ENOUSER      User not found in access file
48 *      AL_ENOMEM       Ran out of memory
49 */
50
51int al_get_access(const char *username, char **access, char **text)
52{
53  FILE *fp;
54  int linesize, haslocal, retval;
55  char *line = NULL;
56  const char *match = NULL;
57  const char *p, *q;
58  struct passwd *pwd;
59
60  /* Null out *text for now, if the caller wants the access text. */
61  if (text)
62    *text = NULL;
63
64  pwd = al__getpwnam(username);
65  if (pwd)
66    {
67      haslocal = 1;
68      al__free_passwd(pwd);
69    }
70  else
71    haslocal = 0;
72
73  fp = fopen(PATH_ACCESS, "r");
74  if (!fp)
75    return (errno == ENOENT) ? AL_ENOENT : AL_EPERM;
76
77  /* Lines in the access file are of the form:
78   *
79   *    username        access-bits     text
80   *
81   * Where "*" matches any username, "*inpasswd" matches any username with
82   * local password information, the access bits 'l' and 'r' set local and
83   * remote access, and text (if specified) gives a message to return if
84   * the user is denied access.
85   */
86  retval = AL_ENOUSER;
87  while (al__read_line(fp, &line, &linesize) == 0)
88    {
89      if (*line == '#')
90        continue;
91      if (first_field_match(line, username))
92        {
93          match = username;
94          break;
95        }
96      else if (first_field_match(line, "*inpasswd") && haslocal)
97        match = "*inpasswd";
98      else if (first_field_match(line, "*") && !match)
99        match = "*";
100    } 
101
102  if (match)
103    {
104      rewind(fp);
105      while (al__read_line(fp, &line, &linesize) == 0)
106        {
107          p = line;
108
109          if (!first_field_match(p, match))
110            continue;
111
112          /* Skip to the access bits. */
113          while (*p && !isspace(*p))
114            p++;
115          while (isspace(*p))
116            p++;
117
118          q = p;
119          while (*q && !isspace(*q))
120            q++;
121          if (access)
122            {
123              *access = malloc(q - p + 1);
124              if (!*access)
125                {
126                  retval = AL_ENOMEM;
127                  break;
128                }
129              memcpy(*access, p, q - p);
130              (*access)[q - p] = 0;
131            }
132
133          if (text)
134            {
135              p = q;
136              while (isspace(*p))
137                p++;
138              if (*p)
139                {
140                  *text = malloc(strlen(p) + 1);
141                  if (!*text)
142                    {
143                      if (access)
144                        free(*access);
145                      retval = AL_ENOMEM;
146                      break;
147                    }
148                  strcpy(*text, p);
149                }
150            }
151
152          retval = AL_SUCCESS;
153          break;
154        }
155    }
156
157  free(line);
158  fclose(fp);
159  return retval;
160}
161
162/* The al_is_local_acct() function determines whether a username is
163 * listed as having a local account in the access file.  Returns
164 * 1 if the user is listed as having a local accounts, 0 if not, and
165 * -1 if there was an out of memory error or a permissions error
166 * reading the access file.
167 */
168int al_is_local_acct(const char *username)
169{
170  int status;
171  char *bits;
172  const char *p;
173
174  status = al_get_access(username, &bits, NULL);
175  if (status == AL_ENOENT || status == AL_ENOUSER)
176    return 0;
177  if (status != AL_SUCCESS)
178    return -1;
179  for (p = bits; *p; p++)
180    {
181      if (*p == 'L')
182        break;
183    }
184  status = (*p == 'L');
185  free(bits);
186  return status;
187}
188
189/* Return true if the first field of line (terminated by whitespace or the
190 * end of the string) matches s.
191 */
192static int first_field_match(const char *line, const char *s)
193{
194  int len = strlen(s);
195
196  return (strncmp(line, s, len) == 0 && (isspace(line[len]) || !line[len]));
197}
Note: See TracBrowser for help on using the repository browser.