1/*
2 * $Id: auth.c,v 1.9 2009-10-13 22:55:37 didg Exp $
3 *
4 * Copyright (c) 1990,1993 Regents of The University of Michigan.
5 * All Rights Reserved.  See COPYRIGHT.
6 */
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif /* HAVE_CONFIG_H */
11
12#include <stdio.h>
13#include <stdlib.h>
14#ifdef HAVE_UNISTD_H
15#include <unistd.h>
16#endif /* HAVE_UNISTD_H */
17#include <sys/types.h>
18#include <sys/param.h>
19#include <sys/stat.h>
20#include <netatalk/endian.h>
21#include <atalk/afp.h>
22#include <atalk/compat.h>
23#include <atalk/util.h>
24#include <limits.h>
25#include <string.h>
26#include <ctype.h>
27#include <pwd.h>
28#include <grp.h>
29#include <atalk/logger.h>
30
31#include "uam_auth.h"
32
33static struct uam_mod uam_modules = {NULL, NULL, &uam_modules, &uam_modules};
34static struct uam_obj uam_login = {"", "", 0, {{NULL, NULL, NULL}}, &uam_login,
35				   &uam_login};
36static struct uam_obj uam_changepw = {"", "", 0, {{NULL, NULL, NULL}}, &uam_changepw,
37				      &uam_changepw};
38static struct uam_obj uam_printer = {"", "", 0, {{NULL, NULL, NULL}}, &uam_printer,
39					&uam_printer};
40
41
42/*
43 * Return a list of names for loaded uams
44 */
45int getuamnames(const int type, char *uamnames)
46{
47    struct uam_obj *prev, *start;
48
49    if (!(start = UAM_LIST(type)))
50        return(-1);
51
52    prev = start;
53
54    while((prev = prev->uam_prev) != start) {
55        strcat(uamnames, prev->uam_name);
56        strcat(uamnames, "\n");
57    }
58
59    strcat(uamnames, "*\n");
60    return(0);
61}
62
63
64/* just do a linked list search. this could be sped up with a hashed
65 * list, but i doubt anyone's going to have enough uams to matter. */
66struct uam_obj *auth_uamfind(const int type, const char *name,
67			     const int len)
68{
69  struct uam_obj *prev, *start;
70
71  if (!name || !(start = UAM_LIST(type)))
72    return NULL;
73
74  prev = start;
75  while ((prev = prev->uam_prev) != start)
76    if (strndiacasecmp(prev->uam_name, name, len) == 0)
77      return prev;
78
79  return NULL;
80}
81
82int auth_register(const int type, struct uam_obj *uam)
83{
84  struct uam_obj *start;
85
86  if (!uam || !uam->uam_name || (*uam->uam_name == '\0'))
87    return -1;
88
89  if (!(start = UAM_LIST(type)))
90    return 1;
91
92  uam_attach(start, uam);
93  return 0;
94}
95
96/* load all of the modules */
97int auth_load(const char *path, const char *list)
98{
99  char name[MAXPATHLEN + 1], buf[MAXPATHLEN + 1], *p;
100  struct uam_mod *mod;
101  struct stat st;
102  size_t len;
103
104  if (!path || !list || (len = strlen(path)) > sizeof(name) - 2)
105    return -1;
106
107  strlcpy(buf, list, sizeof(buf));
108  if ((p = strtok(buf, ",")) == NULL)
109    return -1;
110
111  strcpy(name, path);
112  if (name[len - 1] != '/') {
113    strcat(name, "/");
114    len++;
115  }
116
117  while (p) {
118    strlcpy(name + len, p, sizeof(name) - len);
119    if ((stat(name, &st) == 0) && (mod = uam_load(name, p))) {
120      uam_attach(&uam_modules, mod);
121      LOG(log_info, logtype_papd, "uam: %s loaded", p);
122    }
123    p = strtok(NULL, ",");
124  }
125  return 0;
126}
127
128/* get rid of all of the uams */
129void auth_unload(void)
130{
131  struct uam_mod *mod, *prev, *start = &uam_modules;
132
133  prev = start->uam_prev;
134  while ((mod = prev) != start) {
135    prev = prev->uam_prev;
136    uam_detach(mod);
137    uam_unload(mod);
138  }
139}
140