2 * @brief Filter results according to Unix-style access permissions
4 /* Copyright (C) 2010 Olly Betts
6 * This program is free software; you can redistribute it and/or modify
7 * it 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.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <sys/types.h>
28 #include "safeunistd.h"
33 #ifdef GETGROUPLIST_TAKES_INT_P
42 apply_unix_permissions(Xapian::Query
& query
, const char * user
)
44 // Apply permission filters.
47 allow
.push_back("I*");
48 allow
.push_back(string("I@") + user
);
49 deny
.push_back(string("V@") + user
);
51 struct passwd
* pwent
= getpwnam(user
);
53 query
= Xapian::Query();
57 // Add supplementary groups for user too.
58 #ifdef HAVE_GETGROUPLIST
61 GID_T
*groups
= new GID_T
[ngroups
];
63 while (getgrouplist(user
, pwent
->pw_gid
, groups
, &ngroups
) == -1) {
65 groups
= new GID_T
[ngroups
];
68 for (int i
= 0; i
< ngroups
; ++i
) {
69 struct group
* grentry
= getgrgid(groups
[i
]);
71 const char * group
= grentry
->gr_name
;
72 allow
.push_back(string("I#") + group
);
73 deny
.push_back(string("V#") + group
);
77 gid_t main_gid
= pwent
->pw_gid
;
78 struct group
* grentry
= getgrgid(pwent
->pw_gid
);
80 const char * group
= grentry
->gr_name
;
81 allow
.push_back(string("I#") + group
);
82 deny
.push_back(string("V#") + group
);
85 // Make sure we're rewound.
88 while ((grentry
= getgrent()) != NULL
) {
89 // Don't process the main group again if it happens to be listed as
90 // a supplementary group.
91 if (grentry
->gr_gid
== main_gid
)
93 for (char ** members
= grentry
->gr_mem
; *members
; ++members
) {
94 if (strcmp(*members
, user
) == 0) {
95 const char * group
= grentry
->gr_name
;
96 allow
.push_back(string("I#") + group
);
97 deny
.push_back(string("V#") + group
);
108 query
= Xapian::Query(query
.OP_FILTER
,
110 Xapian::Query(query
.OP_OR
,
113 query
= Xapian::Query(query
.OP_AND_NOT
,
115 Xapian::Query(query
.OP_OR
,