7 /* user name based access control
9 /* #include <user_acl.h>
11 /* const char *check_user_acl_byuid(acl, uid)
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()
26 /* Authorized user name list suitable for input to string_list_init(3).
28 /* The uid to be checked against the access list.
32 /* The Secure Mailer license must be distributed with this software.
35 /* IBM T.J. Watson Research
37 /* Yorktown Heights, NY 10598, USA
48 /* Utility library. */
54 #include <string_list.h>
56 #include <mail_params.h> /* STATIC_ANYONE_ACL */
58 /* Application-specific. */
62 /* check_user_acl_byuid - check user authorization */
64 const char *check_user_acl_byuid(char *acl
, uid_t uid
)
66 struct mypasswd
*mypwd
;
68 static VSTRING
*who
= 0;
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)
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) {
98 name
= mypwd
->pw_name
;
101 list
= string_list_init(MATCH_FLAG_NONE
, acl
);
102 if ((matched
= string_list_match(list
, name
)) == 0) {
104 who
= vstring_alloc(10);
105 vstring_strcpy(who
, name
);
107 string_list_free(list
);
111 return (matched
? 0 : vstring_str(who
));