1 /*
2 ** Copyright 1998 - 2000 Double Precision, Inc. See COPYING for
3 ** distribution information.
4 */
5
6 #if HAVE_CONFIG_H
7 #include "courier_auth_config.h"
8 #endif
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <errno.h>
13 #include <pwd.h>
14 #if HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif
17
18 #include "auth.h"
19 #include "authcustom.h"
20 #include "courierauthdebug.h"
21
22
auth_custom_pre(const char * userid,const char * service,int (* callback)(struct authinfo *,void *),void * arg)23 int auth_custom_pre(const char *userid, const char *service,
24 int (*callback)(struct authinfo *, void *),
25 void *arg)
26 {
27 return (authcustomcommon(userid, 0, callback, arg));
28 }
29
30 static int do_auth_custom(const char *, struct authinfo *);
31
authcustomcommon(const char * user,const char * pass,int (* callback)(struct authinfo *,void *),void * arg)32 int authcustomcommon(const char *user, const char *pass,
33 int (*callback)(struct authinfo *, void *),
34 void *arg)
35 {
36 struct authinfo auth;
37 int rc;
38
39 memset(&auth, 0, sizeof(auth));
40
41 rc=do_auth_custom(user, &auth);
42
43 if (rc)
44 return (rc);
45
46 if (pass == 0)
47 return (0); /* Just get the authentication info */
48
49 if (auth.clearpasswd)
50 {
51 if (strcmp(pass, auth.clearpasswd))
52 return (-1);
53 }
54 else
55 {
56 const char *p=auth.passwd;
57
58 if (!p || authcheckpassword(pass, p))
59 return (-1);
60 }
61
62 auth.clearpasswd=pass;
63 return ((*callback)(&auth, arg));
64 }
65
do_auth_custom(const char * userid,struct authinfo * authinfo)66 static int do_auth_custom(const char *userid, struct authinfo *authinfo)
67 {
68 /*
69 ** Insert custom authentication code here. This code must obtain
70 ** authentication information for account 'userid'.
71 **
72 ** If you need to link with specific external libraries (-lnsl_s,
73 ** et al), you'll just have to bite the bullet, install automake
74 ** and autoconf, then set authcustom.libsdep and authcustom_LDADD
75 ** in Makefile.am
76 */
77
78 /*
79 ** If userid does not exist, return (-1).
80 */
81
82 DPRINTF("authcustom: nothing implemented in do_auth_custom()");
83 return (-1);
84
85 /*
86 ** If there is some kind of a system problem, that is you are
87 ** unable to check whether userid is valid (the back end database
88 ** is down, or something) return (1).
89 */
90
91 /*
92 ** Otherwise, initialize the authinfo structure, and return (0).
93 **
94 ** NOTES: this function can be called repeated within a single
95 ** process, in certain contexts. Do not simply dynamically
96 ** allocate memory for all the character strings, each time, because
97 ** the caller WILL NOT free the memory of any dynamically allocated
98 ** strings. If you keep dynamically allocating memory, each time,
99 ** you're going to get a memory leak, somewhere, and YOU'LL FUCK
100 ** YOURSELF. What you should do is either use a static buffer,
101 ** or dynamically allocate some memory, and free that memory on
102 ** the next function call.
103 **
104 ** Additionally:
105 **
106 ** If you open any files, you MUST set FD_CLOEXEC bit on any
107 ** file descriptor you create (open files, sockets, whatnot).
108 **
109 ** Someone else might do a fork and an exec, so you need to make
110 ** sure things get cleaned up, in that event.
111 **
112 ** Fields in the auth structure:
113 **
114 ** sysusername - REQUIRED - user name, should simply be userid,
115 ** unless you know what you're doing.
116 ** sysuserid - REQUIRED - pointer to the user's uid_t (yes, it's
117 ** a pointer).
118 ** sysgroupid - REQUIRED - gid_t, the group ID of the user.
119 **
120 ** homedir - REQUIRED - home directory.
121 **
122 ** address - REQUIRED - the 'identity' of the authenticated user,
123 ** the e-mail address. It is acceptable to set
124 ** this field also to userid, if you can't think
125 ** of anything better to do.
126 **
127 ** fullname - OPTIONAL - user's full name.
128 **
129 ** maildir - OPTIONAL - user's primary maildir ($HOME/Maildir default)
130 **
131 ** quota - OPTIONAL - user's maildir quota (see a README somewhere)
132 **
133 ** passwd, clearpasswd - one of these fields must be initialized,
134 ** either one is ok. Initialize clearpasswd
135 ** if you store cleartext passwords. If you
136 ** store crypted passwords, initialize passwd.
137 */
138 }
139
authcustomclose()140 void authcustomclose()
141 {
142 /*
143 ** Place any cleanup here.
144 */
145 }
146