summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-05-28 22:12:00 +1000
committerAndrew Tridgell <tridge@samba.org>2009-05-28 22:12:00 +1000
commit67b83d2489788f1899c253fdab554d0998f9c044 (patch)
tree637060cb6bd4ab16fa9464d2bc168ad6c99e0b11 /lib
parent08be1420ba52ef9bba90d0f811c7810841ee8568 (diff)
parente63d9c29c99c5311c9f4a8dbe432ff4cea4fb924 (diff)
downloadsamba-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')
-rw-r--r--lib/nss_wrapper/nss_wrapper.c242
-rw-r--r--lib/nss_wrapper/nss_wrapper.pl197
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;
+}