@@ -13,29 +13,92 @@ auth required pam_user_map.so
1313
1414 And create /etc/security/user_map.conf with the desired mapping
1515 in the format: orig_user_name: mapped_user_name
16+ @user's_group_name: mapped_user_name
1617=========================================================
17- #comments and emty lines are ignored
18+ #comments and emtpy lines are ignored
1819john: jack
1920bob: admin
2021top: accounting
22+ @group_ro: readonly
2123=========================================================
2224
2325*/
2426
27+ #include <stdlib.h>
2528#include <stdio.h>
2629#include <syslog.h>
30+ #include <grp.h>
31+ #include <pwd.h>
32+
2733#include <security/pam_modules.h>
2834
2935#define FILENAME "/etc/security/user_map.conf"
3036#define skip (what ) while (*s && (what)) s++
3137
38+ #define GROUP_BUFFER_SIZE 100
39+
40+
41+ static int populate_user_groups (const char * user , gid_t * * groups )
42+ {
43+ gid_t user_group_id ;
44+ gid_t * loc_groups = * groups ;
45+ int ng ;
46+
47+ {
48+ struct passwd * pw = getpwnam (user );
49+ if (!pw )
50+ return 0 ;
51+ user_group_id = pw -> pw_gid ;
52+ }
53+
54+ ng = GROUP_BUFFER_SIZE ;
55+ if (getgrouplist (user , user_group_id , loc_groups , & ng ) < 0 )
56+ {
57+ /* The rare case when the user is present in more than */
58+ /* GROUP_BUFFER_SIZE groups. */
59+ loc_groups = (gid_t * ) malloc (ng * sizeof (gid_t ));
60+ if (!loc_groups )
61+ return 0 ;
62+
63+ (void ) getgrouplist (user , user_group_id , loc_groups , & ng );
64+ * groups = loc_groups ;
65+ }
66+
67+ return ng ;
68+ }
69+
70+
71+ static int user_in_group (const gid_t * user_groups , int ng ,const char * group )
72+ {
73+ gid_t group_id ;
74+
75+ {
76+ struct group * g = getgrnam (group );
77+ if (!g )
78+ return 0 ;
79+ group_id = g -> gr_gid ;
80+ }
81+
82+ for (; user_groups < user_groups + ng ; user_groups ++ )
83+ {
84+ if (* user_groups == group_id )
85+ return 1 ;
86+ }
87+
88+ return 0 ;
89+ }
90+
91+
3292int pam_sm_authenticate (pam_handle_t * pamh , int flags ,
3393 int argc , const char * argv [])
3494{
3595 int pam_err , line = 0 ;
3696 const char * username ;
3797 char buf [256 ];
3898 FILE * f ;
99+ gid_t group_buffer [GROUP_BUFFER_SIZE ];
100+ gid_t * groups = group_buffer ;
101+ int n_groups = -1 ;
39102
40103 f = fopen (FILENAME , "r" );
41104 if (f == NULL )
@@ -51,10 +114,18 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
51114 while (fgets (buf , sizeof (buf ), f ) != NULL )
52115 {
53116 char * s = buf , * from , * to , * end_from , * end_to ;
117+ int check_group ;
118+
54119 line ++ ;
55120
56121 skip (isspace (* s ));
57122 if (* s == '#' || * s == 0 ) continue ;
123+ if ((check_group = * s == '@' ))
124+ {
125+ if (n_groups < 0 )
126+ n_groups = populate_user_groups (username , & groups );
127+ s ++ ;
128+ }
58129 from = s ;
59130 skip (isalnum (* s ) || (* s == '_' ));
60131 end_from = s ;
@@ -67,7 +138,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
67138 if (end_to == to ) goto syntax_error ;
68139
69140 * end_from = * end_to = 0 ;
70- if (strcmp (username , from ) == 0 )
141+ if (check_group ?
142+ user_in_group (groups , n_groups , from ) :
143+ (strcmp (username , from ) == 0 ))
71144 {
72145 pam_err = pam_set_item (pamh , PAM_USER , to );
73146 goto ret ;
@@ -80,7 +153,11 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
80153 pam_syslog (pamh , LOG_ERR , "Syntax error at %s:%d" , FILENAME , line );
81154 pam_err = PAM_SYSTEM_ERR ;
82155ret :
156+ if (groups != group_buffer )
157+ free (groups );
158+
83159 fclose (f );
160+
84161 return pam_err ;
85162}
86163
0 commit comments