@@ -13,29 +13,92 @@ auth required pam_user_map.so
13
13
14
14
And create /etc/security/user_map.conf with the desired mapping
15
15
in the format: orig_user_name: mapped_user_name
16
+ @user's_group_name: mapped_user_name
16
17
=========================================================
17
- #comments and emty lines are ignored
18
+ #comments and emtpy lines are ignored
18
19
john: jack
19
20
bob: admin
20
21
top: accounting
22
+ @group_ro: readonly
21
23
=========================================================
22
24
23
25
*/
24
26
27
+ #include <stdlib.h>
25
28
#include <stdio.h>
26
29
#include <syslog.h>
30
+ #include <grp.h>
31
+ #include <pwd.h>
32
+
27
33
#include <security/pam_modules.h>
28
34
29
35
#define FILENAME "/etc/security/user_map.conf"
30
36
#define skip (what ) while (*s && (what)) s++
31
37
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
+
32
92
int pam_sm_authenticate (pam_handle_t * pamh , int flags ,
33
93
int argc , const char * argv [])
34
94
{
35
95
int pam_err , line = 0 ;
36
96
const char * username ;
37
97
char buf [256 ];
38
98
FILE * f ;
99
+ gid_t group_buffer [GROUP_BUFFER_SIZE ];
100
+ gid_t * groups = group_buffer ;
101
+ int n_groups = -1 ;
39
102
40
103
f = fopen (FILENAME , "r" );
41
104
if (f == NULL )
@@ -51,10 +114,18 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
51
114
while (fgets (buf , sizeof (buf ), f ) != NULL )
52
115
{
53
116
char * s = buf , * from , * to , * end_from , * end_to ;
117
+ int check_group ;
118
+
54
119
line ++ ;
55
120
56
121
skip (isspace (* s ));
57
122
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
+ }
58
129
from = s ;
59
130
skip (isalnum (* s ) || (* s == '_' ));
60
131
end_from = s ;
@@ -67,7 +138,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
67
138
if (end_to == to ) goto syntax_error ;
68
139
69
140
* 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 ))
71
144
{
72
145
pam_err = pam_set_item (pamh , PAM_USER , to );
73
146
goto ret ;
@@ -80,7 +153,11 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
80
153
pam_syslog (pamh , LOG_ERR , "Syntax error at %s:%d" , FILENAME , line );
81
154
pam_err = PAM_SYSTEM_ERR ;
82
155
ret :
156
+ if (groups != group_buffer )
157
+ free (groups );
158
+
83
159
fclose (f );
160
+
84
161
return pam_err ;
85
162
}
86
163
0 commit comments