Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / user_acl.c
blob11b6cfe648c4cdddb5836740034b52dc18ca6434
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* user_acl 3
6 /* SUMMARY
7 /* user name based access control
8 /* SYNOPSIS
9 /* #include <user_acl.h>
11 /* const char *check_user_acl_byuid(acl, uid)
12 /* const char *acl;
13 /* uid_t uid;
14 /* DESCRIPTION
15 /* check_user_acl_byuid() converts the given uid into a user
16 /* name, and checks the result against a user name matchlist.
17 /* If the uid cannot be resolved to a user name, "unknown"
18 /* is used as the lookup key instead.
19 /* The result is NULL on success, the username upon failure.
20 /* The error result lives in static storage and must be saved
21 /* if it is to be used to across multiple check_user_acl_byuid()
22 /* calls.
24 /* Arguments:
25 /* .IP acl
26 /* Authorized user name list suitable for input to string_list_init(3).
27 /* .IP uid
28 /* The uid to be checked against the access list.
29 /* LICENSE
30 /* .ad
31 /* .fi
32 /* The Secure Mailer license must be distributed with this software.
33 /* AUTHOR(S)
34 /* Wietse Venema
35 /* IBM T.J. Watson Research
36 /* P.O. Box 704
37 /* Yorktown Heights, NY 10598, USA
39 /* Victor Duchovni
40 /* Morgan Stanley
41 /*--*/
43 /* System library. */
45 #include <sys_defs.h>
46 #include <string.h>
48 /* Utility library. */
50 #include <vstring.h>
52 /* Global library. */
54 #include <string_list.h>
55 #include <mypwd.h>
56 #include <mail_params.h> /* STATIC_ANYONE_ACL */
58 /* Application-specific. */
60 #include "user_acl.h"
62 /* check_user_acl_byuid - check user authorization */
64 const char *check_user_acl_byuid(char *acl, uid_t uid)
66 struct mypasswd *mypwd;
67 STRING_LIST *list;
68 static VSTRING *who = 0;
69 int matched;
70 const char *name;
73 * Optimize for the most common case. This also makes Postfix a little
74 * more robust in the face of local infrastructure failures.
76 if (strcmp(acl, STATIC_ANYONE_ACL) == 0)
77 return (0);
80 * XXX: Substitute "unknown" for UIDs without username, so that
81 * static:anyone results in "permit" even when the uid is not found in
82 * the password file, and so that a pattern of !unknown can be used to
83 * block non-existent accounts.
85 * The alternative is to use the UID as a surrogate lookup key for
86 * non-existent accounts. There are several reasons why this is not a
87 * good idea. 1) An ACL with a numerical UID should work regardless of
88 * whether or not an account has a password file entry. Therefore we
89 * would always have search on the numerical UID whenever the username
90 * fails to produce a match. 2) The string-list infrastructure is not
91 * really suitable for mixing numerical and non-numerical user
92 * information, because the numerical match is done in a separate pass
93 * from the non-numerical match. This breaks when the ! operator is used.
95 if ((mypwd = mypwuid(uid)) == 0) {
96 name = "unknown";
97 } else {
98 name = mypwd->pw_name;
101 list = string_list_init(MATCH_FLAG_NONE, acl);
102 if ((matched = string_list_match(list, name)) == 0) {
103 if (!who)
104 who = vstring_alloc(10);
105 vstring_strcpy(who, name);
107 string_list_free(list);
108 if (mypwd)
109 mypwfree(mypwd);
111 return (matched ? 0 : vstring_str(who));