diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-05-28 22:12:00 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-05-28 22:12:00 +1000 |
commit | 67b83d2489788f1899c253fdab554d0998f9c044 (patch) | |
tree | 637060cb6bd4ab16fa9464d2bc168ad6c99e0b11 /lib/nss_wrapper | |
parent | 08be1420ba52ef9bba90d0f811c7810841ee8568 (diff) | |
parent | e63d9c29c99c5311c9f4a8dbe432ff4cea4fb924 (diff) | |
download | samba-67b83d2489788f1899c253fdab554d0998f9c044.tar.gz samba-67b83d2489788f1899c253fdab554d0998f9c044.tar.bz2 samba-67b83d2489788f1899c253fdab554d0998f9c044.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba
Diffstat (limited to 'lib/nss_wrapper')
-rw-r--r-- | lib/nss_wrapper/nss_wrapper.c | 242 | ||||
-rw-r--r-- | lib/nss_wrapper/nss_wrapper.pl | 197 |
2 files changed, 332 insertions, 107 deletions
diff --git a/lib/nss_wrapper/nss_wrapper.c b/lib/nss_wrapper/nss_wrapper.c index da090832b0..1875dc3e4f 100644 --- a/lib/nss_wrapper/nss_wrapper.c +++ b/lib/nss_wrapper/nss_wrapper.c @@ -771,14 +771,11 @@ static int nwrap_gr_copy_r(const struct group *src, struct group *dst, } /* user functions */ -_PUBLIC_ struct passwd *nwrap_getpwnam(const char *name) + +static struct passwd *nwrap_files_getpwnam(const char *name) { int i; - if (!nwrap_enabled()) { - return real_getpwnam(name); - } - nwrap_cache_reload(nwrap_pw_global.cache); for (i=0; i<nwrap_pw_global.num; i++) { @@ -798,15 +795,20 @@ _PUBLIC_ struct passwd *nwrap_getpwnam(const char *name) return NULL; } -_PUBLIC_ int nwrap_getpwnam_r(const char *name, struct passwd *pwdst, - char *buf, size_t buflen, struct passwd **pwdstp) +_PUBLIC_ struct passwd *nwrap_getpwnam(const char *name) { - struct passwd *pw; - if (!nwrap_enabled()) { - return real_getpwnam_r(name, pwdst, buf, buflen, pwdstp); + return real_getpwnam(name); } + return nwrap_files_getpwnam(name); +} + +static int nwrap_files_getpwnam_r(const char *name, struct passwd *pwdst, + char *buf, size_t buflen, struct passwd **pwdstp) +{ + struct passwd *pw; + pw = nwrap_getpwnam(name); if (!pw) { if (errno == 0) { @@ -818,14 +820,20 @@ _PUBLIC_ int nwrap_getpwnam_r(const char *name, struct passwd *pwdst, return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp); } -_PUBLIC_ struct passwd *nwrap_getpwuid(uid_t uid) +_PUBLIC_ int nwrap_getpwnam_r(const char *name, struct passwd *pwdst, + char *buf, size_t buflen, struct passwd **pwdstp) { - int i; - if (!nwrap_enabled()) { - return real_getpwuid(uid); + return real_getpwnam_r(name, pwdst, buf, buflen, pwdstp); } + return nwrap_files_getpwnam_r(name, pwdst, buf, buflen, pwdstp); +} + +static struct passwd *nwrap_files_getpwuid(uid_t uid) +{ + int i; + nwrap_cache_reload(nwrap_pw_global.cache); for (i=0; i<nwrap_pw_global.num; i++) { @@ -845,15 +853,20 @@ _PUBLIC_ struct passwd *nwrap_getpwuid(uid_t uid) return NULL; } -_PUBLIC_ int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst, - char *buf, size_t buflen, struct passwd **pwdstp) +_PUBLIC_ struct passwd *nwrap_getpwuid(uid_t uid) { - struct passwd *pw; - if (!nwrap_enabled()) { - return real_getpwuid_r(uid, pwdst, buf, buflen, pwdstp); + return real_getpwuid(uid); } + return nwrap_files_getpwuid(uid); +} + +static int nwrap_files_getpwuid_r(uid_t uid, struct passwd *pwdst, + char *buf, size_t buflen, struct passwd **pwdstp) +{ + struct passwd *pw; + pw = nwrap_getpwuid(uid); if (!pw) { if (errno == 0) { @@ -865,24 +878,35 @@ _PUBLIC_ int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst, return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp); } +_PUBLIC_ int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst, + char *buf, size_t buflen, struct passwd **pwdstp) +{ + if (!nwrap_enabled()) { + return real_getpwuid_r(uid, pwdst, buf, buflen, pwdstp); + } + + return nwrap_files_getpwuid_r(uid, pwdst, buf, buflen, pwdstp); +} + /* user enum functions */ +static void nwrap_files_setpwent(void) +{ + nwrap_pw_global.idx = 0; +} + _PUBLIC_ void nwrap_setpwent(void) { if (!nwrap_enabled()) { real_setpwent(); } - nwrap_pw_global.idx = 0; + nwrap_files_setpwent(); } -_PUBLIC_ struct passwd *nwrap_getpwent(void) +static struct passwd *nwrap_files_getpwent(void) { struct passwd *pw; - if (!nwrap_enabled()) { - return real_getpwent(); - } - if (nwrap_pw_global.idx == 0) { nwrap_cache_reload(nwrap_pw_global.cache); } @@ -900,13 +924,37 @@ _PUBLIC_ struct passwd *nwrap_getpwent(void) return pw; } -_PUBLIC_ int nwrap_getpwent_r(struct passwd *pwdst, char *buf, - size_t buflen, struct passwd **pwdstp) +_PUBLIC_ struct passwd *nwrap_getpwent(void) +{ + if (!nwrap_enabled()) { + return real_getpwent(); + } + + return nwrap_files_getpwent(); +} + +static int nwrap_files_getpwent_r(struct passwd *pwdst, char *buf, + size_t buflen, struct passwd **pwdstp) { struct passwd *pw; + pw = nwrap_getpwent(); + if (!pw) { + if (errno == 0) { + return ENOENT; + } + return errno; + } + + return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp); +} + +_PUBLIC_ int nwrap_getpwent_r(struct passwd *pwdst, char *buf, + size_t buflen, struct passwd **pwdstp) +{ if (!nwrap_enabled()) { #ifdef SOLARIS_GETPWENT_R + struct passwd *pw; pw = real_getpwent_r(pwdst, buf, buflen); if (!pw) { if (errno == 0) { @@ -923,15 +971,12 @@ _PUBLIC_ int nwrap_getpwent_r(struct passwd *pwdst, char *buf, #endif } - pw = nwrap_getpwent(); - if (!pw) { - if (errno == 0) { - return ENOENT; - } - return errno; - } + return nwrap_files_getpwent_r(pwdst, buf, buflen, pwdstp); +} - return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp); +static void nwrap_files_endpwent(void) +{ + nwrap_pw_global.idx = 0; } _PUBLIC_ void nwrap_endpwent(void) @@ -940,29 +985,30 @@ _PUBLIC_ void nwrap_endpwent(void) real_endpwent(); } - nwrap_pw_global.idx = 0; + nwrap_files_endpwent(); } /* misc functions */ +static int nwrap_files_initgroups(const char *user, gid_t group) +{ + /* TODO: maybe we should also fake this... */ + return EPERM; +} + _PUBLIC_ int nwrap_initgroups(const char *user, gid_t group) { if (!nwrap_enabled()) { return real_initgroups(user, group); } - /* TODO: maybe we should also fake this... */ - return EPERM; + return nwrap_files_initgroups(user, group); } /* group functions */ -_PUBLIC_ struct group *nwrap_getgrnam(const char *name) +static struct group *nwrap_files_getgrnam(const char *name) { int i; - if (!nwrap_enabled()) { - return real_getgrnam(name); - } - nwrap_cache_reload(nwrap_gr_global.cache); for (i=0; i<nwrap_gr_global.num; i++) { @@ -982,15 +1028,20 @@ _PUBLIC_ struct group *nwrap_getgrnam(const char *name) return NULL; } -_PUBLIC_ int nwrap_getgrnam_r(const char *name, struct group *grdst, - char *buf, size_t buflen, struct group **grdstp) +_PUBLIC_ struct group *nwrap_getgrnam(const char *name) { - struct group *gr; - if (!nwrap_enabled()) { - return real_getgrnam_r(name, grdst, buf, buflen, grdstp); + return real_getgrnam(name); } + return nwrap_files_getgrnam(name); +} + +static int nwrap_files_getgrnam_r(const char *name, struct group *grdst, + char *buf, size_t buflen, struct group **grdstp) +{ + struct group *gr; + gr = nwrap_getgrnam(name); if (!gr) { if (errno == 0) { @@ -1002,14 +1053,20 @@ _PUBLIC_ int nwrap_getgrnam_r(const char *name, struct group *grdst, return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp); } -_PUBLIC_ struct group *nwrap_getgrgid(gid_t gid) +_PUBLIC_ int nwrap_getgrnam_r(const char *name, struct group *grdst, + char *buf, size_t buflen, struct group **grdstp) { - int i; - if (!nwrap_enabled()) { - return real_getgrgid(gid); + return real_getgrnam_r(name, grdst, buf, buflen, grdstp); } + return nwrap_files_getgrnam_r(name, grdst, buf, buflen, grdstp); +} + +static struct group *nwrap_files_getgrgid(gid_t gid) +{ + int i; + nwrap_cache_reload(nwrap_gr_global.cache); for (i=0; i<nwrap_gr_global.num; i++) { @@ -1029,15 +1086,20 @@ _PUBLIC_ struct group *nwrap_getgrgid(gid_t gid) return NULL; } -_PUBLIC_ int nwrap_getgrgid_r(gid_t gid, struct group *grdst, - char *buf, size_t buflen, struct group **grdstp) +_PUBLIC_ struct group *nwrap_getgrgid(gid_t gid) { - struct group *gr; - if (!nwrap_enabled()) { - return real_getgrgid_r(gid, grdst, buf, buflen, grdstp); + return real_getgrgid(gid); } + return nwrap_files_getgrgid(gid); +} + +static int nwrap_files_getgrgid_r(gid_t gid, struct group *grdst, + char *buf, size_t buflen, struct group **grdstp) +{ + struct group *gr; + gr = nwrap_getgrgid(gid); if (!gr) { if (errno == 0) { @@ -1051,24 +1113,35 @@ _PUBLIC_ int nwrap_getgrgid_r(gid_t gid, struct group *grdst, return ENOENT; } +_PUBLIC_ int nwrap_getgrgid_r(gid_t gid, struct group *grdst, + char *buf, size_t buflen, struct group **grdstp) +{ + if (!nwrap_enabled()) { + return real_getgrgid_r(gid, grdst, buf, buflen, grdstp); + } + + return nwrap_files_getgrgid_r(gid, grdst, buf, buflen, grdstp); +} + /* group enum functions */ +static void nwrap_files_setgrent(void) +{ + nwrap_gr_global.idx = 0; +} + _PUBLIC_ void nwrap_setgrent(void) { if (!nwrap_enabled()) { real_setgrent(); } - nwrap_gr_global.idx = 0; + nwrap_files_setgrent(); } -_PUBLIC_ struct group *nwrap_getgrent(void) +static struct group *nwrap_files_getgrent(void) { struct group *gr; - if (!nwrap_enabled()) { - return real_getgrent(); - } - if (nwrap_gr_global.idx == 0) { nwrap_cache_reload(nwrap_gr_global.cache); } @@ -1086,13 +1159,37 @@ _PUBLIC_ struct group *nwrap_getgrent(void) return gr; } -_PUBLIC_ int nwrap_getgrent_r(struct group *grdst, char *buf, - size_t buflen, struct group **grdstp) +_PUBLIC_ struct group *nwrap_getgrent(void) +{ + if (!nwrap_enabled()) { + return real_getgrent(); + } + + return nwrap_files_getgrent(); +} + +static int nwrap_files_getgrent_r(struct group *grdst, char *buf, + size_t buflen, struct group **grdstp) { struct group *gr; + gr = nwrap_getgrent(); + if (!gr) { + if (errno == 0) { + return ENOENT; + } + return errno; + } + + return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp); +} + +_PUBLIC_ int nwrap_getgrent_r(struct group *grdst, char *buf, + size_t buflen, struct group **grdstp) +{ if (!nwrap_enabled()) { #ifdef SOLARIS_GETGRENT_R + struct group *gr; gr = real_getgrent_r(grdst, buf, buflen); if (!gr) { if (errno == 0) { @@ -1109,15 +1206,12 @@ _PUBLIC_ int nwrap_getgrent_r(struct group *grdst, char *buf, #endif } - gr = nwrap_getgrent(); - if (!gr) { - if (errno == 0) { - return ENOENT; - } - return errno; - } + return nwrap_files_getgrent_r(grdst, buf, buflen, grdstp); +} - return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp); +static void nwrap_files_endgrent(void) +{ + nwrap_gr_global.idx = 0; } _PUBLIC_ void nwrap_endgrent(void) @@ -1126,5 +1220,5 @@ _PUBLIC_ void nwrap_endgrent(void) real_endgrent(); } - nwrap_gr_global.idx = 0; + nwrap_files_endgrent(); } diff --git a/lib/nss_wrapper/nss_wrapper.pl b/lib/nss_wrapper/nss_wrapper.pl index cfd3206c2a..1f1aef1118 100644 --- a/lib/nss_wrapper/nss_wrapper.pl +++ b/lib/nss_wrapper/nss_wrapper.pl @@ -7,26 +7,35 @@ use Getopt::Long; use Cwd qw(abs_path); my $opt_help = 0; -my $opt_path = undef; +my $opt_passwd_path = undef; +my $opt_group_path = undef; my $opt_action = undef; my $opt_type = undef; my $opt_name = undef; +my $opt_member = undef; my $passwdfn = undef; my $groupfn = undef; +my $memberfn = undef; my $actionfn = undef; -sub passwd_add($$); -sub passwd_delete($$); -sub group_add($$); -sub group_delete($$); +sub passwd_add($$$$); +sub passwd_delete($$$$); +sub group_add($$$$); +sub group_delete($$$$); +sub member_add($$$$); +sub member_delete($$$$); + +sub check_path($$); my $result = GetOptions( 'help|h|?' => \$opt_help, - 'path=s' => \$opt_path, + 'passwd_path=s' => \$opt_passwd_path, + 'group_path=s' => \$opt_group_path, 'action=s' => \$opt_action, 'type=s' => \$opt_type, - 'name=s' => \$opt_name + 'name=s' => \$opt_name, + 'member=s' => \$opt_member ); sub usage($;$) @@ -39,14 +48,16 @@ sub usage($;$) --help|-h|-? Show this help. - --path <path> Path of the 'passwd' or 'group' file. + --passwd_path <path> Path of the 'passwd' file. + --group_path <path> Path of the 'group' file. - --type <type> Only 'passwd' and 'group' are supported yet, - maybe 'member' will be added in future. + --type <type> 'passwd', 'group' and 'member' are supported. --action <action> 'add' or 'delete'. --name <name> The name of the object. + + --member <member> The name of the member. "; exit($ret); } @@ -55,38 +66,39 @@ usage(1) if (not $result); usage(0) if ($opt_help); -if (not defined($opt_path)) { - usage(1, "missing: --path <path>"); -} -if ($opt_path eq "" or $opt_path eq "/") { - usage(1, "invalid: --path <path>: '$opt_path'"); -} -my $opt_fullpath = abs_path($opt_path); -if (not defined($opt_fullpath)) { - usage(1, "invalid: --path <path>: '$opt_path'"); -} - - if (not defined($opt_action)) { usage(1, "missing: --action [add|delete]"); } if ($opt_action eq "add") { $passwdfn = \&passwd_add; $groupfn = \&group_add; + $memberfn = \&member_add; } elsif ($opt_action eq "delete") { $passwdfn = \&passwd_delete; $groupfn = \&group_delete; + $memberfn = \&member_delete; } else { usage(1, "invalid: --action [add|delete]: '$opt_action'"); } if (not defined($opt_type)) { - usage(1, "missing: --type [passwd|group]"); + usage(1, "missing: --type [passwd|group|member]"); } +if ($opt_type eq "member" and not defined($opt_member)) { + usage(1, "missing: --member <member>"); +} +my $opt_fullpath_passwd; +my $opt_fullpath_group; if ($opt_type eq "passwd") { $actionfn = $passwdfn; + $opt_fullpath_passwd = check_path($opt_passwd_path, $opt_type); } elsif ($opt_type eq "group") { $actionfn = $groupfn; + $opt_fullpath_group = check_path($opt_group_path, $opt_type); +} elsif ($opt_type eq "member") { + $actionfn = $memberfn; + $opt_fullpath_passwd = check_path($opt_passwd_path, "passwd"); + $opt_fullpath_group = check_path($opt_group_path, "group"); } else { usage(1, "invalid: --type [passwd|group]: '$opt_type'") } @@ -98,7 +110,24 @@ if ($opt_name eq "") { usage(1, "invalid: --name <name>"); } -exit $actionfn->($opt_fullpath, $opt_name); +exit $actionfn->($opt_fullpath_passwd, $opt_member, $opt_fullpath_group, $opt_name); + +sub check_path($$) +{ + my ($path,$type) = @_; + + if (not defined($path)) { + usage(1, "missing: --$type\_path <path>"); + } + if ($path eq "" or $path eq "/") { + usage(1, "invalid: --$type\_path <path>: '$path'"); + } + my $fullpath = abs_path($path); + if (not defined($fullpath)) { + usage(1, "invalid: --$type\_path <path>: '$path'"); + } + return $fullpath; +} sub passwd_add_entry($$); @@ -260,6 +289,62 @@ sub group_remove_entry($$) delete $group->{gid}{${$eref}[2]}; } +sub group_add_member($$$) +{ + my ($group, $eref, $username) = @_; + + my @members; + my $str = @$eref[3] || undef; + if ($str) { + @members = split(",", $str); + } + + foreach my $member (@members) { + if ($member and $member eq $username) { + die("account[$username] is already member of '@$eref[0]'"); + } + } + + push(@members, $username); + + my $gwent = @$eref[0].":x:".@$eref[2].":".join(",", @members); + + group_remove_entry($group, $eref); + + group_add_entry($group, $gwent); +} + +sub group_delete_member($$$) +{ + my ($group, $eref, $username) = @_; + + my @members = undef; + my $str = @$eref[3] || undef; + if ($str) { + @members = split(",", $str); + } + my @new_members; + my $removed = 0; + + foreach my $member (@members) { + if ($member and $member ne $username) { + push(@new_members, $member); + } else { + $removed = 1; + } + } + + if ($removed != 1) { + die("account[$username] is not member of '@$eref[0]'"); + } + + my $gwent = @$eref[0].":x:".@$eref[2].":".join(",", @new_members); + + group_remove_entry($group, $eref); + + group_add_entry($group, $gwent); +} + sub passwd_save($) { my ($passwd) = @_; @@ -303,9 +388,9 @@ sub group_save($) rename($tmppath, $path) or die("Unable to rename $tmppath => $path"); } -sub passwd_add($$) +sub passwd_add($$$$) { - my ($path, $name) = @_; + my ($path, $dummy, $dummy2, $name) = @_; #print "passwd_add: '$name' in '$path'\n"; @@ -326,9 +411,9 @@ sub passwd_add($$) return 0; } -sub passwd_delete($$) +sub passwd_delete($$$$) { - my ($path, $name) = @_; + my ($path, $dummy, $dummy2, $name) = @_; #print "passwd_delete: '$name' in '$path'\n"; @@ -344,9 +429,9 @@ sub passwd_delete($$) return 0; } -sub group_add($$) +sub group_add($$$$) { - my ($path, $name) = @_; + my ($dummy, $dummy2, $path, $name) = @_; #print "group_add: '$name' in '$path'\n"; @@ -357,7 +442,7 @@ sub group_add($$) my $gid = group_get_free_gid($group); - my $gwent = $name.":x:".$gid.":".""; #no members yet + my $gwent = $name.":x:".$gid.":".""; group_add_entry($group, $gwent); @@ -368,9 +453,9 @@ sub group_add($$) return 0; } -sub group_delete($$) +sub group_delete($$$$) { - my ($path, $name) = @_; + my ($dummy, $dummy2, $path, $name) = @_; #print "group_delete: '$name' in '$path'\n"; @@ -385,3 +470,49 @@ sub group_delete($$) return 0; } + +sub member_add($$$$) +{ + my ($passwd_path, $username, $group_path, $groupname) = @_; + + #print "member_add: adding '$username' in '$passwd_path' to '$groupname' in '$group_path'\n"; + + my $group = group_load($group_path); + + my $g = group_lookup_name($group, $groupname); + die("group[$groupname] does not exists in '$group_path'") unless defined($g); + + my $passwd = passwd_load($passwd_path); + + my $u = passwd_lookup_name($passwd, $username); + die("account[$username] does not exists in '$passwd_path'") unless defined($u); + + group_add_member($group, $g, $username); + + group_save($group); + + return 0; +} + +sub member_delete($$$$) +{ + my ($passwd_path, $username, $group_path, $groupname) = @_; + + #print "member_delete: removing '$username' in '$passwd_path' from '$groupname' in '$group_path'\n"; + + my $group = group_load($group_path); + + my $g = group_lookup_name($group, $groupname); + die("group[$groupname] does not exists in '$group_path'") unless defined($g); + + my $passwd = passwd_load($passwd_path); + + my $u = passwd_lookup_name($passwd, $username); + die("account[$username] does not exists in '$passwd_path'") unless defined($u); + + group_delete_member($group, $g, $username); + + group_save($group); + + return 0; +} |