diff options
-rw-r--r-- | lib/nss_wrapper/nss_wrapper.c | 242 | ||||
-rw-r--r-- | lib/nss_wrapper/nss_wrapper.pl | 197 | ||||
-rw-r--r-- | selftest/target/Samba3.pm | 12 | ||||
-rw-r--r-- | source3/include/passdb.h | 34 | ||||
-rw-r--r-- | source3/include/proto.h | 6 | ||||
-rw-r--r-- | source3/include/smbldap.h | 2 | ||||
-rw-r--r-- | source3/lib/smbldap.c | 20 | ||||
-rw-r--r-- | source3/lib/util_sid.c | 16 | ||||
-rw-r--r-- | source3/lib/util_str.c | 7 | ||||
-rw-r--r-- | source3/lib/util_uuid.c | 4 | ||||
-rw-r--r-- | source3/libads/ldap.c | 14 | ||||
-rw-r--r-- | source3/libads/ldap_schema.c | 4 | ||||
-rw-r--r-- | source3/nmbd/nmbd_processlogon.c | 2 | ||||
-rw-r--r-- | source3/passdb/pdb_interface.c | 6 | ||||
-rwxr-xr-x | source3/script/tests/selftest.sh | 12 | ||||
-rw-r--r-- | source3/winbindd/idmap_ad.c | 8 | ||||
-rw-r--r-- | source3/winbindd/winbindd_ads.c | 14 |
17 files changed, 421 insertions, 179 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; +} diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 30453f2e9b..95d2a8253f 100644 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -458,11 +458,13 @@ sub provision($$$$$$) time server = yes - add user script = $nss_wrapper_pl --path $nss_wrapper_passwd --type passwd --action add --name %u - add group script = $nss_wrapper_pl --path $nss_wrapper_group --type group --action add --name %g - add machine script = $nss_wrapper_pl --path $nss_wrapper_passwd --type passwd --action add --name %u - delete user script = $nss_wrapper_pl --path $nss_wrapper_passwd --type passwd --action delete --name %u - delete group script = $nss_wrapper_pl --path $nss_wrapper_group --type group --action delete --name %g + add user script = $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action add --name %u + add group script = $nss_wrapper_pl --group_path $nss_wrapper_group --type group --action add --name %g + add machine script = $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action add --name %u + add user to group script = $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type member --action add --member %u --name %g --group_path $nss_wrapper_group + delete user script = $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action delete --name %u + delete group script = $nss_wrapper_pl --group_path $nss_wrapper_group --type group --action delete --name %g + delete user from group script = $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type member --action delete --member %u --name %g --group_path $nss_wrapper_group kernel oplocks = no kernel change notify = no diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 9cbc6bd340..03d9f56c5a 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -5,17 +5,17 @@ Copyright (C) Luke Kenneth Casson Leighton 1998 - 2000 Copyright (C) Andrew Bartlett 2002 Copyright (C) Simo Sorce 2003 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -118,7 +118,7 @@ struct samu { time_t pass_last_set_time; /* password last set time */ time_t pass_can_change_time; /* password can change time */ time_t pass_must_change_time; /* password must change time */ - + const char *username; /* UNIX username string */ const char *domain; /* Windows Domain name */ const char *nt_username; /* Windows username string */ @@ -131,22 +131,22 @@ struct samu { const char *workstations; /* login from workstations string */ const char *comment; const char *munged_dial; /* munged path name and dial-back tel number */ - + DOM_SID user_sid; DOM_SID *group_sid; - + DATA_BLOB lm_pw; /* .data is Null if no password */ DATA_BLOB nt_pw; /* .data is Null if no password */ DATA_BLOB nt_pw_his; /* nt hashed password history .data is Null if not available */ char* plaintext_pw; /* is Null if not available */ - + uint32 acct_ctrl; /* account info (ACB_xxxx bit-mask) */ uint32 fields_present; /* 0x00ff ffff */ - + uint16 logon_divs; /* 168 - number of hours in a week */ uint32 hours_len; /* normally 21 bytes */ uint8 hours[MAX_HOURS_LEN]; - + /* Was unknown_5. */ uint16 bad_password_count; uint16 logon_count; @@ -158,7 +158,7 @@ struct samu { const struct pdb_methods *backend_private_methods; void *backend_private_data; void (*backend_private_data_free_fn)(void **); - + /* maintain a copy of the user's struct passwd */ struct passwd *unix_pw; @@ -221,7 +221,7 @@ struct pdb_methods const char *name; /* What name got this module */ NTSTATUS (*getsampwnam)(struct pdb_methods *, struct samu *sam_acct, const char *username); - + NTSTATUS (*getsampwsid)(struct pdb_methods *, struct samu *sam_acct, const DOM_SID *sid); NTSTATUS (*create_user)(struct pdb_methods *, TALLOC_CTX *tmp_ctx, @@ -230,15 +230,15 @@ struct pdb_methods NTSTATUS (*delete_user)(struct pdb_methods *, TALLOC_CTX *tmp_ctx, struct samu *sam_acct); - + NTSTATUS (*add_sam_account)(struct pdb_methods *, struct samu *sampass); - + NTSTATUS (*update_sam_account)(struct pdb_methods *, struct samu *sampass); - + NTSTATUS (*delete_sam_account)(struct pdb_methods *, struct samu *username); - + NTSTATUS (*rename_sam_account)(struct pdb_methods *, struct samu *oldname, const char *newname); - + NTSTATUS (*update_login_attempts)(struct pdb_methods *methods, struct samu *sam_acct, bool success); NTSTATUS (*getgrsid)(struct pdb_methods *methods, GROUP_MAP *map, DOM_SID sid); @@ -378,7 +378,7 @@ struct pdb_methods struct trustdom_info ***domains); void *private_data; /* Private data of some kind */ - + void (*free_private_data)(void **); }; diff --git a/source3/include/proto.h b/source3/include/proto.h index 342c1432eb..2217b3315b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1298,7 +1298,7 @@ int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2); int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2); bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2); bool non_mappable_sid(DOM_SID *sid); -char *sid_binstring(const DOM_SID *sid); +char *sid_binstring(TALLOC_CTX *mem_ctx, const DOM_SID *sid); char *sid_binstring_hex(const DOM_SID *sid); DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src); NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid, @@ -1502,7 +1502,7 @@ void strupper_m(char *s); size_t strlen_m(const char *s); size_t strlen_m_term(const char *s); size_t strlen_m_term_null(const char *s); -char *binary_string_rfc2254(char *buf, int len); +char *binary_string_rfc2254(TALLOC_CTX *mem_ctx, const uint8_t *buf, int len); char *binary_string(char *buf, int len); int fstr_sprintf(fstring s, const char *fmt, ...); bool str_list_sub_basic( char **list, const char *smb_name, @@ -1595,7 +1595,7 @@ int islower_ascii(int c); void smb_uuid_pack(const struct GUID uu, UUID_FLAT *ptr); void smb_uuid_unpack(const UUID_FLAT in, struct GUID *uu); -char *guid_binstring(const struct GUID *guid); +char *guid_binstring(TALLOC_CTX *mem_ctx, const struct GUID *guid); /* The following definitions come from lib/version.c */ diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 3ac770a548..c28d43d53b 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -214,6 +214,8 @@ char * smbldap_talloc_single_attribute(LDAP *ldap_struct, LDAPMessage *entry, char * smbldap_talloc_smallest_attribute(LDAP *ldap_struct, LDAPMessage *entry, const char *attribute, TALLOC_CTX *mem_ctx); +bool smbldap_pull_sid(LDAP *ld, LDAPMessage *msg, const char *attrib, + struct dom_sid *sid); void talloc_autofree_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result); void talloc_autofree_ldapmod(TALLOC_CTX *mem_ctx, LDAPMod **mod); char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld, diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 4360d3ab57..b6921c329c 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -389,6 +389,26 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { return result; } + bool smbldap_pull_sid(LDAP *ld, LDAPMessage *msg, const char *attrib, + struct dom_sid *sid) +{ + struct berval **values; + bool ret = False; + + values = ldap_get_values_len(ld, msg, attrib); + + if (!values) { + return false; + } + + if (values[0] != NULL) { + ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); + } + + ldap_value_free_len(values); + return ret; +} + static int ldapmsg_destructor(LDAPMessage **result) { ldap_msgfree(*result); return 0; diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 97284afae7..9e5d4d38a5 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -520,16 +520,18 @@ bool non_mappable_sid(DOM_SID *sid) Caller must free. *****************************************************************/ -char *sid_binstring(const DOM_SID *sid) +char *sid_binstring(TALLOC_CTX *mem_ctx, const DOM_SID *sid) { - char *buf, *s; + uint8_t *buf; + char *s; int len = ndr_size_dom_sid(sid, NULL, 0); - buf = (char *)SMB_MALLOC(len); - if (!buf) + buf = talloc_array(mem_ctx, uint8_t, len); + if (!buf) { return NULL; - sid_linearize(buf, len, sid); - s = binary_string_rfc2254(buf, len); - free(buf); + } + sid_linearize((char *)buf, len, sid); + s = binary_string_rfc2254(mem_ctx, buf, len); + TALLOC_FREE(buf); return s; } diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 3a941f2c21..cdd7d0a300 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1529,14 +1529,15 @@ size_t strlen_m_term_null(const char *s) Caller must free. **/ -char *binary_string_rfc2254(char *buf, int len) +char *binary_string_rfc2254(TALLOC_CTX *mem_ctx, const uint8_t *buf, int len) { char *s; int i, j; const char *hex = "0123456789ABCDEF"; - s = (char *)SMB_MALLOC(len * 3 + 1); - if (!s) + s = talloc_array(mem_ctx, char, len * 3 + 1); + if (s == NULL) { return NULL; + } for (j=i=0;i<len;i++) { s[j] = '\\'; s[j+1] = hex[((unsigned char)buf[i]) >> 4]; diff --git a/source3/lib/util_uuid.c b/source3/lib/util_uuid.c index c681b66d34..656ba2a57c 100644 --- a/source3/lib/util_uuid.c +++ b/source3/lib/util_uuid.c @@ -43,11 +43,11 @@ void smb_uuid_unpack(const UUID_FLAT in, struct GUID *uu) Caller must free. *****************************************************************/ -char *guid_binstring(const struct GUID *guid) +char *guid_binstring(TALLOC_CTX *mem_ctx, const struct GUID *guid) { UUID_FLAT guid_flat; smb_uuid_pack(*guid, &guid_flat); - return binary_string_rfc2254((char *)guid_flat.info, UUID_FLAT_SIZE); + return binary_string_rfc2254(mem_ctx, guid_flat.info, UUID_FLAT_SIZE); } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 588c0a131c..3e5764a598 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2619,19 +2619,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) bool ads_pull_sid(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, DOM_SID *sid) { - struct berval **values; - bool ret = False; - - values = ldap_get_values_len(ads->ldap.ld, msg, field); - - if (!values) - return False; - - if (values[0]) - ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); - - ldap_value_free_len(values); - return ret; + return smbldap_pull_sid(ads->ldap.ld, msg, field, sid); } /** diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index b5d2d35889..a841fbdca8 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -122,7 +122,7 @@ const char *ads_get_attrname_by_guid(ADS_STRUCT *ads, goto done; } - guid_bin = guid_binstring(schema_guid); + guid_bin = guid_binstring(mem_ctx, schema_guid); if (!guid_bin) { goto done; } @@ -145,7 +145,7 @@ const char *ads_get_attrname_by_guid(ADS_STRUCT *ads, result = ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); done: - SAFE_FREE(guid_bin); + TALLOC_FREE(guid_bin); ads_msgfree(ads, res); return result; diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index 43e80af394..4a993c9d83 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -187,7 +187,7 @@ static void nmbd_proxy_logon(struct nmbd_proxy_logon_context *ctx, (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("failed parse nbt_letlogon_packet: %s\n", + DEBUG(0,("failed parse nbt_netlogon_packet: %s\n", nt_errstr(status))); TALLOC_FREE(state); return; diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 340867a5a6..b4e1bd436c 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1711,7 +1711,7 @@ static NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods, static int pdb_search_destructor(struct pdb_search *search) { - if (!search->search_ended) { + if ((!search->search_ended) && (search->search_end != NULL)) { search->search_end(search); } return 0; @@ -1733,6 +1733,7 @@ struct pdb_search *pdb_search_init(TALLOC_CTX *mem_ctx, result->num_entries = 0; result->cache_size = 0; result->search_ended = False; + result->search_end = NULL; /* Segfault appropriately if not initialized */ result->next_entry = NULL; @@ -2021,7 +2022,8 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods ) { /* allocate memory for the structure as its own talloc CTX */ - if ( !(*methods = TALLOC_ZERO_P(talloc_autofree_context(), struct pdb_methods) ) ) { + *methods = talloc_zero(talloc_autofree_context(), struct pdb_methods); + if (*methods == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh index 1f3ad761b2..956c5af77b 100755 --- a/source3/script/tests/selftest.sh +++ b/source3/script/tests/selftest.sh @@ -216,11 +216,13 @@ cat >$SERVERCONFFILE<<EOF lanman auth = yes time server = yes - add user script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --path $NSS_WRAPPER_PASSWD --type passwd --action add --name %u - add group script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --path $NSS_WRAPPER_GROUP --type group --action add --name %g - add machine script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --path $NSS_WRAPPER_PASSWD --type passwd --action add --name %u - delete user script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --path $NSS_WRAPPER_PASSWD --type passwd --action delete --name %u - delete group script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --path $NSS_WRAPPER_GROUP --type group --action delete --name %g + add user script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --passwd_path $NSS_WRAPPER_PASSWD --type passwd --action add --name %u + add group script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --group_path $NSS_WRAPPER_GROUP --type group --action add --name %g + add user to group script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --group_path $NSS_WRAPPER_GROUP --type member --action add --name %g --member %u --passwd_path $NSS_WRAPPER_PASSWD + add machine script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --passwd_path $NSS_WRAPPER_PASSWD --type passwd --action add --name %u + delete user script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --passwd_path $NSS_WRAPPER_PASSWD --type passwd --action delete --name %u + delete group script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --group_path $NSS_WRAPPER_GROUP --type group --action delete --name %g + delete user from group script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --group_path $NSS_WRAPPER_GROUP --type member --action delete --name %g --member %u --passwd_path $NSS_WRAPPER_PASSWD kernel oplocks = no kernel change notify = no diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c index 5c29ba0b22..3791a86876 100644 --- a/source3/winbindd/idmap_ad.c +++ b/source3/winbindd/idmap_ad.c @@ -570,10 +570,10 @@ again: ids[idx]->status = ID_UNKNOWN; - sidstr = sid_binstring(ids[idx]->sid); + sidstr = sid_binstring(talloc_tos(), ids[idx]->sid); filter = talloc_asprintf_append_buffer(filter, "(objectSid=%s)", sidstr); - free(sidstr); + TALLOC_FREE(sidstr); CHECK_ALLOC_DONE(filter); } filter = talloc_asprintf_append_buffer(filter, "))"); @@ -894,9 +894,9 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e, attrs[2] = ctx->ad_schema->posix_gecos_attr; attrs[3] = ctx->ad_schema->posix_gidnumber_attr; - sidstr = sid_binstring(sid); + sidstr = sid_binstring(mem_ctx, sid); filter = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr); - SAFE_FREE(sidstr); + TALLOC_FREE(sidstr); if (!filter) { nt_status = NT_STATUS_NO_MEMORY; diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index dcf5623d29..0f40419a0e 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -524,14 +524,14 @@ static NTSTATUS query_user(struct winbindd_domain *domain, goto done; } - sidstr = sid_binstring(sid); + sidstr = sid_binstring(talloc_tos(), sid); if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { status = NT_STATUS_NO_MEMORY; goto done; } rc = ads_search_retry(ads, &msg, ldap_exp, attrs); free(ldap_exp); - free(sidstr); + TALLOC_FREE(sidstr); if (!ADS_ERR_OK(rc) || !msg) { DEBUG(1,("query_user(sid=%s) ads_search: %s\n", sid_string_dbg(sid), ads_errstr(rc))); @@ -1011,21 +1011,19 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, goto done; } - if ((sidbinstr = sid_binstring(group_sid)) == NULL) { + if ((sidbinstr = sid_binstring(talloc_tos(), group_sid)) == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } /* search for all members of the group */ - if (!(ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)", - sidbinstr))) - { - SAFE_FREE(sidbinstr); + ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)", sidbinstr); + TALLOC_FREE(sidbinstr); + if (ldap_exp == NULL) { DEBUG(1, ("ads: lookup_groupmem: talloc_asprintf for ldap_exp failed!\n")); status = NT_STATUS_NO_MEMORY; goto done; } - SAFE_FREE(sidbinstr); args.control = ADS_EXTENDED_DN_OID; args.val = ADS_EXTENDED_DN_HEX_STRING; |