---
plugin/auth_pam/mapper/pam_user_map.c | 59 +++++++++++++++++++++++++++++++++--
1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/plugin/auth_pam/mapper/pam_user_map.c b/plugin/auth_pam/mapper/pam_user_map.c
index e73ab6d..a3008bd 100644
--- a/plugin/auth_pam/mapper/pam_user_map.c
+++ b/plugin/auth_pam/mapper/pam_user_map.c
@@ -13,22 +13,71 @@ auth required pam_user_map.so
And create /etc/security/user_map.conf with the desired mapping
in the format: orig_user_name: mapped_user_name
+ @user's_group_name: mapped_user_name
=========================================================
-#comments and emty lines are ignored
+#comments and emtpy lines are ignored
john: jack
bob: admin
top: accounting
+@group_ro: readonly
=========================================================
*/
+#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
+#include <grp.h>
+#include <pwd.h>
+#include <limits.h>
#include <security/pam_modules.h>
#define FILENAME "/etc/security/user_map.conf"
#define skip(what) while (*s && (what)) s++
+#define GROUP_BUFFER_SIZE 100
+int user_in_group(const char *user, const char *group)
+{
+ gid_t group_buffer[GROUP_BUFFER_SIZE];
+ gid_t *groups= group_buffer;
+ gid_t group_id;
+ gid_t user_group_id;
+ int ng, i;
+
+ {
+ struct passwd *pw= getpwnam(user);
+ struct group *g= getgrnam(group);
+ if (pw == NULL || g == NULL)
+ return 0;
+ user_group_id= pw->pw_gid;
+ group_id= g->gr_gid;
+ }
+
+ ng= GROUP_BUFFER_SIZE;
+ if (getgrouplist(user, user_group_id, groups, &ng) < 0)
+ {
+ /* The rare case when the user is present in more than */
+ /* GROUP_BUFFER_SIZE groups. */
+ groups= (gid_t *) malloc(ng * sizeof (gid_t));
+ if (!groups)
+ return 0;
+
+ (void) getgrouplist(user, user_group_id, groups, &ng);
+ }
+
+ for (i= 0; i < ng; i++)
+ {
+ if (groups[i] == group_id)
+ break;
+ }
+
+ if (groups != group_buffer)
+ free(groups);
+
+ return i < ng;
+}
+
+
int pam_sm_authenticate(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
@@ -51,10 +100,14 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
while (fgets(buf, sizeof(buf), f) != NULL)
{
char *s= buf, *from, *to, *end_from, *end_to;
+ int check_group;
+
line++;
skip(isspace(*s));
if (*s == '#' || *s == 0) continue;
+ if ((check_group= *s == '@'))
+ s++;
from= s;
skip(isalnum(*s) || (*s == '_'));
end_from= s;
@@ -67,7 +120,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
if (end_to == to) goto syntax_error;
*end_from= *end_to= 0;
- if (strcmp(username, from) == 0)
+ if (check_group ?
+ user_in_group(username, from) :
+ (strcmp(username, from) == 0))
{
pam_err= pam_set_item(pamh, PAM_USER, to);
goto ret;