diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2015-10-07 15:52:26 +0500 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2015-10-09 03:25:08 +0500 |
commit | b0935fc5dafbd4a6c9adeeec4647a9616abf4b7b (patch) | |
tree | ab5afdaf285c108c14fa285c94cf5adcd9509da8 | |
parent | 3757bc5e895289a6d69e6382bccb11c021e7144c (diff) | |
download | mariadb-git-b0935fc5dafbd4a6c9adeeec4647a9616abf4b7b.tar.gz |
MDEV-8842 add group support to pam_user_map module.
Added to the pam_user_map module.
-rw-r--r-- | plugin/auth_pam/mapper/pam_user_map.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/plugin/auth_pam/mapper/pam_user_map.c b/plugin/auth_pam/mapper/pam_user_map.c index e73ab6de544..1c4bccc7f27 100644 --- a/plugin/auth_pam/mapper/pam_user_map.c +++ b/plugin/auth_pam/mapper/pam_user_map.c @@ -13,22 +13,82 @@ 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 <security/pam_modules.h> #define FILENAME "/etc/security/user_map.conf" #define skip(what) while (*s && (what)) s++ +#define GROUP_BUFFER_SIZE 100 + + +static int populate_user_groups(const char *user, gid_t **groups) +{ + gid_t user_group_id; + gid_t *loc_groups= *groups; + int ng; + + { + struct passwd *pw= getpwnam(user); + if (!pw) + return 0; + user_group_id= pw->pw_gid; + } + + ng= GROUP_BUFFER_SIZE; + if (getgrouplist(user, user_group_id, loc_groups, &ng) < 0) + { + /* The rare case when the user is present in more than */ + /* GROUP_BUFFER_SIZE groups. */ + loc_groups= (gid_t *) malloc(ng * sizeof (gid_t)); + if (!loc_groups) + return 0; + + (void) getgrouplist(user, user_group_id, loc_groups, &ng); + *groups= loc_groups; + } + + return ng; +} + + +static int user_in_group(const gid_t *user_groups, int ng,const char *group) +{ + gid_t group_id; + + { + struct group *g= getgrnam(group); + if (!g) + return 0; + group_id= g->gr_gid; + } + + for (; user_groups < user_groups + ng; user_groups++) + { + if (*user_groups == group_id) + return 1; + } + + return 0; +} + + int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { @@ -36,6 +96,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, const char *username; char buf[256]; FILE *f; + gid_t group_buffer[GROUP_BUFFER_SIZE]; + gid_t *groups= group_buffer; + int n_groups= -1; f= fopen(FILENAME, "r"); if (f == NULL) @@ -51,10 +114,18 @@ 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 == '@')) + { + if (n_groups < 0) + n_groups= populate_user_groups(username, &groups); + s++; + } from= s; skip(isalnum(*s) || (*s == '_')); end_from= s; @@ -67,7 +138,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(groups, n_groups, from) : + (strcmp(username, from) == 0)) { pam_err= pam_set_item(pamh, PAM_USER, to); goto ret; @@ -80,7 +153,11 @@ syntax_error: pam_syslog(pamh, LOG_ERR, "Syntax error at %s:%d", FILENAME, line); pam_err= PAM_SYSTEM_ERR; ret: + if (groups != group_buffer) + free(groups); + fclose(f); + return pam_err; } |