1 /*
2 * Copyright (C) 2013 Nikos Mavrogiannopoulos
3 *
4 * This file is part of ocserv.
5 *
6 * ocserv is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * ocserv is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <pwd.h>
25 #include <grp.h>
26 #include <sec-mod-auth.h>
27 #include "auth-unix.h"
28
29 #ifdef HAVE_GET_USER_AUTH_GROUP
30 /* Fills-in groupname, if the user is in a unix group, via getpwnam().
31 * Returns -1 if the suggested group doesn't match one the groups, or
32 * zero otherwise (an empty group is still success).
33 */
get_user_auth_group(const char * username,const char * suggested,char * groupname,int groupname_size)34 int get_user_auth_group(const char *username, const char *suggested,
35 char *groupname, int groupname_size)
36 {
37 struct passwd * pwd;
38 struct group *grp;
39 int ret;
40 unsigned found;
41
42 groupname[0] = 0;
43
44 pwd = getpwnam(username);
45 if (pwd != NULL) {
46 if (suggested != NULL) {
47 gid_t groups[MAX_GROUPS];
48 int ngroups = sizeof(groups)/sizeof(groups[0]);
49 unsigned i;
50
51 ret = getgrouplist(username, pwd->pw_gid, groups, &ngroups);
52 if (ret <= 0) {
53 return 0;
54 }
55
56 found = 0;
57 for (i=0;i<ngroups;i++) {
58 grp = getgrgid(groups[i]);
59 if (grp != NULL && strcmp(suggested, grp->gr_name) == 0) {
60 strlcpy(groupname, grp->gr_name, groupname_size);
61 found = 1;
62 break;
63 }
64 }
65
66 if (found == 0) {
67 syslog(LOG_NOTICE,
68 "user '%s' requested group '%s' but is not a member",
69 username, suggested);
70 return -1;
71 }
72 } else {
73 struct group* grp = getgrgid(pwd->pw_gid);
74 if (grp != NULL)
75 strlcpy(groupname, grp->gr_name, groupname_size);
76 }
77 }
78
79 return 0;
80 }
81
unix_group_list(void * pool,unsigned gid_min,char *** groupname,unsigned * groupname_size)82 void unix_group_list(void *pool, unsigned gid_min, char ***groupname, unsigned *groupname_size)
83 {
84 struct group *grp;
85
86 setgrent();
87
88 *groupname_size = 0;
89 *groupname = talloc_size(pool, sizeof(char*)*MAX_GROUPS);
90 if (*groupname == NULL) {
91 goto exit;
92 }
93
94 while((grp = getgrent()) != NULL && (*groupname_size) < MAX_GROUPS) {
95 if (grp->gr_gid >= gid_min) {
96 (*groupname)[(*groupname_size)] = talloc_strdup(*groupname, grp->gr_name);
97 if ((*groupname)[(*groupname_size)] == NULL)
98 break;
99 (*groupname_size)++;
100 }
101 }
102
103 exit:
104 endgrent();
105 return;
106 }
107
108 #endif
109