1/*
2 * $Id: uams_guest.c,v 1.18 2009-11-08 01:07:17 didg Exp $
3 *
4 * (c) 2001 (see COPYING)
5 */
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif /* HAVE_CONFIG_H */
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <errno.h>
14
15/* STDC check */
16#if STDC_HEADERS
17#include <string.h>
18#else /* STDC_HEADERS */
19#ifndef HAVE_STRCHR
20#define strchr index
21#define strrchr index
22#endif /* HAVE_STRCHR */
23char *strchr (), *strrchr ();
24#ifndef HAVE_MEMCPY
25#define memcpy(d,s,n) bcopy ((s), (d), (n))
26#define memmove(d,s,n) bcopy ((s), (d), (n))
27#endif /* ! HAVE_MEMCPY */
28#endif /* STDC_HEADERS */
29
30#include <pwd.h>
31#include <atalk/logger.h>
32
33#include <atalk/afp.h>
34#include <atalk/uam.h>
35#include <atalk/util.h>
36
37#ifndef MIN
38#define MIN(a,b) ((a) < (b) ? (a) : (b))
39#endif /* MIN */
40
41/*XXX in etc/papd/file.h */
42struct papfile;
43extern UAM_MODULE_EXPORT void append(struct papfile *, const char *, int);
44
45/* login and login_ext are almost the same */
46static int noauth_login(void *obj, struct passwd **uam_pwd,
47			char *ibuf _U_, size_t ibuflen _U_,
48			char *rbuf _U_, size_t *rbuflen)
49{
50    struct passwd *pwent;
51    char *guest, *username;
52
53    *rbuflen = 0;
54    LOG(log_info, logtype_uams, "login noauth" );
55
56    if (uam_afpserver_option(obj, UAM_OPTION_GUEST, (void *) &guest,
57			     NULL) < 0)
58      return AFPERR_MISC;
59
60    if (uam_afpserver_option(obj, UAM_OPTION_USERNAME,
61			     (void *) &username, NULL) < 0)
62      return AFPERR_MISC;
63
64    strcpy(username, guest);
65    if ((pwent = getpwnam(guest)) == NULL) {
66	LOG(log_error, logtype_uams, "noauth_login: getpwnam( %s ): %s",
67		guest, strerror(errno) );
68	return( AFPERR_BADUAM );
69    }
70
71#ifdef AFS
72    if ( setpag() < 0 ) {
73	LOG(log_error, logtype_uams, "noauth_login: setpag: %s", strerror(errno) );
74	return( AFPERR_BADUAM );
75    }
76#endif /* AFS */
77
78    *uam_pwd = pwent;
79    return( AFP_OK );
80}
81
82static int noauth_login_ext(void *obj, char *uname _U_, struct passwd **uam_pwd,
83                     char *ibuf, size_t ibuflen,
84                     char *rbuf, size_t *rbuflen)
85{
86        return ( noauth_login (obj, uam_pwd, ibuf, ibuflen, rbuf, rbuflen));
87}
88
89
90/* Printer NoAuthUAM Login */
91static int noauth_printer(char *start, char *stop, char *username, struct papfile *out)
92{
93    char	*data, *p, *q;
94    static const char *loginok = "0\r";
95
96    data = (char *)malloc(stop - start + 1);
97    if (!data) {
98	LOG(log_info, logtype_uams,"Bad Login NoAuthUAM: malloc");
99	return(-1);
100    }
101
102    strlcpy(data, start, stop - start + 1);
103
104    /* We are looking for the following format in data:
105     * (username)
106     *
107     * Hopefully username doesn't contain a ")"
108     */
109
110    if ((p = strchr(data, '(' )) == NULL) {
111	LOG(log_info, logtype_uams,"Bad Login NoAuthUAM: username not found in string");
112	free(data);
113	return(-1);
114    }
115    p++;
116    if ((q = strchr(p, ')' )) == NULL) {
117	LOG(log_info, logtype_uams,"Bad Login NoAuthUAM: username not found in string");
118	free(data);
119	return(-1);
120    }
121    memcpy(username, p,  MIN( UAM_USERNAMELEN, q - p ));
122
123    /* Done copying username, clean up */
124    free(data);
125
126    if (getpwnam(username) == NULL) {
127	LOG(log_info, logtype_uams, "Bad Login NoAuthUAM: %s: %s",
128	       username, strerror(errno) );
129	return(-1);
130    }
131
132    /* Login successful */
133    append(out, loginok, strlen(loginok));
134    LOG(log_info, logtype_uams, "Login NoAuthUAM: %s", username);
135    return(0);
136}
137
138
139static int uam_setup(const char *path)
140{
141  if (uam_register(UAM_SERVER_LOGIN_EXT, path, "No User Authent",
142                   noauth_login, NULL, NULL, noauth_login_ext) < 0)
143        return -1;
144
145  if (uam_register(UAM_SERVER_PRINTAUTH, path, "NoAuthUAM",
146		noauth_printer) < 0)
147	return -1;
148
149  return 0;
150}
151
152static void uam_cleanup(void)
153{
154  uam_unregister(UAM_SERVER_LOGIN, "No User Authent");
155  uam_unregister(UAM_SERVER_PRINTAUTH, "NoAuthUAM");
156}
157
158UAM_MODULE_EXPORT struct uam_export uams_guest = {
159  UAM_MODULE_SERVER,
160  UAM_MODULE_VERSION,
161  uam_setup, uam_cleanup
162};
163